LibWeb: Break the Window open steps into two methods for internal use

Some callers (namely WebDriver) will need access to the navigable opened
by these steps. But if the noopener parameter is set, the returned proxy
will always be null.

This splits some of the Window open steps into an internal method that
returns the chosen navigable.
This commit is contained in:
Timothy Flynn 2024-10-20 08:48:52 -04:00 committed by Tim Ledbetter
parent 748e3c2e6c
commit 981aaba96c
Notes: github-actions[bot] 2024-10-20 15:42:16 +00:00
2 changed files with 26 additions and 8 deletions

View file

@ -140,10 +140,25 @@ Window::~Window() = default;
// https://html.spec.whatwg.org/multipage/window-object.html#window-open-steps // https://html.spec.whatwg.org/multipage/window-object.html#window-open-steps
WebIDL::ExceptionOr<JS::GCPtr<WindowProxy>> Window::window_open_steps(StringView url, StringView target, StringView features) WebIDL::ExceptionOr<JS::GCPtr<WindowProxy>> Window::window_open_steps(StringView url, StringView target, StringView features)
{
auto [target_navigable, no_opener, window_type] = TRY(window_open_steps_internal(url, target, features));
if (target_navigable == nullptr)
return nullptr;
// 14. If noopener is true or windowType is "new with no opener", then return null.
if (no_opener == TokenizedFeature::NoOpener::Yes || window_type == Navigable::WindowType::NewWithNoOpener)
return nullptr;
// 15. Return targetNavigable's active WindowProxy.
return target_navigable->active_window_proxy();
}
// https://html.spec.whatwg.org/multipage/window-object.html#window-open-steps
WebIDL::ExceptionOr<Window::OpenedWindow> Window::window_open_steps_internal(StringView url, StringView target, StringView features)
{ {
// 1. If the event loop's termination nesting level is nonzero, return null. // 1. If the event loop's termination nesting level is nonzero, return null.
if (main_thread_event_loop().termination_nesting_level() != 0) if (main_thread_event_loop().termination_nesting_level() != 0)
return nullptr; return OpenedWindow {};
// FIXME: Spec-issue: https://github.com/whatwg/html/issues/10681 // FIXME: Spec-issue: https://github.com/whatwg/html/issues/10681
// We need to check for an invalid URL before running the 'rules for choosing a navigable' otherwise // We need to check for an invalid URL before running the 'rules for choosing a navigable' otherwise
@ -206,7 +221,7 @@ WebIDL::ExceptionOr<JS::GCPtr<WindowProxy>> Window::window_open_steps(StringView
// 11. If targetNavigable is null, then return null. // 11. If targetNavigable is null, then return null.
if (target_navigable == nullptr) if (target_navigable == nullptr)
return nullptr; return OpenedWindow {};
// 12. If windowType is either "new and unrestricted" or "new with no opener", then: // 12. If windowType is either "new and unrestricted" or "new with no opener", then:
if (window_type == Navigable::WindowType::NewAndUnrestricted || window_type == Navigable::WindowType::NewWithNoOpener) { if (window_type == Navigable::WindowType::NewAndUnrestricted || window_type == Navigable::WindowType::NewWithNoOpener) {
@ -253,12 +268,7 @@ WebIDL::ExceptionOr<JS::GCPtr<WindowProxy>> Window::window_open_steps(StringView
target_navigable->active_browsing_context()->set_opener_browsing_context(source_document.browsing_context()); target_navigable->active_browsing_context()->set_opener_browsing_context(source_document.browsing_context());
} }
// 14. If noopener is true or windowType is "new with no opener", then return null. return OpenedWindow { target_navigable, no_opener, window_type };
if (no_opener == TokenizedFeature::NoOpener::Yes || window_type == Navigable::WindowType::NewWithNoOpener)
return nullptr;
// 15. Return targetNavigable's active WindowProxy.
return target_navigable->active_window_proxy();
} }
bool Window::dispatch_event(DOM::Event& event) bool Window::dispatch_event(DOM::Event& event)

View file

@ -102,6 +102,14 @@ public:
void set_import_maps_allowed(bool import_maps_allowed) { m_import_maps_allowed = import_maps_allowed; } void set_import_maps_allowed(bool import_maps_allowed) { m_import_maps_allowed = import_maps_allowed; }
WebIDL::ExceptionOr<JS::GCPtr<WindowProxy>> window_open_steps(StringView url, StringView target, StringView features); WebIDL::ExceptionOr<JS::GCPtr<WindowProxy>> window_open_steps(StringView url, StringView target, StringView features);
struct OpenedWindow {
JS::GCPtr<Navigable> navigable;
TokenizedFeature::NoOpener no_opener { TokenizedFeature::NoOpener::No };
Navigable::WindowType window_type { Navigable::WindowType::ExistingOrNone };
};
WebIDL::ExceptionOr<OpenedWindow> window_open_steps_internal(StringView url, StringView target, StringView features);
bool has_animation_frame_callbacks() const { return m_animation_frame_callback_driver.has_callbacks(); } bool has_animation_frame_callbacks() const { return m_animation_frame_callback_driver.has_callbacks(); }
DOM::Event* current_event() { return m_current_event.ptr(); } DOM::Event* current_event() { return m_current_event.ptr(); }