mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-25 10:48:53 +00:00
LibWeb: Implement some window/frame reference WebDriver AOs
We must also be careful in how we decide if a window's active browsing context is top-level.
This commit is contained in:
parent
0371097e2c
commit
7e1caf30a7
Notes:
github-actions[bot]
2024-11-03 17:08:28 +00:00
Author: https://github.com/trflynn89
Commit: 7e1caf30a7
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2137
2 changed files with 100 additions and 9 deletions
|
@ -13,6 +13,12 @@
|
||||||
|
|
||||||
namespace Web::WebDriver {
|
namespace Web::WebDriver {
|
||||||
|
|
||||||
|
// https://w3c.github.io/webdriver/#dfn-web-window-identifier
|
||||||
|
static ByteString const WEB_WINDOW_IDENTIFIER = "window-fcc6-11e5-b4f8-330a88ab9d7f"sv;
|
||||||
|
|
||||||
|
// https://w3c.github.io/webdriver/#dfn-web-frame-identifier
|
||||||
|
static ByteString const WEB_FRAME_IDENTIFIER = "frame-075b-4da1-b6ba-e579c2d3230a"sv;
|
||||||
|
|
||||||
// https://w3c.github.io/webdriver/#dfn-windowproxy-reference-object
|
// https://w3c.github.io/webdriver/#dfn-windowproxy-reference-object
|
||||||
JsonObject window_proxy_reference_object(HTML::WindowProxy const& window)
|
JsonObject window_proxy_reference_object(HTML::WindowProxy const& window)
|
||||||
{
|
{
|
||||||
|
@ -22,9 +28,9 @@ JsonObject window_proxy_reference_object(HTML::WindowProxy const& window)
|
||||||
// NOTE: We look at the active browsing context's active document's node navigable instead.
|
// NOTE: We look at the active browsing context's active document's node navigable instead.
|
||||||
// Because a Browsing context's top-level traversable is this navigable's top level traversable.
|
// Because a Browsing context's top-level traversable is this navigable's top level traversable.
|
||||||
// Ref: https://html.spec.whatwg.org/multipage/document-sequences.html#bc-traversable
|
// Ref: https://html.spec.whatwg.org/multipage/document-sequences.html#bc-traversable
|
||||||
auto traversable_navigable = window.associated_browsing_context()->active_document()->navigable()->traversable_navigable();
|
auto navigable = window.associated_browsing_context()->active_document()->navigable();
|
||||||
|
|
||||||
auto identifier = traversable_navigable->is_top_level_traversable()
|
auto identifier = navigable->is_top_level_traversable()
|
||||||
? WEB_WINDOW_IDENTIFIER
|
? WEB_WINDOW_IDENTIFIER
|
||||||
: WEB_FRAME_IDENTIFIER;
|
: WEB_FRAME_IDENTIFIER;
|
||||||
|
|
||||||
|
@ -33,9 +39,92 @@ JsonObject window_proxy_reference_object(HTML::WindowProxy const& window)
|
||||||
|
|
||||||
// identifier
|
// identifier
|
||||||
// Associated window handle of the window’s browsing context.
|
// Associated window handle of the window’s browsing context.
|
||||||
object.set(identifier, traversable_navigable->window_handle().to_byte_string());
|
object.set(identifier, navigable->traversable_navigable()->window_handle().to_byte_string());
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static JS::GCPtr<HTML::Navigable> find_navigable_with_handle(StringView handle, bool should_be_top_level)
|
||||||
|
{
|
||||||
|
for (auto* navigable : Web::HTML::all_navigables()) {
|
||||||
|
if (navigable->is_top_level_traversable() != should_be_top_level)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (navigable->traversable_navigable()->window_handle() == handle)
|
||||||
|
return navigable;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://w3c.github.io/webdriver/#dfn-represents-a-web-frame
|
||||||
|
bool represents_a_web_frame(JS::Value value)
|
||||||
|
{
|
||||||
|
// An ECMAScript Object represents a web frame if it has a web frame identifier own property.
|
||||||
|
if (!value.is_object())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto result = value.as_object().has_own_property(WEB_FRAME_IDENTIFIER);
|
||||||
|
return !result.is_error() && result.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://w3c.github.io/webdriver/#dfn-deserialize-a-web-frame
|
||||||
|
ErrorOr<JS::NonnullGCPtr<HTML::WindowProxy>, WebDriver::Error> deserialize_web_frame(JS::Object const& object)
|
||||||
|
{
|
||||||
|
// 1. If object has no own property web frame identifier, return error with error code invalid argument.
|
||||||
|
auto property = object.get(WEB_FRAME_IDENTIFIER);
|
||||||
|
if (property.is_error() || !property.value().is_string())
|
||||||
|
return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Object is not a web frame"sv);
|
||||||
|
|
||||||
|
// 2. Let reference be the result of getting the web frame identifier property from object.
|
||||||
|
auto reference = property.value().as_string().utf8_string();
|
||||||
|
|
||||||
|
// 3. Let browsing context be the browsing context whose window handle is reference, or null if no such browsing
|
||||||
|
// context exists.
|
||||||
|
auto navigable = find_navigable_with_handle(reference, false);
|
||||||
|
|
||||||
|
// 4. If browsing context is null or a top-level browsing context, return error with error code no such frame.
|
||||||
|
// NOTE: We filtered on the top-level browsing context condition in the previous step.
|
||||||
|
if (!navigable)
|
||||||
|
return WebDriver::Error::from_code(WebDriver::ErrorCode::NoSuchFrame, "Could not locate frame"sv);
|
||||||
|
|
||||||
|
// 5. Return success with data browsing context's associated window.
|
||||||
|
return *navigable->active_window_proxy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://w3c.github.io/webdriver/#dfn-represents-a-web-frame
|
||||||
|
bool represents_a_web_window(JS::Value value)
|
||||||
|
{
|
||||||
|
// An ECMAScript Object represents a web window if it has a web window identifier own property.
|
||||||
|
if (!value.is_object())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto result = value.as_object().has_own_property(WEB_WINDOW_IDENTIFIER);
|
||||||
|
return !result.is_error() && result.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://w3c.github.io/webdriver/#dfn-deserialize-a-web-frame
|
||||||
|
ErrorOr<JS::NonnullGCPtr<HTML::WindowProxy>, WebDriver::Error> deserialize_web_window(JS::Object const& object)
|
||||||
|
{
|
||||||
|
// 1. If object has no own property web window identifier, return error with error code invalid argument.
|
||||||
|
auto property = object.get(WEB_WINDOW_IDENTIFIER);
|
||||||
|
if (property.is_error() || !property.value().is_string())
|
||||||
|
return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Object is not a web window"sv);
|
||||||
|
|
||||||
|
// 2. Let reference be the result of getting the web window identifier property from object.
|
||||||
|
auto reference = property.value().as_string().utf8_string();
|
||||||
|
|
||||||
|
// 3. Let browsing context be the browsing context whose window handle is reference, or null if no such browsing
|
||||||
|
// context exists.
|
||||||
|
auto navigable = find_navigable_with_handle(reference, true);
|
||||||
|
|
||||||
|
// 4. If browsing context is null or not a top-level browsing context, return error with error code no such window.
|
||||||
|
// NOTE: We filtered on the top-level browsing context condition in the previous step.
|
||||||
|
if (!navigable)
|
||||||
|
return WebDriver::Error::from_code(WebDriver::ErrorCode::NoSuchWindow, "Could not locate window"sv);
|
||||||
|
|
||||||
|
// 5. Return success with data browsing context's associated window.
|
||||||
|
return *navigable->active_window_proxy();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,16 +8,18 @@
|
||||||
|
|
||||||
#include <AK/Forward.h>
|
#include <AK/Forward.h>
|
||||||
#include <AK/StringView.h>
|
#include <AK/StringView.h>
|
||||||
|
#include <LibJS/Runtime/Value.h>
|
||||||
#include <LibWeb/Forward.h>
|
#include <LibWeb/Forward.h>
|
||||||
|
#include <LibWeb/WebDriver/Error.h>
|
||||||
|
|
||||||
namespace Web::WebDriver {
|
namespace Web::WebDriver {
|
||||||
|
|
||||||
// https://w3c.github.io/webdriver/#dfn-web-window-identifier
|
|
||||||
static constexpr auto WEB_WINDOW_IDENTIFIER = "window-fcc6-11e5-b4f8-330a88ab9d7f"sv;
|
|
||||||
|
|
||||||
// https://w3c.github.io/webdriver/#dfn-web-frame-identifier
|
|
||||||
static constexpr auto WEB_FRAME_IDENTIFIER = "frame-075b-4da1-b6ba-e579c2d3230a"sv;
|
|
||||||
|
|
||||||
JsonObject window_proxy_reference_object(HTML::WindowProxy const&);
|
JsonObject window_proxy_reference_object(HTML::WindowProxy const&);
|
||||||
|
|
||||||
|
bool represents_a_web_frame(JS::Value);
|
||||||
|
ErrorOr<JS::NonnullGCPtr<HTML::WindowProxy>, WebDriver::Error> deserialize_web_frame(JS::Object const&);
|
||||||
|
|
||||||
|
bool represents_a_web_window(JS::Value);
|
||||||
|
ErrorOr<JS::NonnullGCPtr<HTML::WindowProxy>, WebDriver::Error> deserialize_web_window(JS::Object const&);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue