Commit graph

353 commits

Author SHA1 Message Date
Aliaksandr Kalenik
d5c6e45dca LibWeb: Change Element::closest() to check if any of selector matches
...instead of checking if all selectors match an element.

Fixes bug reduced from GitHub's "new issue" page.
2024-03-22 18:43:46 +01:00
Aliaksandr Kalenik
e232a84f0e LibWeb: Do not include box's own scroll offset in get_client_rects()
Fixes https://github.com/SerenityOS/serenity/issues/23631
2024-03-22 12:13:59 +01:00
Andreas Kling
cf60f52a78 LibWeb: Add DOM tree version counter
This patch adds a u64 version counter to DOM::Document that increments
whenever the tree structure changes (via node insertion or removal),
or an element attribute is changed somehow.

This will be used as a crude invalidation mechanism for HTMLCollection
to cache its elements.
2024-03-19 20:59:36 +01:00
Aliaksandr Kalenik
cf7c933312 LibWeb: Add fast path to calculate invalidations for animated css props
- Compare only the animated properties
- Clone only the hash map containing animated properties, instead of
  the entire StyleProperties.

Reduces `KeyframeEffect::update_style_properties()` from 10% to 3% in
GitHub profiles.
2024-03-19 17:30:34 +01:00
Andreas Kling
a6c23d3db5 LibWeb: Make Element::has_class() an inline function
This is extremely hot when running CSS selectors, so let's make it
easier for it to be inlined.
2024-03-19 16:48:22 +01:00
Andreas Kling
4679dbc9df LibWeb: Make Element::inline_style() return specific declaration type
This removes a bunch of RTTI checks in StyleComputer.
2024-03-19 09:44:25 +01:00
Aliaksandr Kalenik
3fd1164171 LibWeb: Account for scroll offset in Element::get_client_rects() 2024-03-17 13:32:04 +01:00
Aliaksandr Kalenik
15524b97b6 LibWeb: Update paint-only props only when needed in get_client_rects()
There is no need to unconditionally resolve them whenever the function
is called.
2024-03-17 13:32:04 +01:00
Andreas Kling
c0d7f748ed LibWeb: Avoid FlyString lookups when setting IDL interface prototypes
This commit introduces a WEB_SET_PROTOTYPE_FOR_INTERFACE macro that
caches the interface name in a local static FlyString. This means that
we only pay for FlyString-from-literal lookup once per browser lifetime
instead of every time the interface is instantiated.
2024-03-16 16:35:54 +01:00
Andreas Kling
43c720db81 LibWeb: Remove a bunch of redundant Document::navigable() lookups
Document::navigable() can be unpleasantly slow, since we don't have a
direct link between documents and navigables at the moment. So let's not
call it twice when once is enough.
2024-03-16 14:27:59 +01:00
Aliaksandr Kalenik
a9b8840a82 LibWeb: Add fast path for animated style properties update
Patch up existing style properties instead of using the regular style
invalidation path, which requires rule matching for each element in the
invalidated subtree.

- !important properties: this change introduces a flag used to skip the
  update of animated properties overridden by !important.
- inherited animated properties: for now, these are invalidated by
  traversing animated element's subtree to propagate the update.
- StyleProperties has a separate array for animated properties that
  allows the removal animated properties after animation has ended,
  without requiring full style invalidation.
2024-03-16 09:49:40 +01:00
Andreas Kling
0c76c7ee36 LibWeb: Make Element::is_document_element() slightly nicer
By following the spec more closely, we can actually make this function
a bit more efficient (by comparing the parent against the document
instead of looking for the first element child of the document).
2024-03-14 12:42:08 +01:00
Aliaksandr Kalenik
3b4230e0b0 LibWeb: Visit custom element's lifecycle callbacks
...instead of using JS::Handle which causes leaks when object holding
the callback can be reached by visiting the callback's dependencies.
2024-03-12 18:18:10 +01:00
Andreas Kling
1b8d8c7bbc LibWeb: Make a Layout::BlockContainer for MathML boxes
Instead of creating a generic Layout::Box, make a BlockContainer. This
allows them to be laid out by BFC, which is better than nothing(?),
even if it's not going to be correct at all.
2024-03-11 18:29:10 +01:00
Andreas Kling
3591a82e8d LibWeb: Look at paintable directly in Element::scroll* APIs
We don't need to go via the layout tree as the element has a link
directly to its paintable where the relevant metrics are stored.
2024-03-11 18:29:10 +01:00
Aliaksandr Kalenik
c6e69d501f LibWeb: Add style sheets to the shadow root if applicable
If a style element belongs to a shadow tree, its CSSStyleSheet is now
added to the corresponding ShadowRoot instead of the document.

