Commit graph

39 commits

Author SHA1 Message Date
Andreas Kling
2bf1f41805 LibWeb: Make computed properties immutable
Move CSS animation values into a mutable overlay on computed properties
and make base computed style data immutable after construction. Base
style mutation now goes through a builder that is consumed on publish,
so installed styles no longer expose mutation APIs.

Build new base style data for inherited style updates instead of cloning
and mutating installed computed properties. Element-specific computed
style adjustments now run before publication, while animation and
transition updates continue to mutate only the animated overlay.
2026-06-20 23:43:17 +02:00
sideshowbarker
9f7a328d9b LibWeb: Reject canvas toDataURL()/toBlob() when not origin-clean
Problem: Drawing a cross-origin image onto a 2D canvas clears its
origin-clean flag, but toDataURL() and toBlob() ignored that flag and
serialized the bitmap regardless. So, a page could read back the
cross-origin pixels it shouldn't (per spec) be allowed to access.

Cause: The origin-clean checks in to_data_url() and to_blob() were left
as FIXMEs. Only getImageData() enforced the flag.

Fix: Throw a SecurityError exception from both serialization entry
points when the canvas isn't origin-clean — matching getImageData() and
the spec. The same check also implements the previously-stubbed
origin-clean step in the WebDriver canvas-encoding algorithm.

Fixes: https://github.com/LadybirdBrowser/ladybird/issues/10009
2026-06-18 10:52:42 +02:00
Aliaksandr Kalenik
f215d9bb9a LibWeb+WebContent: Restore canvas contexts after Compositor loss
Compositor-backed canvas contexts keep their transports tied to a single
Compositor connection. When that connection dies, the 2D backing
storage and WebGL GL objects disappear with it, but WebContent does not
surface the loss to canvas contexts or create fresh host contexts after
reconnect.

Track compositor loss through the WebContent connection, mark WebGL
contexts lost, dispatch the standard context events, and rebuild the
remote proxy when the page opts into restoration. For 2D canvas, queue
the canvas context loss steps, discard the dead backing storage, and
create new storage before firing contextrestored.
2026-06-17 19:07:32 +02:00
Aliaksandr Kalenik
a80babffb6 LibWeb+Compositor: Run canvas contexts in the Compositor
Canvas rendering is a major remaining path where WebContent directly
owns GPU-facing drawing state. Back 2D and WebGL canvas contexts with
remote Compositor transports, so WebContent talks to canvas surfaces
through IPC while the Compositor owns the rasterization resources.

This is a large step toward GPU sandboxing because canvas GPU work now
lives behind the Compositor boundary. It also gives OffscreenCanvas the
process-independent canvas plumbing that HTMLCanvasElement now uses,
making worker-owned canvases possible without another WebContent-local
rendering path.
2026-06-17 19:07:32 +02:00
Andreas Kling
9340d2d1a3 LibWeb: Make layout nodes refcounted
Move the layout tree from GC allocation to refcounted ownership so
removed layout and paint subtrees are destroyed synchronously instead
of waiting for the next GC sweep. This dramatically reduces GC memory
usage peaks after layout tree churn and makes it easier for memory use
to fall back after large document updates.

Update layout factories, tree traversal, SVG layout node creation,
paintable back-pointers, and pseudo-element layout links to use RefPtr
ownership.

Make display: contents follow the same shape as Blink and WebKit: the
element itself does not create a layout node, and its children are
flattened into the nearest layout parent. Wrap direct non-whitespace
text in an anonymous inline node when the boxless element contributes
inherited style to that text.

Use an internal inline wrapper for display: contents pseudo-elements
so generated content can still participate in layout, painting, hit
testing, and pseudo-element queries. Keep CSSOM reporting the computed
display value from the pseudo style, not the internal wrapper.

Remove the retained out-of-tree layout node list and its testing hook,
since the flattened model does not need a side owner for boxless
elements. Add coverage for inherited text style, dynamic insertion
order, pseudo-element hit testing, and computed style queries.
2026-06-07 20:52:49 +02:00
Andreas Kling
7c06c3fd14 LibWeb: Make computed style data refcounted
Move ComputedProperties and CascadedProperties out of the GC. They no
longer contain strong references to GC-managed data.

Keep computed styles alive from DOM elements and animation updates with
RefPtr. Pass style into layout constructors by reference, since layout
only copies the values it needs while building nodes.

