diff --git a/Userland/Libraries/LibWeb/HTML/Navigable.cpp b/Userland/Libraries/LibWeb/HTML/Navigable.cpp
index 6671d5c92b..e9465a5e33 100644
--- a/Userland/Libraries/LibWeb/HTML/Navigable.cpp
+++ b/Userland/Libraries/LibWeb/HTML/Navigable.cpp
@@ -412,17 +412,29 @@ Navigable::ChosenNavigable Navigable::choose_a_navigable(StringView name, Tokeni
if (!Infra::is_ascii_case_insensitive_match(name, "_blank"sv))
target_name = MUST(String::from_utf8(name));
+ auto create_new_traversable_closure = [this, window_type, no_opener, target_name](JS::GCPtr opener) -> JS::NonnullGCPtr {
+ // FIXME: The popup state for window.open is calculated after this call (somehow?)
+ // Probably want to deviate from the spec and pass the popup state in here
+ auto hints = WebViewHints {
+ .popup = window_type != WindowType::ExistingOrNone,
+ };
+ auto [page, window_handle] = traversable_navigable()->page().client().page_did_request_new_web_view(ActivateTab::Yes, hints, no_opener);
+ auto traversable = TraversableNavigable::create_a_new_top_level_traversable(*page, opener, target_name).release_value_but_fixme_should_propagate_errors();
+ page->set_top_level_traversable(traversable);
+ traversable->set_window_handle(window_handle);
+ return traversable;
+ };
+ auto create_new_traversable = JS::create_heap_function(heap(), move(create_new_traversable_closure));
+
// 7. If noopener is true, then set chosen to the result of creating a new top-level traversable given null and targetName.
if (no_opener == TokenizedFeature::NoOpener::Yes) {
- // FIXME: This should do something similar to RemoteBrowsingContext -- but RemoteTraversableNavigable instead
- TODO();
+ chosen = create_new_traversable->function()(nullptr);
}
// 8. Otherwise:
else {
// 1. Set chosen to the result of creating a new top-level traversable given currentNavigable's active browsing context and targetName.
- // FIXME: Make this method return WebIDL::ExceptionOr
- chosen = TraversableNavigable::create_a_new_top_level_traversable(traversable_navigable()->page(), active_browsing_context(), target_name).release_value_but_fixme_should_propagate_errors();
+ chosen = create_new_traversable->function()(active_browsing_context());
// FIXME: 2. If sandboxingFlagSet's sandboxed navigation browsing context flag is set,
// then set chosen's active browsing context's one permitted sandboxed navigator to currentNavigable's active browsing context.
diff --git a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.h b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.h
index 72cc56171a..e252f9b6e3 100644
--- a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.h
+++ b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.h
@@ -82,6 +82,9 @@ public:
Page& page() { return m_page; }
Page const& page() const { return m_page; }
+ String window_handle() const { return m_window_handle; }
+ void set_window_handle(String window_handle) { m_window_handle = move(window_handle); }
+
private:
TraversableNavigable(JS::NonnullGCPtr);
@@ -114,6 +117,8 @@ private:
SessionHistoryTraversalQueue m_session_history_traversal_queue;
JS::NonnullGCPtr m_page;
+
+ String m_window_handle;
};
struct BrowsingContextAndDocument {
diff --git a/Userland/Libraries/LibWeb/Page/Page.h b/Userland/Libraries/LibWeb/Page/Page.h
index d44fa05841..9d7fda1093 100644
--- a/Userland/Libraries/LibWeb/Page/Page.h
+++ b/Userland/Libraries/LibWeb/Page/Page.h
@@ -32,6 +32,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -269,7 +270,11 @@ public:
virtual void page_did_set_cookie(const AK::URL&, Cookie::ParsedCookie const&, Cookie::Source) { }
virtual void page_did_update_cookie(Web::Cookie::Cookie) { }
virtual void page_did_update_resource_count(i32) { }
- virtual String page_did_request_new_web_view(HTML::ActivateTab, HTML::WebViewHints, Optional = {}) { return {}; }
+ struct NewWebViewResult {
+ JS::GCPtr page;
+ String window_handle;
+ };
+ virtual NewWebViewResult page_did_request_new_web_view(HTML::ActivateTab, HTML::WebViewHints, HTML::TokenizedFeature::NoOpener) { return {}; }
virtual void page_did_request_activate_tab() { }
virtual void page_did_close_browsing_context(HTML::BrowsingContext const&) { }
diff --git a/Userland/Services/WebContent/PageClient.cpp b/Userland/Services/WebContent/PageClient.cpp
index 0f43068320..8b7c1db04a 100644
--- a/Userland/Services/WebContent/PageClient.cpp
+++ b/Userland/Services/WebContent/PageClient.cpp
@@ -497,14 +497,25 @@ void PageClient::page_did_update_resource_count(i32 count_waiting)
client().async_did_update_resource_count(count_waiting);
}
-String PageClient::page_did_request_new_web_view(Web::HTML::ActivateTab activate_tab, Web::HTML::WebViewHints hints, Optional page_index)
+PageClient::NewWebViewResult PageClient::page_did_request_new_web_view(Web::HTML::ActivateTab activate_tab, Web::HTML::WebViewHints hints, Web::HTML::TokenizedFeature::NoOpener no_opener)
{
- auto response = client().send_sync_but_allow_failure(activate_tab, hints, page_index);
+ auto& new_client = m_owner.create_page();
+
+ Optional page_id;
+ if (no_opener == Web::HTML::TokenizedFeature::NoOpener::Yes) {
+ // FIXME: Create an abstraction to let this WebContent process know about a new process we create?
+ // FIXME: For now, just create a new page in the same process anyway
+ }
+
+ page_id = new_client.m_id;
+
+ auto response = client().send_sync_but_allow_failure(activate_tab, hints, page_id);
if (!response) {
dbgln("WebContent client disconnected during DidRequestNewWebView. Exiting peacefully.");
exit(0);
}
- return response->take_handle();
+
+ return { &new_client.page(), response->take_handle() };
}
void PageClient::page_did_request_activate_tab()
diff --git a/Userland/Services/WebContent/PageClient.h b/Userland/Services/WebContent/PageClient.h
index 8558c3b17f..ca1ef4ad6c 100644
--- a/Userland/Services/WebContent/PageClient.h
+++ b/Userland/Services/WebContent/PageClient.h
@@ -118,7 +118,7 @@ private:
virtual void page_did_set_cookie(const URL&, Web::Cookie::ParsedCookie const&, Web::Cookie::Source) override;
virtual void page_did_update_cookie(Web::Cookie::Cookie) override;
virtual void page_did_update_resource_count(i32) override;
- virtual String page_did_request_new_web_view(Web::HTML::ActivateTab, Web::HTML::WebViewHints, Optional page_index = {}) override;
+ virtual NewWebViewResult page_did_request_new_web_view(Web::HTML::ActivateTab, Web::HTML::WebViewHints, Web::HTML::TokenizedFeature::NoOpener) override;
virtual void page_did_request_activate_tab() override;
virtual void page_did_close_browsing_context(Web::HTML::BrowsingContext const&) override;
virtual void request_file(Web::FileRequest) override;