Elements are now collected according to paint order as spec says,
replacing the depth-first traversal of the paint tree with hit-testing
on each box.
This change resolves a FIXME in an existing test and adds a new
previously non-working test.
This API seems to be used by WPT for sending synthetic input events.
Implementing the naive translation of elementFromPoint to the spec steps
for this algorithm turns 4 'tests had errors unexpectedly' and 3 'tests
had timeouts unexpectedly' into 1 pass and 7 'tests had unexpected
subtest results' on the infrastructure/ subdirectory of WPT.
In this commit we have optimized the handling of scroll offsets and
clip rectangles to improve performance. Previously, the process
involved multiple full traversals of the paintable tree before each
repaint, which was highly inefficient, especially on pages with a
large number of paintables. The steps were:
1. Traverse the paintable tree to identify all boxes with scrollable or
clipped overflow.
2. Gather the accumulated scroll offset or clip rectangle for each box.
3. Perform another traversal to apply the corresponding scroll offset
and clip rectangle to each paintable.
To address this, we've adopted a new strategy that separates the
assignment of the scroll/clip frame from the refresh of accumulated
scroll offsets and clip rectangles, thus reducing the workload:
1. Post-relayout: Identify all boxes with overflow and link each
paintable to the state of its containing scroll/clip frame.
2. Pre-repaint: Update the clip rectangle and scroll offset only in the
previously identified boxes.
This adjustment ensures that the costly tree traversals are only
necessary after a relayout, substantially decreasing the amount of work
required before each repaint.
A markdown file gets loaded as an inline content document by
`create_document_for_inline_content()`, for which the default document
URL is "about:error". That breaks the fragment links.
Overriding "about:error" URL by passing the URL of the just loaded
markdown file as an argument to `HTMLParser::run()` ensures that the URL
of the document is as expected.
Before this change, `set_needs_to_resolve_paint_only_properties()` was
only called after style invalidation. However, since relayout can be
triggered independently from style invalidation, we need to ensure that
paint-only properties are updated in that case too.
This check has been if (false && stuff) for quite a while, since the
transition to Navigables. No one updates the BrowsingContext's session
history, so the check for it having an about blank document and only an
about blank document is always false.
When an element with an ID is added to or removed from the DOM, or if
an ID is added, removed, or changed, then we must reset the form owner
of all form-associated elements who have a form attribute.
We do this in 2 steps, using the DOM document as the messenger to handle
these changes:
1. All form-associated elements with a form attribute are stored on the
document. If the form attribute is removed, the element is removed
from that list as well.
2. When a DOM element with an ID undergoes any of the aforementioned
changes, it notifies the document of the change. The document then
forwards that change to the stored form-associated elements.
By replacing the `page_did_request_scroll_to()` calls with a request
to perform scrolling in the corresponding navigable, we ensure that
the scrolling of iframes will scroll within them instead of triggering
scroll of top level document.
Recently, we moved the resolution of CSS properties that do not affect
layout to occur within LayoutState::commit(). This decision was a
mistake as it breaks invalidation. With this change, we now re-resolve
all properties that do not affect layout before each repaint.
If the entire document is invalidated, we know a full style update is
coming soon, and there's no need to try and invalidate a smaller part.
This avoids a *lot* of work on some pages. As an example, we are able to
skip ~1.5 million style invalidations on https://html.spec.whatwg.org/
Use the [FlyString] extended attribute to allow these functions to take
an Optional<FlyString> directly, allowing us to tidy up some conversions
from Optional<String>.
Fetching the viewport rect is currently somewhat expensive, since it
requires finding the navigable the document is active in.
We can avoid the cost of repeated calls by simply allowing StyleComputer
to cache the viewport rect at the start of style computation.
We have two known PlatformObjects that need to implement some of the
behavior of LegacyPlatformObjects to date: Window, and HTMLFormElement.
To make this not require double (or virtual) inheritance of
PlatformObject, move the behavior of LegacyPlatformObject into
PlatformObject. The selection of LegacyPlatformObject behavior is done
with a new bitfield of feature flags instead of a dozen virtual
functions that return bool. This change simplifies every class involved
in the diff with the notable exception of Window, which now needs some
ugly const casts to implement named property access.
The entire subtree of an element with display:none is irrelevant for
purposes of layout and/or paint invalidation.
We now simply ignore invalidation triggers inside such subtrees.
This avoids a *lot* of redundant busywork when running CSS animations
inside not-even-rendered content. As an example, this avoids repainting
YouTube embeds repeatedly due to animating-but-hidden progress
indicators.
Note that the subtree *root* (i.e the `display:none` element itself)
still gets to trigger invalidation, since we may need to rebuild the
layout tree when the `display` property changes.