1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-30 21:28:11 +00:00
Commit graph

217 commits

Author SHA1 Message Date
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
3bd29ad98c LibHTML: Remove trailing whitespace in line boxes
After the splitting-into-lines pass, remove any trailing whitespace
from all of a block's line boxes.

This improves the appearance of text-align: justify/right :^)
2019-10-20 17:20:20 +02:00
Andreas Kling
eb77e680ed LibHTML: Implement "text-align: justify"
In order for this to work nicely, I made the line box classes use float
instead of int for its geometry information.

Justification works by distributing all of the whitespace on the line
(including the trailing whitespace before the line break) evenly across
the spaces in-between words.

We should probably use floating point (or maybe fixed point?) for all
the layout metrics stuff. But one thing at a time. :^)
2019-10-20 12:55:55 +02:00
Andreas Kling
ea5da0f9b5 LibHTML: The CSS parser should tolerate whitespace-only stylesheets 2019-10-20 12:55:55 +02:00
Andreas Kling
457e49f528 LibHTML: Rename HTMLImageElement::m_image_loader => m_image_decoder
This matches the new class name, ImageDecoder.
2019-10-20 12:55:55 +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
64ce453050 LibHTML: Only actually-linked <a> elements should be blue+underlined
Turns out this just needed a little push in the selector engine. :^)
2019-10-20 10:07:26 +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
202dfbd6cd LibHTML: Add Element::name() convenience attribute getter 2019-10-20 10:07:26 +02:00
Andreas Kling
8b07025145 LibHTML: Don't insert unnecessary line breaks at start of text lines
Basically the same exact fix as I did for replaced elements. There's no
point in inserting a line break at the start of a line if all you're
trying to achieve is make more horizontal space for something.
2019-10-19 21:34:15 +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
73af2f8d02 LibHTML: DOM fixup should handle a completely empty document
We were forgetting to check if there was even a first child of the
root Document node.
2019-10-19 21:20:42 +02:00
Andreas Kling
b472229781 LibHTML: Do DOM tree fixup before firing insertion callbacks
There's no reason to run the callbacks before fixing up the tree.
2019-10-19 20:54:47 +02:00
Andreas Kling
f970578cd4 LibDraw: Rename ImageLoader => ImageDecoder
ImageLoader was not the right name for this, as there is no loading
happening, only decoding. :^)
2019-10-19 20:54:47 +02:00
Andreas Kling
025d3b49ab LibHTML: Make "display: inline-block" generate a LayoutBlock for now
We're gonna need some more smarts for this, but this at least gives
us something instead of an assertion.
2019-10-19 19:02:02 +02:00
Andreas Kling
96f34d26c9 LibHTML: Batch style updates and make them start from the root
Use a zero-timer to schedule a style update after invalidating style
on any node. Nodes now have a needs_style_update flag which helps us
batch and coalesce the work.

We also start style updates at the root and work our way through the
document, updating any node that has the needs_style_update flag set.
This is slower than what we were doing before, but far more correct.

There is a ton of room for improvement here. :^)
2019-10-19 19:00:31 +02:00
Andreas Kling
b3a63e1d50 LibHTML: Add TreeNode<T>::for_each_in_subtree(callback)
This helper invokes a callback for the node and each of its descendants
in pre-order.
2019-10-19 18:14:54 +02:00
Andreas Kling
fed668f20f LibHTML: Skip over CSS @media rules for now 2019-10-19 17:39:38 +02:00
Andreas Kling
6cbf8a3426 LibHTML: Use the correct inherited color for LayoutListItemMarker 2019-10-19 11:54:28 +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
762f20944c LibHTML: Replaced elements should not break lines at start of line
If the current line box already has zero width, there's no point in
inserting a line break to make space, since we'll just be at x=0 after
breaking as well.

This removes an ugly unnecessary line break before images wider than
their containing block. :^)
2019-10-19 09:44:40 +02:00
Andreas Kling
a5f3f332ed LibHTML: Ignore completed image loads for already-destroyed <img>'s
Capture a weak pointer to the element and pass that to the load finish
callback in HTMLImageElement::load_image(). This allows us to ignore
completed loads if the <img> element is no longer around.
2019-10-19 09:43:05 +02:00
Andreas Kling
877ff6bc13 LibHTML: Make TreeNode inherit from Weakable by default
This makes Node and LayoutNode weakable. Frame was already weakable.
2019-10-19 09:42:20 +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
60be51f908 LibHTML: Add a simple font cache
The FontCache caches the result of font lookups. The cache key is a
simple object called FontSelector which consists of the font family
and font weight (both strings.)

