Matching over event listeners and handlers; r=Ms2ger

fixup! Matching over event listeners and handlers; r=Ms2ger
This commit is contained in:
Ravi Shankar 2015-08-18 02:49:46 +05:30
parent 7c63c7d7c1
commit f3db59972a
4 changed files with 30 additions and 40 deletions

View file

@ -47,7 +47,7 @@ pub fn dispatch_event<'a, 'b>(target: &'a EventTarget,
event.set_current_target(cur_target); event.set_current_target(cur_target);
for listener in &listeners { for listener in &listeners {
// Explicitly drop any exception on the floor. // Explicitly drop any exception on the floor.
let _ = listener.HandleEvent_(*cur_target, event, Report); listener.call_or_handle_event(*cur_target, event, Report);
if event.stop_immediate() { if event.stop_immediate() {
break; break;
@ -73,7 +73,7 @@ pub fn dispatch_event<'a, 'b>(target: &'a EventTarget,
for listeners in opt_listeners.iter() { for listeners in opt_listeners.iter() {
for listener in listeners.iter() { for listener in listeners.iter() {
// Explicitly drop any exception on the floor. // Explicitly drop any exception on the floor.
let _ = listener.HandleEvent_(target, event, Report); listener.call_or_handle_event(target, event, Report);
if event.stop_immediate() { if event.stop_immediate() {
break; break;
@ -92,7 +92,7 @@ pub fn dispatch_event<'a, 'b>(target: &'a EventTarget,
event.set_current_target(cur_target); event.set_current_target(cur_target);
for listener in &listeners { for listener in &listeners {
// Explicitly drop any exception on the floor. // Explicitly drop any exception on the floor.
let _ = listener.HandleEvent_(*cur_target, event, Report); listener.call_or_handle_event(*cur_target, event, Report);
if event.stop_immediate() { if event.stop_immediate() {
break; break;

View file

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::callback::CallbackContainer; use dom::bindings::callback::{CallbackContainer, ExceptionHandling};
use dom::bindings::cell::DOMRefCell; use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::EventListenerBinding::EventListener; use dom::bindings::codegen::Bindings::EventListenerBinding::EventListener;
@ -37,6 +37,8 @@ use url::Url;
use std::collections::HashMap; use std::collections::HashMap;
pub type EventHandler = EventHandlerNonNull;
#[derive(JSTraceable, Copy, Clone, PartialEq, HeapSizeOf)] #[derive(JSTraceable, Copy, Clone, PartialEq, HeapSizeOf)]
pub enum ListenerPhase { pub enum ListenerPhase {
Capturing, Capturing,
@ -94,7 +96,7 @@ impl EventTargetTypeId {
#[derive(JSTraceable, Clone, PartialEq)] #[derive(JSTraceable, Clone, PartialEq)]
pub enum EventListenerType { pub enum EventListenerType {
Additive(Rc<EventListener>), Additive(Rc<EventListener>),
Inline(Rc<EventListener>), Inline(Rc<EventHandler>),
} }
impl HeapSizeOf for EventListenerType { impl HeapSizeOf for EventListenerType {
@ -105,10 +107,17 @@ impl HeapSizeOf for EventListenerType {
} }
impl EventListenerType { impl EventListenerType {
fn get_listener(&self) -> Rc<EventListener> { pub fn call_or_handle_event<T: Reflectable>(&self,
object: &T,
event: &Event,
exception_handle: ExceptionHandling) {
match *self { match *self {
EventListenerType::Additive(ref listener) | EventListenerType::Additive(ref listener) => {
EventListenerType::Inline(ref listener) => listener.clone(), let _ = listener.HandleEvent_(object, event, exception_handle);
},
EventListenerType::Inline(ref handler) => {
let _ = handler.Call_(object, event, exception_handle);
},
} }
} }
} }
@ -137,17 +146,17 @@ impl EventTarget {
} }
} }
pub fn get_listeners(&self, type_: &str) -> Option<Vec<Rc<EventListener>>> { pub fn get_listeners(&self, type_: &str) -> Option<Vec<EventListenerType>> {
self.handlers.borrow().get(type_).map(|listeners| { self.handlers.borrow().get(type_).map(|listeners| {
listeners.iter().map(|entry| entry.listener.get_listener()).collect() listeners.iter().map(|entry| entry.listener.clone()).collect()
}) })
} }
pub fn get_listeners_for(&self, type_: &str, desired_phase: ListenerPhase) pub fn get_listeners_for(&self, type_: &str, desired_phase: ListenerPhase)
-> Option<Vec<Rc<EventListener>>> { -> Option<Vec<EventListenerType>> {
self.handlers.borrow().get(type_).map(|listeners| { self.handlers.borrow().get(type_).map(|listeners| {
let filtered = listeners.iter().filter(|entry| entry.phase == desired_phase); let filtered = listeners.iter().filter(|entry| entry.phase == desired_phase);
filtered.map(|entry| entry.listener.get_listener()).collect() filtered.map(|entry| entry.listener.clone()).collect()
}) })
} }
@ -164,8 +173,8 @@ pub trait EventTargetHelpers {
fn dispatch_event(self, event: &Event) -> bool; fn dispatch_event(self, event: &Event) -> bool;
fn set_inline_event_listener(self, fn set_inline_event_listener(self,
ty: DOMString, ty: DOMString,
listener: Option<Rc<EventListener>>); listener: Option<Rc<EventHandler>>);
fn get_inline_event_listener(self, ty: DOMString) -> Option<Rc<EventListener>>; fn get_inline_event_listener(self, ty: DOMString) -> Option<Rc<EventHandler>>;
fn set_event_handler_uncompiled(self, fn set_event_handler_uncompiled(self,
cx: *mut JSContext, cx: *mut JSContext,
url: Url, url: Url,
@ -192,7 +201,7 @@ impl<'a> EventTargetHelpers for &'a EventTarget {
fn set_inline_event_listener(self, fn set_inline_event_listener(self,
ty: DOMString, ty: DOMString,
listener: Option<Rc<EventListener>>) { listener: Option<Rc<EventHandler>>) {
let mut handlers = self.handlers.borrow_mut(); let mut handlers = self.handlers.borrow_mut();
let entries = match handlers.entry(ty) { let entries = match handlers.entry(ty) {
Occupied(entry) => entry.into_mut(), Occupied(entry) => entry.into_mut(),
@ -226,15 +235,15 @@ impl<'a> EventTargetHelpers for &'a EventTarget {
} }
} }
fn get_inline_event_listener(self, ty: DOMString) -> Option<Rc<EventListener>> { fn get_inline_event_listener(self, ty: DOMString) -> Option<Rc<EventHandler>> {
let handlers = self.handlers.borrow(); let handlers = self.handlers.borrow();
let entries = handlers.get(&ty); let entries = handlers.get(&ty);
entries.and_then(|entries| entries.iter().find(|entry| { entries.and_then(|entries| entries.iter().filter_map(|entry| {
match entry.listener { match entry.listener {
EventListenerType::Inline(_) => true, EventListenerType::Inline(ref handler) => Some(handler.clone()),
_ => false, _ => None,
} }
}).map(|entry| entry.listener.get_listener())) }).next())
} }
#[allow(unsafe_code)] #[allow(unsafe_code)]
@ -283,7 +292,7 @@ impl<'a> EventTargetHelpers for &'a EventTarget {
self, ty: &str, listener: Option<Rc<T>>) self, ty: &str, listener: Option<Rc<T>>)
{ {
let event_listener = listener.map(|listener| let event_listener = listener.map(|listener|
EventListener::new(listener.callback())); EventHandlerNonNull::new(listener.callback()));
self.set_inline_event_listener(ty.to_owned(), event_listener); self.set_inline_event_listener(ty.to_owned(), event_listener);
} }

View file

@ -1,14 +0,0 @@
[013.html]
type: testharness
[onclose]
expected: FAIL
[onopen]
expected: FAIL
[onerror]
expected: FAIL
[onmessage]
expected: FAIL

View file

@ -1,5 +0,0 @@
[onmessage.worker]
type: testharness
[Setting onmessage to an object]
expected: FAIL