Explorar el Código

LibWeb: Update top_level_browsing_context() to use navigables

Aliaksandr Kalenik hace 1 año
padre
commit
6942bdcfce

+ 28 - 7
Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp

@@ -251,8 +251,8 @@ WebIDL::ExceptionOr<BrowsingContext::BrowsingContextAndDocument> BrowsingContext
         if (creator->origin().is_same_origin(creator->relevant_settings_object().top_level_origin)) {
             // then set document's cross-origin opener policy to creator's browsing context's top-level browsing context's active document's cross-origin opener policy.
             VERIFY(creator->browsing_context());
-            VERIFY(creator->browsing_context()->top_level_browsing_context().active_document());
-            document->set_cross_origin_opener_policy(creator->browsing_context()->top_level_browsing_context().active_document()->cross_origin_opener_policy());
+            VERIFY(creator->browsing_context()->top_level_browsing_context()->active_document());
+            document->set_cross_origin_opener_policy(creator->browsing_context()->top_level_browsing_context()->active_document()->cross_origin_opener_policy());
         }
     }
 
@@ -409,6 +409,27 @@ void BrowsingContext::scroll_to_anchor(DeprecatedString const& fragment)
         m_page->client().page_did_request_scroll_into_view(target_rect);
 }
 
+JS::GCPtr<BrowsingContext> BrowsingContext::top_level_browsing_context() const
+{
+    auto const* start = this;
+
+    // 1. If start's active document is not fully active, then return null.
+    if (!start->active_document()->is_fully_active()) {
+        return nullptr;
+    }
+
+    // 2. Let navigable be start's active document's node navigable.
+    auto navigable = start->active_document()->navigable();
+
+    // 3. While navigable's parent is not null, set navigable to navigable's parent.
+    while (navigable->parent()) {
+        navigable = navigable->parent();
+    }
+
+    // 4. Return navigable's active browsing context.
+    return navigable->active_browsing_context();
+}
+
 CSSPixelRect BrowsingContext::to_top_level_rect(CSSPixelRect const& a_rect)
 {
     auto rect = a_rect;
@@ -583,7 +604,7 @@ BrowsingContext::ChosenBrowsingContext BrowsingContext::choose_a_browsing_contex
     // The rules for choosing a browsing context, given a browsing context name name, a browsing context current, and
     // a boolean noopener are as follows:
     JS::GCPtr<AbstractBrowsingContext> matching_name_in_tree = nullptr;
-    top_level_browsing_context().for_each_in_subtree([&](auto& context) {
+    top_level_browsing_context()->for_each_in_subtree([&](auto& context) {
         if (context.name() == name) {
             matching_name_in_tree = &context;
             return IterationDecision::Break;
@@ -618,7 +639,7 @@ BrowsingContext::ChosenBrowsingContext BrowsingContext::choose_a_browsing_contex
     // 6. Otherwise, if name is an ASCII case-insensitive match for "_top", set chosen to current's top-level browsing
     //    context, if any, and current otherwise.
     else if (Infra::is_ascii_case_insensitive_match(name, "_top"sv)) {
-        chosen = &top_level_browsing_context();
+        chosen = top_level_browsing_context();
     }
 
     // 7. Otherwise, if name is not an ASCII case-insensitive match for "_blank", there exists a browsing context
@@ -655,9 +676,9 @@ BrowsingContext::ChosenBrowsingContext BrowsingContext::choose_a_browsing_contex
 
             // 2. If current's top-level browsing context's active document's cross-origin opener policy's value is
             //    "same-origin" or "same-origin-plus-COEP", then:
-            if (top_level_browsing_context().active_document()->cross_origin_opener_policy().value == CrossOriginOpenerPolicyValue::SameOrigin || top_level_browsing_context().active_document()->cross_origin_opener_policy().value == CrossOriginOpenerPolicyValue::SameOriginPlusCOEP) {
+            if (top_level_browsing_context()->active_document()->cross_origin_opener_policy().value == CrossOriginOpenerPolicyValue::SameOrigin || top_level_browsing_context()->active_document()->cross_origin_opener_policy().value == CrossOriginOpenerPolicyValue::SameOriginPlusCOEP) {
                 // 1. Let currentDocument be current's active document.
-                auto* current_document = top_level_browsing_context().active_document();
+                auto* current_document = top_level_browsing_context()->active_document();
 
                 // 2. If currentDocument's origin is not same origin with currentDocument's relevant settings object's
                 //    top-level origin, then set noopener to true, name to "_blank", and windowType to "new with no opener".
@@ -871,7 +892,7 @@ void BrowsingContext::set_system_visibility_state(VisibilityState visibility_sta
     // When a user-agent determines that the system visibility state for top-level browsing context context
     // has changed to newState, it must queue a task on the user interaction task source to update
     // the visibility state of all the Document objects in the top-level browsing context's document family with newState.
-    auto document_family = top_level_browsing_context().document_family();
+    auto document_family = top_level_browsing_context()->document_family();
 
     // From the new navigable version, where it tells us what global object to use here:
     // 1. Let document be navigable's active document.

+ 1 - 9
Userland/Libraries/LibWeb/HTML/BrowsingContext.h

@@ -142,15 +142,7 @@ public:
     void scroll_to(CSSPixelPoint);
     void scroll_to_anchor(DeprecatedString const&);
 
-    BrowsingContext& top_level_browsing_context()
-    {
-        BrowsingContext* context = this;
-        while (context->parent())
-            context = context->parent();
-        return *context;
-    }
-
-    BrowsingContext const& top_level_browsing_context() const { return const_cast<BrowsingContext*>(this)->top_level_browsing_context(); }
+    JS::GCPtr<BrowsingContext> top_level_browsing_context() const;
 
     enum class WindowType {
         ExistingOrNone,

+ 2 - 2
Userland/Libraries/LibWeb/HTML/CrossOrigin/Reporting.cpp

@@ -27,11 +27,11 @@ void check_if_access_between_two_browsing_contexts_should_be_reported(BrowsingCo
     auto accessor_accessed_relationship = AccessorAccessedRelationship::None;
 
     // 5. If accessed's top-level browsing context's opener browsing context is accessor or an ancestor of accessor, then set accessorAccessedRelationship to accessor is opener.
-    if (auto opener = accessed.top_level_browsing_context().opener_browsing_context(); opener && (opener == &accessor || opener->is_ancestor_of(accessor)))
+    if (auto opener = accessed.top_level_browsing_context()->opener_browsing_context(); opener && (opener == &accessor || opener->is_ancestor_of(accessor)))
         accessor_accessed_relationship = AccessorAccessedRelationship::AccessorIsOpener;
 
     // 6. If accessor's top-level browsing context's opener browsing context is accessed or an ancestor of accessed, then set accessorAccessedRelationship to accessor is openee.
-    if (auto opener = accessor.top_level_browsing_context().opener_browsing_context(); opener && (opener == &accessed || opener->is_ancestor_of(accessed)))
+    if (auto opener = accessor.top_level_browsing_context()->opener_browsing_context(); opener && (opener == &accessed || opener->is_ancestor_of(accessed)))
         accessor_accessed_relationship = AccessorAccessedRelationship::AccessorIsOpenee;
 
     // FIXME: 7. Queue violation reports for accesses, given accessorAccessedRelationship, accessor's top-level browsing context's active document's cross-origin opener policy, accessed's top-level browsing context's active document's cross-origin opener policy, accessor's active document's URL, accessed's active document's URL, accessor's top-level browsing context's initial URL, accessed's top-level browsing context's initial URL, accessor's active document's origin, accessed's active document's origin, accessor's top-level browsing context's opener origin at creation, accessed's top-level browsing context's opener origin at creation, accessor's top-level browsing context's active document's referrer, accessed's top-level browsing context's active document's referrer, P, and environment.

+ 7 - 7
Userland/Libraries/LibWeb/HTML/Focus.cpp

@@ -187,13 +187,13 @@ void run_focusing_steps(DOM::Node* new_focus_target, DOM::Node* fallback_target,
     // 5. If new focus target is the currently focused area of a top-level browsing context, then return.
     if (!new_focus_target->document().browsing_context())
         return;
-    auto& top_level_browsing_context = new_focus_target->document().browsing_context()->top_level_browsing_context();
-    if (new_focus_target == top_level_browsing_context.currently_focused_area().ptr())
+    auto top_level_browsing_context = new_focus_target->document().browsing_context()->top_level_browsing_context();
+    if (new_focus_target == top_level_browsing_context->currently_focused_area().ptr())
         return;
 
     // 6. Let old chain be the current focus chain of the top-level browsing context in which
     //    new focus target finds itself.
-    auto old_chain = focus_chain(top_level_browsing_context.currently_focused_area());
+    auto old_chain = focus_chain(top_level_browsing_context->currently_focused_area());
 
     // 7. Let new chain be the focus chain of new focus target.
     auto new_chain = focus_chain(new_focus_target);
@@ -220,8 +220,8 @@ void run_unfocusing_steps(DOM::Node* old_focus_target)
     if (is_shadow_host(old_focus_target)) {
         auto* shadow_root = static_cast<DOM::Element*>(old_focus_target)->shadow_root_internal();
         if (shadow_root->delegates_focus()) {
-            auto& top_level_browsing_context = old_focus_target->document().browsing_context()->top_level_browsing_context();
-            if (auto currently_focused_area = top_level_browsing_context.currently_focused_area()) {
+            auto top_level_browsing_context = old_focus_target->document().browsing_context()->top_level_browsing_context();
+            if (auto currently_focused_area = top_level_browsing_context->currently_focused_area()) {
                 if (shadow_root->is_shadow_including_ancestor_of(*currently_focused_area)) {
                     old_focus_target = currently_focused_area;
                 }
@@ -238,10 +238,10 @@ void run_unfocusing_steps(DOM::Node* old_focus_target)
 
     // NOTE: HTMLAreaElement is currently missing the shapes property
 
-    auto& top_level_browsing_context = old_focus_target->document().browsing_context()->top_level_browsing_context();
+    auto top_level_browsing_context = old_focus_target->document().browsing_context()->top_level_browsing_context();
 
     // 4. Let old chain be the current focus chain of the top-level browsing context in which old focus target finds itself.
-    auto old_chain = focus_chain(top_level_browsing_context.currently_focused_area());
+    auto old_chain = focus_chain(top_level_browsing_context->currently_focused_area());
 
     // 5. If old focus target is not one of the entries in old chain, then return.
     for (auto& node : old_chain) {

+ 1 - 1
Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp

@@ -201,7 +201,7 @@ static void show_the_picker_if_applicable(HTMLInputElement& element)
 
         // FIXME: Pass along accept attribute information https://html.spec.whatwg.org/multipage/input.html#attr-input-accept
         //    The accept attribute may be specified to provide user agents with a hint of what file types will be accepted.
-        element.document().browsing_context()->top_level_browsing_context().page()->client().page_did_request_file_picker(weak_element, multiple);
+        element.document().browsing_context()->top_level_browsing_context()->page()->client().page_did_request_file_picker(weak_element, multiple);
         return;
     }
 

+ 1 - 1
Userland/Libraries/LibWeb/HTML/NavigableContainer.cpp

@@ -64,7 +64,7 @@ WebIDL::ExceptionOr<void> NavigableContainer::create_new_child_navigable()
 
     // 2. Let group be element's node document's browsing context's top-level browsing context's group.
     VERIFY(document().browsing_context());
-    auto group = document().browsing_context()->top_level_browsing_context().group();
+    auto group = document().browsing_context()->top_level_browsing_context()->group();
     VERIFY(group);
 
     // 3. Let browsingContext and document be the result of creating a new browsing context and document given element's node document, element, and group.

+ 1 - 1
Userland/Libraries/LibWeb/HTML/Window.cpp

@@ -895,7 +895,7 @@ JS::GCPtr<WindowProxy const> Window::top() const
         return {};
 
     // 2. Return this's navigable's top-level traversable's active WindowProxy.
-    return browsing_context->top_level_browsing_context().window_proxy();
+    return browsing_context->top_level_browsing_context()->window_proxy();
 }
 
 // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-parent

+ 1 - 1
Userland/Libraries/LibWeb/Internals/Internals.cpp

@@ -42,7 +42,7 @@ void Internals::gc()
 
 JS::Object* Internals::hit_test(double x, double y)
 {
-    auto* active_document = global_object().browsing_context()->top_level_browsing_context().active_document();
+    auto* active_document = global_object().browsing_context()->top_level_browsing_context()->active_document();
     // NOTE: Force a layout update just before hit testing. This is because the current layout tree, which is required
     //       for stacking context traversal, might not exist if this call occurs between the tear_down_layout_tree()
     //       and update_layout() calls

+ 1 - 1
Userland/Libraries/LibWeb/IntersectionObserver/IntersectionObserver.cpp

@@ -155,7 +155,7 @@ Variant<JS::Handle<DOM::Element>, JS::Handle<DOM::Document>, Empty> Intersection
 Variant<JS::Handle<DOM::Element>, JS::Handle<DOM::Document>> IntersectionObserver::intersection_root() const
 {
     if (!m_root.has_value())
-        return JS::make_handle(global_object().browsing_context()->top_level_browsing_context().active_document());
+        return JS::make_handle(global_object().browsing_context()->top_level_browsing_context()->active_document());
     return m_root.value();
 }