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.
Instead of TextPaintable fragments being an offset+length view into the
layout node, they are now a view into the paintable instead.
This removes an awkward time window where we'd have bogus state in text
fragments after layout invalidation but before relayout. It also makes
the code slightly nicer in general, since there's less mixing of layout
and painting concepts.
Instead, just rely on the invalidation and lazy relayout that happens as
a consequence of mutating the DOM.
This allows multiple keystrokes to coalesce into a single relayout if
necessary, dramatically improving performance when typing text into
form fields on complex pages.
Now that all input events are handled by LibWebView, replace the IPCs
which send the fields of Web::KeyEvent / Web::MouseEvent individually
with one IPC per event type (key or mouse).
We can also replace the ad-hoc queued input structure with a smaller
struct that simply holds the tranferred Web::KeyEvent / Web::MouseEvent.
In the future, we can also adapt Web::EventHandler to use these structs.
The Serenity chrome is the only chrome thus far that sends all input key
and mouse events to WebContent, including shortcut activations. This is
necessary for all chromes - we must give web pages a chance to intercept
input events before handling them ourselves.
To make this easier for other chromes, this patch moves Serenity's input
event handling to LibWebView. To do so, we add the Web::InputEvent type,
which models the event data we need within LibWeb. Chromes will then be
responsible for converting between this type and their native events.
This class lives in LibWeb (rather than LibWebView) because the plan is
to use it wholesale throughout the Page's event handler and across IPC.
Right now, we still send the individual fields of the event over IPC,
but it will be an easy refactor to send the event itself. We just can't
do this until all chromes have been ported to this event queueing.
Also note that we now only handle key input events back in the chrome.
WebContent handles all mouse events that it possibly can. If it was not
able to handle a mouse event, there's nothing for the chrome to do (i.e.
there is no clicking, scrolling, etc. the chrome is able to do if the
WebContent couldn't).
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. :^)
We had previous implemented some plumbing for file input elements in
commit 636602a54e.
This implements the return path for chromes to inform WebContent of the
file(s) the user selected. This patch includes a dummy implementation
for headless-browser to enable testing.
Change `EventHandler::handle_keydown()` to no longer assume the cursor
position's node is always a `DOM::Text`. While this assumption holds
for `HTMLInputElement` that has a shadow DOM with a text node, an empty
`contenteditable` might not have any children. With this change,
`handle_keydown()` creates a new text node if the cursor position's
node is not a text node.
Fixes a crash that occurs when inputting into an empty contenteditable
element (`EditEventHandler::handle_delete()` assumes the cursor
position's node is always `DOM::Text`, which is not the case for an
empty `contenteditable`).
`EventHandler::handle_keyup()` and `EventHandler::handle_keydown()`
return true if the event has been handled and false otherwise. This is
the opposite behavior to `EventHandler::fire_keyboard_event()`.
This change inverts the return value from `fire_keyboard_event` in
these methods, allowing shortcut keys to be propagated to the Serenity
Browser UI as expected.
Ceiling width or height of a chrome viewport (this function is only used
when a chrome notifies LibWeb about a new viewport size) is never
correct. If we do that, PageClient::page_did_layout will set content
size to be 1 larger than an actual physical width or height respectively
(it always ceils) and thus a spurious scrollbar will appear.
This prevents occasional scrollbar flickering in Ladybird/Qt on Wayland
with fractional scaling enabled on compositors supporting
wp-fractional-scale-v1.
Attribute values may contain HTML, and may contain invalid HTML at that.
If the latter occurs, let's not generate invalid Inspector HTML when we
embed the attribute values as data attributes. Instead, cache the values
in the InspectorClient, and embed just a lookup index into the HTML.
This also nicely reduces the size of the generated HTML. The Inspector
on https://github.com/SerenityOS/serenity reduces from 2.3MB to 1.9MB
(about 318KB, or 13.8%).
In this change, updating layout and painting are moved to the EventLoop
processing steps. This modification allows the addition of resize
observation dispatching that needs to happen in event loop processing
steps and must occur in the following order relative to layout and
painting:
1. Update layout.
2. Gather and broadcast resize observations.
3. Paint.
Change 'dom_node_for_event_dispatch' to locate the closest layout node
with a DOM node instead of only checking the direct ancestor.
This fixes hit-testing for buttons because they are wrapped into
multiple anonymous layout nodes (internally we use flex formatting for
them).
With this change, clicking on an editable element, such as an `input`
or `textarea` causes the cursor position to be updated to the current
mouse position.
The IPC layer between chromes and LibWeb now understands that multiple
top level traversables can live in each WebContent process.
This largely mechanical change adds a billion page_id/page_index
arguments to make sure that pages that end up opening new WebViews
through mechanisms like window.open() still work properly with those
extra windows.
Instead of spawning these processes from the WebContent process, we now
create them in the Browser chrome.
Part 1/N of "all processes are owned by the chrome".
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')
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.