diff --git a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp index 5d1f577da16..13b143f7213 100644 --- a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp +++ b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp @@ -397,6 +397,11 @@ BrowsingContextGroup* BrowsingContext::group() return m_group; } +BrowsingContextGroup const* BrowsingContext::group() const +{ + return m_group; +} + void BrowsingContext::set_group(BrowsingContextGroup* group) { m_group = group; diff --git a/Userland/Libraries/LibWeb/HTML/BrowsingContext.h b/Userland/Libraries/LibWeb/HTML/BrowsingContext.h index 6900a4201ac..12a022d391f 100644 --- a/Userland/Libraries/LibWeb/HTML/BrowsingContext.h +++ b/Userland/Libraries/LibWeb/HTML/BrowsingContext.h @@ -117,6 +117,7 @@ public: JS::GCPtr top_level_browsing_context() const; BrowsingContextGroup* group(); + BrowsingContextGroup const* group() const; void set_group(BrowsingContextGroup*); // https://html.spec.whatwg.org/multipage/browsers.html#bcg-remove diff --git a/Userland/Libraries/LibWeb/WebDriver/Actions.cpp b/Userland/Libraries/LibWeb/WebDriver/Actions.cpp index 7c39302c96d..789274c6b81 100644 --- a/Userland/Libraries/LibWeb/WebDriver/Actions.cpp +++ b/Userland/Libraries/LibWeb/WebDriver/Actions.cpp @@ -200,7 +200,7 @@ static ErrorOr get_coordinates_relative_to_orig // 1. Let element be the result of trying to run actions options' get element origin steps with origin and // browsing context. // 2. If element is null, return error with error code no such element. - auto element = TRY(actions_options.get_element_origin(origin)); + auto element = TRY(actions_options.get_element_origin(browsing_context, origin)); // 3. Let x element and y element be the result of calculating the in-view center point of element. auto position = in_view_center_point(element, viewport); diff --git a/Userland/Libraries/LibWeb/WebDriver/Actions.h b/Userland/Libraries/LibWeb/WebDriver/Actions.h index e2549fcd469..c2c775ba08c 100644 --- a/Userland/Libraries/LibWeb/WebDriver/Actions.h +++ b/Userland/Libraries/LibWeb/WebDriver/Actions.h @@ -119,7 +119,7 @@ struct ActionObject { // https://w3c.github.io/webdriver/#dfn-actions-options struct ActionsOptions { Function is_element_origin; - Function, WebDriver::Error>(StringView)> get_element_origin; + Function, WebDriver::Error>(HTML::BrowsingContext const&, StringView)> get_element_origin; }; using OnActionsComplete = JS::NonnullGCPtr>; diff --git a/Userland/Libraries/LibWeb/WebDriver/ElementReference.cpp b/Userland/Libraries/LibWeb/WebDriver/ElementReference.cpp index 3273bb968e2..2825c5b5122 100644 --- a/Userland/Libraries/LibWeb/WebDriver/ElementReference.cpp +++ b/Userland/Libraries/LibWeb/WebDriver/ElementReference.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -11,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -27,25 +29,105 @@ static ByteString const web_element_identifier = "element-6066-11e4-a52e-4f73546 // https://w3c.github.io/webdriver/#dfn-shadow-root-identifier static ByteString const shadow_root_identifier = "shadow-6066-11e4-a52e-4f735466cecf"sv; -// https://w3c.github.io/webdriver/#dfn-get-or-create-a-web-element-reference -ByteString get_or_create_a_web_element_reference(Web::DOM::Node const& element) -{ - // FIXME: 1. For each known element of the current browsing context’s list of known elements: - // FIXME: 1. If known element equals element, return success with known element’s web element reference. - // FIXME: 2. Add element to the list of known elements of the current browsing context. - // FIXME: 3. Return success with the element’s web element reference. +// https://w3c.github.io/webdriver/#dfn-browsing-context-group-node-map +static HashMap, HashTable> browsing_context_group_node_map; - return ByteString::number(element.unique_id().value()); +// https://w3c.github.io/webdriver/#dfn-navigable-seen-nodes-map +static HashMap, HashTable> navigable_seen_nodes_map; + +// https://w3c.github.io/webdriver/#dfn-get-a-node +JS::GCPtr get_node(HTML::BrowsingContext const& browsing_context, StringView reference) +{ + // 1. Let browsing context group node map be session's browsing context group node map. + // 2. Let browsing context group be browsing context's browsing context group. + auto const* browsing_context_group = browsing_context.group(); + + // 3. If browsing context group node map does not contain browsing context group, return null. + // 4. Let node id map be browsing context group node map[browsing context group]. + auto node_id_map = browsing_context_group_node_map.get(browsing_context_group); + if (!node_id_map.has_value()) + return nullptr; + + // 5. Let node be the entry in node id map whose value is reference, if such an entry exists, or null otherwise. + JS::GCPtr node; + + if (node_id_map->contains(reference)) { + auto node_id = reference.to_number().value(); + node = Web::DOM::Node::from_unique_id(UniqueNodeID(node_id)); + } + + // 6. Return node. + return node; +} + +// https://w3c.github.io/webdriver/#dfn-get-or-create-a-node-reference +ByteString get_or_create_a_node_reference(HTML::BrowsingContext const& browsing_context, Web::DOM::Node const& node) +{ + // 1. Let browsing context group node map be session's browsing context group node map. + // 2. Let browsing context group be browsing context's browsing context group. + auto const* browsing_context_group = browsing_context.group(); + + // 3. If browsing context group node map does not contain browsing context group, set browsing context group node + // map[browsing context group] to a new weak map. + // 4. Let node id map be browsing context group node map[browsing context group]. + auto& node_id_map = browsing_context_group_node_map.ensure(browsing_context_group); + + auto node_id = ByteString::number(node.unique_id().value()); + + // 5. If node id map does not contain node: + if (!node_id_map.contains(node_id)) { + // 1. Let node id be a new globally unique string. + // 2. Set node id map[node] to node id. + node_id_map.set(node_id); + + // 3. Let navigable be browsing context's active document's node navigable. + auto navigable = browsing_context.active_document()->navigable(); + + // 4. Let navigable seen nodes map be session's navigable seen nodes map. + // 5. If navigable seen nodes map does not contain navigable, set navigable seen nodes map[navigable] to an empty set. + // 6. Append node id to navigable seen nodes map[navigable]. + navigable_seen_nodes_map.ensure(navigable).set(node_id); + } + + // 6. Return node id map[node]. + return node_id; +} + +// https://w3c.github.io/webdriver/#dfn-node-reference-is-known +bool node_reference_is_known(HTML::BrowsingContext const& browsing_context, StringView reference) +{ + // 1. Let navigable be browsing context's active document's node navigable. + auto navigable = browsing_context.active_document()->navigable(); + if (!navigable) + return false; + + // 2. Let navigable seen nodes map be session's navigable seen nodes map. + // 3. If navigable seen nodes map contains navigable and navigable seen nodes map[navigable] contains reference, + // return true, otherwise return false. + if (auto map = navigable_seen_nodes_map.get(navigable); map.has_value()) + return map->contains(reference); + return false; +} + +// https://w3c.github.io/webdriver/#dfn-get-or-create-a-web-element-reference +ByteString get_or_create_a_web_element_reference(HTML::BrowsingContext const& browsing_context, Web::DOM::Node const& element) +{ + // 1. Assert: element implements Element. + VERIFY(element.is_element()); + + // 2. Return the result of trying to get or create a node reference given session, session's current browsing + // context, and element. + return get_or_create_a_node_reference(browsing_context, element); } // https://w3c.github.io/webdriver/#dfn-web-element-reference-object -JsonObject web_element_reference_object(Web::DOM::Node const& element) +JsonObject web_element_reference_object(HTML::BrowsingContext const& browsing_context, Web::DOM::Node const& element) { // 1. Let identifier be the web element identifier. auto identifier = web_element_identifier; // 2. Let reference be the result of get or create a web element reference given element. - auto reference = get_or_create_a_web_element_reference(element); + auto reference = get_or_create_a_web_element_reference(browsing_context, element); // 3. Return a JSON Object initialized with a property with name identifier and value reference. JsonObject object; @@ -54,7 +136,7 @@ JsonObject web_element_reference_object(Web::DOM::Node const& element) } // https://w3c.github.io/webdriver/#dfn-deserialize-a-web-element -ErrorOr, WebDriver::Error> deserialize_web_element(JsonObject const& object) +ErrorOr, WebDriver::Error> deserialize_web_element(Web::HTML::BrowsingContext const& browsing_context, JsonObject const& object) { // 1. If object has no own property web element identifier, return error with error code invalid argument. if (!object.has_string(web_element_identifier)) @@ -64,10 +146,10 @@ ErrorOr, WebDriver::Error> deserialize_web_e auto reference = extract_web_element_reference(object); // 3. Let element be the result of trying to get a known element with session and reference. - auto element = TRY(get_known_element(reference)); + auto element = TRY(get_known_element(browsing_context, reference)); // 4. Return success with data element. - return *element; + return element; } ByteString extract_web_element_reference(JsonObject const& object) @@ -85,39 +167,35 @@ bool represents_a_web_element(JsonValue const& value) } // https://w3c.github.io/webdriver/#dfn-get-a-webelement-origin -ErrorOr, Web::WebDriver::Error> get_web_element_origin(StringView origin) +ErrorOr, Web::WebDriver::Error> get_web_element_origin(Web::HTML::BrowsingContext const& browsing_context, StringView origin) { // 1. Assert: browsing context is the current browsing context. // 2. Let element be equal to the result of trying to get a known element with session and origin. - auto element = TRY(get_known_element(origin)); + auto element = TRY(get_known_element(browsing_context, origin)); // 3. Return success with data element. return element; } // https://w3c.github.io/webdriver/#dfn-get-a-known-element -ErrorOr, Web::WebDriver::Error> get_known_element(StringView element_id) +ErrorOr, Web::WebDriver::Error> get_known_element(Web::HTML::BrowsingContext const& browsing_context, StringView reference) { - // NOTE: The whole concept of "connected elements" is not implemented yet. See get_or_create_a_web_element_reference(). - // For now the element is only represented by its ID. - // 1. If not node reference is known with session, session's current browsing context, and reference return error // with error code no such element. - auto element = element_id.to_number(); - if (!element.has_value()) + if (!node_reference_is_known(browsing_context, reference)) return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchElement, "Element ID is not an integer"); // 2. Let node be the result of get a node with session, session's current browsing context, and reference. - auto* node = Web::DOM::Node::from_unique_id(UniqueNodeID(*element)); + auto node = get_node(browsing_context, reference); // 3. If node is not null and node does not implement Element return error with error code no such element. if (node && !node->is_element()) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchElement, ByteString::formatted("Could not find element with ID: {}", element_id)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchElement, ByteString::formatted("Could not find element with node reference: {}", reference)); // 4. If node is null or node is stale return error with error code stale element reference. if (!node || is_element_stale(*node)) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::StaleElementReference, ByteString::formatted("Element with ID: {} is stale", element_id)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::StaleElementReference, ByteString::formatted("Element reference {} is stale", reference)); // 5. Return success with data node. return static_cast(*node); diff --git a/Userland/Libraries/LibWeb/WebDriver/ElementReference.h b/Userland/Libraries/LibWeb/WebDriver/ElementReference.h index 6818a633dda..905521b64fb 100644 --- a/Userland/Libraries/LibWeb/WebDriver/ElementReference.h +++ b/Userland/Libraries/LibWeb/WebDriver/ElementReference.h @@ -16,13 +16,17 @@ namespace Web::WebDriver { -ByteString get_or_create_a_web_element_reference(Web::DOM::Node const& element); -JsonObject web_element_reference_object(Web::DOM::Node const& element); -ErrorOr, WebDriver::Error> deserialize_web_element(JsonObject const&); +JS::GCPtr get_node(HTML::BrowsingContext const&, StringView reference); +ByteString get_or_create_a_node_reference(HTML::BrowsingContext const&, Web::DOM::Node const&); +bool node_reference_is_known(HTML::BrowsingContext const&, StringView reference); + +ByteString get_or_create_a_web_element_reference(HTML::BrowsingContext const&, Web::DOM::Node const& element); +JsonObject web_element_reference_object(HTML::BrowsingContext const&, Web::DOM::Node const& element); +ErrorOr, WebDriver::Error> deserialize_web_element(Web::HTML::BrowsingContext const&, JsonObject const&); ByteString extract_web_element_reference(JsonObject const&); bool represents_a_web_element(JsonValue const& value); -ErrorOr, Web::WebDriver::Error> get_web_element_origin(StringView origin); -ErrorOr, Web::WebDriver::Error> get_known_element(StringView element_id); +ErrorOr, Web::WebDriver::Error> get_web_element_origin(Web::HTML::BrowsingContext const&, StringView origin); +ErrorOr, Web::WebDriver::Error> get_known_element(Web::HTML::BrowsingContext const&, StringView reference); bool is_element_stale(Web::DOM::Node const& element); bool is_element_interactable(Web::HTML::BrowsingContext const&, Web::DOM::Element const&); diff --git a/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp b/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp index f7acbbd46d9..f1433d361fd 100644 --- a/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp +++ b/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp @@ -46,8 +46,8 @@ namespace Web::WebDriver { _temporary_result.release_value(); \ }) -static ErrorOr internal_json_clone_algorithm(JS::Realm&, JS::Value, HashTable& seen); -static ErrorOr clone_an_object(JS::Realm&, JS::Object&, HashTable& seen, auto const& clone_algorithm); +static ErrorOr internal_json_clone_algorithm(JS::Realm&, HTML::BrowsingContext const&, JS::Value, HashTable& seen); +static ErrorOr clone_an_object(JS::Realm&, HTML::BrowsingContext const&, JS::Object&, HashTable& seen, auto const& clone_algorithm); // https://w3c.github.io/webdriver/#dfn-collection static bool is_collection(JS::Object const& value) @@ -73,15 +73,15 @@ static bool is_collection(JS::Object const& value) } // https://w3c.github.io/webdriver/#dfn-json-clone -static ErrorOr json_clone(JS::Realm& realm, JS::Value value) +static ErrorOr json_clone(JS::Realm& realm, HTML::BrowsingContext const& browsing_context, JS::Value value) { // To perform a JSON clone return the result of calling the internal JSON clone algorithm with arguments value and an empty List. auto seen = HashTable {}; - return internal_json_clone_algorithm(realm, value, seen); + return internal_json_clone_algorithm(realm, browsing_context, value, seen); } // https://w3c.github.io/webdriver/#dfn-internal-json-clone-algorithm -static ErrorOr internal_json_clone_algorithm(JS::Realm& realm, JS::Value value, HashTable& seen) +static ErrorOr internal_json_clone_algorithm(JS::Realm& realm, HTML::BrowsingContext const& browsing_context, JS::Value value, HashTable& seen) { auto& vm = realm.vm(); @@ -122,7 +122,7 @@ static ErrorOr internal_json_clone_algorithm // Otherwise: else { // 1. Let reference be the web element reference object for session and value. - auto reference = web_element_reference_object(element); + auto reference = web_element_reference_object(browsing_context, element); // 2. Return success with data reference. return reference; @@ -168,14 +168,14 @@ static ErrorOr internal_json_clone_algorithm } }; // 3. Let result be the value of running the clone an object algorithm with arguments value and seen, and the internal JSON clone algorithm as the clone algorithm. - auto result = TRY(clone_an_object(realm, value.as_object(), seen, internal_json_clone_algorithm)); + auto result = TRY(clone_an_object(realm, browsing_context, value.as_object(), seen, internal_json_clone_algorithm)); // 5. Return result. return result; } // https://w3c.github.io/webdriver/#dfn-clone-an-object -static ErrorOr clone_an_object(JS::Realm& realm, JS::Object& value, HashTable& seen, auto const& clone_algorithm) +static ErrorOr clone_an_object(JS::Realm& realm, HTML::BrowsingContext const& browsing_context, JS::Object& value, HashTable& seen, auto const& clone_algorithm) { auto& vm = realm.vm(); @@ -217,7 +217,7 @@ static ErrorOr clone_an_object(JS::Realm& re continue; // 3. Let cloned property result be the result of calling the clone algorithm with arguments source property value and seen. - auto cloned_property_result = clone_algorithm(realm, *source_property_value->value, seen); + auto cloned_property_result = clone_algorithm(realm, browsing_context, *source_property_value->value, seen); // 4. If cloned property result is a success, set a property of result with name name and value equal to cloned property result’s data. if (!cloned_property_result.is_error()) { @@ -398,12 +398,12 @@ void execute_script(HTML::BrowsingContext const& browsing_context, ByteString bo }); // 9. Wait until promise is resolved, or timer's timeout fired flag is set, whichever occurs first. - auto reaction_steps = JS::create_heap_function(vm.heap(), [&realm, promise, timer, on_complete](JS::Value) -> WebIDL::ExceptionOr { + auto reaction_steps = JS::create_heap_function(vm.heap(), [&realm, &browsing_context, promise, timer, on_complete](JS::Value) -> WebIDL::ExceptionOr { if (timer->is_timed_out()) return JS::js_undefined(); timer->stop(); - auto json_value_or_error = json_clone(realm, promise->result()); + auto json_value_or_error = json_clone(realm, browsing_context, promise->result()); if (json_value_or_error.is_error()) { auto error_object = JsonObject {}; error_object.set("name", "Error"); @@ -513,12 +513,12 @@ void execute_async_script(HTML::BrowsingContext const& browsing_context, ByteStr }); // 9. Wait until promise is resolved, or timer's timeout fired flag is set, whichever occurs first. - auto reaction_steps = JS::create_heap_function(vm.heap(), [&realm, promise, timer, on_complete](JS::Value) -> WebIDL::ExceptionOr { + auto reaction_steps = JS::create_heap_function(vm.heap(), [&realm, &browsing_context, promise, timer, on_complete](JS::Value) -> WebIDL::ExceptionOr { if (timer->is_timed_out()) return JS::js_undefined(); timer->stop(); - auto json_value_or_error = json_clone(realm, promise->result()); + auto json_value_or_error = json_clone(realm, browsing_context, promise->result()); if (json_value_or_error.is_error()) { auto error_object = JsonObject {}; error_object.set("name", "Error"); diff --git a/Userland/Services/WebContent/WebDriverConnection.cpp b/Userland/Services/WebContent/WebDriverConnection.cpp index 7a06300c919..269dfbd5131 100644 --- a/Userland/Services/WebContent/WebDriverConnection.cpp +++ b/Userland/Services/WebContent/WebDriverConnection.cpp @@ -565,7 +565,7 @@ Messages::WebDriverClient::SwitchToFrameResponse WebDriverConnection::switch_to_ TRY(handle_any_user_prompts()); // 3. Let element be the result of trying to get a known element with session and id. - auto element = TRY(Web::WebDriver::get_known_element(element_id)); + auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); // 4. If element is not a frame or iframe element, return error with error code no such frame. bool is_frame = is(*element); @@ -902,7 +902,7 @@ Messages::WebDriverClient::FindElementFromElementResponse WebDriverConnection::f auto start_node_getter = [&]() -> StartNodeGetter::ReturnType { // 7. Let start node be the result of trying to get a known connected element with url variable element id. - return TRY(Web::WebDriver::get_known_element(element_id)); + return TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); }; // 8. Let result be the value of trying to Find with start node, location strategy, and selector. @@ -938,7 +938,7 @@ Messages::WebDriverClient::FindElementsFromElementResponse WebDriverConnection:: auto start_node_getter = [&]() -> StartNodeGetter::ReturnType { // 7. Let start node be the result of trying to get a known connected element with url variable element id. - return TRY(Web::WebDriver::get_known_element(element_id)); + return TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); }; // 8. Return the result of trying to Find with start node, location strategy, and selector. @@ -1041,7 +1041,7 @@ Messages::WebDriverClient::GetElementShadowRootResponse WebDriverConnection::get TRY(handle_any_user_prompts()); // 3. Let element be the result of trying to get a known connected element with url variable element id. - auto element = TRY(Web::WebDriver::get_known_element(element_id)); + auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); // 4. Let shadow root be element's shadow root. auto shadow_root = element->shadow_root(); @@ -1067,7 +1067,7 @@ Messages::WebDriverClient::IsElementSelectedResponse WebDriverConnection::is_ele TRY(handle_any_user_prompts()); // 3. Let element be the result of trying to get a known connected element with url variable element id. - auto element = TRY(Web::WebDriver::get_known_element(element_id)); + auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); // 4. Let selected be the value corresponding to the first matching statement: bool selected = false; @@ -1103,7 +1103,7 @@ Messages::WebDriverClient::GetElementAttributeResponse WebDriverConnection::get_ TRY(handle_any_user_prompts()); // 3. Let element be the result of trying to get a known connected element with url variable element id. - auto element = TRY(Web::WebDriver::get_known_element(element_id)); + auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); // 4. Let result be the result of the first matching condition: Optional result; @@ -1137,7 +1137,7 @@ Messages::WebDriverClient::GetElementPropertyResponse WebDriverConnection::get_e TRY(handle_any_user_prompts()); // 3. Let element be the result of trying to get a known connected element with url variable element id. - auto element = TRY(Web::WebDriver::get_known_element(element_id)); + auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); Optional result; @@ -1170,7 +1170,7 @@ Messages::WebDriverClient::GetElementCssValueResponse WebDriverConnection::get_e TRY(handle_any_user_prompts()); // 3. Let element be the result of trying to get a known connected element with url variable element id. - auto element = TRY(Web::WebDriver::get_known_element(element_id)); + auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); // 4. Let computed value be the result of the first matching condition: ByteString computed_value; @@ -1203,7 +1203,7 @@ Messages::WebDriverClient::GetElementTextResponse WebDriverConnection::get_eleme TRY(handle_any_user_prompts()); // 3. Let element be the result of trying to get a known connected element with url variable element id. - auto element = TRY(Web::WebDriver::get_known_element(element_id)); + auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); // 4. Let rendered text be the result of performing implementation-specific steps whose result is exactly the same as the result of a Function.[[Call]](null, element) with bot.dom.getVisibleText as the this value. auto rendered_text = element->text_content(); @@ -1222,7 +1222,7 @@ Messages::WebDriverClient::GetElementTagNameResponse WebDriverConnection::get_el TRY(handle_any_user_prompts()); // 3. Let element be the result of trying to get a known connected element with url variable element id. - auto element = TRY(Web::WebDriver::get_known_element(element_id)); + auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); // 4. Let qualified name be the result of getting element’s tagName IDL attribute. auto qualified_name = element->tag_name(); @@ -1241,7 +1241,7 @@ Messages::WebDriverClient::GetElementRectResponse WebDriverConnection::get_eleme TRY(handle_any_user_prompts()); // 3. Let element be the result of trying to get a known connected element with url variable element id. - auto element = TRY(Web::WebDriver::get_known_element(element_id)); + auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); // 4. Calculate the absolute position of element and let it be coordinates. // 5. Let rect be element’s bounding rectangle. @@ -1272,7 +1272,7 @@ Messages::WebDriverClient::IsElementEnabledResponse WebDriverConnection::is_elem TRY(handle_any_user_prompts()); // 3. Let element be the result of trying to get a known connected element with url variable element id. - auto element = TRY(Web::WebDriver::get_known_element(element_id)); + auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); // 4. Let enabled be a boolean initially set to true if the current browsing context’s active document’s type is not "xml". // 5. Otherwise, let enabled to false and jump to the last step of this algorithm. @@ -1298,7 +1298,7 @@ Messages::WebDriverClient::GetComputedRoleResponse WebDriverConnection::get_comp TRY(handle_any_user_prompts()); // 3. Let element be the result of trying to get a known connected element with url variable element id. - auto element = TRY(Web::WebDriver::get_known_element(element_id)); + auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); // 4. Let role be the result of computing the WAI-ARIA role of element. auto role = element->role_or_default(); @@ -1319,7 +1319,7 @@ Messages::WebDriverClient::GetComputedLabelResponse WebDriverConnection::get_com TRY(handle_any_user_prompts()); // 3. Let element be the result of trying to get a known element with url variable element id. - auto element = TRY(Web::WebDriver::get_known_element(element_id)); + auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); // 4. Let label be the result of a Accessible Name and Description Computation for the Accessible Name of the element. auto label = element->accessible_name(element->document()).release_value_but_fixme_should_propagate_errors(); @@ -1338,7 +1338,7 @@ Messages::WebDriverClient::ElementClickResponse WebDriverConnection::element_cli TRY(handle_any_user_prompts()); // 3. Let element be the result of trying to get a known element with element id. - auto element = TRY(Web::WebDriver::get_known_element(element_id)); + auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); // 4. If the element is an input element in the file upload state return error with error code invalid argument. if (is(*element)) { @@ -1467,7 +1467,7 @@ Messages::WebDriverClient::ElementClickResponse WebDriverConnection::element_cli pointer_move_action.pointer_move_fields().position = { 0, 0 }; // 10. Set a property origin to element on pointer move action. - auto origin = Web::WebDriver::get_or_create_a_web_element_reference(*element); + auto origin = Web::WebDriver::get_or_create_a_web_element_reference(current_browsing_context(), *element); pointer_move_action.pointer_move_fields().origin = MUST(String::from_byte_string(origin)); // 11. Let pointer down action be an action object constructed with arguments input id, "pointer", and "pointerDown". @@ -1561,7 +1561,7 @@ Messages::WebDriverClient::ElementClearResponse WebDriverConnection::element_cle TRY(handle_any_user_prompts()); // 3. Let element be the result of trying to get a known element with session and element id. - auto element = TRY(Web::WebDriver::get_known_element(element_id)); + auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); // 4. If element is not editable, return an error with error code invalid element state. if (!Web::WebDriver::is_element_editable(*element)) @@ -1617,7 +1617,7 @@ Messages::WebDriverClient::ElementSendKeysResponse WebDriverConnection::element_ TRY(handle_any_user_prompts()); // 5. Let element be the result of trying to get a known element with session and URL variables[element id]. - auto element = TRY(Web::WebDriver::get_known_element(element_id)); + auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); // 6. Let file be true if element is input element in the file upload state, or false otherwise. auto file = is(*element) && static_cast(*element).type_state() == Web::HTML::HTMLInputElement::TypeAttributeState::FileUpload; @@ -2273,7 +2273,7 @@ Messages::WebDriverClient::TakeElementScreenshotResponse WebDriverConnection::ta TRY(handle_any_user_prompts()); // 3. Let element be the result of trying to get a known connected element with url variable element id. - auto element = TRY(Web::WebDriver::get_known_element(element_id)); + auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); // 4. Scroll into view the element. (void)scroll_element_into_view(*element); @@ -2545,14 +2545,14 @@ ErrorOr WebDriverConnection::find(StartNodeGet // 8. For each element in elements returned, append the web element reference object for element, to result. for (size_t i = 0; i < elements->length(); ++i) - TRY(result.append(Web::WebDriver::web_element_reference_object(*elements->item(i)))); + TRY(result.append(Web::WebDriver::web_element_reference_object(current_browsing_context(), *elements->item(i)))); // 9. Return success with data result. return result; } // https://w3c.github.io/webdriver/#dfn-json-deserialize -static ErrorOr json_deserialize(JS::VM& vm, JsonValue const& value) +static ErrorOr json_deserialize(JS::VM& vm, Web::HTML::BrowsingContext const& browsing_context, JsonValue const& value) { // 1. If seen is not provided, let seen be an empty List. // 2. Jump to the first appropriate step below: @@ -2570,7 +2570,7 @@ static ErrorOr json_deserialize(JS::VM& vm, Js // -> Object that represents a web element if (Web::WebDriver::represents_a_web_element(value)) { // Return the deserialized web element of value. - return Web::WebDriver::deserialize_web_element(value.as_object()); + return Web::WebDriver::deserialize_web_element(browsing_context, value.as_object()); } // FIXME: -> Object that represents a shadow root @@ -2604,7 +2604,7 @@ ErrorOr WebDriverCo auto arguments = JS::MarkedVector { vm.heap() }; TRY(args.try_for_each([&](auto const& arg) -> ErrorOr { - arguments.append(TRY(json_deserialize(vm, arg))); + arguments.append(TRY(json_deserialize(vm, current_browsing_context(), arg))); return {}; }));