Commit Graph

1263 Commits

Author SHA1 Message Date
sideshowbarker
fac81e84ba LibXML: Replace the existing XML parser with libxml2 parsing
This change replaces our LibXML parser with a new implementation that
wraps libxml2's SAX2 API.

The new Parser class uses libxml2's SAX2 callbacks to drive the existing
XML::Listener interface. That preserves backward compatibility with all
existing consumers (XMLDocumentBuilder, DOMParser, etc.).
2026-01-07 14:38:52 +01:00
Andreas Kling
a9cc425cde LibJS+LibWeb: Add missing GC marking visits
This adds visit_edges(Cell::Visitor&) methods to various helper structs
that contain GC pointers, and makes sure they are called from owning
GC-heap-allocated objects as needed.

These were found by our Clang plugin after expanding its capabilities.
The added rules will be enforced by CI going forward.
2026-01-07 12:48:58 +01:00
Aliaksandr Kalenik
5336c53171 LibWeb: Stop intrinsic size cache invalidation at abspos boundaries
When content changes inside a layout node, we now reset intrinsic size
caches only up to the nearest absolutely positioned ancestor, rather
than all the way to the document root.

This optimization is safe because absolutely positioned elements don't
contribute to their ancestors' intrinsic sizes - they are skipped in
min/max content width calculations.

The needs_layout_update flag still propagates to all ancestors so the
document knows layout is needed. Only the cache reset is bounded.
2026-01-05 23:00:06 +01:00
Aliaksandr Kalenik
3353ec9663 LibWeb: Add result caching for :has() pseudo-class matching
The `:has()` pseudo-class requires traversing descendants (or siblings)
to find matches.

With this change we cache results keyed by `(Selector*, Element*)`
pairs. The cache is stored in `StyleComputer` and cleared at the start
of each style computation pass in `Document::update_style()`.

When `:has()` uses a descendant combinator and we find a match, we also
cache that all ancestors between the matching descendant and the
anchor match. For example with `div:has(.target)`:

```html
<div id="A">  <!-- checking :has(.target) here -->
  <div id="B">
    <div id="C">
      <span class="target"/>
    </div>
  </div>
</div>
```

When we find `.target` while checking `div#A`, we also cache that
`div#B` and `div#C` match `:has(.target)` since they also contain
`.target`. Later when styling these elements, we get cache hits and skip
traversal.
2026-01-04 19:36:40 +01:00
Gingeh
789ab3cc57 LibWeb: Declare namespace prefixes in parse_xml_fragment 2026-01-02 11:09:19 +01:00
Aliaksandr Kalenik
ebcf85f6e8 LibWeb: Lowercase attribute only once in NamedNodeMap::get_attribute()
...instead of doing it on every iteration.

This function is hot in profiles on github.com landing page (invoked
through `for_each_matching_attribute()`), so this helps a bit.
2025-12-28 14:11:36 +00:00
Andreas Kling
0949d4d193 LibWeb: Make PseudoElementTreeNode protect its tree pointers from GC 2025-12-27 16:40:34 +01:00
Andreas Kling
418a243c04 LibWeb: Don't run tasks in documents that haven't been BC associated
Documents that have never been associated with a browsing context will
never become "fully active" so we shouldn't schedule tasks in them since
they'll never run.
2025-12-27 16:40:34 +01:00
Andreas Kling
f12f72f139 LibWeb: Don't associate mutation observer microtask with a document
The microtask is conceptually global and fires pending observers at the
agent level. As such, it doesn't make sense for it to be associated with
any specific document.
2025-12-27 16:40:34 +01:00
Tim Ledbetter
cacadc8806 Revert "LibWeb/HTML: Return Promises from Element scroll methods"
This reverts commit 3a7fcde341.
2025-12-26 19:33:51 +01:00
Aliaksandr Kalenik
00562d53e5 LibWeb: Save weak pointer to document in DocumentLoadEventDelayer
This prevents GC leaks caused by a DocumentLoadEventDelayer that is
never destroyed (for example, when its Document becomes inactive) from
holding a strong reference to the Document and keeping it alive.
2025-12-24 10:19:28 +01:00
Callum Law
1bad8e5a78 LibWeb: Update animations regardless of whether timeline time changed
There are times that we want to update an animation regardless of
whether it's timelines time has changed, for example if an animation
associated with a scroll timeline has a pending task we should run that
on the next update regardless of whether the user has scrolled
2025-12-23 14:54:22 +01:00
Callum Law
f235625670 LibWeb: Don't disassociate animations from timeline when target orphaned
An animation with an orphaned owning element should continue to be
ticked by the timeline.

Reverts c8b574e and instead avoids leaking animations by not visiting
`Animation`s from `AnimationTimeline`s.