Use GC::Weak for cascade source links, so entries no longer keep the
style declaration or shadow root alive.
2026-06-06 23:29:48 +02:00
Aliaksandr Kalenik
6c162d8b5d LibWeb+LibWebView+WebContent: Recover after Compositor process crashes
The browser previously treated the out-of-process Compositor as fatal.

Restart the shared Compositor from the browser process, reconnect
process-backed WebContent clients, recreate compositor contexts, restore
viewport state, and ask WebContent to repaint and republish canvas and
media resources. WebContent now marks its compositor connection lost,
returns conservative values for synchronous compositor queries while
reconnecting, and drops outgoing updates until the replacement transport
arrives.

Synchronous input queries through the compositor control connection now
use fallible IPC. If the Compositor exits after the open check or before
the sync reply arrives, scroll and mouse handling report that the
Compositor did not handle the event and let the normal WebContent
fallback run.

Mouse events queued while the Compositor is unavailable now fall back to
direct WebContent dispatch. This keeps input completion in step with the
pending-event queue.

Recovery is capped at three automatic restarts. If the restart limit is
exceeded, if restart, reconnect, or context recreation fails, or if the
replacement Compositor exits during active recovery, the browser crashes
instead of switching process-backed views to a fallback path.
2026-05-24 03:35:07 +01:00
Shannon Booth
637fd51595 LibWeb: Unify WebIDL C++ type generation
Represent WebIDL C++ types with a single CppType model that tracks
nullability, optional presence, and contained storage.

GC-like values now use GC::Ref/GC::Ptr directly, while containers choose
"plain", "Root", or "Conservative" container types depending on what
they contain. For example, sequence<Element> becomes a RootVector of
GC::Ref values, while sequence<SomeDictionary> becomes a
ConservativeVector only when the dictionary contains GC-like values.
This moves the generated bindings away from wrapping GC values in
GC::Root by default.

This has broad fallout as the types passed to interfaces for GC
objects changes almost fully across the board.
2026-05-23 18:26:12 +02:00
Aliaksandr Kalenik
93bbdf1f55 LibWeb: Use compositor surface IDs for embedded content
Display lists kept canvas and nested navigable content alive through
ExternalContentSource objects. That made the resource graph depend on
process-local object identity instead of a stable surface handle, which
blocks compositor process isolation and made teardown-sensitive embedded
content harder to reason about.

Allocate CompositorSurfaceId values for canvases and child navigables,
publish their backing stores to the owning compositor, and paint them
with DrawCompositorSurface. Child navigables now publish to parent
compositors by CompositorContextId instead of raw object pointers, so
the in-process path uses the same stable addressing model required by a
remote compositor.

Clear and skip stale child surfaces during teardown, preserve Skia
canvas state while drawing compositor surfaces, and add display-list
coverage for canvas and iframe compositor surfaces. The nested navigable
async-scrolling baseline now expects DrawCompositorSurface.
2026-05-18 15:27:59 +02:00
Tim Ledbetter
d1fc4b4234 LibWeb: Route presentational hints through the CSS cascade
Previously, presentational hints bypassed the regular cascade pipeline
and wrote directly into `CascadedProperties` under
`CascadeOrigin::Author`. That meant `var()` substitution and the
invalid-at-computed-value-time fallback had to be duplicated in a
separate per-element pass, which in practice missed the IACVT step and
could leave a `GuaranteedInvalidStyleValue` in the cascaded
properties. This caused a crash in downstream code that assumed the
value had been resolved.

This introduces an `AuthorPresentationalHint` cascade origin and feeds
them through the cascade as normal declarations. This means that
`var()` resolution now happens in only one place.
2026-04-30 19:50:28 +01:00
Callum Law
7d15916754 LibWeb: Use correct LRC for absolutizing canvas font values
Canvases belonging to `OffscreenCanvas` and disconnected
`HTMLCanvasElement`s use a LRC based on the initial canvas context font
size of 10px.

This will be covered by WPT tests in a later commit once we expose the
absolutized value in the font getter
2026-04-08 14:31:43 +01:00
Aliaksandr Kalenik
004e5f851e LibWeb: Use ExternalContentSource for canvas painting
present() now snapshots the PaintingSurface into an ImmutableBitmap
and publishes it to the ExternalContentSource, so the rendering thread
never touches the live GPU surface — eliminating the data race
described in the ExternalContentSource commit (problem 1).

