aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/document.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/document.rs')
-rw-r--r--components/script/dom/document.rs53
1 files changed, 47 insertions, 6 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 66b9e379d75..d679ff0dd3f 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -416,6 +416,8 @@ pub struct Document {
/// List of tasks to execute as soon as last script/layout blocker is removed.
#[ignore_malloc_size_of = "Measuring trait objects is hard"]
delayed_tasks: DomRefCell<Vec<Box<dyn TaskBox>>>,
+ /// https://html.spec.whatwg.org/multipage/#completely-loaded
+ completely_loaded: Cell<bool>,
}
#[derive(JSTraceable, MallocSizeOf)]
@@ -507,6 +509,10 @@ impl Document {
self.https_state.set(https_state);
}
+ pub fn is_completely_loaded(&self) -> bool {
+ self.completely_loaded.get()
+ }
+
pub fn is_fully_active(&self) -> bool {
self.activity.get() == DocumentActivity::FullyActive
}
@@ -1735,7 +1741,11 @@ impl Document {
self.process_deferred_scripts();
},
LoadType::PageSource(_) => {
- if self.has_browsing_context {
+ if self.has_browsing_context && self.is_fully_active() {
+ // Note: if the document is not fully active, the layout thread will have exited already.
+ // The underlying problem might actually be that layout exits while it should be kept alive.
+ // See https://github.com/servo/servo/issues/22507
+
// Disarm the reflow timer and trigger the initial reflow.
self.reflow_timeout.set(None);
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
@@ -1899,7 +1909,21 @@ impl Document {
// https://html.spec.whatwg.org/multipage/#the-end
pub fn maybe_queue_document_completion(&self) {
- if self.loader.borrow().is_blocked() {
+ // https://html.spec.whatwg.org/multipage/#delaying-load-events-mode
+ let is_in_delaying_load_events_mode = match self.window.undiscarded_window_proxy() {
+ Some(window_proxy) => window_proxy.is_delaying_load_events_mode(),
+ None => false,
+ };
+
+ // Note: if the document is not fully active, the layout thread will have exited already,
+ // and this method will panic.
+ // The underlying problem might actually be that layout exits while it should be kept alive.
+ // See https://github.com/servo/servo/issues/22507
+ let not_ready_for_load = self.loader.borrow().is_blocked() ||
+ !self.is_fully_active() ||
+ is_in_delaying_load_events_mode;
+
+ if not_ready_for_load {
// Step 6.
return;
}
@@ -1952,8 +1976,6 @@ impl Document {
window.reflow(ReflowGoal::Full, ReflowReason::DocumentLoaded);
- document.notify_constellation_load();
-
if let Some(fragment) = document.url().fragment() {
document.check_and_scroll_fragment(fragment);
}
@@ -2008,8 +2030,26 @@ impl Document {
// Step 11.
// TODO: ready for post-load tasks.
- // Step 12.
- // TODO: completely loaded.
+ // Step 12: completely loaded.
+ // https://html.spec.whatwg.org/multipage/#completely-loaded
+ // TODO: fully implement "completely loaded".
+ let document = Trusted::new(self);
+ if document.root().browsing_context().is_some() {
+ self.window
+ .task_manager()
+ .dom_manipulation_task_source()
+ .queue(
+ task!(completely_loaded: move || {
+ let document = document.root();
+ document.completely_loaded.set(true);
+ // Note: this will, among others, result in the "iframe-load-event-steps" being run.
+ // https://html.spec.whatwg.org/multipage/#iframe-load-event-steps
+ document.notify_constellation_load();
+ }),
+ self.window.upcast(),
+ )
+ .unwrap();
+ }
}
// https://html.spec.whatwg.org/multipage/#pending-parsing-blocking-script
@@ -2701,6 +2741,7 @@ impl Document {
fired_unload: Cell::new(false),
responsive_images: Default::default(),
redirect_count: Cell::new(0),
+ completely_loaded: Cell::new(false),
script_and_layout_blockers: Cell::new(0),
delayed_tasks: Default::default(),
}