diff options
author | bors-servo <metajack+bors@gmail.com> | 2015-05-11 14:35:33 -0500 |
---|---|---|
committer | bors-servo <metajack+bors@gmail.com> | 2015-05-11 14:35:33 -0500 |
commit | 2baa69595e2d57213c34b7e168b60885948fa85b (patch) | |
tree | 3d0eb3473cdccc3a176d7d8fb5dbf4af8a264025 /components/script/script_task.rs | |
parent | 263b69cf7fd99bfc13eecc840f27cdcf1e8178cc (diff) | |
parent | a1ae53a230cf8643dc768669b52b386e62882253 (diff) | |
download | servo-2baa69595e2d57213c34b7e168b60885948fa85b.tar.gz servo-2baa69595e2d57213c34b7e168b60885948fa85b.zip |
Auto merge of #5804 - jdm:docloader, r=Ms2ger
This implements a simple load-tracking system and tracks stylesheet loads as an example of how it fits together. This is a simplified and rebased version of #3714; I do not believe that the main thrust of hsivonen's comments (related to tracking navigation in browsing contexts) affect this part of the work.
r? @Ms2ger
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/5804)
<!-- Reviewable:end -->
Diffstat (limited to 'components/script/script_task.rs')
-rw-r--r-- | components/script/script_task.rs | 59 |
1 files changed, 45 insertions, 14 deletions
diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 10568e308c6..504a4f169b3 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -19,6 +19,7 @@ #![allow(unsafe_code)] +use document_loader::{LoadType, 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. @@ -728,6 +731,10 @@ impl ScriptTask { self.handle_webdriver_msg(pipeline_id, msg), ConstellationControlMsg::TickAllAnimations(pipeline_id) => self.handle_tick_all_animations(pipeline_id), + ConstellationControlMsg::StylesheetLoadComplete(id, url, responder) => { + responder.respond(); + self.handle_resource_loaded(id, LoadType::Stylesheet(url)); + } } } @@ -753,6 +760,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), } } @@ -844,6 +853,12 @@ impl ScriptTask { } /// Handle a request to load a page in a new child frame of an existing page. + fn handle_resource_loaded(&self, pipeline: PipelineId, load: LoadType) { + let page = get_page(&self.root_page(), pipeline); + let doc = page.document().root(); + doc.r().finish_load(load); + } + fn handle_new_layout(&self, new_layout_info: NewLayoutInfo) { let NewLayoutInfo { containing_pipeline_id, @@ -868,6 +883,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(); @@ -1152,12 +1186,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); @@ -1434,22 +1476,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)); } |