diff options
author | Josh Matthews <josh@joshmatthews.net> | 2014-10-13 08:20:06 -0400 |
---|---|---|
committer | Josh Matthews <josh@joshmatthews.net> | 2015-05-11 13:41:51 -0400 |
commit | 7f0706ed42b33ec1da6bf9741811ca97d566ed45 (patch) | |
tree | 9d74b8a50145afb05bd10d6860227f4af17a5754 /components/script/script_task.rs | |
parent | 29a43a00b39e544596e3bcce9bdfca2159313ba5 (diff) | |
download | servo-7f0706ed42b33ec1da6bf9741811ca97d566ed45.tar.gz servo-7f0706ed42b33ec1da6bf9741811ca97d566ed45.zip |
Implement a DocumentLoader type that tracks pending loads and notifies the script task when the queue is empty. Dispatch the document load event based on the DocumentLoader's notification.
Diffstat (limited to 'components/script/script_task.rs')
-rw-r--r-- | components/script/script_task.rs | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/components/script/script_task.rs b/components/script/script_task.rs index b7fc3198511..93b3c794234 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -19,6 +19,7 @@ #![allow(unsafe_code)] +use document_loader::{DocumentLoader, NotifierData}; use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyState}; use dom::bindings::codegen::InheritTypes::{ElementCast, EventTargetCast, HTMLIFrameElementCast, NodeCast, EventCast}; @@ -65,7 +66,7 @@ use msg::constellation_msg::{ConstellationChan, FocusType}; use msg::constellation_msg::{LoadData, PipelineId, SubpageId, MozBrowserEvent, WorkerId}; use msg::constellation_msg::{Failure, WindowSizeData, PipelineExitType}; use msg::constellation_msg::Msg as ConstellationMsg; -use net_traits::{ResourceTask, ControlMsg, LoadResponse, LoadConsumer}; +use net_traits::{ResourceTask, LoadResponse, LoadConsumer, ControlMsg}; use net_traits::LoadData as NetLoadData; use net_traits::image_cache_task::{ImageCacheChan, ImageCacheTask, ImageCacheResult}; use net_traits::storage_task::StorageTask; @@ -190,6 +191,8 @@ pub enum ScriptMsg { RefcountCleanup(TrustedReference), /// The final network response for a page has arrived. PageFetchComplete(PipelineId, Option<SubpageId>, LoadResponse), + /// Notify a document that all pending loads are complete. + DocumentLoadsComplete(PipelineId), } /// A cloneable interface for communicating with an event loop. @@ -753,6 +756,8 @@ impl ScriptTask { LiveDOMReferences::cleanup(self.get_cx(), addr), ScriptMsg::PageFetchComplete(id, subpage, response) => self.handle_page_fetch_complete(id, subpage, response), + ScriptMsg::DocumentLoadsComplete(id) => + self.handle_loads_complete(id), } } @@ -858,6 +863,25 @@ impl ScriptTask { self.start_page_load(new_load, load_data); } + fn handle_loads_complete(&self, pipeline: PipelineId) { + let page = get_page(&self.root_page(), pipeline); + let doc = page.document().root(); + let doc = doc.r(); + if doc.loader().is_blocked() { + return; + } + + doc.mut_loader().inhibit_events(); + + // https://html.spec.whatwg.org/multipage/#the-end step 7 + let addr: Trusted<Document> = Trusted::new(self.get_cx(), doc, self.chan.clone()); + let handler = box DocumentProgressHandler::new(addr.clone(), DocumentProgressTask::Load); + self.chan.send(ScriptMsg::RunnableMsg(handler)).unwrap(); + + let ConstellationChan(ref chan) = self.constellation_chan; + chan.send(ConstellationMsg::LoadComplete).unwrap(); + } + /// Handles a timer that fired. fn handle_fire_timer_msg(&self, id: PipelineId, timer_id: TimerId) { let page = self.root_page(); @@ -1142,12 +1166,20 @@ impl ScriptTask { _ => None }; + let notifier_data = NotifierData { + script_chan: self.chan.clone(), + pipeline: page.pipeline(), + }; + let loader = DocumentLoader::new_with_task(self.resource_task.clone(), + Some(notifier_data), + Some(final_url.clone())); let document = Document::new(window.r(), Some(final_url.clone()), IsHTMLDocument::HTMLDocument, content_type, last_modified, - DocumentSource::FromParser).root(); + DocumentSource::FromParser, + loader).root(); let frame_element = frame_element.r().map(|elem| ElementCast::from_ref(elem)); window.r().init_browser_context(document.r(), frame_element); @@ -1422,22 +1454,11 @@ impl ScriptTask { // https://html.spec.whatwg.org/multipage/#the-end step 4 let addr: Trusted<Document> = Trusted::new(self.get_cx(), document.r(), self.chan.clone()); - let handler = box DocumentProgressHandler::new(addr.clone(), DocumentProgressTask::DOMContentLoaded); - self.chan.send(ScriptMsg::RunnableMsg(handler)).unwrap(); - - // We have no concept of a document loader right now, so just dispatch the - // "load" event as soon as we've finished executing all scripts parsed during - // the initial load. - - // https://html.spec.whatwg.org/multipage/#the-end step 7 - let handler = box DocumentProgressHandler::new(addr, DocumentProgressTask::Load); + let handler = box DocumentProgressHandler::new(addr, DocumentProgressTask::DOMContentLoaded); self.chan.send(ScriptMsg::RunnableMsg(handler)).unwrap(); window.r().set_fragment_name(final_url.fragment.clone()); - let ConstellationChan(ref chan) = self.constellation_chan; - chan.send(ConstellationMsg::LoadComplete).unwrap(); - // Notify devtools that a new script global exists. self.notify_devtools(document.r().Title(), final_url, (id, None)); } |