LibWeb: Implement Window.prompt()

This commit is contained in:
Linus Groh 2021-02-20 12:05:18 +01:00 committed by Andreas Kling
parent f10967e364
commit 5e07c27e25
Notes: sideshowbarker 2024-07-18 22:07:15 +09:00
14 changed files with 74 additions and 2 deletions

View File

@ -69,6 +69,7 @@ void WindowObject::initialize()
define_native_property("performance", performance_getter, nullptr, JS::Attribute::Enumerable);
define_native_function("alert", alert);
define_native_function("confirm", confirm);
define_native_function("prompt", prompt);
define_native_function("setInterval", set_interval, 1);
define_native_function("setTimeout", set_timeout, 1);
define_native_function("clearInterval", clear_interval, 1);
@ -121,6 +122,10 @@ static DOM::Window* impl_from(JS::VM& vm, JS::GlobalObject& global_object)
JS_DEFINE_NATIVE_FUNCTION(WindowObject::alert)
{
// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#simple-dialogs
// Note: This method is defined using two overloads, instead of using an optional argument,
// for historical reasons. The practical impact of this is that alert(undefined) is
// treated as alert("undefined"), but alert() is treated as alert("").
auto* impl = impl_from(vm, global_object);
if (!impl)
return {};
@ -140,7 +145,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::confirm)
if (!impl)
return {};
String message = "";
if (vm.argument_count()) {
if (!vm.argument(0).is_undefined()) {
message = vm.argument(0).to_string(global_object);
if (vm.exception())
return {};
@ -148,6 +153,29 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::confirm)
return JS::Value(impl->confirm(message));
}
JS_DEFINE_NATIVE_FUNCTION(WindowObject::prompt)
{
auto* impl = impl_from(vm, global_object);
if (!impl)
return {};
String message = "";
String default_ = "";
if (!vm.argument(0).is_undefined()) {
message = vm.argument(0).to_string(global_object);
if (vm.exception())
return {};
}
if (!vm.argument(1).is_undefined()) {
default_ = vm.argument(1).to_string(global_object);
if (vm.exception())
return {};
}
auto response = impl->prompt(message, default_);
if (response.is_null())
return JS::js_null();
return JS::js_string(vm, response);
}
JS_DEFINE_NATIVE_FUNCTION(WindowObject::set_interval)
{
auto* impl = impl_from(vm, global_object);

View File

@ -86,6 +86,7 @@ private:
JS_DECLARE_NATIVE_FUNCTION(alert);
JS_DECLARE_NATIVE_FUNCTION(confirm);
JS_DECLARE_NATIVE_FUNCTION(prompt);
JS_DECLARE_NATIVE_FUNCTION(set_interval);
JS_DECLARE_NATIVE_FUNCTION(set_timeout);
JS_DECLARE_NATIVE_FUNCTION(clear_interval);

View File

@ -71,6 +71,13 @@ bool Window::confirm(const String& message)
return false;
}
String Window::prompt(const String& message, const String& default_)
{
if (auto* page = m_document.page())
return page->client().page_did_request_prompt(message, default_);
return {};
}
i32 Window::set_interval(JS::Function& callback, i32 interval)
{
auto timer = Timer::create_interval(*this, interval, callback);

View File

@ -57,6 +57,7 @@ public:
void alert(const String&);
bool confirm(const String&);
String prompt(const String&, const String&);
i32 request_animation_frame(JS::Function&);
void cancel_animation_frame(i32);

View File

@ -30,6 +30,7 @@
#include <LibGUI/Action.h>
#include <LibGUI/Application.h>
#include <LibGUI/Clipboard.h>
#include <LibGUI/InputBox.h>
#include <LibGUI/MessageBox.h>
#include <LibGUI/Painter.h>
#include <LibGUI/ScrollBar.h>
@ -425,4 +426,12 @@ bool InProcessWebView::page_did_request_confirm(const String& message)
return confirm_result == GUI::Dialog::ExecResult::ExecOK;
}
String InProcessWebView::page_did_request_prompt(const String& message, const String& default_)
{
String value { default_ };
if (GUI::InputBox::show(window(), value, message, "Prompt") == GUI::InputBox::ExecOK)
return value;
return {};
}
}

View File

@ -107,6 +107,7 @@ private:
virtual void page_did_request_scroll_into_view(const Gfx::IntRect&) override;
virtual void page_did_request_alert(const String&) override;
virtual bool page_did_request_confirm(const String&) override;
virtual String page_did_request_prompt(const String&, const String&) override;
void layout_and_sync_size();

