Commit graph

716 commits

Author SHA1 Message Date
Sam Atkins
f148af0a93 LibWeb: Move XMLSerializer into HTML directory
The DOMParsing spec is in the process of being merged into the HTML one,
gradually. The linked spec change moves XMLSerializer, but many of the
algorithms are still in the DOMParsing spec so I've left the links to
those alone.

I've done my best to update the GN build but since I'm not actually
using it, I might have done that wrong.

Corresponds to 2edb8cc7ee
2025-03-04 16:44:41 +00:00
Andreas Kling
12f5e9c5f8 LibWeb: Only put connected elements into document's by-name-or-id cache
This fixes an issue where disconnected elements were incorrectly
accessible as named properties on the document.
2025-03-04 00:51:50 +01:00
Aliaksandr Kalenik
c769271e82 LibWeb: Don't invalidate display list in update_animated_style_if_needed
All necessary invalidations are issued while invalidating animated
style. There is no need to drop display list simply because there are
some animations that might need an update.
2025-03-03 21:45:23 +01:00
Aliaksandr Kalenik
1ce1a8f8f1 LibWeb: Reset and update animated style in a single pass
...and skip resetting animated style of finished animations.
2025-03-03 21:45:23 +01:00
Aliaksandr Kalenik
8e481f65f5 LibWeb: Don't invalidate style of finished animations
Removes lots of completely unnecessary work, especially when animated
property affects layout.
2025-03-03 21:45:23 +01:00
Timothy Flynn
b11ba4cc90 LibWeb: Clear the document's page's focused navigable upon destruction
We set the page's focused navigable upon mouse-down events from the UI.
However, we neglected to ever clear that focused navigable upon events
such as subsequent page navigations. This left the page with a stale
reference to a no-longer-active navigable. The effect was that any key
events from the UI would not be sent to the new page until either the
reference was collected by GC, or another mouse-down event occurred.

In the test added here, without this fix, the text sent to the input
element would not be received, and the change event would not fire.
2025-03-02 17:27:24 -05:00
Aliaksandr Kalenik
4d1329e0ea LibWeb: Optimize the case when invalidation set contains "whole subtree"
Instead of marking all nodes in the subtree for style recalculation,
including subtrees of subsequent siblings, we can fall back to the
default invalidation path, which is optimized to skip siblings
unaffected by sibling selectors.

Makes scrolling on https://frame.work/pl/en/about go a lot smoother.
2025-03-01 13:42:10 +01:00
Andreas Kling
043e96946f LibWeb: Block rendering until linked stylesheets are loaded
This commit implements the main "render blocking" behavior for link
elements, drastically reducing the amount of FOUC (flash of unstyled
content) we subject our users to.

The document will now block rendering until linked style sheets
referenced by parser-created link elements have loaded (or failed).

Note that we don't yet extend the blocking period until "critical
subresources" such as imported style sheets have been downloaded
as well.
2025-02-27 21:36:40 +01:00
Aliaksandr Kalenik
b8af3fccf6 LibWeb: Wait until child navigable's SHE is ready before navigating
This change fixes a bug that can be reproduced with the following steps:
```js
const iframe = document.createElement("iframe");
document.body.appendChild(iframe);
iframe.contentWindow.location.href = ("http://localhost:8080/demo.html");
```

These steps are executed in the following order:
1. Create iframe and schedule session history traversal task that adds
   session history entry for the iframe.
2. Generate navigation id for scheduled navigation to
   `http://localhost:8080/demo.html`.
3. Execute the scheduled session history traversal task, which adds
   session history entry for the iframe.
4. Ooops, navigation to `http://localhost:8080/demo.html` is aborted
   because addings SHE for the iframe resets the navigation id.

