diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index fc3025615a7..38d7a5797d6 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -1450,29 +1450,6 @@ impl Document { changed } - pub fn set_pending_parsing_blocking_script(&self, - script: &HTMLScriptElement, - load: Option) { - assert!(!self.has_pending_parsing_blocking_script()); - *self.pending_parsing_blocking_script.borrow_mut() = Some(PendingScript::new_with_load(script, load)); - } - - pub fn has_pending_parsing_blocking_script(&self) -> bool { - self.pending_parsing_blocking_script.borrow().is_some() - } - - pub fn add_deferred_script(&self, script: &HTMLScriptElement) { - self.deferred_scripts.push(script); - } - - pub fn add_asap_script(&self, script: &HTMLScriptElement) { - self.asap_scripts_set.borrow_mut().push_back(PendingScript::new(script)); - } - - pub fn push_asap_in_order_script(&self, script: &HTMLScriptElement) { - self.asap_in_order_scripts_list.push(script); - } - pub fn trigger_mozbrowser_event(&self, event: MozBrowserEvent) { if PREFS.is_mozbrowser_enabled() { if let Some((parent_pipeline_id, _)) = self.window.parent_info() { @@ -1592,14 +1569,6 @@ impl Document { *self.pending_parsing_blocking_script.borrow_mut() = None; parser.resume_with_pending_parsing_blocking_script(&element, result); } - } else if self.reflow_timeout.get().is_none() { - // If we don't have a parser, and the reflow timer has been reset, explicitly - // trigger a reflow. - if let LoadType::Stylesheet(_) = load { - self.window.reflow(ReflowGoal::ForDisplay, - ReflowQueryType::NoQuery, - ReflowReason::StylesheetLoaded); - } } if !self.loader.borrow().is_blocked() && !self.loader.borrow().events_inhibited() { @@ -1613,6 +1582,17 @@ impl Document { } } + pub fn set_pending_parsing_blocking_script(&self, + script: &HTMLScriptElement, + load: Option) { + assert!(!self.has_pending_parsing_blocking_script()); + *self.pending_parsing_blocking_script.borrow_mut() = Some(PendingScript::new_with_load(script, load)); + } + + pub fn has_pending_parsing_blocking_script(&self) -> bool { + self.pending_parsing_blocking_script.borrow().is_some() + } + /// https://html.spec.whatwg.org/multipage/#prepare-a-script step 22.d. pub fn pending_parsing_blocking_script_loaded(&self, element: &HTMLScriptElement, result: ScriptResult) { let mut blocking_script = self.pending_parsing_blocking_script.borrow_mut(); @@ -1621,6 +1601,46 @@ impl Document { entry.loaded(result); } + pub fn add_asap_script(&self, script: &HTMLScriptElement) { + self.asap_scripts_set.borrow_mut().push_back(PendingScript::new(script)); + } + + /// https://html.spec.whatwg.org/multipage/#the-end step 3. + /// https://html.spec.whatwg.org/multipage/#prepare-a-script step 22.d. + pub fn asap_script_loaded(&self, element: &HTMLScriptElement, result: ScriptResult) { + let mut scripts = self.asap_scripts_set.borrow_mut(); + let idx = scripts.iter().position(|entry| &*entry.element == element).unwrap(); + scripts.swap(0, idx); + scripts[0].loaded(result); + } + + pub fn push_asap_in_order_script(&self, script: &HTMLScriptElement) { + self.asap_in_order_scripts_list.push(script); + } + + /// https://html.spec.whatwg.org/multipage/#the-end step 3. + /// https://html.spec.whatwg.org/multipage/#prepare-a-script step 22.c. + pub fn asap_in_order_script_loaded(&self, + element: &HTMLScriptElement, + result: ScriptResult) { + self.asap_in_order_scripts_list.loaded(element, result); + } + + fn process_asap_scripts(&self) { + let pair = self.asap_scripts_set.borrow_mut().front_mut().and_then(PendingScript::take_result); + if let Some((element, result)) = pair { + self.asap_scripts_set.borrow_mut().pop_front(); + element.execute(result); + } + while let Some((element, result)) = self.asap_in_order_scripts_list.take_next_ready_to_be_executed() { + element.execute(result); + } + } + + pub fn add_deferred_script(&self, script: &HTMLScriptElement) { + self.deferred_scripts.push(script); + } + /// https://html.spec.whatwg.org/multipage/#prepare-a-script step 22.d. pub fn deferred_script_loaded(&self, element: &HTMLScriptElement, result: ScriptResult) { self.deferred_scripts.loaded(element, result); @@ -1648,34 +1668,6 @@ impl Document { } } - /// https://html.spec.whatwg.org/multipage/#the-end step 3. - /// https://html.spec.whatwg.org/multipage/#prepare-a-script step 22.d. - pub fn asap_script_loaded(&self, element: &HTMLScriptElement, result: ScriptResult) { - let mut scripts = self.asap_scripts_set.borrow_mut(); - let idx = scripts.iter().position(|entry| &*entry.element == element).unwrap(); - scripts.swap(0, idx); - scripts[0].loaded(result); - } - - /// https://html.spec.whatwg.org/multipage/#the-end step 3. - /// https://html.spec.whatwg.org/multipage/#prepare-a-script step 22.c. - pub fn asap_in_order_script_loaded(&self, - element: &HTMLScriptElement, - result: ScriptResult) { - self.asap_in_order_scripts_list.loaded(element, result); - } - - fn process_asap_scripts(&self) { - let pair = self.asap_scripts_set.borrow_mut().front_mut().and_then(PendingScript::take_result); - if let Some((element, result)) = pair { - self.asap_scripts_set.borrow_mut().pop_front(); - element.execute(result); - } - while let Some((element, result)) = self.asap_in_order_scripts_list.take_next_ready_to_be_executed() { - element.execute(result); - } - } - pub fn maybe_dispatch_dom_content_loaded(&self) { if self.domcontentloaded_dispatched.get() { return; diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index e1b23f9b2b2..42b4a4d149a 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -55,9 +55,6 @@ pub struct HTMLScriptElement { /// (currently unused) non_blocking: Cell, - /// https://html.spec.whatwg.org/multipage/#ready-to-be-parser-executed - ready_to_be_parser_executed: Cell, - /// Document of the parser that created this element parser_document: JS, @@ -74,7 +71,6 @@ impl HTMLScriptElement { already_started: Cell::new(false), parser_inserted: Cell::new(creator.is_parser_created()), non_blocking: Cell::new(!creator.is_parser_created()), - ready_to_be_parser_executed: Cell::new(false), parser_document: JS::from_ref(document), line_number: creator.return_line_number(), } @@ -210,7 +206,6 @@ impl FetchResponseListener for ScriptContext { // https://html.spec.whatwg.org/multipage/#prepare-a-script // Step 18.6 (When the chosen algorithm asynchronously completes). let elem = self.elem.root(); - elem.ready_to_be_parser_executed.set(true); let document = document_from_node(&*elem); match self.kind { @@ -441,7 +436,6 @@ impl HTMLScriptElement { // Step 21. assert!(!text.is_empty()); let result = Ok(ClassicScript::internal(text, base_url)); - self.ready_to_be_parser_executed.set(true); // Step 22. if was_parser_inserted && @@ -456,14 +450,8 @@ impl HTMLScriptElement { } } - pub fn is_ready_to_be_executed(&self) -> bool { - self.ready_to_be_parser_executed.get() - } - /// https://html.spec.whatwg.org/multipage/#execute-the-script-block pub fn execute(&self, result: Result) { - assert!(self.ready_to_be_parser_executed.get()); - // Step 1. let doc = document_from_node(self); if self.parser_inserted.get() && &*doc != &*self.parser_document { diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs index a6c27804295..f71205efe38 100644 --- a/components/script/dom/servoparser/mod.rs +++ b/components/script/dom/servoparser/mod.rs @@ -4,7 +4,7 @@ use document_loader::{DocumentLoader, LoadType}; use dom::bindings::cell::DOMRefCell; -use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; +use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyState}; use dom::bindings::codegen::Bindings::HTMLImageElementBinding::HTMLImageElementMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::Bindings::ServoParserBinding; @@ -20,8 +20,9 @@ use dom::globalscope::GlobalScope; use dom::htmlformelement::HTMLFormElement; use dom::htmlimageelement::HTMLImageElement; use dom::htmlscriptelement::{HTMLScriptElement, ScriptResult}; -use dom::node::{Node, NodeSiblingIterator}; +use dom::node::{Node, NodeDamage, NodeSiblingIterator}; use dom::text::Text; +use dom::window::ReflowReason; use encoding::all::UTF_8; use encoding::types::{DecoderTrap, Encoding}; use html5ever::tokenizer::buffer_queue::BufferQueue; @@ -34,11 +35,13 @@ use net_traits::{FetchMetadata, FetchResponseListener, Metadata, NetworkError}; use network_listener::PreInvoke; use profile_traits::time::{TimerMetadata, TimerMetadataFrameType}; use profile_traits::time::{TimerMetadataReflowType, ProfilerCategory, profile}; +use script_layout_interface::message::ReflowQueryType; use script_thread::ScriptThread; use servo_config::resource_files::read_resource_file; use servo_url::ServoUrl; use std::cell::Cell; use std::mem; +use style::context::ReflowGoal; mod html; mod xml; @@ -333,20 +336,29 @@ impl ServoParser { } } + // https://html.spec.whatwg.org/multipage/#the-end fn finish(&self) { assert!(!self.suspended.get()); assert!(self.last_chunk_received.get()); assert!(self.script_input.borrow().is_empty()); assert!(self.network_input.borrow().is_empty()); - self.tokenizer.borrow_mut().end(); - debug!("finished parsing"); + // Step 1. + self.document.set_ready_state(DocumentReadyState::Interactive); + // Step 2. + self.tokenizer.borrow_mut().end(); self.document.set_current_parser(None); - if let Some(pipeline) = self.pipeline { - ScriptThread::parsing_complete(pipeline); + if self.pipeline.is_some() { + self.document.disarm_reflow_timeout(); + self.document.upcast::().dirty(NodeDamage::OtherNodeDamage); + let window = self.document.window(); + window.reflow(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery, ReflowReason::FirstLoad); } + + // Step 3. + self.document.process_deferred_scripts(); } } diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 65582571025..58a59e2fd91 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -583,13 +583,6 @@ impl ScriptThread { }); } - pub fn parsing_complete(id: PipelineId) { - SCRIPT_THREAD_ROOT.with(|root| { - let script_thread = unsafe { &*root.get().unwrap() }; - script_thread.handle_parsing_complete(id); - }); - } - pub fn process_event(msg: CommonScriptMsg) { SCRIPT_THREAD_ROOT.with(|root| { if let Some(script_thread) = root.get() { @@ -2163,30 +2156,6 @@ impl ScriptThread { context.process_response_eof(Ok(())); } - fn handle_parsing_complete(&self, id: PipelineId) { - let document = match { self.documents.borrow().find_document(id) } { - Some(document) => document, - None => return, - }; - - let final_url = document.url(); - - // https://html.spec.whatwg.org/multipage/#the-end step 1 - document.set_ready_state(DocumentReadyState::Interactive); - - // TODO: Execute step 2 here. - - // Kick off the initial reflow of the page. - debug!("kicking off initial reflow of {:?}", final_url); - document.disarm_reflow_timeout(); - document.upcast::().dirty(NodeDamage::OtherNodeDamage); - let window = window_from_node(&*document); - window.reflow(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery, ReflowReason::FirstLoad); - - // https://html.spec.whatwg.org/multipage/#the-end steps 3-4. - document.process_deferred_scripts(); - } - fn handle_css_error_reporting(&self, pipeline_id: PipelineId, filename: String, line: usize, column: usize, msg: String) { let sender = match self.devtools_chan {