Canvas elements are registered with Page and presented once per frame
from the event loop, rather than on every individual draw call in
CRC2D::did_draw(). A dirty flag on HTMLCanvasElement ensures the
snapshot is only taken when content has actually changed, and makes
the present() call in CanvasPaintable::paint() a no-op when the
surface has already been snapshotted for the current frame.
2026-02-20 18:41:33 +01:00
Luke Wilde
82bd3d3891 LibWeb: Avoid invoking Trusted Types where avoidable
Prevents observably calling Trusted Types, which can run arbitrary JS,
cause crashes due to use of MUST and allow arbitrary JS to modify
internal elements.
2025-11-06 11:43:06 -05:00
Kenneth Myhra
7b4ee57037 LibWeb: Add get_bitmap_from_surface() and use it from to_blob()
This refactors out the reading part of Gfx::Bitmap from
HtmlCanvasElement::surface(). We can then reuse this from
WindowOrWorkerGlobalScopeMixin::create_image_bitmap_impl() when we
create an ImageBitmap from a HtmlCanvasElement.
2025-07-20 12:30:43 +12:00
Jelle Raaijmakers
fac0f82031 LibWeb: Add CanvasRenderingContext2D context attribute parsing
Makes `context.getContextAttributes()` work.
2025-04-29 13:51:23 +02:00
Gingeh
42a8effae5 LibWeb: Notify canvas context when width or height attribute is changed 2024-12-28 10:37:15 +01:00
Andreas Kling
b981e6f7bc LibWeb: Avoid many style invalidations on DOM attribute mutation
Many times, attribute mutation doesn't necessitate a full style
invalidation on the element. However, the conditions are pretty
elaborate, so this first version has a lot of false positives.

We only need to invalidate style when any of these things apply:

1. The change may affect the match state of a selector somewhere.
2. The change may affect presentational hints applied to the element.

For (1) in this first version, we have a fixed list of attribute names
that may affect selectors. We also collect all names referenced by
attribute selectors anywhere in the document.

For (2), we add a new Element::is_presentational_hint() virtual that
tells us whether a given attribute name is a presentational hint.

This drastically reduces style work on many websites. As an example,
https://cnn.com/ is once again browseable.
2024-12-24 17:17:09 +01:00
Andreas Kling
74469a0c1f LibWeb: Make CSS::ComputedProperties GC-allocated 2024-12-22 10:12:49 +01:00
Andreas Kling
c1cad8fa0e LibWeb: Rename CSS::StyleProperties => CSS::ComputedProperties
Now that StyleProperties is only used to hold computed properties, let's
name it ComputedProperties.
2024-12-22 10:12:49 +01:00
Andreas Kling
ed7f4664c2 LibWeb: Split StyleComputer work into two phases with separate outputs
Before this change, StyleComputer would essentially take a DOM element,
find all the CSS rules that apply to it, and resolve the computed value
for each CSS property for that element.

This worked great, but it meant we had to do all the work of selector
matching and cascading every time.

To enable new optimizations, this change introduces a break in the
middle of this process where we've produced a "CascadedProperties".
This object contains the result of the cascade, before we've begun
turning cascaded values into computed values.

The cascaded properties are now stored with each element, which will
later allow us to do partial updates without re-running the full
StyleComputer machine. This will be particularly valuable for
re-implementing CSS inheritance, which is extremely heavy today.

Note that CSS animations and CSS transitions operate entirely on the
computed values, even though the cascade order would have you believe
they happen earlier. I'm not confident we have the right architecture
for this, but that's a separate issue.
2024-12-22 10:12:49 +01:00
Andrew Kaster
af536e1192 LibWeb: Add stubbed-out WebGL2RenderingContext 2024-12-06 15:35:36 +01:00
Aliaksandr Kalenik
e2e54dccc3 LibWeb: Generate WebGLRenderingContext implementation 2024-12-03 23:35:45 +01:00
Aliaksandr Kalenik
f719b05ab9 LibWeb: Delegate painting surface allocation to canvas's active context
This change prepares for the addition of WebGL support, where painting
surface allocation process will differ from that of context2d.
2024-12-03 23:35:45 +01:00
Tim Ledbetter
a486c86eee LibWeb: Limit HTMLCanvasElement width and height to allowed values
Setting the `width` or `height` properties of `HTMLCanvasElement` to a
value greater than 2147483647 will now cause the property to be set to
its default value.
2024-12-01 15:12:04 +00:00
Shannon Booth
f87041bf3a LibGC+Everywhere: Factor out a LibGC from LibJS
Resulting in a massive rename across almost everywhere! Alongside the
namespace change, we now have the following names:

 * JS::NonnullGCPtr -> GC::Ref
 * JS::GCPtr -> GC::Ptr
 * JS::HeapFunction -> GC::Function
 * JS::CellImpl -> GC::Cell
 * JS::Handle -> GC::Root
