Commit graph

42 commits

Author SHA1 Message Date
Andreas Kling
f6439789db LibHTML: Rename parse_html() => parse_html_document() 2019-11-06 20:31:56 +01:00
Andreas Kling
f3f0b08d43 LibHTML: Build some foundation for text selection
Add LayoutPosition and LayoutRange classes. The layout tree root node
now has a selection() LayoutRange. It's essentially a start and end
LayoutPosition.

A LayoutPosition is a LayoutNode, and an optional index into that node.
The index is only relevant for text nodes, where it's the character
index into the rendered text.

HtmlView now updates the selection start/end of the LayoutDocument when
clicking and dragging with the left mouse button.

We don't paint the selection yet, and there's no way to copy what's
selected. It only exists as a LayoutRange.
2019-11-05 22:13:26 +01:00
Andreas Kling
04b94a7695 LibHTML: <a href="#foo"> should prefer any element type with id=foo
It turns out that other engines also prefer <h1 id=x> over <a name=x>.
So we can just use get_element_by_id() directly without worrying about
the type of element we find.
2019-10-21 12:14:00 +02:00
Andreas Kling
8e710b16de LibHTML: Clicking on a fragment link should prefer <a id> over <a name>
It turns out that other engines prefer <a id> over <a name> when
deciding which anchor element to jump to.

This patch aligns LibHTML's behavior with WebKit and Gecko.

Thanks to "/cam 2" for bringing this up. :^)
2019-10-21 12:04:17 +02:00
Andreas Kling
4d9740ecef LibHTML: Add Document::get_element_by_id() and get_elements_by_name()
These will be useful for implementing various things. They don't do any
caching at the moment, but that might become valuable in the future.

To facilitate this change, I also made it possible to abort a tree walk
with for_each_in_subtree() by returning IterationDecision::Break from
the callback.
2019-10-21 12:01:30 +02:00
Andreas Kling
f11c85f4a7 LibHTML: HtmlView only needs to store the main Frame, not the Document
Remove the Document pointer from HtmlView and always get to it through
the main Frame instead.

The idea here is to move towards HtmlView being higher-level than the
DOM stuff (as much as possible and practical.)
2019-10-20 10:36:14 +02:00
Andreas Kling
c41bae3d54 LibHTML+Browser: Support scrolling to anchor with <a href="#foo">
This patch implements basic support for <a href="#foo"> fragment links.

To figure out where we actually want to scroll to, we have to do
something different based on the layout node's box type. So if it's a
regular LayoutBox we can just use the LayoutBox::position().

However, if it's an inline layout node, we use the position of the
first line box fragment in the containing block contributed by this
layout node or one of its descendants.
2019-10-20 10:07:26 +02:00
Andreas Kling
884ae80699 LibHTML+Browser: Show target URL of hovered links in Browser statusbar
HtmlView will now invoke the on_link_hover hook when the cursor enters
or leaves a DOM node that has an enclosing link element.

This patch also updates the meaning of Node::enclosing_link_element()
to find the nearest HTMLAnchorElementAncestor *with an href attribute*.
2019-10-19 21:25:49 +02:00
Andreas Kling
5a34225999 LibHTML: Implement basic tiled background image support
It's now possible to set a page background image via <body background>.
Also, HtmlView now officially handles rendering the body element's
background (color, image or both.) LayoutBox is responsible for all
other background rendering.

Note that it's not yet possible to use CSS background-image properties
directly, since we can't parse them yet. :^)
2019-10-19 11:49:46 +02:00
Andreas Kling
87d13930ef LibHTML: Allow loading of PNG's directly into the HtmlView
When loading a URL that ends in ".png", we now construct a simple
DOM document to contain the image. It also shows the image dimensions
in the document title.