Fixes a timeout in the imported test
2025-12-23 14:54:22 +01:00
Callum Law
d62e2e39a3 LibWeb: Avoid running microtasks too early when updating animations
There were a bunch of places that we created
`HTML::TemporaryExecutionContext`s when updating animations in order to
resolve various promises, this worked but as part of the destructor it
would perform a microtask checkpoint which would result in us executing
microtasks earlier than intended, this is solved by instead having a
single temporary execution context for the entire animation update
process which we then destruct at the intended time.
2025-12-23 14:54:22 +01:00
Sam Atkins
3a7fcde341 LibWeb/HTML: Return Promises from Element scroll methods
Corresponds to part of:
c548a9a1d4
2025-12-23 14:24:28 +01:00
Andreas Kling
63eccc5640 LibJS: Don't make extra copies of every JS function's source code
Instead, let functions have a view into the AST's SourceCode object's
underlying string data. The source string is kept alive by the AST, so
it's fine to have views into it as long as the AST exists.

Reduces memory footprint on my x.com home feed by 65 MiB.
2025-12-21 10:06:04 -06:00
Andreas Kling
737d9727c2 LibJS+LibWeb: Add various fast_is<T>() helpers for common things 2025-12-20 09:13:19 -06:00
Andreas Kling
9e5ce016d5 LibWeb: Add fast_is<T>() for variously commonly-checked DOM node types 2025-12-20 09:13:19 -06:00
Sam Atkins
cb0c428b3a LibWeb/DOM: Use a single scroll queue for all events
Corresponds to:
36f05864a6
302490c80c
https://github.com/w3c/csswg-drafts/pull/13238
https://github.com/w3c/csswg-drafts/pull/13239

The latter two are my own corrections which haven't been merged yet.
2025-12-19 12:09:19 -06:00
Sam Atkins
e3c76d396f LibWeb/DOM: Prevent refreshing to a javascript URL
Corresponds to:
97e0693fb7

We do now pass the test added for this, but can't import it:
http://wpt.live/html/browsers/browsing-the-web/navigating-across-documents/refresh/javascript.window.html
2025-12-19 12:08:03 -06:00
Aliaksandr Kalenik
73de6d4387 LibWeb: Use weak pointer for cache in HTMLCollection
This avoids keeping elements cached in an HTMLCollection alive longer
than necessary in the following scenario:
1. The HTMLCollection cache is populated by querying it.
2. Elements that were included in the cache are removed from the DOM.
3. The cached elements are kept alive by strong references in the cache
   until it is updated, which might never happen.
2025-12-17 11:41:21 +01:00
Sam Atkins
1b817e93c3 LibWeb/DOM: Add a helper method to get a Node's containing ShadowRoot
As in, the ShadowRoot this Node is inside, if any.
2025-12-15 14:12:39 +00:00
Sam Atkins
8d401f7a95 LibWeb/DOM: Give ShadowRoots a "part element map"
It maps part names to the elements (or pseudo-elements) that have them.
The spec warns about this concept being expensive to calculate, and it
is: you have to walk the entire subtree. To make that less painful, I'm
keeping it cached on the ShadowRoot and recalculating it if the DOM
tree version has changed since. This will invalidate it more often than
necessary, but it's also simple and shouldn't be able to miss any cases,
so it seems reasonable for now.
2025-12-15 14:12:39 +00:00
Sam Atkins
bf57b18b9a LibWeb/DOM: Expose Element's parts list
The existing part_list() method used by the bindings lazily creates a
DOMTokenList, which we don't want to do just to check if an Element has
any parts defined.
2025-12-15 14:12:39 +00:00
Psychpsyo
5c67ea640a LibWeb: Propagate overflow to viewport more correctly 2025-12-15 09:47:25 +00:00
bingyuan.ng
6353118809 LibWeb: Update svg type for root element checks when set/get title 2025-12-14 23:22:38 +00:00
Feng Yu
b58fcaeecf LibWeb: Add HTMLSelectedContentElement for customizable select
Introduce the HTMLSelectedContentElement and integrate it into
<select>, <option> and HTMLParser.

See whatwg/html#10548.

There are two bugs with WPT tests which causes the third subtest
in selectedcontent.html and selectedcontent-mutations.html fail.
See whatwg/html#11882, web-platform-tests/wpt#55849.
2025-12-12 12:06:24 +00:00
Callum Law
57b7d0bbe5 LibWeb: Expose AnimationPlaybackEvent time values as CSSNumberish 2025-12-12 10:49:18 +00:00
Callum Law
69f05bd45d LibWeb: Store animation time values in abstract type
In level 2 of the web animations spec, times are no longer always
measures in milliseconds, they can also be percents when dealing with
progress-based (i.e. scroll-based) timelines.

We don't actually support percent times yet but this change will make it
easier to implement when we do.
2025-12-12 10:49:18 +00:00
Callum Law
f9df1c4eea LibWeb: Implement distinct specified timing values for AnimationEffect
Web Animations Level 2 disallows setting some `AnimationEffect` timing
values (start delay, end delay, iteration duration) directly and instead
allows authors to set the specified values which are then normalized
into the actual used values taking into account the type of the
associated timeline (i.e. progress- vs time-based)
2025-12-12 10:49:18 +00:00
Callum Law
f58339de7f LibWeb: Split AnimationTimeline::set_current_time into two methods
This method did two things:
1) on the base class (`AnimationTimeline`) it was a setter for
   `m_current_time` and;
