Commit graph

218 commits

Author SHA1 Message Date
Timothy Flynn
22e0eeada2 Everywhere: Hoist the Services folder to the top-level 2024-11-10 12:50:45 +01:00
Jonne Ransijn
635d4842d1 LibWeb: Return CSS::StyleProperties::property results by reference
This removes unnecessary reference counting.
2024-11-08 10:21:26 +00:00
Timothy Flynn
ad1ba30b27 WebContent: Serialize the document element's outer HTML for WebDriver 2024-11-06 20:44:19 -05:00
Timothy Flynn
7b64942fe2 WebContent: Return element tag names as lowercase for WebDriver
Erring on the side of web reality on this one, as other engines return
lowercase tag names, and this is expected by WPT.
2024-11-06 20:44:19 -05:00
Timothy Flynn
1417314aa9 WebContent: Do not coerce element properties to strings for WebDriver
We want the "raw" value here. The spec sort of assumes we are sending JS
values over the wire, whereas we are actually sending AK::JsonValue. So
using the JSON clone AO here is our best bet.
2024-11-06 20:44:19 -05:00
Timothy Flynn
33a00f45fd WebContent: Ensure the document's style is up to date for WebDriver
Otherwise, we have a timing issue retrieving computed styles.
2024-11-06 20:44:19 -05:00
Timothy Flynn
ecaacd2adf LibWeb+WebContent: Update our list of boolean attributes for WebDriver
Chromium has a larger list of boolean attributes, and WPT depends on it.
We must also compare attribute names case-insensitively.

Note this method is only used by WebDriver.
2024-11-06 20:44:19 -05:00
Timothy Flynn
1a8a3979f9 WebContent: Implement the WebDriver Forward endpoint according spec 2024-11-06 10:54:17 +01:00
Timothy Flynn
d867cd26c4 WebContent: Implement the WebDriver Back endpoint according spec 2024-11-06 10:54:17 +01:00
Timothy Flynn
3afd88330b WebContent: Handle user prompts in the Take Screenshot endpoint
This is a spec issue, and WPT relies on this behavior.
2024-11-06 10:50:33 +01:00
Timothy Flynn
185255efc3 WebContent: Close top-level traversables asynchronously
The spec is a bit out-of-date here, so this works around an issue with
closing top-level traversables while a dialog is open in another window
within the same agent.
2024-11-05 10:58:34 -07:00
Timothy Flynn
d66b54fec5 WebContent+WebDriver: Transfer WebDriver capability init to Session
Capabilities are configured on a per-session basis, but we were only
applying these options to the first WebContent process created. We will
need to pass these options to new windows created from that process.
This patch re-organizes capability processing so that our session can
remember them for new windows.
2024-11-05 10:58:34 -07:00
Timothy Flynn
6bc339b737 WebContent: Ensure we mark a driver endpoint as complete in early return
Fixes a mistake from 3da20aca65.
2024-11-04 16:16:44 -05:00
Timothy Flynn
5010e42cd3 WebContent: Treat <frame> elements as navigable containers in WebDriver 2024-11-04 09:54:32 +00:00
Timothy Flynn
64a8fcc4ef LibWeb: Begin implementing a Selenium-like method to get element text
Unfortunately, there isn't an exact spec method to get the rendered text
of an element, including its shadow DOM. The WebDriver spec requires
just doing exactly what Selenium does.

