mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
implement windowproxy "delay-load-event-mode", and partially document "completely-loaded"
This commit is contained in:
parent
483bf245df
commit
eb82e781a3
10 changed files with 156 additions and 19 deletions
|
@ -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
|
||||
}
|
||||
|
@ -1899,7 +1905,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 +1972,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 +2026,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 +2737,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(),
|
||||
}
|
||||
|
|
|
@ -276,8 +276,13 @@ impl HTMLIFrameElement {
|
|||
);
|
||||
|
||||
let pipeline_id = self.pipeline_id();
|
||||
// If the initial `about:blank` page is the current page, load with replacement enabled.
|
||||
let replace = pipeline_id.is_some() && pipeline_id == self.about_blank_pipeline_id.get();
|
||||
// If the initial `about:blank` page is the current page, load with replacement enabled,
|
||||
// see https://html.spec.whatwg.org/multipage/#the-iframe-element:about:blank-3
|
||||
let is_about_blank =
|
||||
pipeline_id.is_some() && pipeline_id == self.about_blank_pipeline_id.get();
|
||||
// Replacement enabled also takes into account whether the document is "completely loaded",
|
||||
// see https://html.spec.whatwg.org/multipage/#the-iframe-element:completely-loaded
|
||||
let replace = is_about_blank || !document.is_completely_loaded();
|
||||
self.navigate_or_reload_child_browsing_context(
|
||||
Some(load_data),
|
||||
NavigationType::Regular,
|
||||
|
|
|
@ -1417,7 +1417,9 @@ impl Window {
|
|||
dom_count: self.Document().dom_count(),
|
||||
};
|
||||
|
||||
self.layout_chan.send(Msg::Reflow(reflow)).unwrap();
|
||||
self.layout_chan
|
||||
.send(Msg::Reflow(reflow))
|
||||
.expect("Layout thread disconnected.");
|
||||
|
||||
debug!("script: layout forked");
|
||||
|
||||
|
@ -1776,8 +1778,14 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
// Step 7
|
||||
// Step 8
|
||||
if doc.prompt_to_unload(false) {
|
||||
if self.window_proxy().parent().is_some() {
|
||||
// Step 10
|
||||
// If browsingContext is a nested browsing context,
|
||||
// then put it in the delaying load events mode.
|
||||
self.window_proxy().start_delaying_load_events_mode();
|
||||
}
|
||||
self.main_thread_script_chan()
|
||||
.send(MainThreadScriptMsg::Navigate(
|
||||
pipeline_id,
|
||||
|
|
|
@ -94,6 +94,9 @@ pub struct WindowProxy {
|
|||
|
||||
/// The parent browsing context's window proxy, if this is a nested browsing context
|
||||
parent: Option<Dom<WindowProxy>>,
|
||||
|
||||
/// https://html.spec.whatwg.org/multipage/#delaying-load-events-mode
|
||||
delaying_load_events_mode: Cell<bool>,
|
||||
}
|
||||
|
||||
impl WindowProxy {
|
||||
|
@ -118,6 +121,7 @@ impl WindowProxy {
|
|||
disowned: Cell::new(false),
|
||||
frame_element: frame_element.map(Dom::from_ref),
|
||||
parent: parent.map(Dom::from_ref),
|
||||
delaying_load_events_mode: Cell::new(false),
|
||||
opener,
|
||||
}
|
||||
}
|
||||
|
@ -314,6 +318,26 @@ impl WindowProxy {
|
|||
None
|
||||
}
|
||||
|
||||
/// https://html.spec.whatwg.org/multipage/#delaying-load-events-mode
|
||||
pub fn is_delaying_load_events_mode(&self) -> bool {
|
||||
self.delaying_load_events_mode.get()
|
||||
}
|
||||
|
||||
/// https://html.spec.whatwg.org/multipage/#delaying-load-events-mode
|
||||
pub fn start_delaying_load_events_mode(&self) {
|
||||
self.delaying_load_events_mode.set(true);
|
||||
}
|
||||
|
||||
/// https://html.spec.whatwg.org/multipage/#delaying-load-events-mode
|
||||
pub fn stop_delaying_load_events_mode(&self) {
|
||||
self.delaying_load_events_mode.set(false);
|
||||
if let Some(document) = self.document() {
|
||||
if !document.loader().events_inhibited() {
|
||||
ScriptThread::mark_document_with_no_blocked_loads(&document);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#disowned-its-opener
|
||||
pub fn disown(&self) {
|
||||
self.disowned.set(true);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue