瀏覽代碼

LibWeb: Restore check to prevent closing a traversable twice

We removed this check as a workaround for a spec issue that was resolved
in:

https://github.com/whatwg/html/commit/3a8303ece44ed509928be626a6a65639fd
Timothy Flynn 9 月之前
父節點
當前提交
d80d951991

+ 14 - 8
Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp

@@ -1175,21 +1175,27 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_traverse
 // https://html.spec.whatwg.org/multipage/document-sequences.html#close-a-top-level-traversable
 // https://html.spec.whatwg.org/multipage/document-sequences.html#close-a-top-level-traversable
 void TraversableNavigable::close_top_level_traversable()
 void TraversableNavigable::close_top_level_traversable()
 {
 {
-    VERIFY(is_top_level_traversable());
-
     // 1. If traversable's is closing is true, then return.
     // 1. If traversable's is closing is true, then return.
-    // FIXME: Spec-issue: The only place in the spec that sets the `is closing` flag to true is `window.close`, and it
-    //        does so immediately before invoking this method. So it does not make sense to return early here.
-    //        https://github.com/whatwg/html/issues/10678
+    if (is_closing())
+        return;
+
+    // 2. Definitely close traversable.
+    definitely_close_top_level_traversable();
+}
 
 
-    // 2. Let toUnload be traversable's active document's inclusive descendant navigables.
+// https://html.spec.whatwg.org/multipage/document-sequences.html#definitely-close-a-top-level-traversable
+void TraversableNavigable::definitely_close_top_level_traversable()
+{
+    VERIFY(is_top_level_traversable());
+
+    // 1. Let toUnload be traversable's active document's inclusive descendant navigables.
     auto to_unload = active_document()->inclusive_descendant_navigables();
     auto to_unload = active_document()->inclusive_descendant_navigables();
 
 
-    // If the result of checking if unloading is canceled for toUnload is true, then return.
+    // 2. If the result of checking if unloading is canceled for toUnload is true, then return.
     if (check_if_unloading_is_canceled(to_unload) != CheckIfUnloadingIsCanceledResult::Continue)
     if (check_if_unloading_is_canceled(to_unload) != CheckIfUnloadingIsCanceledResult::Continue)
         return;
         return;
 
 
-    // 4. Append the following session history traversal steps to traversable:
+    // 3. Append the following session history traversal steps to traversable:
     append_session_history_traversal_steps(JS::create_heap_function(heap(), [this] {
     append_session_history_traversal_steps(JS::create_heap_function(heap(), [this] {
         // 1. Let afterAllUnloads be an algorithm step which destroys traversable.
         // 1. Let afterAllUnloads be an algorithm step which destroys traversable.
         auto after_all_unloads = JS::create_heap_function(heap(), [this] {
         auto after_all_unloads = JS::create_heap_function(heap(), [this] {

+ 1 - 0
Userland/Libraries/LibWeb/HTML/TraversableNavigable.h

@@ -78,6 +78,7 @@ public:
     void traverse_the_history_by_delta(int delta, Optional<DOM::Document&> source_document = {});
     void traverse_the_history_by_delta(int delta, Optional<DOM::Document&> source_document = {});
 
 
     void close_top_level_traversable();
     void close_top_level_traversable();
+    void definitely_close_top_level_traversable();
     void destroy_top_level_traversable();
     void destroy_top_level_traversable();
 
 
     void append_session_history_traversal_steps(JS::NonnullGCPtr<JS::HeapFunction<void()>> steps)
     void append_session_history_traversal_steps(JS::NonnullGCPtr<JS::HeapFunction<void()>> steps)

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

@@ -826,9 +826,9 @@ void Window::close()
         // 1. Set thisTraversable's is closing to true.
         // 1. Set thisTraversable's is closing to true.
         traversable->set_closing(true);
         traversable->set_closing(true);
 
 
-        // 2. Queue a task on the DOM manipulation task source to close thisTraversable.
+        // 2. Queue a task on the DOM manipulation task source to definitely close thisTraversable.
         HTML::queue_global_task(HTML::Task::Source::DOMManipulation, incumbent_global_object, JS::create_heap_function(heap(), [traversable] {
         HTML::queue_global_task(HTML::Task::Source::DOMManipulation, incumbent_global_object, JS::create_heap_function(heap(), [traversable] {
-            verify_cast<TraversableNavigable>(*traversable).close_top_level_traversable();
+            verify_cast<TraversableNavigable>(*traversable).definitely_close_top_level_traversable();
         }));
         }));
     }
     }
 }
 }