diff options
author | Ms2ger <ms2ger@gmail.com> | 2014-06-10 14:03:04 +0200 |
---|---|---|
committer | Ms2ger <ms2ger@gmail.com> | 2014-06-11 19:51:06 +0200 |
commit | 9acba1477cbfdbc280ed0d6423443f4a37f5168c (patch) | |
tree | 858e34f0db4fb7fabbae47e021f1f1120212fa00 /src/components/script/dom/eventtarget.rs | |
parent | 2aefa3f8055fcb31c34553623b6da6fd15fe9cb0 (diff) | |
download | servo-9acba1477cbfdbc280ed0d6423443f4a37f5168c.tar.gz servo-9acba1477cbfdbc280ed0d6423443f4a37f5168c.zip |
Use internal mutability for EventTarget.
Diffstat (limited to 'src/components/script/dom/eventtarget.rs')
-rw-r--r-- | src/components/script/dom/eventtarget.rs | 94 |
1 files changed, 56 insertions, 38 deletions
diff --git a/src/components/script/dom/eventtarget.rs b/src/components/script/dom/eventtarget.rs index 185913be1dd..7a192d58ab6 100644 --- a/src/components/script/dom/eventtarget.rs +++ b/src/components/script/dom/eventtarget.rs @@ -7,6 +7,7 @@ use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use dom::bindings::codegen::Bindings::EventListenerBinding::EventListener; use dom::bindings::error::{Fallible, InvalidState}; use dom::bindings::js::JSRef; +use dom::bindings::trace::Traceable; use dom::bindings::utils::{Reflectable, Reflector}; use dom::event::Event; use dom::eventdispatcher::dispatch_event; @@ -17,6 +18,7 @@ use js::jsapi::{JS_CompileUCFunction, JS_GetFunctionObject, JS_CloneFunctionObje use js::jsapi::{JSContext, JSObject}; use servo_util::str::DOMString; use libc::{c_char, size_t}; +use std::cell::RefCell; use std::ptr; use url::Url; @@ -59,7 +61,7 @@ pub struct EventListenerEntry { pub struct EventTarget { pub type_id: EventTargetTypeId, pub reflector_: Reflector, - pub handlers: HashMap<DOMString, Vec<EventListenerEntry>>, + handlers: Traceable<RefCell<HashMap<DOMString, Vec<EventListenerEntry>>>>, } impl EventTarget { @@ -67,19 +69,19 @@ impl EventTarget { EventTarget { type_id: type_id, reflector_: Reflector::new(), - handlers: HashMap::new(), + handlers: Traceable::new(RefCell::new(HashMap::new())), } } pub fn get_listeners(&self, type_: &str) -> Option<Vec<EventListener>> { - self.handlers.find_equiv(&type_).map(|listeners| { + self.handlers.deref().borrow().find_equiv(&type_).map(|listeners| { listeners.iter().map(|entry| entry.listener.get_listener()).collect() }) } pub fn get_listeners_for(&self, type_: &str, desired_phase: ListenerPhase) -> Option<Vec<EventListener>> { - self.handlers.find_equiv(&type_).map(|listeners| { + self.handlers.deref().borrow().find_equiv(&type_).map(|listeners| { let filtered = listeners.iter().filter(|entry| entry.phase == desired_phase); filtered.map(|entry| entry.listener.get_listener()).collect() }) @@ -90,19 +92,21 @@ pub trait EventTargetHelpers { fn dispatch_event_with_target<'a>(&self, target: Option<JSRef<'a, EventTarget>>, event: &JSRef<Event>) -> Fallible<bool>; - fn set_inline_event_listener(&mut self, + fn set_inline_event_listener(&self, ty: DOMString, listener: Option<EventListener>); fn get_inline_event_listener(&self, ty: DOMString) -> Option<EventListener>; - fn set_event_handler_uncompiled(&mut self, + fn set_event_handler_uncompiled(&self, cx: *mut JSContext, url: Url, scope: *mut JSObject, ty: &str, source: DOMString); - fn set_event_handler_common<T: CallbackContainer>(&mut self, ty: &str, + fn set_event_handler_common<T: CallbackContainer>(&self, ty: &str, listener: Option<T>); fn get_event_handler_common<T: CallbackContainer>(&self, ty: &str) -> Option<T>; + + fn has_handlers(&self) -> bool; } impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> { @@ -115,10 +119,11 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> { Ok(dispatch_event(self, target, event)) } - fn set_inline_event_listener(&mut self, + fn set_inline_event_listener(&self, ty: DOMString, listener: Option<EventListener>) { - let entries = self.handlers.find_or_insert_with(ty, |_| vec!()); + let mut handlers = self.handlers.deref().borrow_mut(); + let entries = handlers.find_or_insert_with(ty, |_| vec!()); let idx = entries.iter().position(|&entry| { match entry.listener { Inline(_) => true, @@ -147,7 +152,8 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> { } fn get_inline_event_listener(&self, ty: DOMString) -> Option<EventListener> { - let entries = self.handlers.find(&ty); + let handlers = self.handlers.deref().borrow(); + let entries = handlers.find(&ty); entries.and_then(|entries| entries.iter().find(|entry| { match entry.listener { Inline(_) => true, @@ -156,7 +162,7 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> { }).map(|entry| entry.listener.get_listener())) } - fn set_event_handler_uncompiled(&mut self, + fn set_event_handler_uncompiled(&self, cx: *mut JSContext, url: Url, scope: *mut JSObject, @@ -188,7 +194,7 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> { } fn set_event_handler_common<T: CallbackContainer>( - &mut self, ty: &str, listener: Option<T>) + &self, ty: &str, listener: Option<T>) { let event_listener = listener.map(|listener| EventListener::new(listener.callback())); @@ -199,14 +205,18 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> { let listener = self.get_inline_event_listener(ty.to_string()); listener.map(|listener| CallbackContainer::new(listener.parent.callback())) } + + fn has_handlers(&self) -> bool { + !self.handlers.deref().borrow().is_empty() + } } pub trait EventTargetMethods { - fn AddEventListener(&mut self, + fn AddEventListener(&self, ty: DOMString, listener: Option<EventListener>, capture: bool); - fn RemoveEventListener(&mut self, + fn RemoveEventListener(&self, ty: DOMString, listener: Option<EventListener>, capture: bool); @@ -214,40 +224,48 @@ pub trait EventTargetMethods { } impl<'a> EventTargetMethods for JSRef<'a, EventTarget> { - fn AddEventListener(&mut self, + fn AddEventListener(&self, ty: DOMString, listener: Option<EventListener>, capture: bool) { - for &listener in listener.iter() { - let entry = self.handlers.find_or_insert_with(ty.clone(), |_| vec!()); - let phase = if capture { Capturing } else { Bubbling }; - let new_entry = EventListenerEntry { - phase: phase, - listener: Additive(listener) - }; - if entry.as_slice().position_elem(&new_entry).is_none() { - entry.push(new_entry); - } + match listener { + Some(listener) => { + let mut handlers = self.handlers.deref().borrow_mut(); + let entry = handlers.find_or_insert_with(ty, |_| vec!()); + let phase = if capture { Capturing } else { Bubbling }; + let new_entry = EventListenerEntry { + phase: phase, + listener: Additive(listener) + }; + if entry.as_slice().position_elem(&new_entry).is_none() { + entry.push(new_entry); + } + }, + _ => (), } } - fn RemoveEventListener(&mut self, + fn RemoveEventListener(&self, ty: DOMString, listener: Option<EventListener>, capture: bool) { - for &listener in listener.iter() { - let mut entry = self.handlers.find_mut(&ty); - for entry in entry.mut_iter() { - let phase = if capture { Capturing } else { Bubbling }; - let old_entry = EventListenerEntry { - phase: phase, - listener: Additive(listener) - }; - let position = entry.as_slice().position_elem(&old_entry); - for &position in position.iter() { - entry.remove(position); + match listener { + Some(listener) => { + let mut handlers = self.handlers.deref().borrow_mut(); + let mut entry = handlers.find_mut(&ty); + for entry in entry.mut_iter() { + let phase = if capture { Capturing } else { Bubbling }; + let old_entry = EventListenerEntry { + phase: phase, + listener: Additive(listener) + }; + let position = entry.as_slice().position_elem(&old_entry); + for &position in position.iter() { + entry.remove(position); + } } - } + }, + _ => (), } } |