1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 14:37:46 +00:00

LibWeb: Allow HTML parser to delay delivery of the document "load" event

We will now spin in "the end" until there are no more "things delaying
the load event". Of course, nothing actually uses this yet, and there
are a lot of things that need to.
This commit is contained in:
Andreas Kling 2021-09-26 01:03:42 +02:00
parent b1529e3202
commit dbba0a520f
6 changed files with 67 additions and 1 deletions

View file

@ -48,6 +48,7 @@ set(SOURCES
DOM/DOMImplementation.cpp DOM/DOMImplementation.cpp
DOM/Document.cpp DOM/Document.cpp
DOM/DocumentFragment.cpp DOM/DocumentFragment.cpp
DOM/DocumentLoadEventDelayer.cpp
DOM/DocumentType.cpp DOM/DocumentType.cpp
DOM/Element.cpp DOM/Element.cpp
DOM/ElementFactory.cpp DOM/ElementFactory.cpp

View file

@ -285,6 +285,14 @@ public:
Bindings::LocationObject* location(); Bindings::LocationObject* location();
size_t number_of_things_delaying_the_load_event() { return m_number_of_things_delaying_the_load_event; }
void increment_number_of_things_delaying_the_load_event(Badge<DocumentLoadEventDelayer>) { ++m_number_of_things_delaying_the_load_event; }
void decrement_number_of_things_delaying_the_load_event(Badge<DocumentLoadEventDelayer>)
{
VERIFY(m_number_of_things_delaying_the_load_event);
--m_number_of_things_delaying_the_load_event;
}
private: private:
explicit Document(const AK::URL&); explicit Document(const AK::URL&);
@ -367,6 +375,8 @@ private:
u32 m_script_blocking_style_sheet_counter { 0 }; u32 m_script_blocking_style_sheet_counter { 0 };
NonnullRefPtr<HTML::History> m_history; NonnullRefPtr<HTML::History> m_history;
size_t m_number_of_things_delaying_the_load_event { 0 };
}; };
} }

View file

@ -0,0 +1,23 @@
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/DOM/Document.h>
#include <LibWeb/DOM/DocumentLoadEventDelayer.h>
namespace Web::DOM {
DocumentLoadEventDelayer::DocumentLoadEventDelayer(Document& document)
: m_document(document)
{
m_document->increment_number_of_things_delaying_the_load_event({});
}
DocumentLoadEventDelayer::~DocumentLoadEventDelayer()
{
m_document->decrement_number_of_things_delaying_the_load_event({});
}
}

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Noncopyable.h>
#include <AK/NonnullRefPtr.h>
#include <LibWeb/Forward.h>
namespace Web::DOM {
class DocumentLoadEventDelayer {
AK_MAKE_NONMOVABLE(DocumentLoadEventDelayer);
AK_MAKE_NONCOPYABLE(DocumentLoadEventDelayer);
public:
explicit DocumentLoadEventDelayer(Document&);
~DocumentLoadEventDelayer();
private:
NonnullRefPtr<Document> m_document;
};
}

View file

@ -64,6 +64,7 @@ class CharacterData;
class Comment; class Comment;
class Document; class Document;
class DocumentFragment; class DocumentFragment;
class DocumentLoadEventDelayer;
class DocumentType; class DocumentType;
class DOMException; class DOMException;
class DOMImplementation; class DOMImplementation;

View file

@ -231,7 +231,11 @@ void HTMLParser::the_end()
return m_document->scripts_to_execute_as_soon_as_possible().is_empty(); return m_document->scripts_to_execute_as_soon_as_possible().is_empty();
}); });
// FIXME: 8. Spin the event loop until there is nothing that delays the load event in the Document. // 8. Spin the event loop until there is nothing that delays the load event in the Document.
// FIXME: Track down all the things that are supposed to delay the load event.
main_thread_event_loop().spin_until([&] {
return m_document->number_of_things_delaying_the_load_event() == 0;
});
// 9. Queue a global task on the DOM manipulation task source given the Document's relevant global object to run the following steps: // 9. Queue a global task on the DOM manipulation task source given the Document's relevant global object to run the following steps:
queue_global_task(HTML::Task::Source::DOMManipulation, *m_document, [document = m_document]() mutable { queue_global_task(HTML::Task::Source::DOMManipulation, *m_document, [document = m_document]() mutable {