2) on the child classes (e.g. `DocumentTimeline`) it updated the
   timeline's current time given a document timestamp

It makes more sense for theses to be distinct methods
2025-12-12 10:49:18 +00:00
Callum Law
b89b453c70 LibWeb: Make update_animations_and_send_events parameter non-optional
We always have a value for this so there is no need to have it as
optional
2025-12-12 10:49:18 +00:00
Sam Atkins
21d4e734c5 LibWeb/DOM: Update DOMTokenList spec steps, and reorganize to match them
We gain a couple of new methods which previously were combined together,
in order to match the spec closer.

Corresponds to:
7fa95d89f6
2025-12-11 22:54:39 +00:00
Sam Atkins
30a5f84a07 LibWeb/DOM: Use "attribute" validation context for attribute change
Corresponds to:
91f461145c
2025-12-11 22:54:39 +00:00
Sam Atkins
f6356c7342 LibWeb/DOM: Update spec for convert_nodes_to_single_node()
Corresponds to:
769aedf574
2025-12-11 22:54:39 +00:00
Sam Atkins
a831dc83e4 LibWeb/DOM: Update DOM::Node mutation spec steps
Corresponds to most of:
3fbec78b25
2025-12-11 22:54:39 +00:00
Sam Atkins
80787d3a9c LibWeb/DOM: Stub out Document.exitPointerLock()
This lets us leave the main menu on classic.minecraft.net by tapping
Escape again.
2025-12-09 12:11:21 +01:00
Sam Atkins
17e59932f4 LibWeb/DOM: Stub out Element.requestPointerLock()
Does just enough to make classic.minecraft.net load and let you play.
Without actual pointer lock it's quite awkward though.
2025-12-09 12:11:21 +01:00
Lorenz A
924e4d2baa LibWeb: Add sorting to Table row HTMLCollection
Add an optional sorting function to HTMLCollection. We use
insertion_sort as a stable sorting algorithm so tree order can be
maintained.
2025-12-09 09:26:49 +00:00
Jelle Raaijmakers
54d95fc766 LibWeb: Unify selection and cursor rects for painting
Instead of calculating the cursor rect separately, reuse
PaintableFragment::range_rect() and check for the selection state of
'None' where appropriate.
2025-12-08 20:12:23 +01:00
Jelle Raaijmakers
aa1abe778a LibWeb: Misc. code improvements
More usage of `as_if<T>`, fewer unnecessary `const_cast`s, etc. No
functional changes.
2025-12-08 20:12:23 +01:00
Sam Atkins
01b7800068 LibWeb/DOM: Add the Element.part attribute 2025-12-08 09:44:32 +00:00
Sam Atkins
f1f7f4fbbf LibWeb/DOM: Use GC::Ptr/Ref instead of raw pointers on DOM::Element APIs
No behaviour change, though this does clarify that class_list() always
returns a value.
2025-12-08 09:44:32 +00:00
Callum Law
dca80ad5eb LibWeb: Account for animated values when computing font
Computing the font for an element in `compute_font` is premature since
we are yet to apply animated properties - instead we should compute the
value on the fly (with a cache to avoid unnecessary work) to ensure we
are respecting the latest values
2025-12-05 10:03:15 +00:00
Callum Law
6c236d04d8 LibWeb: Separate font computation logic from StyleComputer
Font computation and loading is distinct enough from style computation
that it makes more sense to have this in it's own class.

This will be useful later when we move the font loading process to
`ComputedProperties` in order to respect animated values.
2025-12-05 10:03:15 +00:00
Sam Atkins
ed7a86b8cc LibWeb/DOM: Set the pseudo_element on created Animation/TransitionEvents
Also import a couple of WPT tests that now pass.
2025-12-03 13:29:51 +01:00
Sam Atkins
d717dd64b3 LibWeb: Make Animation's owning element an AbstractElement
From the spec:
> The owning element of a transition refers to the element or
  pseudo-element to which the transition-property property was applied
  that generated the animation.

https://drafts.csswg.org/css-transitions-2/#owning-element

Previously we only stored the element.
2025-12-03 13:29:51 +01:00
Sam Atkins
dacc64cb8b LibWeb/DOM: Add animation helpers to AbstractElement 2025-12-03 13:29:51 +01:00
Callum Law
d7d4f90a2c LibWeb: Update style attribute when calling attributeStyleMap.set()
We also now invalidate the element
2025-12-02 11:37:11 +00:00
Andreas Kling
1c45930767 LibWeb+LibWebView+LibRequests: Reduce dependency on LibIPC includes
Let's try to include the IPC encoder/decoder stuff in fewer headers
to make rebuilds more pleasant when editing these files.
2025-12-01 15:12:52 +01:00