Changes the signature of queue_global_task() from AK:Function to
JS::HeapFunction to be more clear to the user of the function that this
is what it uses internally.
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.
...because existance of this method conflicts with the purpose of
having a queue as it allows to start executing next task in the middle
of ongoing task.
For example:
1. SHTQ timer starts executing a task.
2. Task does SHTQ::process().
Another example:
1. SHTQ::process() start executing a task.
2. task does SHTQ::process().
Workaround spec bug by explicitly carrying information whether
navigation is sync (History api, fragment change) or not.
See for more details https://github.com/whatwg/html/issues/10232
If navigation early returns before reaching "finalize a cross document
navigation" then we have to make sure delaying load events is disabled.
See spec issue https://github.com/whatwg/html/issues/10252
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.
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>
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.
When navigating to about:srcdoc we try to populate the session history
by calling populate_session_history_entry_document, if the resource is
an about:srcdoc this method will rely on the document_resource in the
SessionHistoryEntry to have a String in order for it call the right
method to create navigation params.
However when navigating to about:srcdoc directly, document_resource
will have an Empty, this leads populate_session_history_entry_document
to call the wrong method to create navigation params.
This fixes the issue by populating document_resource with an empty
string if it has an Empty and we're dealing with an about:srcdoc.
Issue: #23216
Resolves a performance regression from
8ba18dfd40, where moving paint scheduling
to `EventLoop::process()` led to unnecessary repaints.
This update introduces a flag to trigger repaints only when necessary,
addressing the issue where repaints previously occurred with each event
loop process, irrespective of actual changes.
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.
Separating the recorder list from the painter will allow us to save it
for later execution without carrying along the painter's state. This
will be useful once we have a separate thread for executing painting
commands, to which we will have to transfer commands from the main
thread.
Preparation for https://github.com/SerenityOS/serenity/pull/23108
There's a chance that we try to choose a navigable before a previously
destroyed navigable is fully destroyed and GC'd. Investigating why this
can happen is a separate endeavor, let's just not crash for now.
In this commit we have optimized the handling of scroll offsets and
clip rectangles to improve performance. Previously, the process
involved multiple full traversals of the paintable tree before each
repaint, which was highly inefficient, especially on pages with a
large number of paintables. The steps were:
1. Traverse the paintable tree to identify all boxes with scrollable or
clipped overflow.
2. Gather the accumulated scroll offset or clip rectangle for each box.
3. Perform another traversal to apply the corresponding scroll offset
and clip rectangle to each paintable.
To address this, we've adopted a new strategy that separates the
assignment of the scroll/clip frame from the refresh of accumulated
scroll offsets and clip rectangles, thus reducing the workload:
1. Post-relayout: Identify all boxes with overflow and link each
paintable to the state of its containing scroll/clip frame.
2. Pre-repaint: Update the clip rectangle and scroll offset only in the
previously identified boxes.
This adjustment ensures that the costly tree traversals are only
necessary after a relayout, substantially decreasing the amount of work
required before each repaint.
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.
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.
Paintable boxes should not hold information stored in device pixels.
It should be converted from CSS pixels only by the time painting
command recording occurs.
With this change, clip rectangles for boxes with hidden overflow or the
clip property are no longer calculated during the recording of painting
commands. Instead, it has moved to the "pre-paint" phase, along with
the assignment of scrolling offsets, and works in the following way:
1. The paintable tree is traversed to collect all paintable boxes that
have hidden overflow or use the CSS clip property. For each of these
boxes, the "final" clip rectangle is calculated by intersecting clip
rectangles in the containing block chain for a box.
2. The paintable tree is traversed another time, and a clip rectangle
is assigned for each paintable box contained by a node with hidden
overflow or the clip property.
This way, clipping becomes much easier during the painting commands
recording phase, as it only concerns the use of already assigned clip
rectangles. The same approach is applied to handle scrolling offsets.
Also, clip rectangle calculation is now implemented more correctly, as
we no longer stop at the stacking context boundary while intersecting
clip rectangles in the containing block chain.
Fixes:
https://github.com/SerenityOS/serenity/issues/22932https://github.com/SerenityOS/serenity/issues/22883https://github.com/SerenityOS/serenity/issues/22679https://github.com/SerenityOS/serenity/issues/22534
This refactoring makes WebContent less aware of LibWeb internals.
The code that initializes paint recording commands now resides in
`Navigable::paint()`. Additionally, we no longer need to reuse
PaintContext across iframes, allowing us to avoid saving and restoring
its state before recursing into an iframe.
This code didn't account for position:fixed elements, which meant that
we'd swallow repaints for such elements when the viewport wasn't
scrolled to the top of the page.
We replace the incomplete optimization with a FIXME noting that this
needs to be handled correctly when reintroduced.
(Apologies for bad commit title, it's hard to explain in such a short
space!)
We're going to need to call this for producing markdown and gemini
documents, both of which need a Document and Realm to fetch the entire
response body, so that they can then generate their HTML. So this
commit modifies `create_document_for_inline_content()` to take a lambda
instead of a fixed HTML string, to support these uses.
Also, we always return a nonnull pointer, so make that the return type.
This is a move and change in the same commit, (Sorry!) but all the
changes are to the function signature and step 6.
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')