aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/script_task.rs
diff options
context:
space:
mode:
authorbors-servo <metajack+bors@gmail.com>2015-05-11 14:35:33 -0500
committerbors-servo <metajack+bors@gmail.com>2015-05-11 14:35:33 -0500
commit2baa69595e2d57213c34b7e168b60885948fa85b (patch)
tree3d0eb3473cdccc3a176d7d8fb5dbf4af8a264025 /components/script/script_task.rs
parent263b69cf7fd99bfc13eecc840f27cdcf1e8178cc (diff)
parenta1ae53a230cf8643dc768669b52b386e62882253 (diff)
downloadservo-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.rs59
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));
}