Commit graph

1500 commits

Author SHA1 Message Date
Shannon Booth
51a52a867c LibWeb: Use "current high resolution time" AO where relevant
And updating some spec comments to latest spec where it is not relevant.
2024-04-12 09:08:46 +02:00
Aliaksandr Kalenik
ee3dd7977d LibWeb: Add popstate event support
It is going to be useful in writing tests for History API.
2024-04-11 21:25:06 +02:00
Timothy Flynn
4b1abcf61d LibWeb: Generalize support for dimension attributes
Rather than each element which supports dimension attributes needing to
implement parsing the attributes and setting the appropriate style, we
can generalize this functionality. This will also make each element more
closely resemble the spec text, as we will be effectively declaring, for
example, "The img element supports dimension attributes" in code.
2024-04-11 18:41:57 +02:00
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
Aliaksandr Kalenik
ba633882bf LibWeb: Change load_html_document to run parsing from deferred_invoke()
...callback, otherwise Networking task source will be blocked until the
end of HTML parsing.

This is a preparation before forbidding to interleave HTML tasks with
the same source.
2024-04-10 07:36:42 +02:00
Andreas Kling
870a954e11 LibWeb: Implement Element.outerHTML
This piggybacks on the same fragment serialization code that innerHTML
uses, but instead of constructing an imaginary parent element like the
spec asks us to, we just add a separate serialization mode that includes
the context element in the serialized markup.

This makes the image carousel on https://utah.edu/ show up :^)
2024-04-09 18:17:14 -04:00
Matthew Olsson
31341b280a LibWeb: Add calls to JS_{DECLARE,DEFINE}_ALLOCATOR() 2024-04-09 09:13:06 +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
Matthew Olsson
ff00d21d58 Everywhere: Mark a bunch of function parameters as NOESCAPE
This fixes the relevant warnings when running LibJSGCVerifier. Note that
the analysis is only performed over LibJS-adjacent code, but could be
performed over the entire codebase. That will have to wait for a future
commit.
2024-04-09 09:10:44 +02:00
Aliaksandr Kalenik
94d72c174a LibWeb: Allow executing scripts for iframes with src=about:blank
Fixes https://github.com/SerenityOS/serenity/issues/23836
2024-04-08 21:27:34 +02:00
Shannon Booth
b873e5bc1d LibWeb: Implement the PointerEvent interface
As defined in: https://w3c.github.io/pointerevents

With the exception of the getCoalescedEvents and getPredictedEvents
APIs.

There are still many other parts of that spec (such as the event
handlers) left to implement, but this does get us at least some of the
way.
2024-04-08 14:25:08 +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
80658743d3 LibWeb: Generate Optional<NonnullGCPtr<T>> as GCPtr<T>
This is the general pattern which has been adopted in LibWeb, so let's
generate our IDL like this too.
2024-04-07 18:01:05 +02:00
Matthew Olsson
7001e0a428 LibWeb: Fix a LibJSGCVerifier warning in DOM::Text 2024-04-07 07:03:13 +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
Timothy Flynn
48fb343230 LibWeb: Change HTMLParser's factory to accept the encoding as StringView
No need to force an allocation. This makes a future patch a bit simpler,
where we will have the encoding as a String. With this patch, we won't
have to convert it to a ByteString.
2024-04-04 11:23:21 +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
Andreas Kling
f1eb837c3d LibWeb: Remove unnecessary JS::Handle in AbortSignal::timeout()
This fixes yet another GC reference cycle.
2024-04-03 18:14:33 +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
adf061a29c LibWeb: Avoid copying cached elements in HTMLCollection
Once we have built up a cache, we can use that internally for operations
on the collection, instead of copying over the list of elements every
time.

On a synthentic benchmark of a page with ~500 link elements, this
results in a 45% percent speedup on my machine.

```html
<body>
    <ul>
        <li><a href="#">Link 1</a></li>
        ...
        <li><a href="#">Link N</a></li>
    </ul>

    <script>
        window.onload = function() {
            const startTime = performance.now();
            for (let i = 0; i < 1_000_000; ++i) {
                const numLinks = document.links.length;
            }
            const endTime = performance.now();
            const timeTaken = endTime - startTime;
            console.log(timeTaken);
        };
    </script>
</body>
</html>
```
2024-04-02 07:33:40 +02:00
Shannon Booth
094ab8b4d2 LibWeb: Remove some uneeded const_casts from HTMLCollection
Correcting a variable name while we're at it.
2024-04-02 07:33:40 +02:00
Shannon Booth
b1be8bd826 LibWeb: Implement is_supported_property_index in terms of length() 2024-04-02 07:33:40 +02:00
Shannon Booth
b9b264e97a LibWeb: Remove redundant is_empty check from is_supported_property_index
An empty list of elements will not return true for any unsigned number,
so we can simply remove this check.
2024-04-02 07:33:40 +02:00
Shannon Booth
cdd0038c9e LibWeb: Factor out a method to update the cached elements
This is useful for any function which is needing to read the from the
cache, instead of onl using `collect_matching_elements`.
2024-04-02 07:33:40 +02:00
Shannon Booth
249ee0a30e LbiWeb: Return an HTMLAllCollection from document.all 2024-04-01 14:41:00 +02:00
Shannon Booth
897f55ca8a LibWeb: Use NonnullGCPtr for HTMLCollection::collect_matching_elements
The pointers here can never be null, so lets engrain that into the type
for clarity.
2024-04-01 14:41:00 +02:00
Shannon Booth
8fa0730b84 LibWeb: Remove resolved FIXME about caching in HTMLCollection 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
Tim Ledbetter
8e6e938167 LibWeb: Remove AbortSignal::follow()
This no longer has any callers.
`AbortSignal::create_dependent_abort_signal()` should be used instead.
2024-03-26 11:42:40 +01:00
Tim Ledbetter
17e64cf08b LibWeb/Fetch: Replace usages of AbortSignal::follow() in Fetch::Request
Since the introduction of `AbortSignal::any()`, the specification says
`AbortSignal::create_dependent_abort_signal()` should be used where
`AbortSignal::follow` was previously.
2024-03-26 11:42:40 +01:00
Aliaksandr Kalenik
4ae2eaead1 LibWeb: Dispatch mouseout and mouseover events 2024-03-25 08:14:13 +01:00
Tim Ledbetter
2227674b91 LibWeb: Don't crash when updating a select with detached option elements
`Node::shadow_including_root()` was missing a null check, which caused
a crash when manipulating a select element, whose option elements were
initially detached.
2024-03-23 20:56:26 +01:00
Tim Ledbetter
521a1be97f LibWeb: Don't crash when querying the CDataSection.assignedSlot property 2024-03-23 20:56:26 +01:00
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
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
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
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
Andreas Kling
6bb4a2bfaa LibWeb: Let HTMLCollection cache its element list
Use the new DOM tree version mechanism to allow HTMLCollection to
remember its internal list of elements instead of rebuilding it on
every access.

This avoids thousands of full DOM walks while loading our GitHub repo.

~15% speed-up on jQuery subtests in Speedometer 3.0 :^)
2024-03-19 20:59:36 +01:00