Commit graph

535 commits

Author SHA1 Message Date
Aliaksandr Kalenik
649f70db65 LibWeb+WebContent: Initialise JS console from Document::initialize()
Before this change JS console was initialise from
activate_history_entry() which is too late for about:blank documents
that are ready to run scripts immediately after creation.
2024-04-11 18:41:20 +02:00
Matthew Olsson
d47f656a3a LibJS+LibWeb: Mark a few variables as IGNORE_USE_IN_ESCAPING_LAMBDA
This is a bit noisy, but it'll be better once we upgrade to C++23.
2024-04-09 09:10:44 +02:00
Aliaksandr Kalenik
a3149c1ce9 LibWeb: Wait for initial navigation to complete before modifying iframe
If initial src of an iframe is "about:blank", it does synchronous
navigation that is not supposed to be interleaved by other navigation
or usage of Document.open().

Fixes crashing in navigation on https://twinings.co.uk/
2024-04-08 09:07:18 +02:00
Shannon Booth
c3217754f1 LibWeb: Remove a bunch of calls to to_byte_string
A bunch of this is leftover from pre porting over to new AK::String.
For example, for functions which previously took a ByteString const&
now accepting a StringView.
2024-04-05 20:01:37 -04:00
Andreas Kling
2ef37c0b06 LibWeb: Make EventLoop, TaskQueue, and Task GC-allocated
...and use HeapFunction instead of SafeFunction for task steps.

Since there is only one EventLoop per process, it lives as a global
handle in the VM custom data.

This makes it much easier to reason about lifetimes of tasks, task
steps, and random stuff captured by them.
2024-04-05 08:14:19 +02:00
Andreas Kling
d91d6ee205 LibWeb: Stop leaking entire realms via Blob URLs
This patch implements the File API spec's supplemental steps for
document's "unloading document cleanup steps" so that we now remove blob
URLs associated with the document's relevant settings object when the
document is being unloaded.

Fixes two realm leaks when running our test suite.
2024-04-03 22:20:50 +02:00
Andrew Kaster
12fce55caf LibWeb: Don't load favicons twice for non-SVG documents
This seems to be a rebase mishap in bdb8af94ee.
2024-04-03 09:56:53 -06:00
mobounya
bdb8af94ee LibWeb: Don't load fallback icon for SVG documents
Skip loading a fallback favicon if Document represents a decoded SVG.

Issue: #23405
2024-04-03 09:45:31 -06:00
Shannon Booth
ce341c0230 LibWeb: Add support for document.lastModified 2024-04-02 07:51:02 +02:00
Tim Ledbetter
558fef237c LibWeb: Use the global object to access the performance object
Previously, we were accessing the performance through the current
window object. Thus caused a crash when `animate()` was called on an
element within a document with no associated window object. The global
object is now used to access the performance object in places where
a window object is not guaranteed to exist.
2024-04-02 07:46:16 +02:00
Shannon Booth
249ee0a30e LbiWeb: Return an HTMLAllCollection from document.all 2024-04-01 14:41:00 +02:00
Aliaksandr Kalenik
9098fa23a2 LibWeb: Catch up with the spec on document destroy, abort and unload
These changes do not solve hanging `location.reload()` and
`location.go()` but only align implementation with the latest edits in
the specification.

`WindowProxy-Get-after-detaching-from-browsing-context` test output is
affected because `iframe.remove();` no longer synchronously does
destruction of a document, but queues a task on event loop.

Co-Authored-By: Andrew Kaster <akaster@serenityos.org>
2024-04-01 13:23:58 +02:00
Matthew Olsson
e4f1cb6f8c LibWeb: Track the transition generation
This is used for transition's class-specific composite ordering
2024-03-29 21:58:12 +01:00
Timothy Flynn
43e55668eb LibWeb: Implement Document's supported property names closer to the spec
Our implementation was errantly matching HTML tags other than the list
specified by the spec. For example, a <meta name=title> tag would be a
match for document.title.

For example, bandcamp will dynamically update its title when audio is
played as follows:

    document.title = "▶︎ " + document.title;

And bandcamp also has a <meta name=title> tag. The result was that the
title would become "▶︎ [object HTMLMetaElement]".
2024-03-29 08:52:01 -04:00
Matthew Olsson
4dc8492155 LibWeb: Move animation event dispatch into update_animations_and_...()
This will be important for the next commit
2024-03-29 06:59:37 +01:00
Aliaksandr Kalenik
ca363f0024 LibWeb: Add basic "top layer" support
Implements the "top layer" concept from "CSS Positioned Layout Module
Level 4" specification.

- The tree builder is modified to ensure that layout nodes created by
  top layer elements are children of the viewport.
- Implements missing steps in `showModal()` to add an element top top
  layer.
- Implements missing steps in `close()` to remove an element from top
  layer.