View File

@ -28,6 +28,7 @@
#include "WebContentClient.h"
#include <AK/String.h>
#include <AK/URLParser.h>
#include <LibGUI/InputBox.h>
#include <LibGUI/MessageBox.h>
#include <LibGUI/Painter.h>
#include <LibGUI/ScrollBar.h>
@ -293,6 +294,14 @@ bool OutOfProcessWebView::notify_server_did_request_confirm(Badge<WebContentClie
return confirm_result == GUI::Dialog::ExecResult::ExecOK;
}
String OutOfProcessWebView::notify_server_did_request_prompt(Badge<WebContentClient>, const String& message, const String& default_)
{
String response { default_ };
if (GUI::InputBox::show(window(), response, message, "Prompt") == GUI::InputBox::ExecOK)
return response;
return {};
}
void OutOfProcessWebView::did_scroll()
{
client().post_message(Messages::WebContentServer::SetViewportRect(visible_content_rect()));

View File

@ -67,6 +67,7 @@ public:
void notify_server_did_request_link_context_menu(Badge<WebContentClient>, const Gfx::IntPoint&, const URL&, const String& target, unsigned modifiers);
void notify_server_did_request_alert(Badge<WebContentClient>, const String& message);
bool notify_server_did_request_confirm(Badge<WebContentClient>, const String& message);
String notify_server_did_request_prompt(Badge<WebContentClient>, const String& message, const String& default_);
private:
OutOfProcessWebView();

View File

@ -106,6 +106,7 @@ public:
virtual void page_did_request_scroll_into_view(const Gfx::IntRect&) { }
virtual void page_did_request_alert(const String&) { }
virtual bool page_did_request_confirm(const String&) { return false; }
virtual String page_did_request_prompt(const String&, const String&) { return {}; }
};
}

View File

@ -139,8 +139,14 @@ OwnPtr<Messages::WebContentClient::DidRequestAlertResponse> WebContentClient::ha
OwnPtr<Messages::WebContentClient::DidRequestConfirmResponse> WebContentClient::handle(const Messages::WebContentClient::DidRequestConfirm& message)
{
bool result = m_view.notify_server_did_request_confirm({}, message.message());
auto result = m_view.notify_server_did_request_confirm({}, message.message());
return make<Messages::WebContentClient::DidRequestConfirmResponse>(result);
}
OwnPtr<Messages::WebContentClient::DidRequestPromptResponse> WebContentClient::handle(const Messages::WebContentClient::DidRequestPrompt& message)
{
auto result = m_view.notify_server_did_request_prompt({}, message.message(), message.default_());
return make<Messages::WebContentClient::DidRequestPromptResponse>(result);
}
}

View File

@ -66,6 +66,7 @@ private:
virtual void handle(const Messages::WebContentClient::DidRequestLinkContextMenu&) override;
virtual OwnPtr<Messages::WebContentClient::DidRequestAlertResponse> handle(const Messages::WebContentClient::DidRequestAlert&) override;
virtual OwnPtr<Messages::WebContentClient::DidRequestConfirmResponse> handle(const Messages::WebContentClient::DidRequestConfirm&) override;
virtual OwnPtr<Messages::WebContentClient::DidRequestPromptResponse> handle(const Messages::WebContentClient::DidRequestPrompt&) override;
OutOfProcessWebView& m_view;
};

View File

@ -181,4 +181,9 @@ bool PageHost::page_did_request_confirm(const String& message)
return m_client.send_sync<Messages::WebContentClient::DidRequestConfirm>(message)->result();
}
String PageHost::page_did_request_prompt(const String& message, const String& default_)
{
return m_client.send_sync<Messages::WebContentClient::DidRequestPrompt>(message, default_)->response();
}
}

View File

@ -69,6 +69,7 @@ private:
virtual void page_did_finish_loading(const URL&) override;
virtual void page_did_request_alert(const String&) override;
virtual bool page_did_request_confirm(const String&) override;
virtual String page_did_request_prompt(const String&, const String&) override;
explicit PageHost(ClientConnection&);

View File

@ -16,4 +16,5 @@ endpoint WebContentClient = 90
DidRequestLinkContextMenu(Gfx::IntPoint content_position, URL url, String target, unsigned modifiers) =|
DidRequestAlert(String message) => ()
DidRequestConfirm(String message) => (bool result)
DidRequestPrompt(String message, String default_) => (String response)
}