This patch does not implement this, but is a step in the right direction
as we will now handle text transforms.
2024-11-03 20:42:46 -05:00
Timothy Flynn
a4daf6f928 WebContent: Implement WebDriver's Switch Frame endpoint for numeric IDs 2024-11-03 20:42:46 -05:00
Timothy Flynn
3da20aca65 WebContent+WebDriver: Convert all user prompt handlers to be async
Making these async were all actually pretty trivial. This patch does so,
and removes the deprecated synchronous user prompt handler.
2024-11-03 22:11:19 +01:00
Timothy Flynn
fd3f8b7645 LibWeb+WebContent: Fully implement WebDriver JSON deserialization 2024-11-03 17:51:58 +01:00
Timothy Flynn
6fb8500a7a LibWeb+WebContent: Simplify hand-rolled script execution result struct
Instead of maintaining a list of script execution result types, which we
then map to WebDriver error types, just return the WebDriver error that
is specified by the spec. Then perform the JSON clone algorithm from the
caller in WebDriverConnection, again as specified by the spec. To do so,
this moves the JSON clone algorithm to its own file. This will also be
the future home of the JSON deserialize algorithm, which will need some
of the internal AOs implemented there.
2024-11-03 17:51:58 +01:00
Timothy Flynn
a5ca036d36 LibWeb+WebContent: Update and fully implement the JSON clone algorithm
We have the facilities now to fully implement this AO. Do so, and update
the AO to match the latest spec.
2024-11-03 17:51:58 +01:00
Timothy Flynn
f16eebb95c WebContent: Begin handling user prompts asynchronously
We have to handle user prompts during the exection of most WebDriver
endpoints. Of the ~50 endpoints which call this AO, ~20 are currently
currently async and handled here.
2024-11-02 11:09:41 +01:00
Timothy Flynn
5515cb56e8 WebContent: Deprecate the curent implementation of handling user prompts
There are approximately 1000 WPT subtests that rely on the handling of
user prompts being completely asynchronous. It will take a bit of elbow
grease to make all of our WebDriver endpoints comply with this. So for
now, we will deprecate the currently synchronous implementation, and a
future patch will implement an asynchronous version that already-async
endpoints can use.
2024-11-02 11:09:41 +01:00
Timothy Flynn
9dc1302768 WebContent+WebDriver: Consolidate driver execution completion callbacks
Some WebDriver hooks will need to inform the client that execution has
completed, but without any knowledge of what endpoint was running. Since
there can only ever be a single WebDriver endpoint executing at once, we
can replace the completion callbacks with a single callback.
2024-11-02 11:09:41 +01:00
Timothy Flynn
1be67faab7 LibWeb+WebContent: Handle user prompts that open during script execution
If a dialog is opened while a script is executing, we must give control
back to the WebDriver client. The script must also continue executing
though, so once it completes, we ignore its result.
2024-11-02 11:09:41 +01:00
Shannon Booth
cc91473f4d LibWeb: Make TemporaryExecutionContext take a Realm& 2024-11-01 18:55:23 -06:00
Timothy Flynn
f064c6e930 LibWeb+WebContent+WebDriver: Make the screenshot endpoints asynchronous
These were the last WebDriver endpoints spinning the event loop.
2024-10-31 02:39:36 +00:00
Timothy Flynn
ad9d623664 WebContent+WebDriver: Make the element locator endpoints asynchronous
We currently spin the event loop to wait for the specified element to
become available. As we've seen with other endpoints, this can result
in dead locks if another web component also spins the event loop.

This patch makes the locator implementations asynchronous.
2024-10-31 00:42:29 +00:00
Shannon Booth
7487a782db LibWeb: Use HeapFunction for EventLoopPlugin::spin_until 2024-10-30 20:55:45 +01:00
Aliaksandr Kalenik
a8077f79cc LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.

With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.

This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.

I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
2024-10-30 19:29:56 +01:00
Timothy Flynn
3ca2ee9c72 LibWeb+WebContent+WebDriver+UI: Make window min/maximize asynchronous
This follows suit of previous changes to never block the WebContent
process in WebDriver endpoints.
2024-10-29 11:03:20 +00:00
Timothy Flynn
fa83cc722c LibWeb+WebContent+WebDriver+UI: Make window rect updates asynchronous
It's currently possible for window size/position updates to hang, as the
underlying IPCs are synchronous. This updates the WebDriver endpoint to
be async, to unblock the WebContent process while the update is ongoing.
The UI process is now responsible for informing WebContent when the
update is complete.
2024-10-29 11:03:20 +00:00
Jonne Ransijn
07cd7d479f LibWeb: Remove reference counting for CSS::StyleProperties
`AK::CopyOnWrite` already does reference counting, so there is no need
to do it again.
2024-10-27 13:26:30 +01:00
Timothy Flynn
0722a3b1c0 LibWeb+WebContent+WebDriver: Asynchronously wait for dialog dismissal
There was a timing issue here where WebDriver would dismiss a dialog,
and then invoke another endpoint before the dialog was actually closed.
This is because the dismissal first has to hop over to the UI process to
close the graphical dialog, which then asynchronously informs WebContent
of the result. It's not until WebContent receives that result that the
dialog is considered closed, thus those subsequent endpoints would abort
due a dialog being "open".

We now wait for dialogs to be fully closed before returning from the
dismissal endpoints.
2024-10-26 11:25:42 +02:00
Timothy Flynn
bf0bc62654 WebContent+WebDriver: Asynchronously wait for navigations to complete
Similar to commit c2cf65adac, we should
avoid spinning the event loop from the WebContent-side of the WebDriver
connection. This can result in deadlocks if another component in LibWeb
also spins the event loop.

