mirror of
https://github.com/RGBCube/serenity
synced 2025-07-23 20:17:42 +00:00
LibWeb: Create a new WebView for window.open()'d top level traversables
This commit is contained in:
parent
677bdc2a4f
commit
adb5c27331
5 changed files with 42 additions and 9 deletions
|
@ -412,17 +412,29 @@ Navigable::ChosenNavigable Navigable::choose_a_navigable(StringView name, Tokeni
|
||||||
if (!Infra::is_ascii_case_insensitive_match(name, "_blank"sv))
|
if (!Infra::is_ascii_case_insensitive_match(name, "_blank"sv))
|
||||||
target_name = MUST(String::from_utf8(name));
|
target_name = MUST(String::from_utf8(name));
|
||||||
|
|
||||||
|
auto create_new_traversable_closure = [this, window_type, no_opener, target_name](JS::GCPtr<BrowsingContext> opener) -> JS::NonnullGCPtr<Navigable> {
|
||||||
|
// 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.
|
// 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) {
|
if (no_opener == TokenizedFeature::NoOpener::Yes) {
|
||||||
// FIXME: This should do something similar to RemoteBrowsingContext -- but RemoteTraversableNavigable instead
|
chosen = create_new_traversable->function()(nullptr);
|
||||||
TODO();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8. Otherwise:
|
// 8. Otherwise:
|
||||||
else {
|
else {
|
||||||
// 1. Set chosen to the result of creating a new top-level traversable given currentNavigable's active browsing context and targetName.
|
// 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<ChosenNavigable>
|
chosen = create_new_traversable->function()(active_browsing_context());
|
||||||
chosen = TraversableNavigable::create_a_new_top_level_traversable(traversable_navigable()->page(), active_browsing_context(), target_name).release_value_but_fixme_should_propagate_errors();
|
|
||||||
|
|
||||||
// FIXME: 2. If sandboxingFlagSet's sandboxed navigation browsing context flag is set,
|
// 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.
|
// then set chosen's active browsing context's one permitted sandboxed navigator to currentNavigable's active browsing context.
|
||||||
|
|
|
@ -82,6 +82,9 @@ public:
|
||||||
Page& page() { return m_page; }
|
Page& page() { return m_page; }
|
||||||
Page const& page() const { 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:
|
private:
|
||||||
TraversableNavigable(JS::NonnullGCPtr<Page>);
|
TraversableNavigable(JS::NonnullGCPtr<Page>);
|
||||||
|
|
||||||
|
@ -114,6 +117,8 @@ private:
|
||||||
SessionHistoryTraversalQueue m_session_history_traversal_queue;
|
SessionHistoryTraversalQueue m_session_history_traversal_queue;
|
||||||
|
|
||||||
JS::NonnullGCPtr<Page> m_page;
|
JS::NonnullGCPtr<Page> m_page;
|
||||||
|
|
||||||
|
String m_window_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BrowsingContextAndDocument {
|
struct BrowsingContextAndDocument {
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <LibWeb/HTML/ActivateTab.h>
|
#include <LibWeb/HTML/ActivateTab.h>
|
||||||
#include <LibWeb/HTML/ColorPickerUpdateState.h>
|
#include <LibWeb/HTML/ColorPickerUpdateState.h>
|
||||||
#include <LibWeb/HTML/SelectItem.h>
|
#include <LibWeb/HTML/SelectItem.h>
|
||||||
|
#include <LibWeb/HTML/TokenizedFeatures.h>
|
||||||
#include <LibWeb/HTML/WebViewHints.h>
|
#include <LibWeb/HTML/WebViewHints.h>
|
||||||
#include <LibWeb/Loader/FileRequest.h>
|
#include <LibWeb/Loader/FileRequest.h>
|
||||||
#include <LibWeb/PixelUnits.h>
|
#include <LibWeb/PixelUnits.h>
|
||||||
|
@ -269,7 +270,11 @@ public:
|
||||||
virtual void page_did_set_cookie(const AK::URL&, Cookie::ParsedCookie const&, Cookie::Source) { }
|
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_cookie(Web::Cookie::Cookie) { }
|
||||||
virtual void page_did_update_resource_count(i32) { }
|
virtual void page_did_update_resource_count(i32) { }
|
||||||
virtual String page_did_request_new_web_view(HTML::ActivateTab, HTML::WebViewHints, Optional<u64> = {}) { return {}; }
|
struct NewWebViewResult {
|
||||||
|
JS::GCPtr<Page> 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_request_activate_tab() { }
|
||||||
virtual void page_did_close_browsing_context(HTML::BrowsingContext const&) { }
|
virtual void page_did_close_browsing_context(HTML::BrowsingContext const&) { }
|
||||||
|
|
||||||
|
|
|
@ -497,14 +497,25 @@ void PageClient::page_did_update_resource_count(i32 count_waiting)
|
||||||
client().async_did_update_resource_count(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<u64> 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<Messages::WebContentClient::DidRequestNewWebView>(activate_tab, hints, page_index);
|
auto& new_client = m_owner.create_page();
|
||||||
|
|
||||||
|
Optional<u64> 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<Messages::WebContentClient::DidRequestNewWebView>(activate_tab, hints, page_id);
|
||||||
if (!response) {
|
if (!response) {
|
||||||
dbgln("WebContent client disconnected during DidRequestNewWebView. Exiting peacefully.");
|
dbgln("WebContent client disconnected during DidRequestNewWebView. Exiting peacefully.");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
return response->take_handle();
|
|
||||||
|
return { &new_client.page(), response->take_handle() };
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageClient::page_did_request_activate_tab()
|
void PageClient::page_did_request_activate_tab()
|
||||||
|
|
|
@ -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_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_cookie(Web::Cookie::Cookie) override;
|
||||||
virtual void page_did_update_resource_count(i32) 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<u64> 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_request_activate_tab() override;
|
||||||
virtual void page_did_close_browsing_context(Web::HTML::BrowsingContext const&) override;
|
virtual void page_did_close_browsing_context(Web::HTML::BrowsingContext const&) override;
|
||||||
virtual void request_file(Web::FileRequest) override;
|
virtual void request_file(Web::FileRequest) override;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue