Move the layout tree from GC allocation to refcounted ownership so
removed layout and paint subtrees are destroyed synchronously instead
of waiting for the next GC sweep. This dramatically reduces GC memory
usage peaks after layout tree churn and makes it easier for memory use
to fall back after large document updates.
Update layout factories, tree traversal, SVG layout node creation,
paintable back-pointers, and pseudo-element layout links to use RefPtr
ownership.
Make display: contents follow the same shape as Blink and WebKit: the
element itself does not create a layout node, and its children are
flattened into the nearest layout parent. Wrap direct non-whitespace
text in an anonymous inline node when the boxless element contributes
inherited style to that text.
Use an internal inline wrapper for display: contents pseudo-elements
so generated content can still participate in layout, painting, hit
testing, and pseudo-element queries. Keep CSSOM reporting the computed
display value from the pseudo style, not the internal wrapper.
Remove the retained out-of-tree layout node list and its testing hook,
since the flattened model does not need a side owner for boxless
elements. Add coverage for inherited text style, dynamic insertion
order, pseudo-element hit testing, and computed style queries.
Move ComputedProperties and CascadedProperties out of the GC. They no
longer contain strong references to GC-managed data.
Keep computed styles alive from DOM elements and animation updates with
RefPtr. Pass style into layout constructors by reference, since layout
only copies the values it needs while building nodes.
Use GC::Weak for cascade source links, so entries no longer keep the
style declaration or shadow root alive.
Previously, the LibWeb bindings generator would output multiple per
interface files like Prototype/Constructor/Namespace/GlobalMixin
depending on the contents of that IDL file.
This complicates the build system as it means that it does not know
what files will be generated without knowledge of the contents of that
IDL file.
Instead, for each IDL file only generate a single Bindings/<IDLFile>.h
and Bindings/<IDLFile>.cpp.
An SVGLength can be read-only, e.g. all animVal values cannot be
modified. Implement this for all instantiations of SVGLength.
While we're here, add `fake_animated_length_fixme()` so we can easily
find all sites where we need to improve our animated length game.
We were already using the XML parser for SVG files when opening at the
top level. This patch makes things consistent by using the same code
path when parsing SVG-as-image.
We also make some tweaks in SVG presentation attribute handling since
we can no longer rely on the HTML length attribute parsing quirk when
parsing width/height attributes.
Before this change, we were going through the chain of base classes for
each IDL interface object and having them set the prototype to their
prototype.
Instead of doing that, reorder things so that we set the right prototype
immediately in Foo::initialize(), and then don't bother in all the base
class overrides.
This knocks off a ~1% profile item on Speedometer 3.
This is not really a context, but more of a set of parameters for
creating a Parser. So, treat it as such: Rename it to ParsingParams,
and store its values and methods directly in the Parser instead of
keeping the ParsingContext around.
This has a nice side-effect of not including DOM/Document.h everywhere
that needs a Parser.
Many times, attribute mutation doesn't necessitate a full style
invalidation on the element. However, the conditions are pretty
elaborate, so this first version has a lot of false positives.
We only need to invalidate style when any of these things apply:
1. The change may affect the match state of a selector somewhere.
2. The change may affect presentational hints applied to the element.
For (1) in this first version, we have a fixed list of attribute names
that may affect selectors. We also collect all names referenced by
attribute selectors anywhere in the document.
For (2), we add a new Element::is_presentational_hint() virtual that
tells us whether a given attribute name is a presentational hint.
This drastically reduces style work on many websites. As an example,
https://cnn.com/ is once again browseable.
Before this change, StyleComputer would essentially take a DOM element,
find all the CSS rules that apply to it, and resolve the computed value
for each CSS property for that element.
This worked great, but it meant we had to do all the work of selector
matching and cascading every time.
To enable new optimizations, this change introduces a break in the
middle of this process where we've produced a "CascadedProperties".
This object contains the result of the cascade, before we've begun
turning cascaded values into computed values.
The cascaded properties are now stored with each element, which will
later allow us to do partial updates without re-running the full
StyleComputer machine. This will be particularly valuable for
re-implementing CSS inheritance, which is extremely heavy today.
Note that CSS animations and CSS transitions operate entirely on the
computed values, even though the cascade order would have you believe
they happen earlier. I'm not confident we have the right architecture
for this, but that's a separate issue.
Resulting in a massive rename across almost everywhere! Alongside the
namespace change, we now have the following names:
* JS::NonnullGCPtr -> GC::Ref
* JS::GCPtr -> GC::Ptr
* JS::HeapFunction -> GC::Function
* JS::CellImpl -> GC::Cell
* JS::Handle -> GC::Root
Now that the heap has no knowledge about a JavaScript realm and is
purely for managing the memory of the heap, it does not make sense
to name this function to say that it is a non-realm variant.