This change fixes this by delaying all navigations until SHE for a
navigable is created.
2025-02-27 14:31:41 +01:00
Timothy Flynn
d5be18617e LibWeb: Ensure EventHandler visits its mouse selection target
We hold a raw pointer to the mouse selection target, which is a mixin-
style class inherited only by JS::Cell classes. By not visiting this
object, we sometime had a dangling reference to it after it had been
garbage collected.
2025-02-27 09:53:13 +00:00
Luke Wilde
12a07b4fad LibWeb: Close WebSockets when document is unloaded
Previously, they would stay open for the entire WebContent lifetime,
or until the server closed the connection. This was particularly
noticeable on collaborative websites/games such as
https://jigsawpuzzles.io/, where the user using Ladybird would stick
around even after they had navigated away.
2025-02-26 11:47:32 +01:00
Sam Atkins
03a058ba5e LibWeb: Update Document.write spec steps
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
The spec changes seem to mostly be about introducing a TrustedHTML type
which we do not yet support, so we have a couple of FIXMEs.

TrustedTypes::InjectionSink is an attempt at matching the spec, but it's
not entirely clear to me how it should work. I'm sure it'll get
revisited once we start implementing trusted types.
2025-02-25 15:19:38 +01:00
Luke Wilde
2797f9f73e LibWeb: Return actual callback object from TreeWalker::filter
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
2025-02-24 18:29:03 +01:00
Luke Wilde
95949ba8f2 LibWeb: Return actual callback object from NodeIterator::filter 2025-02-24 18:29:03 +01:00
Timothy Flynn
72905c84d5 LibWeb+LibWebView+WebContent: Support both inspecting/highlighting nodes
Our own Inspector differs from most other DevTools implementations with
regard to highlighting DOM nodes as you hover elements in the inspected
DOM tree. In other implementations, as you change the hovered node, the
browser will render a box model overlay onto the page for that node. We
currently don't do this; we wait until you click the node, at which
point we both paint the overlay and inspect the node's properties.

This patch does not change that behavior, but separates the IPCs and
internal tracking of inspected nodes to support the standard DevTools
behavior. So the DOM document now stores an inspected node and a
highlighted node. The former is used for features such as "$0" in the
JavaScript console, and the latter is used for the box model overlay.
Our Inspector continues to set these to the same node.
2025-02-24 12:05:29 -05:00
Sam Atkins
0fcd7f9aea LibWeb/DOM: Update an attribute's node document
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
Corresponds to b64559cc08
2025-02-23 22:36:42 +00:00
InvalidUsernameException
f7276bfab3 LibWeb: Reduced number of recompiled files for CSS property headers
Some checks are pending
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
This reduces the number of `.cpp` files that need to be recompiled when
one of the below header files changes as follows:

CSS/ComputedProperties.h: 1113 -> 49
CSS/ComputedValues.h: 1120 -> 209
2025-02-23 10:14:39 -05:00
Jelle Raaijmakers
63b451cb46 LibWeb: Add SVGFilterElement 2025-02-22 10:14:29 +01:00
Aliaksandr Kalenik
0ab61a94d7 LibWeb: Bucket hover rules using RuleCache
Analysis of selectors on modern websites shows that the `:hover`
pseudo-class is mostly used in the subject position within relatively
simple selectors like `.a:hover`. This suggests that we could greatly
benefit from segregating them by id/class/tag name, this way reducing
number of selectors tested during hover style invalidation.

With this change, hover invalidation on Discord goes down from 70ms to
3ms on my machine. I also tested GMail and GitHub where this change
shows nice 2x-3x speedup.
2025-02-22 10:12:24 +01:00
Luke Wilde
cae0ab2139 LibWeb: Make PolicyContainer GC allocated
This is required to store Content Security Policies, as their
Directives are implemented as subclasses with overridden virtual
functions. Thus, they cannot be stored as generic Directive classes, as
it'll lose the ability to call overridden functions when they are
copied.
2025-02-21 12:43:48 +00:00
Tim Ledbetter
8547c1a743 LibWeb: Ensure inert contenteditable elements are not editable 2025-02-21 12:41:57 +00:00
Tim Ledbetter
a9ffc6359a LibWeb: Set inertness of HTMLElement when inert attribute is changed 2025-02-21 12:41:57 +00:00
Andreas Kling
d8f95c5050 LibWeb: Don't neglect DOM range updates on CharacterData changes
Regressed in 036327332f.

