summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb/DOM/Document.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Libraries/LibWeb/DOM/Document.cpp')
-rw-r--r--Userland/Libraries/LibWeb/DOM/Document.cpp92
1 files changed, 92 insertions, 0 deletions
diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp
index 4e4ce27477..121056bddb 100644
--- a/Userland/Libraries/LibWeb/DOM/Document.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Document.cpp
@@ -61,6 +61,7 @@
#include <LibWeb/HTML/Scripting/ExceptionReporter.h>
#include <LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.h>
#include <LibWeb/HTML/Window.h>
+#include <LibWeb/HighResolutionTime/CoarsenTime.h>
#include <LibWeb/Layout/BlockFormattingContext.h>
#include <LibWeb/Layout/InitialContainingBlock.h>
#include <LibWeb/Layout/TreeBuilder.h>
@@ -2119,4 +2120,95 @@ void Document::set_browsing_context(HTML::BrowsingContext* 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;
+}
+
}