diff --git a/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp b/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp index 2077f283a6..0c80fd1679 100644 --- a/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp +++ b/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -347,23 +348,46 @@ void OutOfProcessWebView::notify_server_did_request_image_context_menu(Badge, String const& message) { - GUI::MessageBox::show(window(), message, "Alert"sv, GUI::MessageBox::Type::Information); + m_dialog = GUI::MessageBox::construct(window(), message, "Alert"sv, GUI::MessageBox::Type::Information, GUI::MessageBox::InputType::OK); + m_dialog->set_icon(window()->icon()); + m_dialog->exec(); + client().async_alert_closed(); + m_dialog = nullptr; } void OutOfProcessWebView::notify_server_did_request_confirm(Badge, String const& message) { - auto confirm_result = GUI::MessageBox::show(window(), message, "Confirm"sv, GUI::MessageBox::Type::Warning, GUI::MessageBox::InputType::OKCancel); - client().async_confirm_closed(confirm_result == GUI::Dialog::ExecResult::OK); + m_dialog = GUI::MessageBox::construct(window(), message, "Confirm"sv, GUI::MessageBox::Type::Warning, GUI::MessageBox::InputType::OKCancel); + m_dialog->set_icon(window()->icon()); + + client().async_confirm_closed(m_dialog->exec() == GUI::Dialog::ExecResult::OK); + m_dialog = nullptr; } void OutOfProcessWebView::notify_server_did_request_prompt(Badge, String const& message, String const& default_) { - String response { default_ }; - if (GUI::InputBox::show(window(), response, message, "Prompt"sv) == GUI::InputBox::ExecResult::OK) - client().async_prompt_closed(move(response)); + m_dialog = GUI::InputBox::construct(window(), default_, message, "Prompt"sv, StringView {}, GUI::InputType::Text); + m_dialog->set_icon(window()->icon()); + + if (m_dialog->exec() == GUI::InputBox::ExecResult::OK) + client().async_prompt_closed(static_cast(*m_dialog).text_value()); else client().async_prompt_closed({}); + + m_dialog = nullptr; +} + +void OutOfProcessWebView::notify_server_did_request_accept_dialog(Badge) +{ + if (m_dialog) + m_dialog->done(GUI::Dialog::ExecResult::OK); +} + +void OutOfProcessWebView::notify_server_did_request_dismiss_dialog(Badge) +{ + if (m_dialog) + m_dialog->done(GUI::Dialog::ExecResult::Cancel); } void OutOfProcessWebView::notify_server_did_get_source(const AK::URL& url, String const& source) diff --git a/Userland/Libraries/LibWebView/OutOfProcessWebView.h b/Userland/Libraries/LibWebView/OutOfProcessWebView.h index 9d6370bff1..4d192f65fb 100644 --- a/Userland/Libraries/LibWebView/OutOfProcessWebView.h +++ b/Userland/Libraries/LibWebView/OutOfProcessWebView.h @@ -158,6 +158,8 @@ private: virtual void notify_server_did_request_alert(Badge, String const& message) override; virtual void notify_server_did_request_confirm(Badge, String const& message) override; virtual void notify_server_did_request_prompt(Badge, String const& message, String const& default_) override; + virtual void notify_server_did_request_accept_dialog(Badge) override; + virtual void notify_server_did_request_dismiss_dialog(Badge) override; virtual void notify_server_did_get_source(const AK::URL& url, String const& source) override; virtual void notify_server_did_get_dom_tree(String const& dom_tree) override; virtual void notify_server_did_get_dom_node_properties(i32 node_id, String const& specified_style, String const& computed_style, String const& custom_properties, String const& node_box_sizing) override; @@ -204,6 +206,7 @@ private: } m_client_state; RefPtr m_backup_bitmap; + RefPtr m_dialog; }; } diff --git a/Userland/Libraries/LibWebView/ViewImplementation.h b/Userland/Libraries/LibWebView/ViewImplementation.h index 43a41dacf7..9600825979 100644 --- a/Userland/Libraries/LibWebView/ViewImplementation.h +++ b/Userland/Libraries/LibWebView/ViewImplementation.h @@ -44,6 +44,8 @@ public: virtual void notify_server_did_request_alert(Badge, String const& message) = 0; virtual void notify_server_did_request_confirm(Badge, String const& message) = 0; virtual void notify_server_did_request_prompt(Badge, String const& message, String const& default_) = 0; + virtual void notify_server_did_request_accept_dialog(Badge) = 0; + virtual void notify_server_did_request_dismiss_dialog(Badge) = 0; virtual void notify_server_did_get_source(const AK::URL& url, String const& source) = 0; virtual void notify_server_did_get_dom_tree(String const& dom_tree) = 0; virtual void notify_server_did_get_dom_node_properties(i32 node_id, String const& specified_style, String const& computed_style, String const& custom_properties, String const& node_box_sizing) = 0; diff --git a/Userland/Libraries/LibWebView/WebContentClient.cpp b/Userland/Libraries/LibWebView/WebContentClient.cpp index ec579542c8..d8b231103e 100644 --- a/Userland/Libraries/LibWebView/WebContentClient.cpp +++ b/Userland/Libraries/LibWebView/WebContentClient.cpp @@ -191,6 +191,16 @@ void WebContentClient::did_request_prompt(String const& message, String const& d m_view.notify_server_did_request_prompt({}, message, default_); } +void WebContentClient::did_request_accept_dialog() +{ + m_view.notify_server_did_request_accept_dialog({}); +} + +void WebContentClient::did_request_dismiss_dialog() +{ + m_view.notify_server_did_request_dismiss_dialog({}); +} + void WebContentClient::did_change_favicon(Gfx::ShareableBitmap const& favicon) { if (!favicon.is_valid()) { diff --git a/Userland/Libraries/LibWebView/WebContentClient.h b/Userland/Libraries/LibWebView/WebContentClient.h index 7c53edea82..baf756bd4f 100644 --- a/Userland/Libraries/LibWebView/WebContentClient.h +++ b/Userland/Libraries/LibWebView/WebContentClient.h @@ -60,6 +60,8 @@ private: virtual void did_request_alert(String const&) override; virtual void did_request_confirm(String const&) override; virtual void did_request_prompt(String const&, String const&) override; + virtual void did_request_accept_dialog() override; + virtual void did_request_dismiss_dialog() override; virtual Messages::WebContentClient::DidRequestAllCookiesResponse did_request_all_cookies(AK::URL const&) override; virtual Messages::WebContentClient::DidRequestNamedCookieResponse did_request_named_cookie(AK::URL const&, String const&) override; virtual Messages::WebContentClient::DidRequestCookieResponse did_request_cookie(AK::URL const&, u8) override; diff --git a/Userland/Services/WebContent/PageHost.cpp b/Userland/Services/WebContent/PageHost.cpp index f328109226..71d9f39c7f 100644 --- a/Userland/Services/WebContent/PageHost.cpp +++ b/Userland/Services/WebContent/PageHost.cpp @@ -305,6 +305,21 @@ void PageHost::prompt_closed(String response) } } +void PageHost::dismiss_dialog() +{ + switch (m_pending_dialog) { + case PendingDialog::None: + break; + case PendingDialog::Alert: + m_client.async_did_request_accept_dialog(); + break; + case PendingDialog::Confirm: + case PendingDialog::Prompt: + m_client.async_did_request_dismiss_dialog(); + break; + } +} + void PageHost::page_did_change_favicon(Gfx::Bitmap const& favicon) { m_client.async_did_change_favicon(favicon.to_shareable_bitmap()); diff --git a/Userland/Services/WebContent/PageHost.h b/Userland/Services/WebContent/PageHost.h index 15ba8fc6fc..a63c5be750 100644 --- a/Userland/Services/WebContent/PageHost.h +++ b/Userland/Services/WebContent/PageHost.h @@ -55,6 +55,7 @@ public: }; bool has_pending_dialog() const { return m_pending_dialog != PendingDialog::None; } PendingDialog pending_dialog() const { return m_pending_dialog; } + void dismiss_dialog(); private: // ^PageClient diff --git a/Userland/Services/WebContent/WebContentClient.ipc b/Userland/Services/WebContent/WebContentClient.ipc index 6fa9c350a6..45569f9762 100644 --- a/Userland/Services/WebContent/WebContentClient.ipc +++ b/Userland/Services/WebContent/WebContentClient.ipc @@ -32,6 +32,8 @@ endpoint WebContentClient did_request_alert(String message) =| did_request_confirm(String message) =| did_request_prompt(String message, String default_) =| + did_request_accept_dialog() =| + did_request_dismiss_dialog() =| did_get_source(URL url, String source) =| did_get_dom_tree(String dom_tree) =| did_get_dom_node_properties(i32 node_id, String specified_style, String computed_style, String custom_properties, String node_box_sizing_json) =| diff --git a/Userland/Services/WebContent/WebDriverConnection.cpp b/Userland/Services/WebContent/WebDriverConnection.cpp index b369449d19..d63b1da4bc 100644 --- a/Userland/Services/WebContent/WebDriverConnection.cpp +++ b/Userland/Services/WebContent/WebDriverConnection.cpp @@ -322,7 +322,10 @@ Messages::WebDriverClient::NavigateToResponse WebDriverConnection::navigate_to(J URL url(payload.as_object().get_ptr("url"sv)->as_string()); // FIXME: 3. If url is not an absolute URL or is not an absolute URL with fragment or not a local scheme, return error with error code invalid argument. - // FIXME: 4. Handle any user prompts and return its value if it is an error. + + // 4. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); + // FIXME: 5. Let current URL be the current top-level browsing context’s active document’s URL. // FIXME: 6. If current URL and url do not have the same absolute URL: // FIXME: a. If timer has not been started, start a timer. If this algorithm has not completed before timer reaches the session’s session page load timeout in milliseconds, return an error with error code timeout. @@ -348,7 +351,8 @@ Messages::WebDriverClient::GetCurrentUrlResponse WebDriverConnection::get_curren // 1. If the current top-level browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 2. Handle any user prompts and return its value if it is an error. + // 2. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); // 3. Let url be the serialization of the current top-level browsing context’s active document’s document URL. auto url = m_page_host.page().top_level_browsing_context().active_document()->url().to_string(); @@ -363,7 +367,8 @@ Messages::WebDriverClient::BackResponse WebDriverConnection::back() // 1. If the current top-level browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 2. Handle any user prompts and return its value if it is an error. + // 2. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); // 3. Traverse the history by a delta –1 for the current browsing context. m_web_content_client.async_did_request_navigate_back(); @@ -381,7 +386,8 @@ Messages::WebDriverClient::ForwardResponse WebDriverConnection::forward() // 1. If the current top-level browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 2. Handle any user prompts and return its value if it is an error. + // 2. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); // 3. Traverse the history by a delta 1 for the current browsing context. m_web_content_client.async_did_request_navigate_forward(); @@ -399,7 +405,8 @@ Messages::WebDriverClient::RefreshResponse WebDriverConnection::refresh() // 1. If the current top-level browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 2. Handle any user prompts and return its value if it is an error. + // 2. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); // 3. Initiate an overridden reload of the current top-level browsing context’s active document. m_web_content_client.async_did_request_refresh(); @@ -419,7 +426,8 @@ Messages::WebDriverClient::GetTitleResponse WebDriverConnection::get_title() // 1. If the current top-level browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 2. Handle any user prompts and return its value if it is an error. + // 2. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); // 3. Let title be the initial value of the title IDL attribute of the current top-level browsing context's active document. auto title = m_page_host.page().top_level_browsing_context().active_document()->title(); @@ -444,7 +452,8 @@ Messages::WebDriverClient::CloseWindowResponse WebDriverConnection::close_window // 1. If the current top-level browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 2. Handle any user prompts and return its value if it is an error. + // 2. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); // 3. Close the current top-level browsing context. m_page_host.page().top_level_browsing_context().close(); @@ -478,7 +487,8 @@ Messages::WebDriverClient::GetWindowRectResponse WebDriverConnection::get_window // 1. If the current top-level browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 2. Handle any user prompts and return its value if it is an error. + // 2. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); // 3. Return success with data set to the WindowRect object for the current top-level browsing context. return serialize_rect(compute_window_rect(m_page_host.page())); @@ -533,7 +543,9 @@ Messages::WebDriverClient::SetWindowRectResponse WebDriverConnection::set_window // 8. If the current top-level browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 9. Handle any user prompts and return its value if it is an error. + // 9. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); + // FIXME: 10. Fully exit fullscreen. // 11. Restore the window. @@ -572,7 +584,9 @@ Messages::WebDriverClient::MaximizeWindowResponse WebDriverConnection::maximize_ // 2. If the current top-level browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 3. Handle any user prompts and return its value if it is an error. + // 3. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); + // FIXME: 4. Fully exit fullscreen. // 5. Restore the window. @@ -593,7 +607,9 @@ Messages::WebDriverClient::MinimizeWindowResponse WebDriverConnection::minimize_ // 2. If the current top-level browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 3. Handle any user prompts and return its value if it is an error. + // 3. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); + // FIXME: 4. Fully exit fullscreen. // 5. Iconify the window. @@ -611,7 +627,8 @@ Messages::WebDriverClient::FullscreenWindowResponse WebDriverConnection::fullscr // 2. If the current top-level browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 3. Handle any user prompts and return its value if it is an error. + // 3. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); // 4. Restore the window. restore_the_window(); @@ -643,7 +660,8 @@ Messages::WebDriverClient::FindElementResponse WebDriverConnection::find_element // 5. If the current browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 6. Handle any user prompts and return its value if it is an error. + // 6. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); // 7. Let start node be the current browsing context’s document element. auto* start_node = m_page_host.page().top_level_browsing_context().active_document(); @@ -680,7 +698,8 @@ Messages::WebDriverClient::FindElementsResponse WebDriverConnection::find_elemen // 5. If the current browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 6. Handle any user prompts and return its value if it is an error. + // 6. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); // 7. Let start node be the current browsing context’s document element. auto* start_node = m_page_host.page().top_level_browsing_context().active_document(); @@ -711,7 +730,8 @@ Messages::WebDriverClient::FindElementFromElementResponse WebDriverConnection::f // 5. If the current browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 6. Handle any user prompts and return its value if it is an error. + // 6. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); // 7. Let start node be the result of trying to get a known connected element with url variable element id. auto* start_node = TRY(get_known_connected_element(element_id)); @@ -744,7 +764,8 @@ Messages::WebDriverClient::FindElementsFromElementResponse WebDriverConnection:: // 5. If the current browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 6. Handle any user prompts and return its value if it is an error. + // 6. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); // 7. Let start node be the result of trying to get a known connected element with url variable element id. auto* start_node = TRY(get_known_connected_element(element_id)); @@ -771,7 +792,8 @@ Messages::WebDriverClient::FindElementFromShadowRootResponse WebDriverConnection // 5. If the current browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 6. Handle any user prompts and return its value if it is an error. + // 6. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); // 7. Let start node be the result of trying to get a known shadow root with url variable shadow id. auto* start_node = TRY(get_known_shadow_root(shadow_id)); @@ -804,7 +826,8 @@ Messages::WebDriverClient::FindElementsFromShadowRootResponse WebDriverConnectio // 5. If the current browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 6. Handle any user prompts and return its value if it is an error. + // 6. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); // 7. Let start node be the result of trying to get a known shadow root with url variable shadow id. auto* start_node = TRY(get_known_shadow_root(shadow_id)); @@ -819,7 +842,8 @@ Messages::WebDriverClient::GetActiveElementResponse WebDriverConnection::get_act // 1. If the current browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 2. Handle any user prompts and return its value if it is an error. + // 2. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); // 3. Let active element be the active element of the current browsing context’s document element. auto* active_element = m_page_host.page().top_level_browsing_context().active_document()->active_element(); @@ -838,7 +862,8 @@ Messages::WebDriverClient::GetElementShadowRootResponse WebDriverConnection::get // 1. If the current browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 2. Handle any user prompts and return its value if it is an error. + // 2. Handle any user prompts and return its value if it is an error. + 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(get_known_connected_element(element_id)); @@ -863,7 +888,8 @@ Messages::WebDriverClient::IsElementSelectedResponse WebDriverConnection::is_ele // 1. If the current browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 2. Handle any user prompts and return its value if it is an error. + // 2. Handle any user prompts and return its value if it is an error. + 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(get_known_connected_element(element_id)); @@ -898,7 +924,8 @@ Messages::WebDriverClient::GetElementAttributeResponse WebDriverConnection::get_ // 1. If the current browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 2. Handle any user prompts and return its value if it is an error. + // 2. Handle any user prompts and return its value if it is an error. + 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(get_known_connected_element(element_id)); @@ -930,7 +957,8 @@ Messages::WebDriverClient::GetElementPropertyResponse WebDriverConnection::get_e // 1. If the current browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 2. Handle any user prompts and return its value if it is an error. + // 2. Handle any user prompts and return its value if it is an error. + 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(get_known_connected_element(element_id)); @@ -960,7 +988,8 @@ Messages::WebDriverClient::GetElementCssValueResponse WebDriverConnection::get_e // 1. If the current browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 2. Handle any user prompts and return its value if it is an error. + // 2. Handle any user prompts and return its value if it is an error. + 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(get_known_connected_element(element_id)); @@ -992,7 +1021,8 @@ Messages::WebDriverClient::GetElementTextResponse WebDriverConnection::get_eleme // 1. If the current browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 2. Handle any user prompts and return its value if it is an error. + // 2. Handle any user prompts and return its value if it is an error. + 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(get_known_connected_element(element_id)); @@ -1010,7 +1040,8 @@ Messages::WebDriverClient::GetElementTagNameResponse WebDriverConnection::get_el // 1. If the current browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 2. Handle any user prompts and return its value if it is an error. + // 2. Handle any user prompts and return its value if it is an error. + 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(get_known_connected_element(element_id)); @@ -1028,7 +1059,8 @@ Messages::WebDriverClient::GetElementRectResponse WebDriverConnection::get_eleme // 1. If the current browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 2. Handle any user prompts and return its value if it is an error. + // 2. Handle any user prompts and return its value if it is an error. + 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(get_known_connected_element(element_id)); @@ -1058,7 +1090,8 @@ Messages::WebDriverClient::IsElementEnabledResponse WebDriverConnection::is_elem // 1. If the current browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 2. Handle any user prompts and return its value if it is an error. + // 2. Handle any user prompts and return its value if it is an error. + 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(get_known_connected_element(element_id)); @@ -1083,7 +1116,8 @@ Messages::WebDriverClient::GetSourceResponse WebDriverConnection::get_source() // 1. If the current browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 2. Handle any user prompts and return its value if it is an error. + // 2. Handle any user prompts and return its value if it is an error. + TRY(handle_any_user_prompts()); auto* document = m_page_host.page().top_level_browsing_context().active_document(); Optional source; @@ -1340,7 +1374,8 @@ Messages::WebDriverClient::TakeElementScreenshotResponse WebDriverConnection::ta // 1. If the current top-level browsing context is no longer open, return error with error code no such window. TRY(ensure_open_top_level_browsing_context()); - // FIXME: 2. Handle any user prompts and return its value if it is an error. + // 2. Handle any user prompts and return its value if it is an error. + 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(get_known_connected_element(element_id)); @@ -1375,6 +1410,40 @@ ErrorOr WebDriverConnection::ensure_open_top_level_ return {}; } +// https://w3c.github.io/webdriver/#dfn-handle-any-user-prompts +ErrorOr WebDriverConnection::handle_any_user_prompts() +{ + // 1. If there is no current user prompt, abort these steps and return success. + if (!m_page_host.has_pending_dialog()) + return {}; + + // 2. Perform the following substeps based on the current session’s user prompt handler: + + // FIXME: The user prompt handler is a capability-level configuration, which we have no support + // for yet. It defaults to "dismiss and notify", so that is all that is handled here. + + // -> dismiss state + // Dismiss the current user prompt. + // -> accept state + // Accept the current user prompt. + // -> dismiss and notify state + if (true) { + // Dismiss the current user prompt. + m_page_host.dismiss_dialog(); + + // Return an annotated unexpected alert open error. + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::UnexpectedAlertOpen, "A user dialog is open"sv); + } + // -> accept and notify state + // Accept the current user prompt. + // Return an annotated unexpected alert open error. + // -> ignore state + // Return an annotated unexpected alert open error. + + // 3. Return success. + return {}; +} + // https://w3c.github.io/webdriver/#dfn-restore-the-window void WebDriverConnection::restore_the_window() { diff --git a/Userland/Services/WebContent/WebDriverConnection.h b/Userland/Services/WebContent/WebDriverConnection.h index e052fb889b..6c31d61c95 100644 --- a/Userland/Services/WebContent/WebDriverConnection.h +++ b/Userland/Services/WebContent/WebDriverConnection.h @@ -82,6 +82,7 @@ private: virtual Messages::WebDriverClient::TakeElementScreenshotResponse take_element_screenshot(String const& element_id) override; ErrorOr ensure_open_top_level_browsing_context(); + ErrorOr handle_any_user_prompts(); void restore_the_window(); Gfx::IntRect maximize_the_window(); Gfx::IntRect iconify_the_window();