diff options
author | Josh Matthews <josh@joshmatthews.net> | 2014-03-31 18:41:28 -0400 |
---|---|---|
committer | Josh Matthews <josh@joshmatthews.net> | 2014-05-03 14:18:30 -0400 |
commit | d7b96db33ca8f2b8a162df38e0f00e95f5ea6fa1 (patch) | |
tree | efd1e7f7ec1dd30467c2a67306e1a639837abead /src/components/script/dom/eventdispatcher.rs | |
parent | ffdc3f5b32a345b88eed774848924e862d47c093 (diff) | |
download | servo-d7b96db33ca8f2b8a162df38e0f00e95f5ea6fa1.tar.gz servo-d7b96db33ca8f2b8a162df38e0f00e95f5ea6fa1.zip |
Implement safe rooting strategy via Unrooted, Root, JSRef, and JS.
Diffstat (limited to 'src/components/script/dom/eventdispatcher.rs')
-rw-r--r-- | src/components/script/dom/eventdispatcher.rs | 37 |
1 files changed, 20 insertions, 17 deletions
diff --git a/src/components/script/dom/eventdispatcher.rs b/src/components/script/dom/eventdispatcher.rs index b8fbce59974..9d45b398e02 100644 --- a/src/components/script/dom/eventdispatcher.rs +++ b/src/components/script/dom/eventdispatcher.rs @@ -4,35 +4,32 @@ use dom::bindings::callback::ReportExceptions; use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, NodeDerived}; -use dom::bindings::js::{JS, JSRef}; +use dom::bindings::js::{JSRef, OptionalAssignable, RootCollection, Root}; use dom::eventtarget::{Capturing, Bubbling, EventTarget}; use dom::event::{Event, PhaseAtTarget, PhaseNone, PhaseBubbling, PhaseCapturing}; use dom::node::{Node, NodeHelpers}; // See http://dom.spec.whatwg.org/#concept-event-dispatch for the full dispatch algorithm -pub fn dispatch_event(target: &JSRef<EventTarget>, - pseudo_target: Option<JSRef<EventTarget>>, - event: &mut JSRef<Event>) -> bool { +pub fn dispatch_event<'a>(target: &JSRef<'a, EventTarget>, + pseudo_target: Option<JSRef<'a, EventTarget>>, + event: &mut JSRef<Event>) -> bool { + let roots = RootCollection::new(); assert!(!event.get().dispatching); { let event = event.get_mut(); - event.target = pseudo_target.map(|pseudo_target| { - pseudo_target.unrooted() - }).or_else(|| { - Some(target.unrooted()) - }); + event.target.assign(Some(pseudo_target.unwrap_or(target.clone()))); event.dispatching = true; } let type_ = event.get().type_.clone(); //TODO: no chain if not participating in a tree - let chain: Vec<JS<EventTarget>> = if target.get().is_node() { - let target_node: JS<Node> = NodeCast::to(&target.unrooted()).unwrap(); + let mut chain: Vec<Root<EventTarget>> = if target.get().is_node() { + let target_node: &JSRef<Node> = NodeCast::to_ref(target).unwrap(); target_node.ancestors().map(|ancestor| { - let ancestor_target: JS<EventTarget> = EventTargetCast::from(&ancestor); - ancestor_target + let ancestor_target: &JSRef<EventTarget> = EventTargetCast::from_ref(&ancestor); + ancestor_target.unrooted().root(&roots) }).collect() } else { vec!() @@ -44,9 +41,9 @@ pub fn dispatch_event(target: &JSRef<EventTarget>, /* capturing */ for cur_target in chain.as_slice().rev_iter() { - let stopped = match cur_target.get().get_listeners_for(type_, Capturing) { + let stopped = match cur_target.get_listeners_for(type_, Capturing) { Some(listeners) => { - event.get_mut().current_target = Some(cur_target.clone()); + event.current_target.assign(Some(cur_target.deref().clone())); for listener in listeners.iter() { //FIXME: this should have proper error handling, or explicitly // drop the exception on the floor @@ -72,7 +69,7 @@ pub fn dispatch_event(target: &JSRef<EventTarget>, { let event = event.get_mut(); event.phase = PhaseAtTarget; - event.current_target = Some(target.unrooted()); + event.current_target.assign(Some(target.clone())); } let opt_listeners = target.get().get_listeners(type_); @@ -95,7 +92,7 @@ pub fn dispatch_event(target: &JSRef<EventTarget>, for cur_target in chain.iter() { let stopped = match cur_target.get().get_listeners_for(type_, Bubbling) { Some(listeners) => { - event.get_mut().current_target = Some(cur_target.clone()); + event.get_mut().current_target.assign(Some(cur_target.deref().clone())); for listener in listeners.iter() { //FIXME: this should have proper error handling or explicitly // drop exceptions on the floor. @@ -116,6 +113,12 @@ pub fn dispatch_event(target: &JSRef<EventTarget>, } } + // Root ordering restrictions mean we need to unroot the chain entries + // in the same order they were rooted. + while chain.len() > 0 { + let _ = chain.pop(); + } + let event = event.get_mut(); event.dispatching = false; event.phase = PhaseNone; |