This change implements the “C: Embedded Control” step at
https://w3c.github.io/accname/#step2C in the “Accessible Name and
Description Computation” spec — to compute the accessible names for
labeled form controls.
We basically need to do this for every invocation of invalidate_style()
right now, so let's just do it inside invalidate_style() itself.
Fixes one missing invalidation issue caught by a WPT test. :^)
This is strictly nicer than passing them around as i32 everywhere,
and by switching to i64 as the underlying type, ID allocation becomes as
simple as incrementing an integer.
These flags always propagate to the root, so once we encounter an
ancestor with the flag set, we can stop traversal since everything above
it will already be set as well.
CSS fragmentation implies 1:N relationship between layout nodes and
paintables. This change is a preparation for implementation of inline
fragmentation where InlinePaintable will be replaced with
PaintableWithLines corresponding to each line.
There was no need to use FlyString for error messages, and it just
caused a bunch of churn since these strings typically only existed
during the lifetime of the error.
While Origin is defined in the HTML spec - this leaves us with quite an
awkward relationship as the URL spec makes use of AO's from what is
defined in the HTML spec.
To simplify this factoring, relocate Origin into LibURL.
When an element is invalidated, it's possible for any subsequent sibling
or any of their descendants to also need invalidation. (Due to the CSS
sibling combinators, `+` and `~`)
For DOM node insertion/removal, we must also invalidate preceding
siblings, since they could be affected by :first-child, :last-child or
:nth-child() selectors.
This increases the amount of invalidation we do, but it's more correct.
In the future, we will implement optimizations that drastically reduce
the number of elements invalidated.
DOM nodes that didn't have a layout node before being removed from the
DOM are not going to change the shape of the layout tree after being
removed.
Observing this, we can avoid a full layout tree rebuild on some DOM node
removals.
This avoids a bunch of tree building work when loading https://x.com/
You can now build with STYLE_INVALIDATION_DEBUG and get a debug stream
of reasons why style invalidations are happening and where.
I've rewritten this code many times, so instead of throwing it away once
again, I figured we should at least have it behind a flag.
If a DOM node is an element with pseudo-elements, but it has no child
DOM nodes and is not a shadow host, then the code that serializes its
pseudo-elements would get skipped, making them not show up in the
inspector.
To avoid expensive lookups, we now cache a weak pointer from document to
the last known node navigable. Before using the cache, we validate that
the document is still the navigable's active document.
The spec says to just call the XML serialization algorithm, but it
returns the "outer serialization", and we need the "inner" one. Let's
just concatenate serializations of children; then the result produced is
similar to one from Blink or Gecko.
This method puts the given node and all of its sub-tree into a
normalized form. A normalized sub-tree has no empty text nodes and no
adjacent text nodes.
And let the old shadow_root(), which was only supposed to be used by
bindings, be called shadow_root_for_bindings() instead.
This makes it much easier to read DOM code, and we don't have to worry
about when to use shadow_root_internal() or why.
Link elements that aren't "browsing-context connected" should not
trigger a resource fetch when their attributes change.
This fixes an issue where we'd waste time by loading every style sheet
twice! :^)
We can't rely on Element.setAttribute() in cloneNode() since that will
throw on weird attribute names. Instead, just follow the spec and copy
attributes into cloned elements verbatim.
This fixes a crash when loading the "issues" tab on GitHub repos.
They are actually sending us unintentionally broken markup, but we
should still support cloning it. :^)
If a DOM node isn't connected, there's no need to invalidate, since it's
not going to be visible anyway. The node will be automatically inserted
if/when it becomes connected in the future.
This piggybacks on the same fragment serialization code that innerHTML
uses, but instead of constructing an imaginary parent element like the
spec asks us to, we just add a separate serialization mode that includes
the context element in the serialized markup.
This makes the image carousel on https://utah.edu/ show up :^)
A bunch of this is leftover from pre porting over to new AK::String.
For example, for functions which previously took a ByteString const&
now accepting a StringView.
`Node::shadow_including_root()` was missing a null check, which caused
a crash when manipulating a select element, whose option elements were
initially detached.
This patch adds a u64 version counter to DOM::Document that increments
whenever the tree structure changes (via node insertion or removal),
or an element attribute is changed somehow.
This will be used as a crude invalidation mechanism for HTMLCollection
to cache its elements.
When inserting a node into a parent, any live DOM ranges that reference
the parent may need to be updated. The spec does this by increasing or
decreasing the start/end offsets of each live range *before* actually
performing the insertion.
This caused us to crash with a verification failure, since it was
possible to set the range offset to an invalid value (that would go on
to immediately become valid after the insertion was finished).
This patch fixes the issue by adding special badged helpers on Range for
Node to reach into it and increase/decrease the offsets during node
insertion. This skips the offset validity check and actually makes our
code read slightly more like the spec.
Found by Domato :^)
When a node is removed from the DOM tree, its paintable needs to be
removed to ensure that it is not used to obtain sizes that are no
longer valid.
This change enables the ResizeObserver to send a notification if a node
is removed, as it should, because a removed node now has a size of zero
It should be okay to nullify pointers without concerning
parent/sibling/child relationships because the layout and paintable
trees will be rebuilt following any DOM mutation anyway.
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/