2024-11-15 14:49:20 +01:00
justus2510
a6e9f107eb LibWeb: Fix Canvas.toDataURL and Canvas.toBlob signatures
Fix the function signatures of Canvas.toDataURL() and Canvas.toBlob()
and make both functions accept non-numbers as the quality parameter, in
which case it will just use the default quality instead of raising an
exception.
This makes toDataURL.arguments.1.html, toDataURL.arguments.2.html and
toDataURL.jpeg.quality.notnumber.html in
wpt/html/semantics/embedded-content/the-canvas-element pass :^)
2024-11-15 10:46:24 +01:00
Michael Watt
3b1d1d4582 LibWeb: Compute display: contents as none for unusual elements
https://drafts.csswg.org/css-display-3/#unbox-html specifies certain
elements that have their `display` style computed as `none` when
specified as `contents`.

This fixes at least one WPT test:
http://wpt.live/css/css-display/display-contents-suppression-dynamic-001.html
2024-11-13 11:11:07 +01:00
Timothy Flynn
93712b24bf Everywhere: Hoist the Libraries folder to the top-level 2024-11-10 12:50:45 +01:00
Andreas Kling
13d7c09125 Libraries: Move to Userland/Libraries/ 2021-01-12 12:17:46 +01:00
Andreas Kling
29a4da30b7 LibWeb: Make DOM::Node::create_layout_node() not need parent's style
The StyleResolver can find the specified CSS values for the parent
element via the DOM. Forcing everyone to locate specified values for
their parent was completely unnecessary.
2021-01-06 14:58:48 +01:00
Andreas Kling
865f524d5b AK+LibGUI+LibWeb: Remove AK::TypeTraits in favor of RTTI-based helpers
Now that we have RTTI in userspace, we can do away with all this manual
hackery and use dynamic_cast.

We keep the is<T> and downcast<T> helpers since they still provide good
readability improvements. Note that unlike dynamic_cast<T>, downcast<T>
does not fail in a recoverable way, but will assert if the object being
casted is not a T.
2021-01-01 15:33:30 +01:00
Andreas Kling
5aeab9878e LibWeb: Rename LayoutNode classes and move them into Layout namespace
Bring the names of various boxes closer to spec language. This should
hopefully make things easier to understand and hack on. :^)

Some notable changes:

- LayoutNode -> Layout::Node
- LayoutBox -> Layout::Box
- LayoutBlock -> Layout::BlockBox
- LayoutReplaced -> Layout::ReplacedBox
- LayoutDocument -> Layout::InitialContainingBlockBox
- LayoutText -> Layout::TextNode
- LayoutInline -> Layout::InlineNode

Note that this is not strictly a "box tree" as we also hang inline/text
nodes in the same tree, and they don't generate boxes. (Instead, they
contribute line box fragments to their containing block!)
2020-11-22 15:56:27 +01:00
Luke
e8a9e8aed5 LibWeb: Add namespace to Element 2020-10-22 15:24:42 +02:00
Luke
a86ce7eaca LibWeb: Make all existing HTML elements "final" 2020-08-09 21:14:51 +02:00
Andreas Kling
c46439f240 LibWeb: Move HTML classes into the Web::HTML namespace 2020-07-28 18:55:48 +02:00
Andreas Kling
1f008c95b6 LibWeb: Move CSS classes into the Web::CSS namespace 2020-07-26 20:05:15 +02:00
Andreas Kling
11ff9d0f17 LibWeb: Move DOM classes into the Web::DOM namespace
LibWeb keeps growing and the Web namespace is filling up fast.
Let's put DOM stuff into Web::DOM, just like we already started doing
with SVG stuff in Web::SVG.
2020-07-26 20:05:15 +02:00
Andreas Kling
71556e39a4 LibWeb: Switch to using AK::is and AK::downcast 2020-07-26 17:51:00 +02:00
Andreas Kling
a565121793 LibWeb: Move HTML object model stuff into LibWeb/HTML/
Take a hint from SVG and more all the HTML classes into HTML instead of
mixing them with the DOM classes.
2020-07-26 17:51:00 +02:00
Renamed from Libraries/LibWeb/DOM/HTMLCanvasElement.h (Browse further)