ソースを参照

LibWeb: Wait until new document becomes active before running scripts

Fixes https://github.com/SerenityOS/serenity/issues/22485

With this change WebContent does not crash when `location.reload()` is
invoked but `Navigable::reload()` still not working because of spec
issue (https://github.com/whatwg/html/issues/9869) so we can't add a
test yet.
Aliaksandr Kalenik 1 年間 前
コミット
07928129dd

+ 2 - 1
Userland/Libraries/LibWeb/DOM/Document.cpp

@@ -3628,7 +3628,8 @@ void Document::update_for_history_step_application(JS::NonnullGCPtr<HTML::Sessio
         //        "process scroll behavior".
         scroll_to_the_fragment();
 
-        // FIXME: 2. At this point scripts may run for the newly-created document document.
+        // 2. At this point scripts may run for the newly-created document document.
+        m_ready_to_run_scripts = true;
     }
 
     // 7. Otherwise, if documentsEntryChanged is false and doNotReactivate is false, then:

+ 5 - 0
Userland/Libraries/LibWeb/DOM/Document.h

@@ -551,6 +551,8 @@ public:
     };
     void append_pending_animation_event(PendingAnimationEvent const&);
 
+    bool ready_to_run_scripts() const { return m_ready_to_run_scripts; }
+
 protected:
     virtual void initialize(JS::Realm&) override;
     virtual void visit_edges(Cell::Visitor&) override;
@@ -769,6 +771,9 @@ private:
     Vector<PendingAnimationEvent> m_pending_animation_event_queue;
 
     bool m_needs_to_call_page_did_load { false };
+
+    // https://html.spec.whatwg.org/multipage/browsing-the-web.html#scripts-may-run-for-the-newly-created-document
+    bool m_ready_to_run_scripts { false };
 };
 
 template<>

+ 6 - 0
Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp

@@ -2729,6 +2729,12 @@ void HTMLParser::handle_text(HTMLToken& token)
 
     // -> An end tag whose tag name is "script"
     if (token.is_end_tag() && token.tag_name() == HTML::TagNames::script) {
+        // https://html.spec.whatwg.org/multipage/document-lifecycle.html#read-html
+        // Before any script execution occurs, the user agent must wait for scripts may run for the newly-created document to be true for document.
+        if (!m_document->ready_to_run_scripts()) {
+            main_thread_event_loop().spin_until([&] { return m_document->ready_to_run_scripts(); });
+        }
+
         // FIXME: If the active speculative HTML parser is null and the JavaScript execution context stack is empty, then perform a microtask checkpoint.
 
         // Non-standard: Make sure the <script> element has up-to-date text content before preparing the script.