Co-authored-by: Simon Wanner <simon+git@skyrising.xyz>
2024-03-09 16:13:32 +01:00
Matthew Olsson
24ec5838ba LibWeb: Visit Animatable::m_associated_effects 2024-03-09 15:34:27 +01:00
Bastiaan van der Plaat
76f767c867 LibWeb: Apply transform origin in Element::get_client_rects() 2024-03-07 00:28:29 +01:00
Matthew Olsson
1ca31e0dc1 LibWeb: Remove unnecessary ErrorOr<> from StyleComputer
All of this error propogation came from a single call to
HashMap::try_ensure_capacity! As part of the ongoing effort to ignore
small allocation failures, lets just assert this works. This has the
nice side-effect of propogating out to a few other classes.
2024-03-06 07:45:56 +01:00
Andreas Kling
d1b5f55f91 LibWeb: Make Paintable::containing_block() return a PaintableBox*
Every single client of this function was immediately calling paintable()
on the result anyway, so there was no need to return a layout node!

This automatically leverages the cached containing block pointer we
already have in Paintable, which melts away a bunch of unnecessary
traversal in hit testing and painting. :^)
2024-03-01 17:57:10 +01:00
Luke Wilde
48e11a1f12 LibWeb: Empty CE reaction queue instead of destroying it on exception
If an exception occurs in a custom element constructor, we clear the
reaction queue by destroying it, instead of emptying the Vector.
3da6916383/Userland/Libraries/LibWeb/DOM/Element.cpp (L2033)

This causes a UAF here, as async upgrades (i.e. custom elements not
created by document.createElement) are performed in this loop:
3da6916383/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp (L657)

Fixes crash when loading https://github.com/SerenityOS/serenity
2024-02-29 21:58:01 -05:00
Aliaksandr Kalenik
591c8d2b68 LibWeb: Return overflow rect height from Element::scroll_height()
Spec says that this function has to return "height of the element
scrolling area" which is height of "scrolling overflow rect" in our
model.
2024-02-19 20:07:12 +01:00
Aliaksandr Kalenik
9f581d0bc9 LibWeb: Return overflow rect width from Element::scroll_width()
Spec says that this function has to return "width of the element
scrolling area" which is width of "scrolling overflow rect" in our
model.
2024-02-19 20:07:12 +01:00
Aliaksandr Kalenik
89319cd0c9 LibWeb: Make sure layout is up to date in Element::scroll_height() 2024-02-19 20:07:12 +01:00
Aliaksandr Kalenik
639e9b5012 LibWeb: Make sure layout is up to date in Element::scroll_width() 2024-02-19 20:07:12 +01:00
Andrew Kaster
94149db073 LibWeb: Implement Document named properties with light caching
We now cache potentially named elements on the Document when elements
are inserted and removed. This allows us to do lookup of what names are
supported much faster than if we had to iterate the tree every time.

This first cut doesn't implement the rules for 'exposed' object and
embed elements.
2024-02-16 16:18:31 -05:00
Aliaksandr Kalenik
fc40d35012 LibWeb: Move paint properties invalidation flag into Document
Move paint-only properties invalidation flag to Document for
consistency, as style and layout invalidation flags are already
managed there.
2024-02-09 16:45:44 +01:00
Timothy Flynn
a17074422e LibWeb: Reset form association when any element with an ID changes
When an element with an ID is added to or removed from the DOM, or if
an ID is added, removed, or changed, then we must reset the form owner
of all form-associated elements who have a form attribute.

We do this in 2 steps, using the DOM document as the messenger to handle
these changes:

1. All form-associated elements with a form attribute are stored on the
   document. If the form attribute is removed, the element is removed
   from that list as well.

2. When a DOM element with an ID undergoes any of the aforementioned
   changes, it notifies the document of the change. The document then
   forwards that change to the stored form-associated elements.