Because we use <img src> to load the image into the synthetic document,
we end up loading the image resource twice. This issue will go away
once we have a smarter, caching, loader mechanism.
2019-10-19 09:31:52 +02:00
Andreas Kling
775cbbb422 LibHTML: Add basic keyboard navigation (up/down/pgdn/pgup/home/end/etc) 2019-10-17 23:39:31 +02:00
Andreas Kling
b4c0ea89d5 LibHTML: Add the currently visible viewport rect to RenderingContext
This will allow rendering code to skip various things sometimes. :^)
2019-10-15 21:52:01 +02:00
Andreas Kling
667b31746a LibHTML: Rename Document's invalidate_{style,layout}() to update_foo() 2019-10-14 17:57:06 +02:00
Andreas Kling
3309bdf722 LibHTML: Add some convenient geometry getters on LayoutNode
Add x(), y(), size() and position() and use them around the codebase.
2019-10-13 18:47:16 +02:00
Andreas Kling
0e61d84749 LibHTML: Run second layout pass if first layout adds/removes scrollbars
If you do a layout and it turns out that the page contents don't fit in
the viewport vertically, we add a vertical scrollbar. Since the
scrollbar takes up some horizontal space, this reduces the amount of
space available to the page. So we have to do a second layout pass. :^)

Fixes #650.
2019-10-13 16:31:31 +02:00
Andreas Kling
49ac0c2e24 LibHTML: Move layout root from HtmlView to Document
The layout root is now kept alive via Document::m_layout_root.
This will allow us to do more layout-related things inside the inner
layer of LibHTML without reaching out to the HtmlView.

I'd like to keep HtmlView at a slightly higher level, to prevent it
from getting too complex.

This patch also fixes accidental disconnection of the layout tree from
the DOM after doing a layout tree rebuild. ~LayoutNode() now only
unsets the DOM node's layout_node() if it's itself.
2019-10-13 12:43:31 +02:00
Andreas Kling
2530378f59 LibHTML+Browser: Add debug option to draw borders around line boxes
This will be very useful when debugging line layout.
2019-10-12 15:02:53 +02:00
Andreas Kling
c294c97cdf LibHTML: Show a hand cursor when hovering over a clickable link :^) 2019-10-10 21:35:50 +02:00
Andreas Kling
c458327429 LibHTML: Tear down the layout tree before changing the Frame's document
We don't want to deal with document().frame() being null inside layout
tree code, so this makes sure we tear it down before the frame has a
chance to get nulled out.
2019-10-09 21:53:39 +02:00
Andreas Kling
fdbad6284c LibHTML: Implement the <blink> element
Just in time for Serenity's 1st birthday, here is the <blink> element!

This patch adds a bunch of different mechanisms to enable partial
repaints of the layout tree (LayoutNode::set_needs_display()))
It also adds LayoutNode::is_visible(), which can be toggled to prevent
a LayoutNode from rendering anything (it still takes up space though.)
2019-10-09 21:25:29 +02:00
Andreas Kling
850955053f LibHTML: Rename Document::normalize() to fixup() and always do it
Node.normalize() is a standard DOM API that coalesces Text nodes.
To avoid clashing with that, rename it to fixup().

This patch also makes it happen automagically as part of parsing.
2019-10-09 18:54:34 +02:00
Andreas Kling
3be6d1aff0 LibHTML: Add ResourceLoader to support protocol-agnostic URL loading
We now support loading both file:// and http:// URLs. Feel free to
visit http://www.serenityos.org/ and enjoy the fancy good times. :^)
2019-10-08 19:37:15 +02:00
Andreas Kling
6287c2b270 LibHTML: Don't crash when calling set_document(nullptr) 2019-10-07 19:33:06 +02:00
Andreas Kling
edbf09ea29 LibHTML: Make the CSS and HTML parsers take StringViews
This allows us to avoid unnecessary making unnecessary String copies of
all the source text.
2019-10-07 19:11:33 +02:00
Andreas Kling
71e8ddcd1c LibHTML: Start adding support for <link rel="stylesheet">
This patch adds basic support for external stylesheets. It currently
only works with file:// URLs.

We do a synchronous full relayout after loading a stylesheet, which is
definitely on the aggressive side, but it gives us something to work
on improving. :^)
2019-10-07 19:06:47 +02:00
Andreas Kling
66caa7af2b LibHTML: Optionally pass document URL to the HTML parser
This makes the document URL available to all the parse_attributes()
callbacks, in case they need it for anything.
2019-10-06 21:13:24 +02:00
Conrad Pankoff
ef8b754a46 LibHTML: Add function for invalidating the document layout
This allows any external actor to signal that the document layout may be
stale. This can be used when loading resources, changing the size or
placement of an element, adding/removing nodes, or really any time.
2019-10-06 14:33:00 +02:00
Andreas Kling
56d1ae98bc LibHTML: Always fill the entire paint event rect with background
And do the filling before translating the painter.

