浏览代码

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.
Timothy Flynn 8 月之前
父节点
当前提交
981aaba96c
共有 2 个文件被更改,包括 26 次插入8 次删除
  1. 18 8
      Userland/Libraries/LibWeb/HTML/Window.cpp
  2. 8 0
      Userland/Libraries/LibWeb/HTML/Window.h

+ 18 - 8
Userland/Libraries/LibWeb/HTML/Window.cpp

@@ -140,10 +140,25 @@ Window::~Window() = default;
 
 // 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)
+{
+    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.
     if (main_thread_event_loop().termination_nesting_level() != 0)
-        return nullptr;
+        return OpenedWindow {};
 
     // 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
@@ -206,7 +221,7 @@ WebIDL::ExceptionOr<JS::GCPtr<WindowProxy>> Window::window_open_steps(StringView
 
     // 11. If targetNavigable is null, then return null.
     if (target_navigable == nullptr)
-        return nullptr;
+        return OpenedWindow {};
 
     // 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) {
@@ -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());
     }
 
-    // 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();
+    return OpenedWindow { target_navigable, no_opener, window_type };
 }
 
 bool Window::dispatch_event(DOM::Event& event)

+ 8 - 0
Userland/Libraries/LibWeb/HTML/Window.h

@@ -102,6 +102,14 @@ public:
     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);
+
+    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(); }
 
     DOM::Event* current_event() { return m_current_event.ptr(); }