aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Yeung <kungfukeith11@gmail.com>2016-01-06 11:44:54 -0500
committerKeith Yeung <kungfukeith11@gmail.com>2016-03-10 01:05:53 -0500
commit3f2cbf002520289f706e7a7c6448a39ca7fa4bef (patch)
tree668324ce1c47e981314f28aab246b6524f92fda9
parentfa93d3f4674c0e326a644826f5c394136a858f2b (diff)
downloadservo-3f2cbf002520289f706e7a7c6448a39ca7fa4bef.tar.gz
servo-3f2cbf002520289f706e7a7c6448a39ca7fa4bef.zip
Add task_source directory
Use DOMManipulationTaskSource whenever possible
-rw-r--r--components/script/dom/bindings/global.rs19
-rw-r--r--components/script/dom/document.rs19
-rw-r--r--components/script/dom/htmldetailselement.rs30
-rw-r--r--components/script/dom/htmlformelement.rs17
-rw-r--r--components/script/dom/htmlscriptelement.rs43
-rw-r--r--components/script/dom/storage.rs11
-rw-r--r--components/script/dom/webidls/Worker.webidl4
-rw-r--r--components/script/dom/window.rs16
-rw-r--r--components/script/dom/worker.rs10
-rw-r--r--components/script/lib.rs1
-rw-r--r--components/script/script_thread.rs113
-rw-r--r--components/script/task_source/dom_manipulation.rs63
-rw-r--r--components/script/task_source/file_reading.rs21
-rw-r--r--components/script/task_source/history_traversal.rs21
-rw-r--r--components/script/task_source/mod.rs16
-rw-r--r--components/script/task_source/networking.rs21
-rw-r--r--components/script/task_source/user_interaction.rs21
17 files changed, 261 insertions, 185 deletions
diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs
index c7ba5aaaf6c..dab74fd5850 100644
--- a/components/script/dom/bindings/global.rs
+++ b/components/script/dom/bindings/global.rs
@@ -21,8 +21,10 @@ use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL};
use msg::constellation_msg::{ConstellationChan, PipelineId};
use net_traits::ResourceThread;
use profile_traits::mem;
-use script_thread::{CommonScriptMsg, ScriptChan, ScriptPort, ScriptThread};
+use script_thread::{CommonScriptMsg, MainThreadScriptChan, ScriptChan, ScriptPort, ScriptThread};
use script_traits::{MsDuration, ScriptMsg as ConstellationMsg, TimerEventRequest};
+use task_source::TaskSource;
+use task_source::dom_manipulation::DOMManipulationTask;
use timers::{OneshotTimerCallback, OneshotTimerHandle};
use url::Url;
@@ -142,13 +144,24 @@ impl<'a> GlobalRef<'a> {
/// `ScriptChan` used to send messages to the event loop of this global's
/// thread.
- pub fn dom_manipulation_task_source(&self) -> Box<ScriptChan + Send> {
+ pub fn script_chan(&self) -> Box<ScriptChan + Send> {
match *self {
- GlobalRef::Window(ref window) => window.dom_manipulation_task_source(),
+ GlobalRef::Window(ref window) => {
+ MainThreadScriptChan(window.main_thread_script_chan().clone()).clone()
+ }
GlobalRef::Worker(ref worker) => worker.script_chan(),
}
}
+ /// `TaskSource` used to queue DOM manipulation messages to the event loop of this global's
+ /// thread.
+ pub fn dom_manipulation_task_source(&self) -> Box<TaskSource<DOMManipulationTask> + Send> {
+ match *self {
+ GlobalRef::Window(ref window) => window.dom_manipulation_task_source(),
+ GlobalRef::Worker(_) => unimplemented!(),
+ }
+ }
+
/// `ScriptChan` used to send messages to the event loop of this global's
/// thread.
pub fn user_interaction_task_source(&self) -> Box<ScriptChan + Send> {
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 7d0a3be8b14..e0f4c0c5592 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -89,7 +89,7 @@ use net_traits::CookieSource::NonHTTP;
use net_traits::response::HttpsState;
use net_traits::{AsyncResponseTarget, PendingAsyncLoad};
use num::ToPrimitive;
-use script_thread::{MainThreadScriptMsg, Runnable};
+use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, Runnable, ScriptChan};
use script_traits::{AnimationState, MouseButton, MouseEventType, MozBrowserEvent};
use script_traits::{ScriptMsg as ConstellationMsg, ScriptToCompositorMsg};
use script_traits::{TouchEventType, TouchId};
@@ -108,6 +108,7 @@ use string_cache::{Atom, QualName};
use style::context::ReflowGoal;
use style::restyle_hints::ElementSnapshot;
use style::servo::Stylesheet;
+use task_source::dom_manipulation::DOMManipulationTask;
use time;
use url::percent_encoding::percent_decode;
use url::{Host, Url};
@@ -1406,11 +1407,11 @@ impl Document {
update_with_current_time(&self.dom_content_loaded_event_start);
- let doctarget = self.upcast::<EventTarget>();
- let _ = doctarget.fire_event("DOMContentLoaded",
- EventBubbles::Bubbles,
- EventCancelable::NotCancelable);
-
+ let chan = MainThreadScriptChan(self.window().main_thread_script_chan().clone()).clone();
+ let doctarget = Trusted::new(self.upcast::<EventTarget>(), chan);
+ let task_source = self.window().dom_manipulation_task_source();
+ let _ = task_source.queue(DOMManipulationTask::FireEvent(
+ atom!("DOMContentLoaded"), doctarget, EventBubbles::Bubbles, EventCancelable::NotCancelable));
self.window().reflow(ReflowGoal::ForDisplay,
ReflowQueryType::NoQuery,
ReflowReason::DOMContentLoaded);
@@ -2590,13 +2591,13 @@ fn update_with_current_time(marker: &Cell<u64>) {
}
pub struct DocumentProgressHandler {
- addr: Trusted<Document>,
+ addr: Trusted<Document>
}
impl DocumentProgressHandler {
- pub fn new(addr: Trusted<Document>) -> DocumentProgressHandler {
+ pub fn new(addr: Trusted<Document>) -> DocumentProgressHandler {
DocumentProgressHandler {
- addr: addr,
+ addr: addr
}
}
diff --git a/components/script/dom/htmldetailselement.rs b/components/script/dom/htmldetailselement.rs
index 8b8735ca0d6..01286dd2265 100644
--- a/components/script/dom/htmldetailselement.rs
+++ b/components/script/dom/htmldetailselement.rs
@@ -14,10 +14,10 @@ use dom::eventtarget::EventTarget;
use dom::htmlelement::HTMLElement;
use dom::node::{Node, window_from_node};
use dom::virtualmethods::VirtualMethods;
-use script_thread::ScriptThreadEventCategory::DomEvent;
-use script_thread::{CommonScriptMsg, Runnable};
+use script_thread::{MainThreadScriptChan, Runnable, ScriptChan};
use std::cell::Cell;
use string_cache::Atom;
+use task_source::dom_manipulation::DOMManipulationTask;
use util::str::DOMString;
#[dom_struct]
@@ -69,7 +69,17 @@ impl VirtualMethods for HTMLDetailsElement {
if attr.local_name() == &atom!("open") {
let counter = self.toggle_counter.get() + 1;
self.toggle_counter.set(counter);
- ToggleEventRunnable::send(&self, counter);
+
+ let window = window_from_node(self);
+ let window = window.r();
+ let task_source = window.dom_manipulation_task_source();
+ let chan = MainThreadScriptChan(window.main_thread_script_chan().clone()).clone();
+ let details = Trusted::new(self, chan.clone());
+ let runnable = box ToggleEventRunnable {
+ element: details,
+ toggle_number: counter
+ };
+ let _ = task_source.queue(DOMManipulationTask::FireToggleEvent(runnable));
}
}
}
@@ -79,20 +89,6 @@ pub struct ToggleEventRunnable {
toggle_number: u32
}
-impl ToggleEventRunnable {
- pub fn send(node: &HTMLDetailsElement, toggle_number: u32) {
- let window = window_from_node(node);
- let window = window.r();
- let chan = window.dom_manipulation_task_source();
- let handler = Trusted::new(node, chan.clone());
- let dispatcher = ToggleEventRunnable {
- element: handler,
- toggle_number: toggle_number,
- };
- let _ = chan.send(CommonScriptMsg::RunnableMsg(DomEvent, box dispatcher));
- }
-}
-
impl Runnable for ToggleEventRunnable {
fn handler(self: Box<ToggleEventRunnable>) {
let target = self.element.root();
diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs
index 167e1698845..1d84c78f78b 100644
--- a/components/script/dom/htmlformelement.rs
+++ b/components/script/dom/htmlformelement.rs
@@ -37,12 +37,12 @@ use hyper::header::ContentType;
use hyper::method::Method;
use hyper::mime;
use msg::constellation_msg::{LoadData, PipelineId};
-use script_thread::ScriptThreadEventCategory::FormPlannedNavigation;
-use script_thread::{CommonScriptMsg, MainThreadScriptMsg, Runnable, ScriptChan};
+use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, Runnable, ScriptChan};
use std::borrow::ToOwned;
use std::cell::Cell;
use std::sync::mpsc::Sender;
use string_cache::Atom;
+use task_source::dom_manipulation::DOMManipulationTask;
use url::form_urlencoded::serialize;
use util::str::DOMString;
@@ -76,6 +76,10 @@ impl HTMLFormElement {
let element = HTMLFormElement::new_inherited(localName, prefix, document);
Node::reflect_node(box element, document, HTMLFormElementBinding::Wrap)
}
+
+ pub fn generation_id(&self) -> GenerationId {
+ self.generation_id.get()
+ }
}
impl HTMLFormElementMethods for HTMLFormElement {
@@ -322,17 +326,20 @@ impl HTMLFormElement {
// generation ID is the same as its own generation ID.
let GenerationId(prev_id) = self.generation_id.get();
self.generation_id.set(GenerationId(prev_id + 1));
+
// Step 2
+ let chan = MainThreadScriptChan(window.main_thread_script_chan().clone()).clone();
let nav = box PlannedNavigation {
load_data: load_data,
pipeline_id: window.pipeline(),
script_chan: window.main_thread_script_chan().clone(),
generation_id: self.generation_id.get(),
- form: Trusted::new(self, window.dom_manipulation_task_source())
+ form: Trusted::new(self, chan)
};
+
// Step 3
- window.dom_manipulation_task_source().send(
- CommonScriptMsg::RunnableMsg(FormPlannedNavigation, nav)).unwrap();
+ window.dom_manipulation_task_source().queue(
+ DOMManipulationTask::PlannedNavigation(nav)).unwrap();
}
/// Interactively validate the constraints of form elements
diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs
index b0e0c9c041e..bbd1884dc4f 100644
--- a/components/script/dom/htmlscriptelement.rs
+++ b/components/script/dom/htmlscriptelement.rs
@@ -19,6 +19,7 @@ use dom::bindings::trace::JSTraceable;
use dom::document::Document;
use dom::element::{AttributeMutation, Element, ElementCreator};
use dom::event::{Event, EventBubbles, EventCancelable};
+use dom::eventtarget::EventTarget;
use dom::htmlelement::HTMLElement;
use dom::node::{ChildrenMutation, CloneChildrenFlag, Node};
use dom::node::{document_from_node, window_from_node};
@@ -34,13 +35,13 @@ use js::jsapi::RootedValue;
use js::jsval::UndefinedValue;
use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata};
use network_listener::{NetworkListener, PreInvoke};
-use script_thread::ScriptThreadEventCategory::ScriptEvent;
-use script_thread::{CommonScriptMsg, Runnable, ScriptChan};
+use script_thread::{MainThreadScriptChan, ScriptChan};
use std::ascii::AsciiExt;
use std::cell::Cell;
use std::mem;
use std::sync::{Arc, Mutex};
use string_cache::Atom;
+use task_source::dom_manipulation::DOMManipulationTask;
use url::Url;
use util::str::{DOMString, HTML_SPACE_CHARACTERS, StaticStringVec};
@@ -442,26 +443,20 @@ impl HTMLScriptElement {
if external {
self.dispatch_load_event();
} else {
- let chan = window.dom_manipulation_task_source();
- let handler = Trusted::new(self, chan.clone());
- let dispatcher = box EventDispatcher {
- element: handler,
- is_error: false,
- };
- chan.send(CommonScriptMsg::RunnableMsg(ScriptEvent, dispatcher)).unwrap();
+ let chan = MainThreadScriptChan(window.main_thread_script_chan().clone()).clone();
+ let script_element = Trusted::new(self.upcast::<EventTarget>(), chan);
+ let task_source = window.dom_manipulation_task_source();
+ task_source.queue(DOMManipulationTask::FireSimpleEvent(atom!("load"), script_element)).unwrap();
}
}
pub fn queue_error_event(&self) {
let window = window_from_node(self);
let window = window.r();
- let chan = window.dom_manipulation_task_source();
- let handler = Trusted::new(self, chan.clone());
- let dispatcher = box EventDispatcher {
- element: handler,
- is_error: true,
- };
- chan.send(CommonScriptMsg::RunnableMsg(ScriptEvent, dispatcher)).unwrap();
+ let chan = MainThreadScriptChan(window.main_thread_script_chan().clone()).clone();
+ let task_source = window.dom_manipulation_task_source();
+ let script_element = Trusted::new(self.upcast::<EventTarget>(), chan);
+ task_source.queue(DOMManipulationTask::FireSimpleEvent(atom!("error"), script_element)).unwrap();
}
pub fn dispatch_before_script_execute_event(&self) -> bool {
@@ -610,19 +605,3 @@ impl HTMLScriptElementMethods for HTMLScriptElement {
self.upcast::<Node>().SetTextContent(Some(value))
}
}
-
-struct EventDispatcher {
- element: Trusted<HTMLScriptElement>,
- is_error: bool,
-}
-
-impl Runnable for EventDispatcher {
- fn handler(self: Box<EventDispatcher>) {
- let target = self.element.root();
- if self.is_error {
- target.dispatch_error_event();
- } else {
- target.dispatch_load_event();
- }
- }
-}
diff --git a/components/script/dom/storage.rs b/components/script/dom/storage.rs
index c5d79fe7baf..b264580495a 100644
--- a/components/script/dom/storage.rs
+++ b/components/script/dom/storage.rs
@@ -16,7 +16,8 @@ use dom::urlhelper::UrlHelper;
use ipc_channel::ipc;
use net_traits::storage_thread::{StorageThread, StorageThreadMsg, StorageType};
use page::IterablePage;
-use script_thread::{MainThreadRunnable, MainThreadScriptMsg, ScriptThread};
+use script_thread::{MainThreadRunnable, MainThreadScriptChan, ScriptChan, ScriptThread};
+use task_source::dom_manipulation::DOMManipulationTask;
use url::Url;
use util::str::DOMString;
@@ -153,10 +154,10 @@ impl Storage {
new_value: Option<String>) {
let global_root = self.global();
let global_ref = global_root.r();
- let main_script_chan = global_ref.as_window().main_thread_script_chan();
- let script_chan = global_ref.dom_manipulation_task_source();
- let trusted_storage = Trusted::new(self, script_chan);
- main_script_chan.send(MainThreadScriptMsg::MainThreadRunnableMsg(
+ let task_source = global_ref.as_window().dom_manipulation_task_source();
+ let chan = MainThreadScriptChan(global_ref.as_window().main_thread_script_chan().clone()).clone();
+ let trusted_storage = Trusted::new(self, chan);
+ task_source.queue(DOMManipulationTask::SendStorageNotification(
box StorageEventRunnable::new(trusted_storage, key, old_value, new_value))).unwrap();
}
}
diff --git a/components/script/dom/webidls/Worker.webidl b/components/script/dom/webidls/Worker.webidl
index c80ff3898cc..62cd5c89f92 100644
--- a/components/script/dom/webidls/Worker.webidl
+++ b/components/script/dom/webidls/Worker.webidl
@@ -14,8 +14,8 @@ interface AbstractWorker {
interface Worker : EventTarget {
//void terminate();
- [Throws]
- void postMessage(any message/*, optional sequence<Transferable> transfer*/);
+[Throws]
+void postMessage(any message/*, optional sequence<Transferable> transfer*/);
attribute EventHandler onmessage;
};
Worker implements AbstractWorker;
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index e81efa4a77c..eeb62d833c6 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -53,9 +53,8 @@ use page::Page;
use profile_traits::mem;
use reporter::CSSErrorReporter;
use rustc_serialize::base64::{FromBase64, STANDARD, ToBase64};
-use script_thread::{DOMManipulationTaskSource, UserInteractionTaskSource, NetworkingTaskSource};
-use script_thread::{HistoryTraversalTaskSource, FileReadingTaskSource, SendableMainThreadScriptChan};
-use script_thread::{ScriptChan, ScriptPort, MainThreadScriptChan, MainThreadScriptMsg, RunnableWrapper};
+use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, RunnableWrapper};
+use script_thread::{SendableMainThreadScriptChan, ScriptChan, ScriptPort};
use script_traits::{ConstellationControlMsg, UntrustedNodeAddress};
use script_traits::{DocumentState, MsDuration, ScriptToCompositorMsg, TimerEvent, TimerEventId};
use script_traits::{MozBrowserEvent, ScriptMsg as ConstellationMsg, TimerEventRequest, TimerSource};
@@ -75,6 +74,12 @@ use string_cache::Atom;
use style::context::ReflowGoal;
use style::error_reporting::ParseErrorReporter;
use style::selector_impl::PseudoElement;
+use task_source::TaskSource;
+use task_source::dom_manipulation::{DOMManipulationTaskSource, DOMManipulationTask};
+use task_source::file_reading::FileReadingTaskSource;
+use task_source::history_traversal::HistoryTraversalTaskSource;
+use task_source::networking::NetworkingTaskSource;
+use task_source::user_interaction::UserInteractionTaskSource;
use time;
use timers::{IsInterval, OneshotTimerCallback, OneshotTimerHandle, OneshotTimers, TimerCallback};
use url::Url;
@@ -258,7 +263,7 @@ impl Window {
self.js_runtime.borrow().as_ref().unwrap().cx()
}
- pub fn dom_manipulation_task_source(&self) -> Box<ScriptChan + Send> {
+ pub fn dom_manipulation_task_source(&self) -> Box<TaskSource<DOMManipulationTask> + Send> {
self.dom_manipulation_task_source.clone()
}
@@ -279,8 +284,7 @@ impl Window {
}
pub fn main_thread_script_chan(&self) -> &Sender<MainThreadScriptMsg> {
- let MainThreadScriptChan(ref sender) = self.script_chan;
- sender
+ &self.script_chan.0
}
pub fn image_cache_chan(&self) -> ImageCacheChan {
diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs
index 815100ba32f..dfa8d1363f3 100644
--- a/components/script/dom/worker.rs
+++ b/components/script/dom/worker.rs
@@ -71,7 +71,7 @@ impl Worker {
let (sender, receiver) = channel();
let worker = Worker::new(global, sender.clone());
- let worker_ref = Trusted::new(worker.r(), global.dom_manipulation_task_source());
+ let worker_ref = Trusted::new(worker.r(), global.script_chan());
let worker_id = global.get_next_worker_id();
let (devtools_sender, devtools_receiver) = ipc::channel().unwrap();
@@ -102,7 +102,7 @@ impl Worker {
};
DedicatedWorkerGlobalScope::run_worker_scope(
init, worker_url, global.pipeline(), devtools_receiver, worker_ref,
- global.dom_manipulation_task_source(), sender, receiver);
+ global.script_chan(), sender, receiver);
Ok(worker)
}
@@ -138,15 +138,15 @@ impl Worker {
}
impl WorkerMethods for Worker {
- // https://html.spec.whatwg.org/multipage/#dom-dedicatedworkerglobalscope-postmessage
+ // https://html.spec.whatwg.org/multipage/#dom-worker-postmessage
fn PostMessage(&self, cx: *mut JSContext, message: HandleValue) -> ErrorResult {
let data = try!(StructuredCloneData::write(cx, message));
- let address = Trusted::new(self, self.global().r().dom_manipulation_task_source());
+ let address = Trusted::new(self, self.global().r().script_chan());
self.sender.send((address, WorkerScriptMsg::DOMMessage(data))).unwrap();
Ok(())
}
- // https://html.spec.whatwg.org/multipage/#handler-dedicatedworkerglobalscope-onmessage
+ // https://html.spec.whatwg.org/multipage/#handler-worker-onmessage
event_handler!(message, GetOnmessage, SetOnmessage);
// https://html.spec.whatwg.org/multipage/#handler-workerglobalscope-onerror
diff --git a/components/script/lib.rs b/components/script/lib.rs
index bee43944c69..ed7b530d6f6 100644
--- a/components/script/lib.rs
+++ b/components/script/lib.rs
@@ -91,6 +91,7 @@ pub mod parse;
pub mod reporter;
#[allow(unsafe_code)]
pub mod script_thread;
+mod task_source;
pub mod textinput;
mod timers;
mod unpremultiplytable;
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index a735603431a..9cfc2627786 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -99,6 +99,12 @@ use std::sync::atomic::{Ordering, AtomicBool};
use std::sync::mpsc::{Receiver, Select, Sender, channel};
use std::sync::{Arc, Mutex};
use style::context::ReflowGoal;
+use task_source::TaskSource;
+use task_source::dom_manipulation::{DOMManipulationTaskSource, DOMManipulationTask};
+use task_source::file_reading::FileReadingTaskSource;
+use task_source::history_traversal::HistoryTraversalTaskSource;
+use task_source::networking::NetworkingTaskSource;
+use task_source::user_interaction::UserInteractionTaskSource;
use time::{Tm, now};
use url::Url;
use util::opts;
@@ -251,11 +257,11 @@ pub enum MainThreadScriptMsg {
/// Notifies the script that a window associated with a particular pipeline
/// should be closed (only dispatched to ScriptThread).
ExitWindow(PipelineId),
- /// Generic message for running threads in the ScriptThread
- MainThreadRunnableMsg(Box<MainThreadRunnable + Send>),
/// Begins a content-initiated load on the specified pipeline (only
/// dispatched to ScriptThread).
Navigate(PipelineId, LoadData),
+ /// Tasks that originate from the DOM manipulation task source
+ DOMManipulation(DOMManipulationTask),
}
/// A cloneable interface for communicating with an event loop.
@@ -357,102 +363,6 @@ impl MainThreadScriptChan {
}
}
-// FIXME: Use a task source specific message instead of MainThreadScriptMsg
-#[derive(JSTraceable)]
-pub struct DOMManipulationTaskSource(pub Sender<MainThreadScriptMsg>);
-
-impl ScriptChan for DOMManipulationTaskSource {
- fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
- let DOMManipulationTaskSource(ref chan) = *self;
- chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
- }
-
- fn clone(&self) -> Box<ScriptChan + Send> {
- let DOMManipulationTaskSource(ref chan) = *self;
- box DOMManipulationTaskSource((*chan).clone())
- }
-}
-
-// FIXME: Use a task source specific message instead of MainThreadScriptMsg
-#[derive(JSTraceable)]
-pub struct UserInteractionTaskSource(pub Sender<MainThreadScriptMsg>);
-
-impl ScriptChan for UserInteractionTaskSource {
- fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
- let UserInteractionTaskSource(ref chan) = *self;
- chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
- }
-
- fn clone(&self) -> Box<ScriptChan + Send> {
- let UserInteractionTaskSource(ref chan) = *self;
- box UserInteractionTaskSource((*chan).clone())
- }
-}
-
-// FIXME: Use a task source specific message instead of MainThreadScriptMsg
-#[derive(JSTraceable)]
-pub struct NetworkingTaskSource(pub Sender<MainThreadScriptMsg>);
-
-impl ScriptChan for NetworkingTaskSource {
- fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
- let NetworkingTaskSource(ref chan) = *self;
- chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
- }
-
- fn clone(&self) -> Box<ScriptChan + Send> {
- let NetworkingTaskSource(ref chan) = *self;
- box NetworkingTaskSource((*chan).clone())
- }
-}
-
-// FIXME: Use a task source specific message instead of MainThreadScriptMsg
-#[derive(JSTraceable)]
-pub struct HistoryTraversalTaskSource(pub Sender<MainThreadScriptMsg>);
-
-impl ScriptChan for HistoryTraversalTaskSource {
- fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
- let HistoryTraversalTaskSource(ref chan) = *self;
- chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
- }
-
- fn clone(&self) -> Box<ScriptChan + Send> {
- let HistoryTraversalTaskSource(ref chan) = *self;
- box HistoryTraversalTaskSource((*chan).clone())
- }
-}
-
-// FIXME: Use a task source specific message instead of MainThreadScriptMsg
-#[derive(JSTraceable)]
-pub struct FileReadingTaskSource(pub Sender<MainThreadScriptMsg>);
-
-impl ScriptChan for FileReadingTaskSource {
- fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
- let FileReadingTaskSource(ref chan) = *self;
- chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
- }
-
- fn clone(&self) -> Box<ScriptChan + Send> {
- let FileReadingTaskSource(ref chan) = *self;
- box FileReadingTaskSource((*chan).clone())
- }
-}
-
-// FIXME: Use a task source specific message instead of MainThreadScriptMsg
-#[derive(JSTraceable)]
-pub struct ProfilerThreadSource(pub Sender<MainThreadScriptMsg>);
-
-impl ScriptChan for ProfilerThreadSource {
- fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
- let ProfilerThreadSource(ref chan) = *self;
- chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
- }
-
- fn clone(&self) -> Box<ScriptChan + Send> {
- let ProfilerThreadSource(ref chan) = *self;
- box ProfilerThreadSource((*chan).clone())
- }
-}
-
pub struct StackRootTLS<'a>(PhantomData<&'a u32>);
impl<'a> StackRootTLS<'a> {
@@ -494,6 +404,7 @@ pub struct ScriptThread {
/// A channel to hand out to script thread-based entities that need to be able to enqueue
/// events in the event queue.
chan: MainThreadScriptChan,
+
dom_manipulation_task_source: DOMManipulationTaskSource,
user_interaction_task_source: UserInteractionTaskSource,
@@ -1155,8 +1066,6 @@ impl ScriptThread {
self.handle_navigate(id, None, load_data),
MainThreadScriptMsg::ExitWindow(id) =>
self.handle_exit_window_msg(id),
- MainThreadScriptMsg::MainThreadRunnableMsg(runnable) =>
- runnable.handler(self),
MainThreadScriptMsg::DocumentLoadsComplete(id) =>
self.handle_loads_complete(id),
MainThreadScriptMsg::Common(CommonScriptMsg::RunnableMsg(_, runnable)) => {
@@ -1170,6 +1079,8 @@ impl ScriptThread {
LiveDOMReferences::cleanup(addr),
MainThreadScriptMsg::Common(CommonScriptMsg::CollectReports(reports_chan)) =>
self.collect_reports(reports_chan),
+ MainThreadScriptMsg::DOMManipulation(msg) =>
+ msg.handle_msg(self),
}
}
@@ -1366,7 +1277,7 @@ impl ScriptThread {
// https://html.spec.whatwg.org/multipage/#the-end step 7
let addr: Trusted<Document> = Trusted::new(doc, self.chan.clone());
let handler = box DocumentProgressHandler::new(addr.clone());
- self.chan.send(CommonScriptMsg::RunnableMsg(ScriptThreadEventCategory::DocumentEvent, handler)).unwrap();
+ self.dom_manipulation_task_source.queue(DOMManipulationTask::DocumentProgress(handler)).unwrap();
let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(ConstellationMsg::LoadComplete(pipeline)).unwrap();
diff --git a/components/script/task_source/dom_manipulation.rs b/components/script/task_source/dom_manipulation.rs
new file mode 100644
index 00000000000..d60ce7de93d
--- /dev/null
+++ b/components/script/task_source/dom_manipulation.rs
@@ -0,0 +1,63 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use dom::bindings::refcounted::Trusted;
+use dom::event::{EventBubbles, EventCancelable};
+use dom::eventtarget::EventTarget;
+use script_thread::{MainThreadRunnable, MainThreadScriptMsg, Runnable, ScriptThread};
+use std::result::Result;
+use std::sync::mpsc::Sender;
+use string_cache::Atom;
+use task_source::TaskSource;
+
+#[derive(JSTraceable)]
+pub struct DOMManipulationTaskSource(pub Sender<MainThreadScriptMsg>);
+
+impl TaskSource<DOMManipulationTask> for DOMManipulationTaskSource {
+ fn queue(&self, msg: DOMManipulationTask) -> Result<(), ()> {
+ let DOMManipulationTaskSource(ref chan) = *self;
+ chan.send(MainThreadScriptMsg::DOMManipulation(msg)).map_err(|_| ())
+ }
+
+ fn clone(&self) -> Box<TaskSource<DOMManipulationTask> + Send> {
+ let DOMManipulationTaskSource(ref chan) = *self;
+ box DOMManipulationTaskSource((*chan).clone())
+ }
+}
+
+pub enum DOMManipulationTask {
+ // https://html.spec.whatwg.org/multipage/#the-end step 7
+ DocumentProgress(Box<Runnable + Send>),
+ // https://dom.spec.whatwg.org/#concept-event-fire
+ FireEvent(Atom, Trusted<EventTarget>, EventBubbles, EventCancelable),
+ // https://html.spec.whatwg.org/multipage/#fire-a-simple-event
+ FireSimpleEvent(Atom, Trusted<EventTarget>),
+ // https://html.spec.whatwg.org/multipage/#details-notification-task-steps
+ FireToggleEvent(Box<Runnable + Send>),
+ // https://html.spec.whatwg.org/multipage/#planned-navigation
+ PlannedNavigation(Box<Runnable + Send>),
+ // https://html.spec.whatwg.org/multipage/#send-a-storage-notification
+ SendStorageNotification(Box<MainThreadRunnable + Send>)
+}
+
+impl DOMManipulationTask {
+ pub fn handle_msg(self, script_thread: &ScriptThread) {
+ use self::DOMManipulationTask::*;
+
+ match self {
+ DocumentProgress(runnable) => runnable.handler(),
+ FireEvent(name, element, bubbles, cancelable) => {
+ let target = element.root();
+ target.fire_event(&*name, bubbles, cancelable);
+ }
+ FireSimpleEvent(name, element) => {
+ let target = element.root();
+ target.fire_simple_event(&*name);
+ }
+ FireToggleEvent(runnable) => runnable.handler(),
+ PlannedNavigation(runnable) => runnable.handler(),
+ SendStorageNotification(runnable) => runnable.handler(script_thread)
+ }
+ }
+}
diff --git a/components/script/task_source/file_reading.rs b/components/script/task_source/file_reading.rs
new file mode 100644
index 00000000000..e4afad34b4b
--- /dev/null
+++ b/components/script/task_source/file_reading.rs
@@ -0,0 +1,21 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use script_thread::{CommonScriptMsg, MainThreadScriptMsg, ScriptChan};
+use std::sync::mpsc::Sender;
+
+#[derive(JSTraceable)]
+pub struct FileReadingTaskSource(pub Sender<MainThreadScriptMsg>);
+
+impl ScriptChan for FileReadingTaskSource {
+ fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
+ let FileReadingTaskSource(ref chan) = *self;
+ chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
+ }
+
+ fn clone(&self) -> Box<ScriptChan + Send> {
+ let FileReadingTaskSource(ref chan) = *self;
+ box FileReadingTaskSource((*chan).clone())
+ }
+}
diff --git a/components/script/task_source/history_traversal.rs b/components/script/task_source/history_traversal.rs
new file mode 100644
index 00000000000..0916c121345
--- /dev/null
+++ b/components/script/task_source/history_traversal.rs
@@ -0,0 +1,21 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use script_thread::{CommonScriptMsg, MainThreadScriptMsg, ScriptChan};
+use std::sync::mpsc::Sender;
+
+#[derive(JSTraceable)]
+pub struct HistoryTraversalTaskSource(pub Sender<MainThreadScriptMsg>);
+
+impl ScriptChan for HistoryTraversalTaskSource {
+ fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
+ let HistoryTraversalTaskSource(ref chan) = *self;
+ chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
+ }
+
+ fn clone(&self) -> Box<ScriptChan + Send> {
+ let HistoryTraversalTaskSource(ref chan) = *self;
+ box HistoryTraversalTaskSource((*chan).clone())
+ }
+}
diff --git a/components/script/task_source/mod.rs b/components/script/task_source/mod.rs
new file mode 100644
index 00000000000..74dd7347e9e
--- /dev/null
+++ b/components/script/task_source/mod.rs
@@ -0,0 +1,16 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+pub mod dom_manipulation;
+pub mod file_reading;
+pub mod history_traversal;
+pub mod networking;
+pub mod user_interaction;
+
+use std::result::Result;
+
+pub trait TaskSource<T> {
+ fn queue(&self, msg: T) -> Result<(), ()>;
+ fn clone(&self) -> Box<TaskSource<T> + Send>;
+}
diff --git a/components/script/task_source/networking.rs b/components/script/task_source/networking.rs
new file mode 100644
index 00000000000..8ebeecdb965
--- /dev/null
+++ b/components/script/task_source/networking.rs
@@ -0,0 +1,21 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use script_thread::{CommonScriptMsg, MainThreadScriptMsg, ScriptChan};
+use std::sync::mpsc::Sender;
+
+#[derive(JSTraceable)]
+pub struct NetworkingTaskSource(pub Sender<MainThreadScriptMsg>);
+
+impl ScriptChan for NetworkingTaskSource {
+ fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
+ let NetworkingTaskSource(ref chan) = *self;
+ chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
+ }
+
+ fn clone(&self) -> Box<ScriptChan + Send> {
+ let NetworkingTaskSource(ref chan) = *self;
+ box NetworkingTaskSource((*chan).clone())
+ }
+}
diff --git a/components/script/task_source/user_interaction.rs b/components/script/task_source/user_interaction.rs
new file mode 100644
index 00000000000..7912eac720d
--- /dev/null
+++ b/components/script/task_source/user_interaction.rs
@@ -0,0 +1,21 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use script_thread::{CommonScriptMsg, MainThreadScriptMsg, ScriptChan};
+use std::sync::mpsc::Sender;
+
+#[derive(JSTraceable)]
+pub struct UserInteractionTaskSource(pub Sender<MainThreadScriptMsg>);
+
+impl ScriptChan for UserInteractionTaskSource {
+ fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
+ let UserInteractionTaskSource(ref chan) = *self;
+ chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
+ }
+
+ fn clone(&self) -> Box<ScriptChan + Send> {
+ let UserInteractionTaskSource(ref chan) = *self;
+ box UserInteractionTaskSource((*chan).clone())
+ }
+}