aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/script_task.rs
diff options
context:
space:
mode:
authorTetsuharu OHZEKI <saneyuki.snyk@gmail.com>2015-01-02 11:45:18 +0900
committerTetsuharu OHZEKI <saneyuki.snyk@gmail.com>2015-01-10 04:05:46 +0900
commit0237561511c3218b1781357ac2ccc3ff6dcfdb38 (patch)
tree5a15114730f04abc4d98b9d6388e68436dc8a5a1 /components/script/script_task.rs
parent43e34d6d1050227eecc8fa293f9faec066f173a1 (diff)
downloadservo-0237561511c3218b1781357ac2ccc3ff6dcfdb38.tar.gz
servo-0237561511c3218b1781357ac2ccc3ff6dcfdb38.zip
Make DOMContentLoaded and load asynchronous with using Runnable.
Diffstat (limited to 'components/script/script_task.rs')
-rw-r--r--components/script/script_task.rs75
1 files changed, 63 insertions, 12 deletions
diff --git a/components/script/script_task.rs b/components/script/script_task.rs
index 976c2b78011..1c4af120334 100644
--- a/components/script/script_task.rs
+++ b/components/script/script_task.rs
@@ -18,7 +18,7 @@ use dom::bindings::conversions::StringificationBehavior;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable};
use dom::bindings::js::{RootCollection, RootCollectionPtr};
-use dom::bindings::refcounted::LiveDOMReferences;
+use dom::bindings::refcounted::{LiveDOMReferences, Trusted};
use dom::bindings::trace::JSTraceable;
use dom::bindings::utils::{wrap_for_same_compartment, pre_wrap};
use dom::document::{Document, IsHTMLDocument, DocumentHelpers, DocumentSource};
@@ -867,24 +867,23 @@ impl ScriptTask {
}
// https://html.spec.whatwg.org/multipage/#the-end step 4
- let event = Event::new(GlobalRef::Window(window.r()), "DOMContentLoaded".into_string(),
- EventBubbles::DoesNotBubble,
- EventCancelable::NotCancelable).root();
- let doctarget: JSRef<EventTarget> = EventTargetCast::from_ref(document.r());
- let _ = doctarget.DispatchEvent(event.r());
+ let addr: Trusted<Document> = Trusted::new(self.get_cx(), document.r(), self.chan.clone());
+
+ self.chan.send(ScriptMsg::RunnableMsg(box DocumentProgressHandler {
+ addr: addr.clone(),
+ task: DocumentProgressTask::DOMContentLoaded,
+ }));
// 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
- document.r().set_ready_state(DocumentReadyState::Complete);
+ self.chan.send(ScriptMsg::RunnableMsg(box DocumentProgressHandler {
+ addr: addr,
+ task: DocumentProgressTask::Load,
+ }));
- let event = Event::new(GlobalRef::Window(window.r()), "load".into_string(),
- EventBubbles::DoesNotBubble,
- EventCancelable::NotCancelable).root();
- let wintarget: JSRef<EventTarget> = EventTargetCast::from_ref(window.r());
- let _ = wintarget.dispatch_event_with_target(doctarget, event.r());
*page.fragment_name.borrow_mut() = final_url.fragment.clone();
@@ -1346,3 +1345,55 @@ impl HeaderFormat for LastModified {
fn dom_last_modified(tm: &Tm) -> String {
format!("{}", tm.to_local().strftime("%m/%d/%Y %H:%M:%S").unwrap())
}
+
+enum DocumentProgressTask {
+ DOMContentLoaded,
+ Load,
+}
+
+struct DocumentProgressHandler {
+ addr: Trusted<Document>,
+ task: DocumentProgressTask,
+}
+
+impl DocumentProgressHandler {
+ fn dispatch_dom_content_loaded(&self) {
+ let document = self.addr.to_temporary().root();
+ let window = document.r().window().root();
+ let event = Event::new(GlobalRef::Window(window.r()), "DOMContentLoaded".into_string(),
+ EventBubbles::DoesNotBubble,
+ EventCancelable::NotCancelable).root();
+ let doctarget: JSRef<EventTarget> = EventTargetCast::from_ref(document.r());
+ let _ = doctarget.DispatchEvent(event.r());
+ }
+
+ fn set_ready_state_complete(&self) {
+ let document = self.addr.to_temporary().root();
+ document.r().set_ready_state(DocumentReadyState::Complete);
+ }
+
+ fn dispatch_load(&self) {
+ let document = self.addr.to_temporary().root();
+ let window = document.r().window().root();
+ let event = Event::new(GlobalRef::Window(window.r()), "load".into_string(),
+ EventBubbles::DoesNotBubble,
+ EventCancelable::NotCancelable).root();
+ let wintarget: JSRef<EventTarget> = EventTargetCast::from_ref(window.r());
+ let doctarget: JSRef<EventTarget> = EventTargetCast::from_ref(document.r());
+ let _ = wintarget.dispatch_event_with_target(doctarget, event.r());
+ }
+}
+
+impl Runnable for DocumentProgressHandler {
+ fn handler(&self) {
+ match self.task {
+ DocumentProgressTask::DOMContentLoaded => {
+ self.dispatch_dom_content_loaded();
+ }
+ DocumentProgressTask::Load => {
+ self.set_ready_state_complete();
+ self.dispatch_load();
+ }
+ }
+ }
+}