Further steps could be:
- Add support for `::backdrop` pseudo-element.
- Implement the "inert" concept from HTML spec to block hit-testing
  when element from top layer is displayed.
2024-03-29 06:57:07 +01:00
Aliaksandr Kalenik
ffd3639b17 LibWeb: Pass navigation params by const-ref to load_document() 2024-03-28 15:34:52 +01:00
Aliaksandr Kalenik
b590d1b48b LibWeb: Transform SessionHistoryEntry from a struct to a class
No behaviour change intended.
2024-03-27 18:07:07 +01:00
Aliaksandr Kalenik
4ae2eaead1 LibWeb: Dispatch mouseout and mouseover events 2024-03-25 08:14:13 +01:00
Andreas Kling
afe6abfc09 LibWeb: Use an ancestor filter to quickly reject many CSS selectors
Given a selector like `.foo .bar #baz`, we know that elements with
the class names `foo` and `bar` must be present in the ancestor chain of
the candidate element, or the selector cannot match.

By keeping track of the current ancestor chain during style computation,
and which strings are used in tag names and attribute names, we can do
a quick check before evaluating the selector itself, to see if all the
required ancestors are present.

The way this works:

1. CSS::Selector now has a cache of up to 8 strings that must be present
   in the ancestor chain of a matching element. Note that we actually
   store string *hashes*, not the strings themselves.

2. When Document performs a recursive style update, we now push and pop
   elements to the ancestor chain stack as they are entered and exited.

3. When entering/exiting an ancestor, StyleComputer collects all the
   relevant string hashes from that ancestor element and updates a
   counting bloom filter.

4. Before evaluating a selector, we first check if any of the hashes
   required by the selector are definitely missing from the ancestor
   filter. If so, it cannot be a match, and we reject it immediately.

5. Otherwise, we carry on and evaluate the selector as usual.

I originally tried doing this with a HashMap, but we ended up losing
a huge chunk of the time saved to HashMap instead. As it turns out,
a simple counting bloom filter is way better at handling this.
The cost is a flat 8KB per StyleComputer, and since it's a bloom filter,
false positives are a thing.

This is extremely efficient, and allows us to quickly reject the
majority of selectors on many huge websites.

Some example rejection rates:
- https://amazon.com: 77%
- https://github.com/SerenityOS/serenity: 61%
- https://nytimes.com: 57%
- https://store.steampowered.com: 55%
- https://en.wikipedia.org: 45%
- https://youtube.com: 32%
- https://shopify.com: 25%

This also yields a chunky 37% speedup on StyleBench. :^)
2024-03-22 18:27:32 +01:00
Aliaksandr Kalenik
42d5883d57 LibWeb: Set animation update flag from Animation::invalidate_effect()
Fixes regressed animation tests.
2024-03-21 16:10:26 +01:00
Aliaksandr Kalenik
b7d28ee57d LibWeb: Change update_style() to update animated style only if needed
Instead of invalidating animated style properties whenever
`Document::update_style()` is called, now we only do that when
animations might have actually progressed. We still have to ensure
animated properties are up-to-date in `update_style()` to ensure that
JS methods can access updated style properties.
2024-03-21 11:29:02 +01:00
Aliaksandr Kalenik
96d67ded3e LibWeb: Always run layout and style updates from event loop processing
Before this change, we ran style and layout updates from both event
loop processing and update timers. This could have caused missed resize
observer updates and unnecessary updating of style or layout more than
once before repaint.

Also, we can now be sure unnecessary style or layout updates won't
happen in `EventLoop::spin_processing_tasks_with_source_until()`.
2024-03-20 20:28:21 +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
4e4b9f440f Revert "LibWeb: Run IntersectionObserver steps only when needed"
This reverts commit 11b4216e65.
2024-03-19 13:04:39 +01:00
Shannon Booth
e800605ad3 AK+LibURL: Move AK::URL into a new URL library
This URL library ends up being a relatively fundamental base library of
the system, as LibCore depends on LibURL.

This change has two main benefits:
 * Moving AK back more towards being an agnostic library that can
   be used between the kernel and userspace. URL has never really fit
   that description - and is not used in the kernel.
 * URL _should_ depend on LibUnicode, as it needs punnycode support.
   However, it's not really possible to do this inside of AK as it can't
   depend on any external library. This change brings us a little closer
   to being able to do that, but unfortunately we aren't there quite
   yet, as the code generators depend on LibCore.
2024-03-18 14:06:28 -04:00
Andreas Kling
1987318cc2 LibWeb: Move selection state from layout tree to paint tree
Where we paint the selection is obviously paint-related information,
so let's keep it in the paint tree.
2024-03-18 13:42:16 +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
98cf845d8a LibWeb: Use HTML::EventNames::animation* instead of string literals 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
b98a2be96b LibWeb: Ignore window-forwarded document.body.onfoo in detached DOM
Normally, assigning to e.g document.body.onload will forward to
window.onload. However, in a detached DOM tree, there is no associated
window, so we have nowhere to forward to, making this a no-op.