This drastically reduces time spent in font lookup.
2019-10-18 23:06:03 +02:00
Andreas Kling
07cbe2daa4 LibHTML: Preserve UTF-8 codepoints when collapsing whitespace
This is extremely awkward and I'm sure there are many better ways to
achieve this..
2019-10-18 22:50:44 +02:00
Andreas Kling
39546303da LibHTML: CSS parser should trim whitespace from values
This makes sure that values like "auto !important" don't have a space
character after "auto".
2019-10-18 17:14:25 +02:00
Andreas Kling
2305dee455 LibHTML: Add LayoutNode::first_ancestor_of_type<T>() 2019-10-18 10:16:33 +02:00
Andreas Kling
65ad6c35f0 LibHTML: Add typed child/sibling traversal helpers for LayoutNode
Also add some special variants for the table classes, to make it a bit
more pleasant to write table code. :^)
2019-10-18 09:38:12 +02:00
Andreas Kling
6202a0ab32 LibHTML: Only accumulate Text children's content in inline stylesheets
Some inline stylesheets use HTML comments like "<!--blah blah-->".
The HTML parser currently generates a comment child node of the <style>
element whenever this happens, and we don't want the comment itself to
be interpreted as part of the stylesheet.
2019-10-17 23:54:27 +02:00
Andreas Kling
9ac7b6fad1 LibHTML: Don't assert when encountering an unknown font-weight 2019-10-17 23:54:19 +02:00
Andreas Kling
6c22b46b37 LibHTML: Hard-code LayoutTable to never have inline children
This is a total hack to get around the auto-detection mechanism for
whether a block has inline or block children. We'll say that tables
never have inline children for now, and then anything that actually
turns out to be an inline child will just be ignored by layout.
2019-10-17 23:39:31 +02:00
Andreas Kling
b4c2621ed7 LibHTML: Add is<T> helpers for the table-related LayoutNode subclasses 2019-10-17 23:39:31 +02:00
Andreas Kling
5e29238a49 LibHTML: Make "children are inline" flag imperative
Instead of computing whether a block's children are inline based on the
first child, make it an imperatively-set flag.

This gives us some flexibility to ignore things like text nodes inside
a <table>, for example. I'm still unsure what the "correct" way to deal
with those will be. We'll find out sooner or later. :^)
2019-10-17 23:39:31 +02:00
Andreas Kling
41896ff521 LibHTML: Add stub classes for basic table layout
This class introduces LayoutTable, LayoutTableRow and LayoutTableCell.
These are produced by "display" values table, table-row and table-cell
respectively.

Note that there's no layout happening yet, I'm just adding the classes.
2019-10-17 23:39:31 +02:00
Andreas Kling
14f380f87a LibHTML: Use is_inline() instead of !is_block() when building tree 2019-10-17 23:39:31 +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
06f084fedd LibHTML: Add the <center> element
This is really just "center { display: block; text-align: center; }" in
the default stylesheet, but it totally works!
2019-10-16 20:33:00 +02:00
Andreas Kling
6dbba6ad85 LibHTML: Implement CSS text-align: left/center/right
This was easier than I imagined; we just shift each line box to the
left based on the alignment and the remaining space on each line. :^)
2019-10-16 20:32:17 +02:00
Andreas Kling
38b55ee067 LibHTML: LayoutBlock::hit_test() was calling the wrong parent class
Oops, we now need to call LayoutBox instead of LayoutNode for blocks
with non-inline children.
2019-10-15 22:02:58 +02:00
Andreas Kling
18fa662eb2 LibHTML: Use ImageLoader for <img> elements to defer bitmap decoding
We now wait until the pixels are actually needed before fully decoding
images in <img> elements.

This needs some more work and is currently a bit memory-wasteful since
we'll hang on to the raw image data forever.
2019-10-15 21:53:08 +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
5c2b21705a LibHTML: LayoutNode::set_needs_display() needs to invalidate fragments
If a LayoutNode is split into line box fragments, we need to walk our
fragments and invalidate them. It was not enough to do this only for
LayoutBox nodes.
2019-10-15 20:45:52 +02:00
Andreas Kling
110b2d52f2 LibHTML: Fix missing backgrounds an borders after LayoutBox refactoring
The render() implementation in both LayoutBlock and LayoutBox need to
be calling the immediate parent class. :^)
2019-10-15 19:12:56 +02:00
Andreas Kling
4814253589 LibHTML: Introduce LayoutBox and LayoutNodeWithStyleAndBoxModelMetrics
To streamline the layout tree and remove irrelevant data from classes
that don't need it, this patch adds two new LayoutNode subclasses.

LayoutNodeWithStyleAndBoxModelMetrics should be inherited by any layout
node that cares about box model metrics (margin, border, and padding.)
LayoutBox should be inherited by any layout node that can have a rect.

This makes LayoutText significantly smaller (from 140 to 40 bytes) and
clarifies a lot of things about the layout tree.

I'm also adding next_sibling() and previous_sibling() overloads to
LayoutBlock that return a LayoutBlock*. This is okay since blocks only
ever have block siblings.

Do also note that the semantics of is<T> slightly change in this patch:
is<T>(nullptr) now returns true, to facilitate allowing to<T>(nullptr).
2019-10-15 16:48:38 +02:00
Andreas Kling
f4f5ede10a LibHTML: Simplify Node::create_layout_node()
There's no need to pass the StyleResolver to this function. Nodes that
need it can just get it from the document.
2019-10-15 15:06:16 +02:00
Andreas Kling
f7cd5662ef LibHTML: Move layout tree building to a LayoutTreeBuilder class
Building a whole layout tree shouldn't be a concern of Node, so this
patch moves it to a separate class.
2019-10-15 14:24:26 +02:00
Andreas Kling
d14b60533f LibHTML: Add is<T> and to<T> helpers for LayoutNode class family 2019-10-15 14:24:26 +02:00