With this change, instead of applying scroll offsets during the
recording of the painting command list, we do the following:
1. Collect all boxes with scrollable overflow into a PaintContext,
each with an id and the total amount of scrolling offset accumulated
from ancestor scrollable boxes.
2. During the recording phase assign a corresponding scroll_frame_id to
each command that paints content within a scrollable box.
3. Before executing the recorded commands, translate each command that
has a scroll_frame_id by the accumulated scroll offset.
This approach has following advantages:
- Implementing nested scrollables becomes much simpler, as the
recording phase only requires the correct assignment of the nearest
scrollable's scroll_frame_id, while the accumulated offset from
ancestors is applied subsequently.
- The recording of painting commands is not tied to a specific offset
within scrollable boxes, which means in the future, it will be
possible to update the scrolling offset and repaint without the need
to re-record painting commands.
In a bunch of cases, this actually ends up simplifying the code as
to_number will handle something such as:
```
Optional<I> opt;
if constexpr (IsSigned<I>)
opt = view.to_int<I>();
else
opt = view.to_uint<I>();
```
For us.
The main goal here however is to have a single generic number conversion
API between all of the String classes.
With this change, chrome no longer has to ask the WebContent process
to paint the next frame into a specified bitmap. Instead, it allocates
bitmaps and sends them to WebContent, which then lets chrome know when
the painting is done.
This work is a preparation to move the execution of painting commands
into a separate thread. Now, it is much easier to start working on the
next frame while the current one is still rendering. This is because
WebContent does not have to inform chrome that the current frame is
ready before it can request the next frame.
Additionally, as a side bonus, we can now eliminate the
did_invalidate_content_rect and did_change_selection IPC calls. These
were used solely for the purpose of informing chrome that it needed to
request a repaint.
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')
Let's not assume there is one global OpenGL context because it might
change once we will start creating >1 page inside single WebContent
process or contexts for WebGL.
No functional impact intended. This is just a more complicated way of
writing what we have now.
The goal of this commit is so that we are able to store the 'name' of a
pseudo element for use in serializing 'unknown -webkit-
pseudo-elements', see:
https://www.w3.org/TR/selectors-4/#compat
This is quite awkward, as in pretty much all cases just the selector
type enum is enough, but we will need to cache the name for serializing
these unknown selectors. I can't figure out any reason why we would need
this name anywhere else in the engine, so pretty much everywhere is
still just passing around this raw enum. But this change will allow us
to easily store the name inside of this new struct for when it is needed
for serialization, once those webkit unknown elements are supported by
our engine.
The empty value we are currently returning hits the `decltype(nullptr)`
constructor of TakeDocumentScreenshotResponse. This is interpreted as an
invalid response by LibIPC. Instead, return a Gfx::ShareableBitmap that
the client-side can handle, and e.g. display an error, rather than the
message just being dropped.
It was a bit short-sighted to combine the tag and attribute names into
one string when the Inspector requests a context menu. We will want both
values for some context menu actions. Send both names, as well as the
attribute value, when requesting the context menu.
Currently, when editing a DOM attribute, the replacement method first
removes the attribute, then adds the replacement attributes. This
results in the edited attribute jumping to the end of the attribute
list in the Inspector.
This patch will try to avoid removing the attribute if one of the
replacements has the same name. This will keep the edited attribute in
the same location.
The FIXME added to ConnectionFromClient::remove_dom_node is copied from
Web::EditEventHandler. The same behavior is observed here, with many
lingering Layout::TextNodes, for example.
The Inspector will have context menu support to manipulate the DOM, e.g.
adding or removing nodes/attributes. This context menu will require some
detailed knowledge about what element in the Inspector has been clicked.
To support this, we intercept the `contextmenu` event and collect the
required information to be sent to the Inspector client over IPC.
This is a first step towards removing the various Page& and Page*
we have littering the engine with "trust me bro" safety guarantees.
Co-Authored-By: Andreas Kling <kling@serenityos.org>
This is a first step towards simplifying the ownership model of
Web::Page. Soon Web::Page will store its WebClient as a
NonnullGCPtr to help solve lifetime issues of the client being
destroyed before the page.
This adds APIs to allow Ispector clients to:
* Change a DOM text or comment node's text data.
* Add, replace, or remove a DOM element's attribute.
* Change a DOM element's tag.
The Inspector will have an <input> element to execute user-provided JS.
This adds an IDL method and IPC to forward that JS from the Inspector
WebView to the Inspector client.
In order for same-origin NavigableContainers (iframe, frame, embed, ...)
and window.open() WindowProxies to have the proper JS access to their
embedder/opener, we need to host multiple top level traversables in the
same WebContent process. As a first step, make WebContent::PageHost hold
a HashMap of PageClient objects, each holding their own Web::Page that
represents a TraversableNavigable's API surface with the UI process.
The `page_did_request_scroll_to` API takes a CSS position, and thus
callers should not scale to device pixels before invoking it. Instead,
align this API with (most) other PageHost APIs which scale to device
pixels before sending the corresponding IPC message.
In the AppKit chrome, convert the provided device pixel position to a
widget position.
For each stacking context with an opacity less than 1, we create a
separate framebuffer. We then blit the texture attached to this
framebuffer with the specified opacity.
To avoid the performance overhead of reading pixels from the texture
into Gfx::Bitmap, a new method that allows for direct blitting from
the texture is introduced, named blit_scaled_texture().
This is an internal object that must be explicitly enabled by the chrome
before it is added to the Window. The Inspector object will be used by a
special WebView that will replace all chrome-specific inspector windows.
The IDL defines methods that this WebView will need to inform the chrome
of various events, such as the user clicking a DOM node.
We now create a WorkerAgent for the parent context, which is currently
only a Window. Note that Workers can have Workers per the spec.
The WorkerAgent spawns a WebWorker process to hold the actual
script execution of the Worker. This is modeled with the
DedicatedWorkerHost object in the WebWorker process.
A start_dedicated_worker IPC method in the WebWorker IPC creates the
WorkerHost object. Future different worker types may use different IPC
messages to create their WorkerHost instance.
This implementation cannot yet postMessage between the parent and the
child processes.
Co-Authored-By: Andreas Kling <kling@serenityos.org>
Framebuffer object is allocated using OpenGL's API and is not platform
specific which means it could be used on both macOS and Linux unlike
EGL specific PBuffer.