diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs index 17a2688a910..7dea10fd0a0 100644 --- a/components/script/dom/bindings/global.rs +++ b/components/script/dom/bindings/global.rs @@ -173,15 +173,6 @@ impl<'a> GlobalRef<'a> { } } - /// `ScriptChan` used to send messages to the event loop of this global's - /// thread. - pub fn user_interaction_task_source(&self) -> Box { - match *self { - GlobalRef::Window(ref window) => window.user_interaction_task_source(), - GlobalRef::Worker(ref worker) => worker.script_chan(), - } - } - /// `ScriptChan` used to send messages to the event loop of this global's /// thread. pub fn networking_task_source(&self) -> Box { diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 0e675b35b27..ed9f4826fb6 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -12,10 +12,8 @@ use dom::bindings::codegen::Bindings::HTMLInputElementBinding; use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementMethods; use dom::bindings::codegen::Bindings::KeyboardEventBinding::KeyboardEventMethods; use dom::bindings::error::{Error, ErrorResult}; -use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, LayoutJS, Root, RootedReference}; -use dom::bindings::refcounted::Trusted; use dom::document::Document; use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers, LayoutElementHelpers}; use dom::event::{Event, EventBubbles, EventCancelable}; @@ -31,9 +29,7 @@ use dom::nodelist::NodeList; use dom::validation::Validatable; use dom::virtualmethods::VirtualMethods; use msg::constellation_msg::ConstellationChan; -use script_runtime::CommonScriptMsg; -use script_runtime::ScriptThreadEventCategory::InputEvent; -use script_thread::Runnable; +use script_runtime::ScriptChan; use script_traits::ScriptMsg as ConstellationMsg; use std::borrow::ToOwned; use std::cell::Cell; @@ -919,7 +915,13 @@ impl VirtualMethods for HTMLInputElement { self.value_changed.set(true); if event.IsTrusted() { - ChangeEventRunnable::send(self.upcast::()); + let window = window_from_node(self); + let task_source = window.user_interaction_task_source(); + let _ = task_source.queue_event( + &self.upcast(), + atom!("input"), + EventBubbles::Bubbles, + EventCancelable::NotCancelable); } self.upcast::().dirty(NodeDamage::OtherNodeDamage); @@ -1148,31 +1150,3 @@ impl Activatable for HTMLInputElement { } } } - -pub struct ChangeEventRunnable { - element: Trusted, -} - -impl ChangeEventRunnable { - pub fn send(node: &Node) { - let handler = Trusted::new(node); - let dispatcher = ChangeEventRunnable { - element: handler, - }; - let chan = window_from_node(node).user_interaction_task_source(); - let _ = chan.send(CommonScriptMsg::RunnableMsg(InputEvent, box dispatcher)); - } -} - -impl Runnable for ChangeEventRunnable { - fn handler(self: Box) { - let target = self.element.root(); - let window = window_from_node(target.r()); - let window = window.r(); - let event = Event::new(GlobalRef::Window(window), - atom!("input"), - EventBubbles::Bubbles, - EventCancelable::NotCancelable); - target.upcast::().dispatch_event(&event); - } -} diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index 597c9a2bb60..44e331f4a9d 100644 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -14,18 +14,18 @@ use dom::bindings::reflector::{Reflectable}; use dom::document::Document; use dom::element::RawLayoutElementHelpers; use dom::element::{AttributeMutation, Element}; -use dom::event::{Event}; +use dom::event::{Event, EventBubbles, EventCancelable}; use dom::htmlelement::HTMLElement; use dom::htmlfieldsetelement::HTMLFieldSetElement; use dom::htmlformelement::{FormControl, HTMLFormElement}; -use dom::htmlinputelement::ChangeEventRunnable; use dom::keyboardevent::KeyboardEvent; use dom::node::{ChildrenMutation, Node, NodeDamage, UnbindContext}; -use dom::node::{document_from_node}; +use dom::node::{document_from_node, window_from_node}; use dom::nodelist::NodeList; use dom::validation::Validatable; use dom::virtualmethods::VirtualMethods; use msg::constellation_msg::ConstellationChan; +use script_runtime::ScriptChan; use script_traits::ScriptMsg as ConstellationMsg; use std::cell::Cell; use std::ops::Range; @@ -373,7 +373,13 @@ impl VirtualMethods for HTMLTextAreaElement { self.value_changed.set(true); if event.IsTrusted() { - ChangeEventRunnable::send(self.upcast::()); + let window = window_from_node(self); + let task_source = window.user_interaction_task_source(); + let _ = task_source.queue_event( + &self.upcast(), + atom!("input"), + EventBubbles::Bubbles, + EventCancelable::NotCancelable); } self.upcast::().dirty(NodeDamage::OtherNodeDamage); diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index dc6fb8704e8..4d60facbe84 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -277,7 +277,7 @@ impl Window { self.dom_manipulation_task_source.clone() } - pub fn user_interaction_task_source(&self) -> Box { + pub fn user_interaction_task_source(&self) -> UserInteractionTaskSource { self.user_interaction_task_source.clone() } diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 5891bd35c7c..d615a937fcf 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -100,7 +100,7 @@ use task_source::dom_manipulation::{DOMManipulationTaskSource, DOMManipulationTa use task_source::file_reading::FileReadingTaskSource; use task_source::history_traversal::HistoryTraversalTaskSource; use task_source::networking::NetworkingTaskSource; -use task_source::user_interaction::UserInteractionTaskSource; +use task_source::user_interaction::{UserInteractionTaskSource, UserInteractionTask}; use time::Tm; use url::{Url, Position}; use util::opts; @@ -222,6 +222,8 @@ pub enum MainThreadScriptMsg { Navigate(PipelineId, LoadData), /// Tasks that originate from the DOM manipulation task source DOMManipulation(DOMManipulationTask), + /// Tasks that originate from the user interaction task source + UserInteraction(UserInteractionTask), } impl OpaqueSender for Box { @@ -934,6 +936,8 @@ impl ScriptThread { self.collect_reports(reports_chan), MainThreadScriptMsg::DOMManipulation(task) => task.handle_task(self), + MainThreadScriptMsg::UserInteraction(task) => + task.handle_task(), } } diff --git a/components/script/task_source/dom_manipulation.rs b/components/script/task_source/dom_manipulation.rs index de3fc19710e..05b0722f889 100644 --- a/components/script/task_source/dom_manipulation.rs +++ b/components/script/task_source/dom_manipulation.rs @@ -18,8 +18,10 @@ impl TaskSource for DOMManipulationTaskSource { fn queue(&self, msg: DOMManipulationTask) -> Result<(), ()> { self.0.send(MainThreadScriptMsg::DOMManipulation(msg)).map_err(|_| ()) } +} - fn clone(&self) -> Box + Send> { +impl DOMManipulationTaskSource { + pub fn clone(&self) -> Box + Send> { box DOMManipulationTaskSource((&self.0).clone()) } } diff --git a/components/script/task_source/mod.rs b/components/script/task_source/mod.rs index 74dd7347e9e..fe2d159b04a 100644 --- a/components/script/task_source/mod.rs +++ b/components/script/task_source/mod.rs @@ -12,5 +12,4 @@ use std::result::Result; pub trait TaskSource { fn queue(&self, msg: T) -> Result<(), ()>; - fn clone(&self) -> Box + Send>; } diff --git a/components/script/task_source/user_interaction.rs b/components/script/task_source/user_interaction.rs index 8f79b8ddaed..59d7d728185 100644 --- a/components/script/task_source/user_interaction.rs +++ b/components/script/task_source/user_interaction.rs @@ -2,19 +2,55 @@ * 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_runtime::{CommonScriptMsg, ScriptChan}; +use dom::bindings::refcounted::Trusted; +use dom::event::{EventBubbles, EventCancelable}; +use dom::eventtarget::EventTarget; +use script_runtime::ScriptChan; use script_thread::MainThreadScriptMsg; +use std::result::Result; use std::sync::mpsc::Sender; +use string_cache::Atom; +use task_source::TaskSource; #[derive(JSTraceable)] pub struct UserInteractionTaskSource(pub Sender); -impl ScriptChan for UserInteractionTaskSource { - fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> { - self.0.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ()) - } - - fn clone(&self) -> Box { - box UserInteractionTaskSource((&self.0).clone()) +impl TaskSource for UserInteractionTaskSource { + fn queue(&self, msg: UserInteractionTask) -> Result<(), ()> { + self.0.send(MainThreadScriptMsg::UserInteraction(msg)).map_err(|_| ()) + } +} + +impl UserInteractionTaskSource { + pub fn queue_event(&self, + target: &EventTarget, + name: Atom, + bubbles: EventBubbles, + cancelable: EventCancelable) { + let target = Trusted::new(target); + let _ = self.0.send(MainThreadScriptMsg::UserInteraction(UserInteractionTask::FireEvent( + target, name, bubbles, cancelable))); + } + + pub fn clone(&self) -> UserInteractionTaskSource { + UserInteractionTaskSource((&self.0).clone()) + } +} + +pub enum UserInteractionTask { + // https://dom.spec.whatwg.org/#concept-event-fire + FireEvent(Trusted, Atom, EventBubbles, EventCancelable), +} + +impl UserInteractionTask { + pub fn handle_task(self) { + use self::UserInteractionTask::*; + + match self { + FireEvent(element, name, bubbles, cancelable) => { + let target = element.root(); + target.fire_event(&*name, bubbles, cancelable); + } + } } }