This fixes a bug where scrolling down in the Help app would render the
bottom part of the page with a different background color.
2019-10-05 21:53:09 +02:00
Andreas Kling
a8297657ab LibHTML: Fire the HtmlView::on_title_change hook after a load finishes 2019-10-05 10:30:14 +02:00
Andreas Kling
78d65c1c64 LibHTML: Add load(URL) and reload() functions to HtmlView
You can now pass a file:/// URL to HtmlView and it will take care of
the loading logic for you. Each Document remembers the URL it was
loaded from, which allows us to also have reload().

This patch also adds a very simple function for resolving relative
URL's into absolute ones.
2019-10-05 10:17:33 +02:00
Andreas Kling
9808d35554 LibHTML: Add support for <body bgcolor="#rrggbb" text="#rrggbb">
This patch implements basic support for presentational hints, which are
old-school HTML attributes that affect style.

You add support for a presentational hint attribute by overriding
Element::apply_presentational_hints(StyleProperties&) and setting all
of the corresponding CSS properties as appropriate.

To make the background color fill the entire document, not just the
bounds of the <body> element's LayoutNode, we special-case it in the
HtmlView::paint_event() code for now. I'm not entirely sure what the
nicest solution would be, but I'm sure we'll discover it eventually.
2019-10-04 21:05:52 +02:00
Andreas Kling
7bc9310170 LibHTML: Add a Frame class and use it for document layout width
Each HtmlView now has a main_frame(), which represents the main frame
of the web page. Frame inherits from TreeNode<Frame>, which will allow
us to someday implement a Frame tree (to support the <frame> element.)
2019-10-04 15:50:04 +02:00
Andreas Kling
5966fcff31 LibHTML: Reduce debug spam from mouse events 2019-10-03 14:52:36 +02:00
Andreas Kling
9290117b77 LibHTML: Let's put debug output on the debugger stream 2019-10-03 10:25:34 +02:00
Andreas Kling
786494b62d LibHTML: Adjust mouse event positions before using them for hit testing
This fixes the issue where you couldn't click on links at the bottom of
scrollable documents. :^)
2019-10-03 09:17:27 +02:00
Andreas Kling
c9bab8b870 LibHTML: Reduce debug spam in HtmlView mouse event handlers 2019-09-29 18:10:39 +02:00
Andreas Kling
f38b0f667e LibHTML: Implement basic HTMLElement.title support
We now show a tooltip for the hovered node's enclosing HTML element's
title attribute, if one is present.

This patch also adds HTMLHeadingElement. The tags h1-h6 will now create
the right kind of objects.
2019-09-29 12:26:13 +02:00
Andreas Kling
92aae72025 LibHTML: Detect link clicks
Clicking on a link in an HtmlView will now call on_link_click(String)
if present, allowing you to implement basic hypertext navigation. :^)
2019-09-29 12:04:02 +02:00
Andreas Kling
b477aff843 LibHTML: Detect hovering over links
HtmlView now calls Node::enclosing_link_element() to find the nearest
ancestor <a> element.

This patch also adds HTMLElement and HTMLAnchorElement.
2019-09-29 11:59:38 +02:00
Andreas Kling
88de955073 LibHTML: Have Document track its hovered Node
This gets set from HtmlView::mousemove_event() at the moment.
2019-09-29 11:50:35 +02:00
Andreas Kling
3de4b99dc3 LibHTML: Implement naive hit testing
We don't have proper line boxes yet, so we can't easily hit test
inline text.
2019-09-28 23:04:59 +02:00
Sergey Bugaev
b9493ba783 LibHTML: Introduce the HtmlView widget
This is a GWidget that can display contents of an HTML document.
It replaces the Frame class.
2019-09-28 18:29:42 +02:00