For the slight cost of counting code points when converting between
encodings and a teeny bit of memory, this commit adds a fast path for
all-happy utf-16 substrings and code point operations.
This seems to be a significant chunk of time spent in many regex
benchmarks.
For unscrolled elements (already at 0, 0) that aren't eligible to be the
Document.scrollingElement, we can short-circuit here and avoid doing a
synchronous relayout of the page.
This avoids a bunch of synchronous layouts on Speedometer3's NewsSite
subtests.
Instead of indiscriminately clearing the cache for all anonymous boxes,
we now only clear it for those that were generated by a non-anonymous
box in need of layout update.
This increases the cache hit rate and allows us to avoid more work.
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.
Many elements never end up needing this string, so instead of eagerly
generating it in the Element constructor, let's defer it until someone
actually requests it.
Knocks off a ~1% profile item on Speedometer3's jQuery test.
The basic idea is that style sheets can block script execution under
some circumstances. With this commit, we now handle the simplest cases
where a parser-inserted link element gets to download its style sheet
before script execution continues.
This improves performance on Speedometer 3 where JavaScript APIs that
depend on layout results (like Element.scrollIntoView()) would get
called too early (before the relevant CSS was downloaded), and so we'd
perform premature layout work. This work then had to be redone after
downloading the CSS anyway, wasting time.
Note that our Text/input/link-re-enable-crash.html test had to be
tweaked after these changes, since it relied on the old, incorrect,
behavior where scripts would run before downloading CSS.
We now cache the containing block (box) once at the start of layout,
which allows Layout::Node::containing_block() to return instantly
instead of doing tree traversal.
Removes a 0.7% profile item on Speedometer 3.
These are slightly unfortunate as we're crossing the library boundary,
but there's precedent with Object::is_dom_node(), and these are just
knocking down a few more items that were showing up in profiles.
Corresponds to dba6e7b6c2
and 4c0401186c
The spec algorithms now use "the relevant global object's associated
document", so remove the concept of the History object itself having an
associated document. The spec has also combined the implementations for
forward/back/go so I've matched that too.
Corresponds to 03ab71775b
I've also split the `Document::has_focus()` method for clarity. Actually
implementing the "has focus steps" turns out to be quite involved so
I've left it for now.
We achieve this by keeping track of all checked pseudo class selectors
in the SelectorEngine code. We also give StyleComputer per-pseudo-class
rule caches.
These callbacks are evaluated synchronously via JS::Call. We do not need
to construct an expensive RootVector container just to immediately
invoke the callbacks.
Stylistically, this also helps indicate where the actual arguments start
at the call sites, by wrapping the arguments in braces.
The spec is unclear about when exactly we should parse the style sheet.
Previously we'd do so before calling this algorithm, which was
error-prone, as seen by the bug fixed by the previous commit. The spec
for step 1 of "create a CSS style sheet" says:
1. Create a new CSS style sheet object and set its properties as
specified.
The definitions linked are UA-defined enough that it seems reasonable to
put the parsing here. That simplifies the user code a little and makes
it harder to mess up. It does raise the question of what to do if
parsing fails. I've matched our previous behaviour by just logging and
returning in that case.
While I'm modifying this method, I've also converted the bool params to
enums so they're a little clearer to read.
Check if box has associated layout node is not mentioned in the spec,
but it is required to match behavior of other browsers that do not
invoke intersection observer steps for boxes without layout node.
EventTarget::dispatch_event, per comments, does ad-hoc solution for UA,
and I don't know why it checks if `this` is window or `element`, but
web platform tests would fail, because `this` would actually be a
`Document` type.
Before this change, we'd skip storing the new ComputedProperties in
Element::recompute_style() if there was no invalidation needed.
This caused us to lose the information about which properties are
inherited and/or important (which is also carried by ComputedProperties,
but doesn't affect invalidation).
Consequently, we'd then fail to recompute inherited styles, since that
mechanism depends on this data.
The fix is simply to always store the new ComputedProperties.
This fixes one source of flakiness on WPT (of many) where we wouldn't
recompute style after programmatically altering the contents of a style
sheet, but instead had to wait for something else to cause invalidation.
With this change we save a copy of of scroll state at the time of
recording a display list, instead of actual ScrollState pointer that
could be modifed by the main thread while display list is beings
rasterized on the rendering thread, which leads to a frame painted with
inconsistent scroll state.
Fixes https://github.com/LadybirdBrowser/ladybird/issues/4288
This will be needed by Streams. To support this, we now store callbacks
in a hash table, keyed by an ID. Callers may use that ID to remove the
callback at a later point.
The fast path of to_i32() can be neatly inlined everywhere, and we still
have to_i32_slow_case() for non-trivial conversions.
For to_u32(), it really can just be implemented as a static cast to i32!
This is ad-hoc, and the spec doesn't seem to tell us what to actually do
here. Without this, following the spec steps for loading relative
`@import` URLs from a `<style>` tag always fails, because that uses the
parent style sheet's location as the base URL.
There's a bit of a UTF-8 assumption with this change. But nearly every
caller of these methods were immediately creating a String from the
resulting ByteString anyways.
Fixes bug when we always return null from getElementById() on
unconnected roots because id to element cache is only maintained for
connected roots.
Fixes broken Perf-Dashboard suite in Speedometer 3.
This patch adds a workaround for a Swift issue where boolean bitfields
with getters and setters in SWIFT_UNSAFE_REFERENCE types are improperly
imported, causing an ICE.