The AO to await navigations has two event loop spinners - waiting for
the navigation to complete and for the document to reach the target
readiness state. We now use NavigationObserver and DocumentObserver to
be notified when these conditions are met. And we use the same async IPC
mechanism as script execution to notify the WebDriver process when all
conditions are met (or timed out).
2024-10-26 11:25:42 +02:00
Timothy Flynn
e89d889219 LibWeb+WebContent: Ensure elements are in view before clicking them
This implements a couple of missing steps in the Element Click endpoint.
2024-10-24 18:59:51 -04:00
Timothy Flynn
9682b150ac WebContent: Do not raise errors from invoking element.scrollIntoView
The spec does not say to do this. We must instead implement methods to
validate the element after attempting to scroll.
2024-10-24 18:59:51 -04:00
Timothy Flynn
9f872d9aab WebContent: Do not use NodeIterator to iterate DOM nodes backwards
A NodeIterator rooted at some element cannot produce an element before
that root. That is, in a DOM tree such as:

    <div id=one><div id=two><div id=three></div></div></div>

If we create a NodeIterator rooted at element `three`, then invoking the
previousNode() method on that iterator is guaranteed to return null.

There was also a bug here where if we ever did enter the while() loop,
we would have looped indefinitely, as we were not updating the current
node.
2024-10-24 18:59:51 -04:00
Timothy Flynn
a9c858fc78 LibWeb: Implement WebDriver element references according to the spec
Our currently ad-hoc method of tracking element references is basically
a process-wide map, rather than grouping elements according to their
browsing context groups. This prevents us from recognizing when an
element reference is invalid due to its browsing context having been
closed.

This implements the WebDriver spec concept of element references grouped
according to their browsing context groups.

This patch is a bit noisy because we now need to plumb the current BC
through to the element reference AOs.
2024-10-24 18:59:51 -04:00
Andrew Kaster
7372b2af48 LibIPC+Everywhere: Introduce an IPC Transport abstraction
This abstraction will help us to support multiple IPC transport
mechanisms going forward. For now, we only have a TransportSocket that
implements the same behavior we previously had, using Unix Sockets for
IPC.
2024-10-23 12:29:01 -06:00
Timothy Flynn
b75a4d25b7 WebContent: Further validate cookie attributes set from WebDriver
Implement a few missing steps in the Add Cookie endpoint.
2024-10-23 09:05:33 +02:00
Timothy Flynn
ebe89a3207 WebContent: Parse the type hint in WebDriver's New Window endpoint
Although we aren't using this hint (we always create tabs), we do need
to validate the payload.
2024-10-21 13:15:11 -04:00
Timothy Flynn
6cba55893e WebContent: Return the handle of the newly opened window from New Window
We were returning the handle of the already opened window, rather than
the handle of the window we just opened.
2024-10-20 16:41:11 +01:00
Andreas Kling
4fdb266077 LibWeb: Make DOM Node unique IDs strongly typed (and 64 bit)
This is strictly nicer than passing them around as i32 everywhere,
and by switching to i64 as the underlying type, ID allocation becomes as
simple as incrementing an integer.
2024-10-20 13:42:33 +02:00
Tim Ledbetter
eca2318390 WebContent: Use window open steps to create a new window with WebDriver
This matches the specification steps and fixes a WPT regression caused
by us not loading `about:blank` when opening a new window.
2024-10-20 11:42:19 +01:00
Timothy Flynn
048b51eb54 WebContent: Add a JS visitor to WebDriver's IPC connection
We've added a few JS::Handle members to this class over time. Let's
avoid creating a new GC root for each of these, and explicitly add a
visitation method.
2024-10-18 09:45:04 +02:00
Timothy Flynn
022e2b8a94 LibWeb+WebContent: Rename the WebDriver get-known-element AO
The underlying concept is the same, but this method was renamed in the
spec to drop the word "connected".
2024-10-18 09:45:04 +02:00
Timothy Flynn
a96a762305 LibWeb+WebContent: Use NNGCPtr in WebDriver code where appropriate
Some of this code is older than widespread use of GCPtr. These functions
returning raw pointers has been a point of confusion at times, so lets
just indicate that they are non-null.
2024-10-18 09:45:04 +02:00
Timothy Flynn
dae6200c1d LibWeb: Update (not replace) timeout values in WebDriver's Set Timeouts
Contradictory to the spec, the Set Timeouts endpoint should update the
existing timeouts configuration in-place, rather than replacing it. WPT
expects this, and other browsers already implement this endpoint this
way.
2024-10-12 15:02:41 +02:00
Timothy Flynn
8396afeb76 LibWeb: Update WebDriver timeout parsing/serializing to the latest spec
Namely, all fields in the timeouts object may now be null. There are a
few calling AOs that we will want to bring up to date as well.
2024-10-12 15:02:41 +02:00
Timothy Flynn
8598ed86fe LibWeb+WebContent: Implement the Element Clear endpoint 2024-10-12 15:01:35 +02:00