2024-02-03 15:30:16 -07:00
Aliaksandr Kalenik
bf14de4118 LibWeb: Remove direct calls of page_did_request_scroll_to()
By replacing the `page_did_request_scroll_to()` calls with a request
to perform scrolling in the corresponding navigable, we ensure that
the scrolling of iframes will scroll within them instead of triggering
scroll of top level document.
2024-02-03 19:00:26 +01:00
Aliaksandr Kalenik
1af466babf LibWeb: Fix invalidation of CSS properties that do not affect layout
Recently, we moved the resolution of CSS properties that do not affect
layout to occur within LayoutState::commit(). This decision was a
mistake as it breaks invalidation. With this change, we now re-resolve
all properties that do not affect layout before each repaint.
2024-02-03 09:28:03 +01:00
Aliaksandr Kalenik
79b73b7fbb LibWeb: Use Window::scroll() in Element::set_scroll_top()
Now when Window::scroll() could do actual scrolling we can remove
this FIXME.
2024-02-01 09:23:48 -05:00
Aliaksandr Kalenik
a4d78c7df9 LibWeb: Use Window::scroll() in Element::set_scroll_left()
Now when Window::scroll() could do actual scrolling we can remove
this FIXME.
2024-02-01 09:23:48 -05:00
Aliaksandr Kalenik
fb2166f19c LibWeb: Account for CSS transform in Element::getClientRects() 2024-01-30 14:50:25 +01:00
Aliaksandr Kalenik
768b8415f2 LibWeb: Follow the spec more precisely in Element::getClientRects()
Now, `Element::getBoundingClientRect()` implementation depends on
`Element::getClientRects()`, as defined in the specification.
2024-01-30 14:50:25 +01:00
Bastiaan van der Plaat
a681429dff LibWeb: Remove DOM element deprecated_get_attribute() 2024-01-19 13:12:54 -07:00
Aliaksandr Kalenik
7c2713c14f LibWeb: Move set_needs_display() from layout node to paintable
For this method, there is no need to go through the layout node when we
can directly reach the paintable.
2024-01-15 09:00:35 +01:00
Shannon Booth
3910efb80b LibWeb: Implement Element.removeAttributeNS 2024-01-14 16:10:18 -07:00
Shannon Booth
7a26a889cb LibWeb: Implement Element.getAttributeNodeNS 2024-01-14 16:10:18 -07:00
Shannon Booth
e6861cb5ef LibWeb: Port Element::insert_adjacent from ByteString 2024-01-13 12:05:36 +01:00
Shannon Booth
41f84deb9f LibWeb: Port Element::name to a cached FlyString
Also removing some handling of OOM while we are in the area.
2024-01-13 12:05:36 +01:00
Shannon Booth
785fa60cca LibWeb: Implement Element.getAttributeNS 2024-01-13 08:33:10 +01:00
Shannon Booth
fa1ef30985 LibWeb: Port Element::set_attribute_value from ByteString
Also making set_attribute_ns take a String instead of a FlyString as
this is only used as an Attr value and no FlyString properties are used.
2024-01-03 10:13:47 +01:00
Shannon Booth
285bca1633 LibWeb: Use Optional<FlyString> const& in Element and NamedNodeMap
This is enabled with the newly added IDL generator support for
FlyStrings.
2024-01-03 10:13:47 +01:00
Shannon Booth
f32185420d LibWeb: Use FlyString where possible in NamedNodeMap
We cannot port over Optional<FlyString> until the IDL generator supports
passing that through as an argument (as opposed to an Optional<String>).

Change to FlyString where possible, and resolve any fallout as a result.
2024-01-03 10:13:47 +01:00
Shannon Booth
462f97b28a LibWeb: Port Element::get_attribute_value from ByteString 2023-12-27 09:23:44 +01:00
Bastiaan van der Plaat
c30911ab10 LibWeb: Hide select chevron icon when appearance: none; 2023-12-23 10:12:36 +01:00
Aliaksandr Kalenik
cda1d886df LibWeb: Fix not working Element::scroll_an_element_into_view()
Fixes following mistakes:
- "scrolling box" for a document is not `scrollable_overflow_rect()`
   but size of viewport (initial containing block, like spec says).
- comparing edges of "scrolling box" with edges of target element
  does not make any sense because "scrolling box" edges are relative
  to page while result of `get_bounding_client_rect()` is relative
  to viewport.
2023-12-19 10:45:07 +01:00
Ali Mohammad Pur
5e1499d104 Everywhere: Rename {Deprecated => Byte}String
This commit un-deprecates DeprecatedString, and repurposes it as a byte
string.
As the null state has already been removed, there are no other
particularly hairy blockers in repurposing this type as a byte string
(what it _really_ is).

This commit is auto-generated:
  $ xs=$(ack -l \bDeprecatedString\b\|deprecated_string AK Userland \
    Meta Ports Ladybird Tests Kernel)
  $ perl -pie 's/\bDeprecatedString\b/ByteString/g;
    s/deprecated_string/byte_string/g' $xs
  $ clang-format --style=file -i \
    $(git diff --name-only | grep \.cpp\|\.h)
  $ gn format $(git ls-files '*.gn' '*.gni')
2023-12-17 18:25:10 +03:30
Aliaksandr Kalenik
7d757fefeb LibWeb: Remove FIXME if paintable is missing in getBoundingClientRect()
We should not print FIXME when paintable is missing (display: none)
because that means actually we can't to get a rect.
2023-12-16 16:11:15 +01:00
Aliaksandr Kalenik
8f8ec37d58 LibWeb: Add missing paintable null check in get_bounding_client_rect()
Fixes crashing on https://github.com/
2023-12-16 16:11:15 +01:00