This should allow us to add a Element::attribute which returns an
Optional<String>. Eventually all callers should be ported to switch from
the DeprecatedString version, but in the meantime, this should allow us
to port some more IDL interfaces away from DeprecatedString.
Which for now will just call the DeprecatedString version of this
function. This is intended to be used in porting code over to using the
new String equivalent with the end goal of removing the DeprecatedString
version of this function.
This allows us to port a whole heap of IDL interfaces from
DeprecatedString to String.
Currently, every public DOM::Element method which changes an attribute
fires this handler itself. This was missed in commit 720f7ba, so any
user of that API would not fire the internal handler.
To fix this, and prevent any missing invocations in the future, invoke
the handler from from Attr::handle_attribute_changes. This method is
reached for all attribute changes, including adding/removing attributes.
This ensures the handler will always be fired, and reduces the footprint
of this ad-hoc behavior.
Note that our ad-hoc handler is not the "attribute change steps" noted
by the spec. Those are overridden only by a couple of specific elements,
e.g. HTMLSlotElement. However, we could easily make our ad-hoc handler
hook into those steps in the future.
Instead of calling to_lowercase() on two strings for every step while
iterating over the HTMLCollection returned by getElementsByTagName(),
we now cache the lowercased tag name beforehand and reuse it.
2.4x speed-up on WebKit/PerformanceTests/DOM/DOMDivWalk.html
The main missing features are rootMargin, proper nested browsing
context support and content clip/clip-path support.
This makes images appear on some sites, such as YouTube and
howstuffworks.com.
We now create a flex container inside the input element's UA shadow tree
and add the placeholder and non-placeholder text as flex items (wrapped
in elements whose style we can manipulate).
This fixes the visual glitch where the placeholder would appear below
the bounding box of the input element. It also allows us to align the
text vertically inside the input element (like we're supposed to).
In order to achieve this, I had to make two small architectural changes
to layout tree building:
- Elements can now report that they represent a given pseudo element.
This allows us to instantiate the ::placeholder pseudo element as an
actual DOM element inside the input element's UA shadow tree.
- We no longer create a separate layout node for the shadow root itself.
Instead, children of the shadow root are treated as if they were
children of the DOM element itself for the purpose of layout tree
building.
Before this, any style change that mutated a property we consider
"layout-affecting" would trigger a complete teardown and rebuild of the
layout tree.
This isn't actually necessary for the vast majority of CSS properties,
so this patch makes the invalidation a bit finer, and we now only
rebuild the layout tree when the CSS display property changes.
For other layout-affecting properties, we keep the old layout tree (if
we have one) and run the layout algorithms over that once again.
This is significantly faster, since we don't have to run all the CSS
selectors all over again.
The resolved property sets are stored with the element in a
per-pseudo-element array (same as for pseudo element layout nodes).
Longer term, we should stop storing this with elements entirely and make
it temporary state in StyleComputer somehow, so we don't waste memory
keeping all the resolved properties around.
This makes various gradients show up on https://shopify.com/ :^)
This makes selector matching significantly faster by not forcing us to
convert from FlyString to DeprecatedFlyString when matching class
selectors. :^)
The shadowRoot property getter that will be added in subsequent commits
has an additional check that checks whether the shadow root is opened.
I didn't update the function logic to match with the IDL interface,
because it's very likely we don't want that check in the existing code,
so that for example closed shadow root elements can still be updated.
ARIA has its own spec and is not part of the DOM spec, which is what the
Web::DOM namespace is for (https://www.w3.org/TR/wai-aria-1.2/).
This allows us to stay closer to the spec with function names and don't
have to add the word "ARIA" to identifiers constantly - the namespace
now provides that clarity.
Note that as of this commit, there aren't any such throwers, and the
call site in Heap::allocate will drop exceptions on the floor. This
commit only serves to change the declaration of the overrides, make sure
they return an empty value, and to propagate OOM errors frm their base
initialize invocations.
DeprecatedFlyString relies heavily on DeprecatedString's StringImpl, so
let's rename it to A) match the name of DeprecatedString, B) write a new
FlyString class that is tied to String.
We have a new, improved string type coming up in AK (OOM aware, no null
state), and while it's going to use UTF-8, the name UTF8String is a
mouthful - so let's free up the String name by renaming the existing
class.
Making the old one have an annoying name will hopefully also help with
quick adoption :^)
The ::placeholder pseudo element was added in commit 1fbad9c, but the
total number of pseudo elements was not updated. Instead of this manual
bookkeeping, add a dummy value at the end of the enumeration for the
count.
These are required for hit testing the document in Google Docs. If they
aren't defined, the Google Docs hit test code will add undefined to
certain values, causing them to turn into NaN. This causes NaNs to
propagate through their hit test code, which eventually makes it
infinitely loop.
We now only invalidate the style of the context element and all of its
descendants. It's still very aggressive, but much less than before.
Note that this will need to become a lot smarter once we implement the
CSS :has() selector.