Use an Atom for Event.type

This commit is contained in:
David Zbarsky 2015-10-25 10:29:33 -07:00
parent 601169c0e5
commit 0070adb71f
5 changed files with 27 additions and 21 deletions

View file

@ -13,6 +13,7 @@ use dom::eventtarget::EventTarget;
use std::borrow::ToOwned; use std::borrow::ToOwned;
use std::cell::Cell; use std::cell::Cell;
use std::default::Default; use std::default::Default;
use string_cache::Atom;
use time; use time;
use util::str::DOMString; use util::str::DOMString;
@ -43,7 +44,7 @@ pub struct Event {
reflector_: Reflector, reflector_: Reflector,
current_target: MutNullableHeap<JS<EventTarget>>, current_target: MutNullableHeap<JS<EventTarget>>,
target: MutNullableHeap<JS<EventTarget>>, target: MutNullableHeap<JS<EventTarget>>,
type_: DOMRefCell<DOMString>, type_: DOMRefCell<Atom>,
phase: Cell<EventPhase>, phase: Cell<EventPhase>,
canceled: Cell<bool>, canceled: Cell<bool>,
stop_propagation: Cell<bool>, stop_propagation: Cell<bool>,
@ -62,7 +63,7 @@ impl Event {
reflector_: Reflector::new(), reflector_: Reflector::new(),
current_target: Default::default(), current_target: Default::default(),
target: Default::default(), target: Default::default(),
type_: DOMRefCell::new("".to_owned()), type_: DOMRefCell::new(atom!("")),
phase: Cell::new(EventPhase::None), phase: Cell::new(EventPhase::None),
canceled: Cell::new(false), canceled: Cell::new(false),
stop_propagation: Cell::new(false), stop_propagation: Cell::new(false),
@ -153,6 +154,11 @@ impl Event {
pub fn initialized(&self) -> bool { pub fn initialized(&self) -> bool {
self.initialized.get() self.initialized.get()
} }
#[inline]
pub fn type_(&self) -> Atom {
self.type_.borrow().clone()
}
} }
impl EventMethods for Event { impl EventMethods for Event {
@ -163,7 +169,7 @@ impl EventMethods for Event {
// https://dom.spec.whatwg.org/#dom-event-type // https://dom.spec.whatwg.org/#dom-event-type
fn Type(&self) -> DOMString { fn Type(&self) -> DOMString {
self.type_.borrow().clone() (*self.type_()).to_owned()
} }
// https://dom.spec.whatwg.org/#dom-event-target // https://dom.spec.whatwg.org/#dom-event-target
@ -229,7 +235,7 @@ impl EventMethods for Event {
self.canceled.set(false); self.canceled.set(false);
self.trusted.set(false); self.trusted.set(false);
self.target.set(None); self.target.set(None);
*self.type_.borrow_mut() = type_; *self.type_.borrow_mut() = Atom::from_slice(&type_);
self.bubbles.set(bubbles); self.bubbles.set(bubbles);
self.cancelable.set(cancelable); self.cancelable.set(cancelable);
} }

View file

@ -60,7 +60,7 @@ fn dispatch_to_listeners(event: &Event, target: &EventTarget, chain: &[&EventTar
_ => None, _ => None,
}; };
let type_ = event.Type(); let type_ = event.type_();
/* capturing */ /* capturing */
event.set_phase(EventPhase::Capturing); event.set_phase(EventPhase::Capturing);

View file

@ -19,7 +19,6 @@ use js::jsapi::{HandleObject, JSContext, RootedFunction};
use js::jsapi::{JSAutoCompartment, JSAutoRequest}; use js::jsapi::{JSAutoCompartment, JSAutoRequest};
use js::rust::{AutoObjectVectorWrapper, CompileOptionsWrapper}; use js::rust::{AutoObjectVectorWrapper, CompileOptionsWrapper};
use libc::{c_char, size_t}; use libc::{c_char, size_t};
use std::borrow::ToOwned;
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::hash_state::DefaultState; use std::collections::hash_state::DefaultState;
@ -27,6 +26,7 @@ use std::default::Default;
use std::ffi::CString; use std::ffi::CString;
use std::rc::Rc; use std::rc::Rc;
use std::{intrinsics, ptr}; use std::{intrinsics, ptr};
use string_cache::Atom;
use url::Url; use url::Url;
use util::mem::HeapSizeOf; use util::mem::HeapSizeOf;
use util::str::DOMString; use util::str::DOMString;
@ -114,7 +114,7 @@ pub struct EventListenerEntry {
#[dom_struct] #[dom_struct]
pub struct EventTarget { pub struct EventTarget {
reflector_: Reflector, reflector_: Reflector,
handlers: DOMRefCell<HashMap<DOMString, Vec<EventListenerEntry>, DefaultState<FnvHasher>>>, handlers: DOMRefCell<HashMap<Atom, Vec<EventListenerEntry>, DefaultState<FnvHasher>>>,
} }
impl EventTarget { impl EventTarget {
@ -125,13 +125,13 @@ impl EventTarget {
} }
} }
pub fn get_listeners(&self, type_: &str) -> Option<Vec<EventListenerType>> { pub fn get_listeners(&self, type_: &Atom) -> Option<Vec<EventListenerType>> {
self.handlers.borrow().get(type_).map(|listeners| { self.handlers.borrow().get(type_).map(|listeners| {
listeners.iter().map(|entry| entry.listener.clone()).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_: &Atom, desired_phase: ListenerPhase)
-> Option<Vec<EventListenerType>> { -> 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);
@ -150,7 +150,7 @@ impl EventTarget {
} }
pub fn set_inline_event_listener(&self, pub fn set_inline_event_listener(&self,
ty: DOMString, ty: Atom,
listener: Option<Rc<EventHandler>>) { 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) {
@ -185,9 +185,9 @@ impl EventTarget {
} }
} }
pub fn get_inline_event_listener(&self, ty: DOMString) -> Option<Rc<EventHandler>> { pub fn get_inline_event_listener(&self, ty: &Atom) -> 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().filter_map(|entry| { entries.and_then(|entries| entries.iter().filter_map(|entry| {
match entry.listener { match entry.listener {
EventListenerType::Inline(ref handler) => Some(handler.clone()), EventListenerType::Inline(ref handler) => Some(handler.clone()),
@ -243,11 +243,11 @@ impl EventTarget {
{ {
let event_listener = listener.map(|listener| let event_listener = listener.map(|listener|
EventHandlerNonNull::new(listener.callback())); EventHandlerNonNull::new(listener.callback()));
self.set_inline_event_listener(ty.to_owned(), event_listener); self.set_inline_event_listener(Atom::from_slice(ty), event_listener);
} }
pub fn get_event_handler_common<T: CallbackContainer>(&self, ty: &str) -> Option<Rc<T>> { pub fn get_event_handler_common<T: CallbackContainer>(&self, ty: &str) -> Option<Rc<T>> {
let listener = self.get_inline_event_listener(ty.to_owned()); let listener = self.get_inline_event_listener(&Atom::from_slice(ty));
listener.map(|listener| CallbackContainer::new(listener.parent.callback())) listener.map(|listener| CallbackContainer::new(listener.parent.callback()))
} }
@ -265,7 +265,7 @@ impl EventTargetMethods for EventTarget {
match listener { match listener {
Some(listener) => { Some(listener) => {
let mut handlers = self.handlers.borrow_mut(); let mut handlers = self.handlers.borrow_mut();
let entry = match handlers.entry(ty) { let entry = match handlers.entry(Atom::from_slice(&ty)) {
Occupied(entry) => entry.into_mut(), Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.insert(vec!()), Vacant(entry) => entry.insert(vec!()),
}; };
@ -291,7 +291,7 @@ impl EventTargetMethods for EventTarget {
match listener { match listener {
Some(ref listener) => { Some(ref listener) => {
let mut handlers = self.handlers.borrow_mut(); let mut handlers = self.handlers.borrow_mut();
let entry = handlers.get_mut(&ty); let entry = handlers.get_mut(&Atom::from_slice(&ty));
for entry in entry { for entry in entry {
let phase = if capture { ListenerPhase::Capturing } else { ListenerPhase::Bubbling }; let phase = if capture { ListenerPhase::Capturing } else { ListenerPhase::Bubbling };
let old_entry = EventListenerEntry { let old_entry = EventListenerEntry {

View file

@ -607,7 +607,7 @@ impl VirtualMethods for HTMLInputElement {
s.handle_event(event); s.handle_event(event);
} }
if &*event.Type() == "click" && !event.DefaultPrevented() { if event.type_() == atom!("click") && !event.DefaultPrevented() {
match self.input_type.get() { match self.input_type.get() {
InputType::InputRadio => self.update_checked_state(true, true), InputType::InputRadio => self.update_checked_state(true, true),
_ => {} _ => {}
@ -619,7 +619,7 @@ impl VirtualMethods for HTMLInputElement {
//TODO: set the editing position for text inputs //TODO: set the editing position for text inputs
document_from_node(self).request_focus(self.upcast()); document_from_node(self).request_focus(self.upcast());
} else if &*event.Type() == "keydown" && !event.DefaultPrevented() && } else if event.type_() == atom!("keydown") && !event.DefaultPrevented() &&
(self.input_type.get() == InputType::InputText || (self.input_type.get() == InputType::InputText ||
self.input_type.get() == InputType::InputPassword) { self.input_type.get() == InputType::InputPassword) {
if let Some(keyevent) = event.downcast::<KeyboardEvent>() { if let Some(keyevent) = event.downcast::<KeyboardEvent>() {

View file

@ -323,11 +323,11 @@ impl VirtualMethods for HTMLTextAreaElement {
s.handle_event(event); s.handle_event(event);
} }
if &*event.Type() == "click" && !event.DefaultPrevented() { if event.type_() == atom!("click") && !event.DefaultPrevented() {
//TODO: set the editing position for text inputs //TODO: set the editing position for text inputs
document_from_node(self).request_focus(self.upcast()); document_from_node(self).request_focus(self.upcast());
} else if &*event.Type() == "keydown" && !event.DefaultPrevented() { } else if event.type_() == atom!("keydown") && !event.DefaultPrevented() {
if let Some(kevent) = event.downcast::<KeyboardEvent>() { if let Some(kevent) = event.downcast::<KeyboardEvent>() {
match self.textinput.borrow_mut().handle_keydown(kevent) { match self.textinput.borrow_mut().handle_keydown(kevent) {
KeyReaction::TriggerDefaultAction => (), KeyReaction::TriggerDefaultAction => (),