mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 03:47:35 +00:00
LibWeb+WebContent: Move pending dialog handling from PageHost to Page
Currently, all handling of pending dialogs occurs in PageHost. In order to re-use this functionality to run WebDriver in a headless move, move it to Page.
This commit is contained in:
parent
7c00619e47
commit
1f08cb7020
7 changed files with 189 additions and 126 deletions
|
@ -426,20 +426,20 @@ WebIDL::ExceptionOr<JS::GCPtr<HTML::WindowProxy>> Window::open_impl(StringView u
|
|||
void Window::alert_impl(String const& message)
|
||||
{
|
||||
if (auto* page = this->page())
|
||||
page->client().page_did_request_alert(message);
|
||||
page->did_request_alert(message);
|
||||
}
|
||||
|
||||
bool Window::confirm_impl(String const& message)
|
||||
{
|
||||
if (auto* page = this->page())
|
||||
return page->client().page_did_request_confirm(message);
|
||||
return page->did_request_confirm(message);
|
||||
return false;
|
||||
}
|
||||
|
||||
String Window::prompt_impl(String const& message, String const& default_)
|
||||
{
|
||||
if (auto* page = this->page())
|
||||
return page->client().page_did_request_prompt(message, default_);
|
||||
return page->did_request_prompt(message, default_);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -4,9 +4,13 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/SourceLocation.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/HTML/BrowsingContext.h>
|
||||
#include <LibWeb/HTML/EventLoop/EventLoop.h>
|
||||
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||
#include <LibWeb/Page/Page.h>
|
||||
#include <LibWeb/Platform/EventLoopPlugin.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
|
@ -105,4 +109,112 @@ HTML::BrowsingContext const& Page::top_level_browsing_context() const
|
|||
return *m_top_level_browsing_context;
|
||||
}
|
||||
|
||||
template<typename ResponseType>
|
||||
static ResponseType spin_event_loop_until_dialog_closed(PageClient& client, Optional<ResponseType>& response, SourceLocation location = SourceLocation::current())
|
||||
{
|
||||
auto& event_loop = Web::HTML::current_settings_object().responsible_event_loop();
|
||||
|
||||
ScopeGuard guard { [&] { event_loop.set_execution_paused(false); } };
|
||||
event_loop.set_execution_paused(true);
|
||||
|
||||
Web::Platform::EventLoopPlugin::the().spin_until([&]() {
|
||||
return response.has_value() || !client.is_connection_open();
|
||||
});
|
||||
|
||||
if (!client.is_connection_open()) {
|
||||
dbgln("WebContent client disconnected during {}. Exiting peacefully.", location.function_name());
|
||||
exit(0);
|
||||
}
|
||||
|
||||
return response.release_value();
|
||||
}
|
||||
|
||||
void Page::did_request_alert(String const& message)
|
||||
{
|
||||
m_pending_dialog = PendingDialog::Alert;
|
||||
m_client.page_did_request_alert(message);
|
||||
|
||||
if (!message.is_empty())
|
||||
m_pending_dialog_text = message;
|
||||
|
||||
spin_event_loop_until_dialog_closed(m_client, m_pending_alert_response);
|
||||
}
|
||||
|
||||
void Page::alert_closed()
|
||||
{
|
||||
if (m_pending_dialog == PendingDialog::Alert) {
|
||||
m_pending_dialog = PendingDialog::None;
|
||||
m_pending_alert_response = Empty {};
|
||||
m_pending_dialog_text.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool Page::did_request_confirm(String const& message)
|
||||
{
|
||||
m_pending_dialog = PendingDialog::Confirm;
|
||||
m_client.page_did_request_confirm(message);
|
||||
|
||||
if (!message.is_empty())
|
||||
m_pending_dialog_text = message;
|
||||
|
||||
return spin_event_loop_until_dialog_closed(m_client, m_pending_confirm_response);
|
||||
}
|
||||
|
||||
void Page::confirm_closed(bool accepted)
|
||||
{
|
||||
if (m_pending_dialog == PendingDialog::Confirm) {
|
||||
m_pending_dialog = PendingDialog::None;
|
||||
m_pending_confirm_response = accepted;
|
||||
m_pending_dialog_text.clear();
|
||||
}
|
||||
}
|
||||
|
||||
String Page::did_request_prompt(String const& message, String const& default_)
|
||||
{
|
||||
m_pending_dialog = PendingDialog::Prompt;
|
||||
m_client.page_did_request_prompt(message, default_);
|
||||
|
||||
if (!message.is_empty())
|
||||
m_pending_dialog_text = message;
|
||||
|
||||
return spin_event_loop_until_dialog_closed(m_client, m_pending_prompt_response);
|
||||
}
|
||||
|
||||
void Page::prompt_closed(String response)
|
||||
{
|
||||
if (m_pending_dialog == PendingDialog::Prompt) {
|
||||
m_pending_dialog = PendingDialog::None;
|
||||
m_pending_prompt_response = move(response);
|
||||
m_pending_dialog_text.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void Page::dismiss_dialog()
|
||||
{
|
||||
switch (m_pending_dialog) {
|
||||
case PendingDialog::None:
|
||||
break;
|
||||
case PendingDialog::Alert:
|
||||
m_client.page_did_request_accept_dialog();
|
||||
break;
|
||||
case PendingDialog::Confirm:
|
||||
case PendingDialog::Prompt:
|
||||
m_client.page_did_request_dismiss_dialog();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Page::accept_dialog()
|
||||
{
|
||||
switch (m_pending_dialog) {
|
||||
case PendingDialog::None:
|
||||
break;
|
||||
case PendingDialog::Alert:
|
||||
case PendingDialog::Confirm:
|
||||
case PendingDialog::Prompt:
|
||||
m_client.page_did_request_accept_dialog();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -83,6 +83,27 @@ public:
|
|||
Gfx::IntSize const& window_size() const { return m_window_size; }
|
||||
void set_window_size(Gfx::IntSize const& size) { m_window_size = size; }
|
||||
|
||||
void did_request_alert(String const& message);
|
||||
void alert_closed();
|
||||
|
||||
bool did_request_confirm(String const& message);
|
||||
void confirm_closed(bool accepted);
|
||||
|
||||
String did_request_prompt(String const& message, String const& default_);
|
||||
void prompt_closed(String response);
|
||||
|
||||
enum class PendingDialog {
|
||||
None,
|
||||
Alert,
|
||||
Confirm,
|
||||
Prompt,
|
||||
};
|
||||
bool has_pending_dialog() const { return m_pending_dialog != PendingDialog::None; }
|
||||
PendingDialog pending_dialog() const { return m_pending_dialog; }
|
||||
Optional<String> const& pending_dialog_text() const { return m_pending_dialog_text; }
|
||||
void dismiss_dialog();
|
||||
void accept_dialog();
|
||||
|
||||
private:
|
||||
PageClient& m_client;
|
||||
|
||||
|
@ -102,10 +123,17 @@ private:
|
|||
|
||||
Gfx::IntPoint m_window_position {};
|
||||
Gfx::IntSize m_window_size {};
|
||||
|
||||
PendingDialog m_pending_dialog { PendingDialog::None };
|
||||
Optional<String> m_pending_dialog_text;
|
||||
Optional<Empty> m_pending_alert_response;
|
||||
Optional<bool> m_pending_confirm_response;
|
||||
Optional<String> m_pending_prompt_response;
|
||||
};
|
||||
|
||||
class PageClient {
|
||||
public:
|
||||
virtual bool is_connection_open() const = 0;
|
||||
virtual Gfx::Palette palette() const = 0;
|
||||
virtual Gfx::IntRect screen_rect() const = 0;
|
||||
virtual CSS::PreferredColorScheme preferred_color_scheme() const = 0;
|
||||
|
@ -131,8 +159,10 @@ public:
|
|||
virtual void page_did_request_scroll_to(Gfx::IntPoint const&) { }
|
||||
virtual void page_did_request_scroll_into_view(Gfx::IntRect const&) { }
|
||||
virtual void page_did_request_alert(String const&) { }
|
||||
virtual bool page_did_request_confirm(String const&) { return false; }
|
||||
virtual String page_did_request_prompt(String const&, String const&) { return {}; }
|
||||
virtual void page_did_request_confirm(String const&) { }
|
||||
virtual void page_did_request_prompt(String const&, String const&) { }
|
||||
virtual void page_did_request_accept_dialog() { }
|
||||
virtual void page_did_request_dismiss_dialog() { }
|
||||
virtual String page_did_request_cookie(const AK::URL&, Cookie::Source) { return {}; }
|
||||
virtual void page_did_set_cookie(const AK::URL&, Cookie::ParsedCookie const&, Cookie::Source) { }
|
||||
virtual void page_did_update_resource_count(i32) { }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue