This moves communication and route matching for WebDriver endpoints into
LibWeb. This is to reduce the amount of duplication required to create a
WebDriver implementation for Ladybird.
In doing so, this introduces some cleanup of WebDriver handling. Routes
are now a compile-time array, and matching a route is nearly free of
allocations (we still allocate a Vector for parsed parameters). This
implementation also makes heavier use of TRY semantics to propagate
errors into one handler.
This will allow for implementing the screenshot action closer to the
spec, as we can now use HTMLCanvasElement to encode the bitmap, and
capture the screenshot on the animation frame loop.
This can resolve height early in some cases, notably this kind of setup:
position: absolute;
top: 0px;
bottom: 0px;
By resolving height before inside layout, descendants of the abspos
element can resolve automatic and relative vertical lengths against it.
This makes the Discord UI occupy the whole window instead of looking
"shrink-to-fit".
This is essentially an ErrorOr<JsonValue, Web::WebDriver::Error> class.
Unfortunately, that ErrorOr would not be default-constructible, which is
required for the generated IPC classes. So this is a thin wrapper around
a Variant<JsonValue, Web::WebDriver::Error> to emulate ErrorOr.
This makes hovering over the link in the following HTML snippet work,
i.e. the tooltip is shown and the link target is shown at the bottom
of the browser window:
<html lang="en"><head><style>
.site-link{display:inline-block}
.site-link:before{content:"derp"}
.site-link::after{content:"";display:block}
</style></head><body><a class="site-link" href="#"
title="Tooltip, maybe!"></a>
The container appears to be null for certain elements such as the
"update your browser" box when clicking on the document during certain
parts of loading. Skipping it works fine, but should obviously be
fixed, so it prints a debug output when this happens.
Google Docs focuses a "text event target" iframe using Window.focus on
the iframe's contentWindow. Doing so makes the iframe's document the
focused element we have to fire text events at. However, in the top
level browsing context, the focused element is still the iframe, so we
have to repeat the keyboard event steps but with the iframe's nested
browsing context instead.
process_the_iframe_attributes already causes a navigation, so this
would cause a double navigation and blow away any setup that JS may
have done from events fired in process_the_iframe_attributes.
This was a missing spec step. This prevents it navigating to
about:blank, which will blow away the document and thus any setup that
was done in the iframe load event.
These are required for hit testing the document in Google Docs. If they
aren't defined, the Google Docs hit test code will add undefined to
certain values, causing them to turn into NaN. This causes NaNs to
propagate through their hit test code, which eventually makes it
infinitely loop.