mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:37:35 +00:00
LibWeb: Flesh out most of the "unload" algorithm for documents
Yet another small steps towards spec-compliant document lifecycles.
This commit is contained in:
parent
797d28adca
commit
0c7ab663c1
3 changed files with 103 additions and 0 deletions
|
@ -61,6 +61,7 @@
|
||||||
#include <LibWeb/HTML/Scripting/ExceptionReporter.h>
|
#include <LibWeb/HTML/Scripting/ExceptionReporter.h>
|
||||||
#include <LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.h>
|
#include <LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.h>
|
||||||
#include <LibWeb/HTML/Window.h>
|
#include <LibWeb/HTML/Window.h>
|
||||||
|
#include <LibWeb/HighResolutionTime/CoarsenTime.h>
|
||||||
#include <LibWeb/Layout/BlockFormattingContext.h>
|
#include <LibWeb/Layout/BlockFormattingContext.h>
|
||||||
#include <LibWeb/Layout/InitialContainingBlock.h>
|
#include <LibWeb/Layout/InitialContainingBlock.h>
|
||||||
#include <LibWeb/Layout/TreeBuilder.h>
|
#include <LibWeb/Layout/TreeBuilder.h>
|
||||||
|
@ -2119,4 +2120,95 @@ void Document::set_browsing_context(HTML::BrowsingContext* browsing_context)
|
||||||
m_browsing_context = browsing_context;
|
m_browsing_context = browsing_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#unload-a-document
|
||||||
|
void Document::unload(bool recursive_flag, Optional<DocumentUnloadTimingInfo> unload_timing_info)
|
||||||
|
{
|
||||||
|
// 1. Increase the event loop's termination nesting level by one.
|
||||||
|
HTML::main_thread_event_loop().increment_termination_nesting_level();
|
||||||
|
|
||||||
|
// 2. Increase document's unload counter by 1.
|
||||||
|
m_unload_counter += 1;
|
||||||
|
|
||||||
|
// 3. If the user agent does not intend to keep document alive in a session history entry
|
||||||
|
// (such that it can be reused later on history traversal), set document's salvageable state to false.
|
||||||
|
// FIXME: If we want to implement fast back/forward cache, this has to change.
|
||||||
|
m_salvageable = false;
|
||||||
|
|
||||||
|
// 4. If document's page showing flag is true:
|
||||||
|
if (m_page_showing) {
|
||||||
|
// 1. Set document's page showing flag to false.
|
||||||
|
m_page_showing = false;
|
||||||
|
|
||||||
|
// 2. Fire a page transition event named pagehide at document's relevant global object with document's salvageable state.
|
||||||
|
global_object().fire_a_page_transition_event(HTML::EventNames::pagehide, m_salvageable);
|
||||||
|
|
||||||
|
// 3. Update the visibility state of newDocument to "hidden".
|
||||||
|
update_the_visibility_state(HTML::VisibilityState::Hidden);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. If unloadTimingInfo is not null,
|
||||||
|
if (unload_timing_info.has_value()) {
|
||||||
|
// then set unloadTimingInfo's unload event start time to the current high resolution time given newGlobal,
|
||||||
|
// coarsened given document's relevant settings object's cross-origin isolated capability.
|
||||||
|
unload_timing_info->unload_event_start_time = HighResolutionTime::coarsen_time(
|
||||||
|
HTML::main_thread_event_loop().unsafe_shared_current_time(),
|
||||||
|
relevant_settings_object().cross_origin_isolated_capability() == HTML::CanUseCrossOriginIsolatedAPIs::Yes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. If document's salvageable state is false,
|
||||||
|
if (!m_salvageable) {
|
||||||
|
// then fire an event named unload at document's relevant global object, with legacy target override flag set.
|
||||||
|
// FIXME: The legacy target override flag is currently set by a virtual override of dispatch_event()
|
||||||
|
// We should reorganize this so that the flag appears explicitly here instead.
|
||||||
|
auto event = DOM::Event::create(global_object(), HTML::EventNames::unload);
|
||||||
|
global_object().dispatch_event(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. If unloadTimingInfo is not null,
|
||||||
|
if (unload_timing_info.has_value()) {
|
||||||
|
// then set unloadTimingInfo's unload event end time to the current high resolution time given newGlobal,
|
||||||
|
// coarsened given document's relevant settings object's cross-origin isolated capability.
|
||||||
|
unload_timing_info->unload_event_end_time = HighResolutionTime::coarsen_time(
|
||||||
|
HTML::main_thread_event_loop().unsafe_shared_current_time(),
|
||||||
|
relevant_settings_object().cross_origin_isolated_capability() == HTML::CanUseCrossOriginIsolatedAPIs::Yes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8. Decrease the event loop's termination nesting level by one.
|
||||||
|
HTML::main_thread_event_loop().decrement_termination_nesting_level();
|
||||||
|
|
||||||
|
// FIXME: 9. Set document's suspension time to the current high resolution time given document's relevant global object.
|
||||||
|
|
||||||
|
// FIXME: 10. Set document's suspended timer handles to the result of getting the keys for the map of active timers.
|
||||||
|
|
||||||
|
// FIXME: 11. Run any unloading document cleanup steps for document that are defined by this specification and other applicable specifications.
|
||||||
|
|
||||||
|
// 12. If the recursiveFlag is not set, then:
|
||||||
|
if (!recursive_flag) {
|
||||||
|
// 1. Let descendants be the list of the descendant browsing contexts of document.
|
||||||
|
auto descendants = list_of_descendant_browsing_contexts();
|
||||||
|
|
||||||
|
// 2. For each browsingContext in descendants:
|
||||||
|
for (auto browsing_context : descendants) {
|
||||||
|
JS::GCPtr<Document> active_document = browsing_context->active_document();
|
||||||
|
if (!active_document)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// 1. Unload the active document of browsingContext with the recursiveFlag set.
|
||||||
|
active_document->unload(true);
|
||||||
|
|
||||||
|
// 2. If the salvageable state of the active document of browsingContext is false,
|
||||||
|
// then set the salvageable state of document to false also.
|
||||||
|
if (!active_document->m_salvageable)
|
||||||
|
m_salvageable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. If document's salvageable state is false, then discard document.
|
||||||
|
if (!m_salvageable)
|
||||||
|
discard();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 13. Decrease document's unload counter by 1.
|
||||||
|
m_unload_counter -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -420,6 +420,9 @@ public:
|
||||||
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#abort-a-document
|
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#abort-a-document
|
||||||
void abort();
|
void abort();
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#unload-a-document
|
||||||
|
void unload(bool recursive_flag = false, Optional<DocumentUnloadTimingInfo> = {});
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/dom.html#active-parser
|
// https://html.spec.whatwg.org/multipage/dom.html#active-parser
|
||||||
RefPtr<HTML::HTMLParser> active_parser();
|
RefPtr<HTML::HTMLParser> active_parser();
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,11 @@ public:
|
||||||
void spin_until(Function<bool()> goal_condition);
|
void spin_until(Function<bool()> goal_condition);
|
||||||
void process();
|
void process();
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#termination-nesting-level
|
||||||
|
size_t termination_nesting_level() const { return m_termination_nesting_level; }
|
||||||
|
void increment_termination_nesting_level() { ++m_termination_nesting_level; }
|
||||||
|
void decrement_termination_nesting_level() { --m_termination_nesting_level; }
|
||||||
|
|
||||||
Task const* currently_running_task() const { return m_currently_running_task; }
|
Task const* currently_running_task() const { return m_currently_running_task; }
|
||||||
|
|
||||||
JS::VM& vm() { return *m_vm; }
|
JS::VM& vm() { return *m_vm; }
|
||||||
|
@ -96,6 +101,9 @@ private:
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/webappapis.html#backup-incumbent-settings-object-stack
|
// https://html.spec.whatwg.org/multipage/webappapis.html#backup-incumbent-settings-object-stack
|
||||||
Vector<EnvironmentSettingsObject&> m_backup_incumbent_settings_object_stack;
|
Vector<EnvironmentSettingsObject&> m_backup_incumbent_settings_object_stack;
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#termination-nesting-level
|
||||||
|
size_t m_termination_nesting_level { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
EventLoop& main_thread_event_loop();
|
EventLoop& main_thread_event_loop();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue