Most elements don't have pseudo elements with CSS custom properties.
By only allocating this data structure when it's used, we can shrink
most elements by 208 bytes each. :^)
Most DOM nodes don't have registered mutation observers, so let's put
the metadata about them behind an OwnPtr to save space in the common
case.
Saves 16 bytes per DOM node that doesn't have registered observers.
With this change, we now have ~1200 CellAllocators across both LibJS and
LibWeb in a normal WebContent instance.
This gives us a minimum heap size of 4.7 MiB in the scenario where we
only have one cell allocated per type. Of course, in practice there will
be many more of each type, so the effective overhead is quite a bit
smaller than that in practice.
I left a few types unconverted to this mechanism because I got tired of
doing this. :^)
This will be required for propagating the current animation time to all
relevant timelines, which each propagate that time to all of their
relevant animations.
No IDL file pulls in these requiring DeprecatedString support, so we
are now able to remove these functions! :^)
Also leave a FIXME while we are at it, as ideally this function would
take an Optional<FlyString> - but the IDL generator does not currently
support this.
This is the API for NamedNodeMap which we are wanting to eventually use
instead of taking a StringView. Currently we just end up deferring to
the StringView versions of these functions, but at some stage in the
future, this will allow us to have O(1) comparison when making attribute
lookups.
In the meantime, the advantage of this API is that it makes it much less
awkward to use than the StringView variant when you have an
Optional<FlyString> namespace to pass through.
This required dealing with a *lot* of fallout, but it's all basically
just switching from DeprecatedFlyString to either FlyString or
Optional<FlyString> in a hundred places to accommodate the change.
For example, on https://html.spec.whatwg.org, there are hundreds of
thousands of nodes. This method is invoked as each node is inserted.
Traversing the entire tree each time takes a prohibitively long time,
so let's bail early when we know the operation is a no-op.
Errantly copied the variable name from the spec. The `node` variable in
this scope is what we passed to Node::insert_before; `node_to_insert` is
what the spec is actually referring to as `node` here.
Before this change, we were doing it after every layout, which meant
that already-propagated overflow could be propagated again, which led to
incorrect scrolling behavior.
This avoids the O(n) walk of element attributes, although there is still
a huge space for improvement here if we start keeping a lookup cache for
elements-by-ID.
The old name was pretty confusing, since it had nothing to do with the
common "id" content attribute.
This makes way for using id() to return the "id" attribute instead. :^)
We don't need to make a list of the target node's ancestors before
iterating over them, since nothing happens while iterating them that
can disturb the list anyway (no arbitrary JS execution etc).
The incessant construction and destruction of handles here was showing
up in profiles of basically every website that uses JavaScript to build
some or all of their DOM tree.
For example, serenityos.org does not contain a <link rel="icon"> element
to indicate its favicon. Before navigables, we implemented attempting to
load a fallback favicon in a rather ad-hoc manner. This implements the
full spec steps to do so after the HTML document is parsed.