Allows us to avoid invalidating layout when CharacterData didn't change.
Results in visible improvement on Discord that continuously invokes
this function with the same data, which previously resulted in relayout
on every frame.
Before this change, we did the following:
1. Created a bitmap with the matching state for each rule containing
`:hover`.
2. Changed the actively hovered element in the document.
3. Created another bitmap with the matching state for each rule
containing `:hover`.
With this change, we iterate rule by rule and compare the matching
state. This allows us to break early once we find the first rule whose
matching state changes after the hovered element update. Additionally,
this removes the need to allocate a bitmap.
Instead of using `has_pseudo_elements()` that iterates over all pseudo
elements, only check if `::before` or `::after` are present.
Before this change, `has_pseudo_elements()` was 10% of profiles on
Discord while now it's 1-2%.
Having one big `if` to determine whether or not we should restructure an
inline layout node became a bit unwieldy. This extracts the logic into a
separate method.
When restructuring inline nodes because of a block element insertion
during the layout tree build, we might end up with a `display: contents`
element in the ancestor stack that is not part of the actual layout
tree, since it's never actually used as a parent for any node. Because
we were only rewinding the ancestor stack with actual new layout nodes,
it became corrupted and layout nodes were added to the wrong parent.
This new logic leaves the ancestor stack intact, only replacing layout
nodes whenever a new one is created.
Fixes the sidebar on https://reddit.com.
Fixes#3590.
We only need a Page for file:// urls. At some point we probably
needed it for other kinds of requests, but the current functionality
doesn't need to store the Page pointer on the ResourceLoader.
...in inherited style update. Instead of comparing old absolutized value
with new non-absolutized value, we should wait until
`absolutize_values()` and then compare old and new values, when both are
absolutized.
Improves performance on pages with GitHub action logs where previously
we had to invalidate layout after hover style recalculation, because
there was `margin-left: 1rem`.
When drawing a table, some of the CSS properties must be moved from the
table grid box to an anonamyous table wrapper box. One of these
properties is `position`. `z-index` however is not. This leads to the
following behavior if a table has both `position` and `z-index`:
* The wrapper box has the `position`, but a `z-index` of `auto`.
* The grid box has the `z-index`, but `position: static`.
This effectively means that the `z-index property is ignored since it
has no effect on non-positioned elements. This behavior contradicts what
other browsers do and causes layout issues on websites.
To align Ladybird behavior with other browser this commit also moves the
`z-index` property to the wrapper box.
If the expansion of a custom property in variable expansion returns
tokens, then the custom property is not the initial guaranteed-invalid
value.
If it didn't return any tokens, then it is the initial
guaranteed-invalid value, and thus we should move on to the fallback
value.
Makes Shopify checkout show the background colours, borders, skeletons,
etc.
Our existing coalescing mechanism for input events didn't prevent
multiple mousemove/mousewheel events from being processed between paint
cycles. Since handling these events can trigger style & layout updates
solely for hit-testing purposes, we might end up doing work that won't
be observable by a user and could be avoided by shceduling input events
processing to happen right before painting the next frame.