The bulk of this change is making Document::window() return a nullable
pointer, as documents created by DOMParser or DOMImplementation do not
have an associated window object, and so must be able to return null
from here.
2024-03-11 18:29:10 +01:00
Aliaksandr Kalenik
ecce570cb7 LibWeb: Stop animation driver timer after document becomes inactive 2024-03-11 16:44:05 +01:00
Aliaksandr Kalenik
fd63ffb8c3 LibWeb: Use Core::Timer instead for animation driver timer
Platform::Timer uses JS::SafeFunction that prevents document from ever
being deallocated because of strong reference.
2024-03-11 16:44:05 +01:00
Matthew Olsson
e91f4dcd79 LibWeb: Use Performance for animation time instead of MonotonicTime
Performance handles the document origin time correctly, and prevents
these times from being unusually large. Also initialize the
DocumentTimeline time in the constructor, since these can be created
from JS.
2024-03-10 15:13:47 +01:00
Aliaksandr Kalenik
91ec1d6f95 LibWeb: Maintain list of allocated shadow roots in Document
Doing that will allow us to get a list of style sheets for each shadow
root from StyleComputer without having to traverse the entire tree in
upcoming changes.
2024-03-09 16:13:32 +01:00
Aliaksandr Kalenik
8ce8697a66 LibWeb: Add styleSheets and adoptedStyleSheets attributes in ShadowRoot
Co-authored-by: Simon Wanner <simon+git@skyrising.xyz>
2024-03-09 16:13:32 +01:00
Aliaksandr Kalenik
f19c92d78e LibWeb: Add ObservableArray::for_each() 2024-03-09 16:13:32 +01:00
Aliaksandr Kalenik
7c322ec710 LibWeb: Implement adoptedStyleSheets attribute for Document
https://drafts.csswg.org/cssom/#dom-documentorshadowroot-adoptedstylesheets

The attribute implementation for ShadowRoot is currently missing
because we do not yet distinguish between the style sheets of
ShadowRoot and Document, and we need to address the issue first.
2024-03-08 16:31:21 +01:00
Shannon Booth
9ce8189f21 Everywhere: Use unqualified AK::URL
Now possible in LibWeb now that there is no longer a Web::URL.
2024-02-25 08:54:31 +01:00
Andreas Kling
11b4216e65 LibWeb: Run IntersectionObserver steps only when needed
Instead of updating IOs in every iteration of the HTML event loop,
we now only do it after a relayout, or after the viewport changes.
2024-02-24 19:56:08 +01:00
Matthew Olsson
fc62989f1a LibWeb: Add missing visits for Document's pending animation event queue 2024-02-23 20:52:37 +01:00
Matthew Olsson
65858154de LibWeb: Dispatch Animation events 2024-02-23 20:52:37 +01:00
Matthew Olsson
ae3326a447 LibWeb: Transition StyleComputer to Web Animations
With this commit, we are finally running animations off of the web
animations spec! A lot of the work StyleComputer is doing is now done
elsewhere. For example, fill-forward animations are handled by
Animation::is_relevant() returning true in the after phase, meaning the
"active_state_if_fill_forward" map is no longer needed.
2024-02-23 20:52:37 +01:00
Matthew Olsson
10fddb99fc LibWeb: Implement Document::remove_replaced_animations() 2024-02-22 07:31:54 +01:00
Matthew Olsson
fe848487db LibWeb: Add Document::update_animations_and_send_events 2024-02-22 07:31:54 +01:00
Timothy Flynn
af57bd5cca LibWeb: Stop parsing after document.write at the insertion point
If a call to `document.write` inserts an incomplete HTML tag, e.g.:

    document.write("<p");

we would previously continue parsing the document until we reached a
closing angle bracket. However, the spec states we should stop once we
reach the new insertion point.
2024-02-20 17:04:36 +01:00
Aliaksandr Kalenik
fcf293a8df LibWeb: Implement gathering and broadcasting of resize observations
Extends event loop processing steps to include gathering and
broadcasting resize observations.

Moves layout updates from Navigable::paint() to event loop processing
steps. This ensures resize observation processing occurs between layout
updates and painting.
2024-02-20 10:55:10 +01:00
Aliaksandr Kalenik
fb8edcea00 LibWeb: Flesh out implementation of ResizeObserver interfaces
Adds the initial implementation for interfaces defined in the
ResizeObserver specification. These interfaces will be used to
construct and send observation events in the upcoming changes.
2024-02-20 10:55:10 +01:00
Tim Ledbetter
02c2b1e67e LibWeb: Implement document.createCDATASection() 2024-02-19 10:42:56 +01:00