Skip to content

Commit

Permalink
Auto merge of #9217 - KiChjang:dom-manipulation-msg, r=jdm
Browse files Browse the repository at this point in the history
Redesign ScriptMsg to be more specific to DOMManipulationTaskSource

This is a large-ish PR that contains the following:
* A new directory is created under `components/script/` called `task_source`, which houses all the stuff for different task sources. Note that the ones that I have now aren't exhaustive - there are more task sources than just the generic ones.
* A `DOMManipulationTaskMsg` which eliminates some usage of `Runnable`s to fire events. Instead, they send event information to the `DOMManipulationTaskSource` and lets the `ScriptTask` handle all the event firing.
* Re-added `fn script_chan`, since I can't think of any other way to give `Trusted` values an appropriate sender.
* Rewrote step 7 of [the end](https://html.spec.whatwg.org/multipage/syntax.html#the-end) to make use of the `DOMManipulationTaskSource`

Partial #7959

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9217)
<!-- Reviewable:end -->
  • Loading branch information
bors-servo committed Mar 10, 2016
2 parents 396812b + 3f2cbf0 commit 740965e
Show file tree
Hide file tree
Showing 17 changed files with 261 additions and 185 deletions.
19 changes: 16 additions & 3 deletions components/script/dom/bindings/global.rs
Expand Up @@ -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;

Expand Down Expand Up @@ -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> {
Expand Down
19 changes: 10 additions & 9 deletions components/script/dom/document.rs
Expand Up @@ -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};
Expand All @@ -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};
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
}
}

Expand Down
30 changes: 13 additions & 17 deletions components/script/dom/htmldetailselement.rs
Expand Up @@ -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]
Expand Down Expand Up @@ -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));
}
}
}
Expand All @@ -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();
Expand Down
17 changes: 12 additions & 5 deletions components/script/dom/htmlformelement.rs
Expand Up @@ -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;

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
43 changes: 11 additions & 32 deletions components/script/dom/htmlscriptelement.rs
Expand Up @@ -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};
Expand All @@ -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};

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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();
}
}
}
11 changes: 6 additions & 5 deletions components/script/dom/storage.rs
Expand Up @@ -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;

Expand Down Expand Up @@ -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();
}
}
Expand Down
4 changes: 2 additions & 2 deletions components/script/dom/webidls/Worker.webidl
Expand Up @@ -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;
16 changes: 10 additions & 6 deletions components/script/dom/window.rs
Expand Up @@ -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};
Expand All @@ -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;
Expand Down Expand Up @@ -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()
}

Expand All @@ -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 {
Expand Down
10 changes: 5 additions & 5 deletions components/script/dom/worker.rs
Expand Up @@ -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();
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions components/script/lib.rs
Expand Up @@ -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;
Expand Down

0 comments on commit 740965e

Please sign in to comment.