This commit moves the optimization a little later in replaceData(),
still avoiding relayout (the important part).

Recovers 480 points on WPT. :^)
2025-02-21 11:54:00 +01:00
Glenn Skrzypczak
0750513993 LibWeb: Support reversed ordered lists
Some checks are pending
CI / Lagom (false, NO_FUZZ, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (true, NO_FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (false, FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
This PR adds support for the `reversed` attribute of
ordered lists.
2025-02-21 04:23:28 +00:00
Sam Atkins
c4889f3c5c LibWeb/DOM: Stop moving is_value in create_element()
Clangd points out that 1) `set_is_value()` takes a reference so moving
isn't useful, and 2) we're reading `is_value` in step 3 after moving
it.
2025-02-20 21:55:34 +00:00
Aliaksandr Kalenik
1843a54df7 LibWeb: Skip quick selector rejection using ancestor filter if possible
If selector does not have any descendant combinators then we know for
sure it won't be filtered out by ancestor filter, which means there is
no need to check for it.

This change makes hover style invalidation go faster on Discord where
with this change we spend 4-5% in `should_reject_with_ancestor_filter()`
instead of 20%.
2025-02-20 19:48:27 +01:00
Aliaksandr Kalenik
036327332f LibWeb: Early return from replace_data() if data didn't change
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.
2025-02-19 22:32:09 +01:00
Aliaksandr Kalenik
0f8050f0bd LibWeb: Break early from rule testing in hover style invalidation
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.
2025-02-19 21:52:29 +01:00
Aliaksandr Kalenik
e1119023e9 LibWeb: Optimize pseudo elements presence check in hover style update
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%.
2025-02-19 19:56:52 +01:00
Timothy Flynn
82206d2abb LibWeb: Move DOM::NodeType to its own file
This is to allow using these values in libraries that otherwise do not
need to depend on LibWeb.
2025-02-19 08:45:51 -05:00
Piotr
c9edb6ffc4 LibWeb: Support for Content-Language HTTP header 2025-02-19 10:53:31 +00:00
Aliaksandr Kalenik
93253e993b LibWeb: Fix invalidations calculation for values with relative units
...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`.
2025-02-18 00:24:45 +01:00
Aliaksandr Kalenik
1e07227e98 LibWeb: Early return when invalidations=none in inherited style update
This allows to skip a bunch of unnecessary work performed by
`apply_style()`.
2025-02-18 00:24:45 +01:00
Aliaksandr Kalenik
e5b4fe2c65 LibWeb: Fix wrong invalidations calculation in inherited style update
We were incorrectly comparing new value against itself instead of the
old value to determine required set of invalidations.
2025-02-18 00:24:45 +01:00
Gingeh
91e4fb248b LibWeb: Hide unrelated popovers when showing popovers
Also hides decendant popovers when hiding.
Also hides unrelated popovers when showing dialogs.
2025-02-16 19:40:07 +00:00
Gingeh
bc0729f5d2 LibWeb: Create a BlockContainer for 'block ruby' elements
Prevents the layout engine from crashing.
(and unlocks ~200 new subtests)
2025-02-16 19:40:07 +00:00
Andreas Kling
31a69ce887 LibWeb+LibGfx: Make IntersectionObserver checks edge-inclusive
This fixes an issue where 0x0 rectangles were not considered to be
intersecting, even when they fell inside (or were adjacent to) the
viewport.
2025-02-16 18:09:08 +01:00
Psychpsyo
f839f1b44b LibWeb: Make a elements honor base element's target 2025-02-16 09:21:52 +01:00
Shannon Booth
9072a7caef Everywhere: Use URL::about_XXX factory functions 2025-02-15 17:05:55 +00:00
Andreas Kling
c9cd795257 LibWeb: Don't lose change events on MediaQueryList internal state change
MediaQueryList will now remember if a state change occurred when
evaluating its match state. This memory can then be used by the document
later on when it's updating all queries, to ensure that we don't forget
to fire at least one change event.

This also required plumbing the system visibility state to initial
about:blank documents, since otherwise they would be stuck in "hidden"
state indefinitely and never evaluate their media queries.
2025-02-13 20:52:31 +01:00
Aliaksandr Kalenik
327dc8e82a LibWeb: Avoid full tree traversal for non-subject :has() invalidation
Instead of checking all elements in a document for containment in
`:has()` invalidation set, we could narrow this down to ancestors and
ancestor siblings, like we already do for subject `:has()` invalidation.

This change brings great improvement on GitHub that has selectors with
non-subject `:has()` and sibling combinators (e.g., `.a:has(.b) ~ .c`)
which prior to this change meant style invalidation for whole document.
2025-02-13 16:24:51 +01:00
Sam Atkins
f9e90ca430 LibWeb/DOM: Assert that composed_path() currentTarget is non-null
Corresponds to cbf4c0d6b4

The assert is a little different, because we do know it's an
EventTarget pointer, but it could be null.
2025-02-12 23:48:18 +00:00
Sam Atkins
29d5eda02d LibWeb/DOM: Add container option to scrollIntoView options
Corresponds to https://github.com/w3c/csswg-drafts/pull/11673 , with the
addition of the fixes in https://github.com/w3c/csswg-drafts/pull/11701
2025-02-12 22:08:17 +01:00
Sam Atkins
a01a3b18f5 LibWeb: Fix CSP navigation request blocking
Corresponds to 304782ca57
2025-02-12 17:05:37 +00:00
Aliaksandr Kalenik
976af84287 LibWeb: Check all siblings in ancestors chain while invalidating :has()
Fixes underinvalidaiton of `:has()` selectors with sibling combinators.
2025-02-12 16:15:14 +01:00
Sam Atkins
49b505e4ae LibWeb/DOM: Cache computed style for ::marker
This allows us to inspect its properties. To avoid wasted work, we only
compute and cache the properties if the originating element was, or is,
displaying as a list item.
2025-02-12 13:48:53 +00:00
Aliaksandr Kalenik
761e9aeaf7 LibWeb: Optimize inherited style update
This commit changes the strategy for updating inherited styles. Instead
of marking all potentially affected nodes during style invalidation, the
decision is now made on-the-fly during style recalculation. Child nodes
will only have their inherited styles recalculated if their parent's
properties have changed.

On Discord this allows to 1000x reduce number of nodes with recalculated
inherited style.
2025-02-11 19:23:12 +01:00
Aliaksandr Kalenik
875a7141a3 LibWeb: Skip pending :has() invalidations if there are no :has()
`invalidate_style()` already tries to avoid scheduling invalidation for
`:has()` by checking result of `may_have_has_selectors()`, but it might
still result in unnecessary work because `may_have_has_selectors()`
does not force building of rules cache. This change adds
`have_has_selectors()` that forces building of rules cache and is
invoked in `update_style()` to double-check whether we actually need to
process scheduled `:has()` invalidations.

This allows to skip ~100000 ancestor traversals on this WPT test:
https://wpt.live/html/select/options-length-too-large.html
2025-02-11 10:22:23 +01:00
Aliaksandr Kalenik
90ba4b16c2 LibWeb: Postpone :has() style invalidation until update_style()
This allows to do ancestors traversal only once even if
`invalidate_style()` was called multiple times for the same node.
2025-02-11 10:22:23 +01:00
Sam Atkins
dc58f6567f LibWeb: Support :open for file and color <input> elements 2025-02-10 13:57:36 +00:00