diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/script/dom/bindings/codegen/Bindings.conf | 13 | ||||
-rw-r--r-- | src/components/script/dom/bindings/codegen/CodegenRust.py | 16 | ||||
-rw-r--r-- | src/components/script/dom/bindings/utils.rs | 7 | ||||
-rw-r--r-- | src/components/script/dom/document.rs | 20 | ||||
-rw-r--r-- | src/components/script/dom/event.rs | 154 | ||||
-rw-r--r-- | src/components/script/dom/eventtarget.rs | 100 | ||||
-rw-r--r-- | src/components/script/dom/mouseevent.rs | 61 | ||||
-rw-r--r-- | src/components/script/dom/uievent.rs | 35 | ||||
-rw-r--r-- | src/test/html/content/test_event_listener.html | 7 |
9 files changed, 327 insertions, 86 deletions
diff --git a/src/components/script/dom/bindings/codegen/Bindings.conf b/src/components/script/dom/bindings/codegen/Bindings.conf index d1760f27901..6de264edc35 100644 --- a/src/components/script/dom/bindings/codegen/Bindings.conf +++ b/src/components/script/dom/bindings/codegen/Bindings.conf @@ -182,6 +182,9 @@ DOMInterfaces = { }, 'Event': { + 'nativeType': 'AbstractEvent', + 'concreteType': 'Event', + 'pointerType': '', }, 'EventListener': { @@ -189,6 +192,10 @@ DOMInterfaces = { }, 'EventTarget': { + 'nativeType': 'AbstractEventTarget', + 'concreteType': 'EventTarget', + 'pointerType': '', + 'needsAbstract': ['dispatchEvent'] }, 'FileList': [ @@ -277,6 +284,9 @@ DOMInterfaces = { }], 'MouseEvent': { + 'nativeType': 'AbstractEvent', + 'concreteType': 'MouseEvent', + 'pointerType': '', }, 'Navigator': { @@ -374,6 +384,9 @@ DOMInterfaces = { }], 'UIEvent': { + 'nativeType': 'AbstractEvent', + 'concreteType': 'UIEvent', + 'pointerType': '', }, 'ValidityState': { diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 8252135b0a5..b36f0ebd860 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -2410,12 +2410,13 @@ class Argument(): """ A class for outputting the type and name of an argument """ - def __init__(self, argType, name, default=None): + def __init__(self, argType, name, default=None, mutable=False): self.argType = argType self.name = name self.default = default + self.mutable = mutable def declare(self): - string = self.name + ((': ' + self.argType) if self.argType else '') + string = ('mut ' if self.mutable else '') + self.name + ((': ' + self.argType) if self.argType else '') #XXXjdm Support default arguments somehow :/ #if self.default is not None: # string += " = " + self.default @@ -5225,6 +5226,8 @@ class CGBindingRoot(CGThing): 'dom::bindings::proxyhandler::*', 'dom::document::AbstractDocument', 'dom::node::{AbstractNode, ScriptView}', + 'dom::eventtarget::AbstractEventTarget', + 'dom::event::AbstractEvent', 'servo_util::vec::zip_copies', 'std::cast', 'std::libc', @@ -5652,6 +5655,11 @@ class CGCallback(CGClass): # CallSetup should re-throw exceptions on aRv. args.append(Argument("ExceptionHandling", "aExceptionHandling", "eReportExceptions")) + + # Ensure the first argument is mutable + args[0] = Argument(args[0].argType, args[0].name, args[0].default, mutable=True) + method.args[2] = args[0] + # And now insert our template argument. argsWithoutThis = list(args) args.insert(0, Argument("@mut T", "thisObj")) @@ -5661,7 +5669,7 @@ class CGCallback(CGClass): args.insert(0, Argument(None, "&self")) argsWithoutThis.insert(0, Argument(None, "&self")) - setupCall = ("let s = CallSetup::new(cx_for_dom_object(${cxProvider}), aExceptionHandling);\n" + setupCall = ("let s = CallSetup::new(cx_for_dom_object(&mut ${cxProvider}), aExceptionHandling);\n" "if s.GetContext().is_null() {\n" " return${errorReturn};\n" "}\n") @@ -5676,7 +5684,7 @@ class CGCallback(CGClass): "errorReturn" : method.getDefaultRetval(), "callArgs" : ", ".join(argnamesWithThis), "methodName": 'self.' + method.name, - "cxProvider": 'thisObj' + "cxProvider": '*thisObj' }) bodyWithoutThis = string.Template( setupCall + diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index 8e8200fb18e..32639d706e7 100644 --- a/src/components/script/dom/bindings/utils.rs +++ b/src/components/script/dom/bindings/utils.rs @@ -768,6 +768,7 @@ pub enum Error { NotFound, HierarchyRequest, InvalidCharacter, + NotSupported } pub type Fallible<T> = Result<T, Error>; @@ -841,7 +842,7 @@ pub fn CreateDOMGlobal(cx: *JSContext, class: *JSClass) -> *JSObject { } #[fixed_stack_segment] -fn cx_for_dom_wrapper(obj: *JSObject) -> *JSContext { +fn cx_for_dom_reflector(obj: *JSObject) -> *JSContext { unsafe { let global = GetGlobalForObjectCrossCompartment(obj); let clasp = JS_GetClass(global); @@ -860,8 +861,8 @@ fn cx_for_dom_wrapper(obj: *JSObject) -> *JSContext { } } -pub fn cx_for_dom_object<T: Reflectable>(obj: @mut T) -> *JSContext { - cx_for_dom_wrapper(obj.reflector().get_jsobject()) +pub fn cx_for_dom_object<T: Reflectable>(obj: &mut T) -> *JSContext { + cx_for_dom_reflector(obj.reflector().get_jsobject()) } /// Check if an element name is valid. See http://www.w3.org/TR/xml/#NT-Name diff --git a/src/components/script/dom/document.rs b/src/components/script/dom/document.rs index 72f0c378a95..ffea5809fda 100644 --- a/src/components/script/dom/document.rs +++ b/src/components/script/dom/document.rs @@ -5,16 +5,20 @@ use dom::comment::Comment; use dom::bindings::codegen::DocumentBinding; use dom::bindings::utils::{DOMString, ErrorResult, Fallible}; -use dom::bindings::utils::{Reflectable, Reflector, DerivedWrapper}; -use dom::bindings::utils::{is_valid_element_name, InvalidCharacter, Traceable, null_str_as_empty, null_str_as_word_null}; +use dom::bindings::utils::{Reflectable, Reflector, DerivedWrapper, NotSupported}; +use dom::bindings::utils::{is_valid_element_name, InvalidCharacter, Traceable}; +use dom::bindings::utils::{null_str_as_empty_ref, null_str_as_empty, null_str_as_word_null}; use dom::documentfragment::DocumentFragment; use dom::element::{Element}; use dom::element::{HTMLHeadElementTypeId, HTMLTitleElementTypeId}; -use dom::event::Event; +use dom::event::{AbstractEvent, Event, HTMLEventTypeId, UIEventTypeId}; use dom::htmlcollection::HTMLCollection; use dom::htmldocument::HTMLDocument; +use dom::htmlelement::HTMLElement; +use dom::mouseevent::MouseEvent; use dom::node::{AbstractNode, ScriptView, Node, ElementNodeTypeId, DocumentNodeTypeId}; use dom::text::Text; +use dom::uievent::UIEvent; use dom::window::Window; use dom::htmltitleelement::HTMLTitleElement; use html::hubbub_html_parser::build_element_from_tag; @@ -256,9 +260,13 @@ impl Document { Comment::new(null_str_as_word_null(data), abstract_self) } - pub fn CreateEvent(&self, interface: &DOMString) -> Fallible<@mut Event> { - //FIXME: We need to do a proper Event inheritance simulation - Ok(Event::new(self.window, interface)) + pub fn CreateEvent(&self, interface: &DOMString) -> Fallible<AbstractEvent> { + match null_str_as_empty_ref(interface) { + "UIEvents" => Ok(UIEvent::new(self.window, UIEventTypeId)), + "MouseEvents" => Ok(MouseEvent::new(self.window)), + "HTMLEvents" => Ok(Event::new(self.window, HTMLEventTypeId)), + _ => Err(NotSupported) + } } pub fn Title(&self, _: AbstractDocument) -> DOMString { diff --git a/src/components/script/dom/event.rs b/src/components/script/dom/event.rs index 1fd709f2dfe..b8ff54f5755 100644 --- a/src/components/script/dom/event.rs +++ b/src/components/script/dom/event.rs @@ -2,17 +2,23 @@ * 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 dom::eventtarget::EventTarget; +use dom::eventtarget::AbstractEventTarget; use dom::window::Window; use dom::bindings::codegen::EventBinding; -use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; +use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object, DerivedWrapper}; use dom::bindings::utils::{DOMString, ErrorResult, Fallible, null_str_as_word_null}; +use dom::mouseevent::MouseEvent; +use dom::uievent::UIEvent; use geom::point::Point2D; -use js::jsapi::{JSObject, JSContext}; +use js::jsapi::{JSObject, JSContext, JSVal}; +use js::glue::RUST_OBJECT_TO_JSVAL; use script_task::page_from_context; +use std::cast; +use std::unstable::raw::Box; + pub enum Event_ { ResizeEvent(uint, uint), ReflowEvent, @@ -21,7 +27,116 @@ pub enum Event_ { MouseUpEvent(uint, Point2D<f32>), } +pub struct AbstractEvent { + event: *mut Box<Event> +} + +impl AbstractEvent { + pub fn from_box(box: *mut Box<Event>) -> AbstractEvent { + AbstractEvent { + event: box + } + } + + // + // Downcasting borrows + // + + fn transmute<'a, T>(&'a self) -> &'a T { + unsafe { + let box: *Box<T> = self.event as *Box<T>; + &(*box).data + } + } + + fn transmute_mut<'a, T>(&'a self) -> &'a mut T { + unsafe { + let box: *mut Box<T> = self.event as *mut Box<T>; + &mut (*box).data + } + } + + pub fn type_id(&self) -> EventTypeId { + self.event().type_id + } + + pub fn event<'a>(&'a self) -> &'a Event { + self.transmute() + } + + pub fn mut_event<'a>(&'a self) -> &'a mut Event { + self.transmute_mut() + } + + pub fn is_uievent(&self) -> bool { + self.type_id() == UIEventTypeId + } + + pub fn uievent<'a>(&'a self) -> &'a UIEvent { + assert!(self.is_uievent()); + self.transmute() + } + + pub fn mut_uievent<'a>(&'a self) -> &'a mut UIEvent { + assert!(self.is_uievent()); + self.transmute_mut() + } + + pub fn is_mouseevent(&self) -> bool { + self.type_id() == MouseEventTypeId + } + + pub fn mouseevent<'a>(&'a self) -> &'a MouseEvent { + assert!(self.is_mouseevent()); + self.transmute() + } + + pub fn mut_mouseevent<'a>(&'a self) -> &'a mut MouseEvent { + assert!(self.is_mouseevent()); + self.transmute_mut() + } +} + +impl DerivedWrapper for AbstractEvent { + #[fixed_stack_segment] + fn wrap(&mut self, _cx: *JSContext, _scope: *JSObject, vp: *mut JSVal) -> i32 { + let wrapper = self.reflector().get_jsobject(); + if wrapper.is_not_null() { + unsafe { *vp = RUST_OBJECT_TO_JSVAL(wrapper) }; + return 1; + } + unreachable!() + } +} + +impl Reflectable for AbstractEvent { + fn reflector<'a>(&'a self) -> &'a Reflector { + self.event().reflector() + } + + fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector { + self.mut_event().mut_reflector() + } + + fn wrap_object_shared(@mut self, _cx: *JSContext, _scope: *JSObject) -> *JSObject { + fail!(~"doesn't make any sense"); + } + + fn GetParentObject(&self, cx: *JSContext) -> Option<@mut Reflectable> { + self.event().GetParentObject(cx) + } +} + +#[deriving(Eq)] +pub enum EventTypeId { + HTMLEventTypeId, + UIEventTypeId, + MouseEventTypeId, + KeyEventTypeId +} + pub struct Event { + type_id: EventTypeId, reflector_: Reflector, type_: ~str, default_prevented: bool, @@ -31,10 +146,11 @@ pub struct Event { } impl Event { - pub fn new_inherited(type_: &DOMString) -> Event { + pub fn new_inherited(type_id: EventTypeId) -> Event { Event { + type_id: type_id, reflector_: Reflector::new(), - type_: null_str_as_word_null(type_), + type_: ~"", default_prevented: false, cancelable: true, bubbles: true, @@ -42,8 +158,18 @@ impl Event { } } - pub fn new(window: @mut Window, type_: &DOMString) -> @mut Event { - reflect_dom_object(@mut Event::new_inherited(type_), window, EventBinding::Wrap) + //FIXME: E should be bounded by some trait that is only implemented for Event types + pub fn as_abstract<E>(event: @mut E) -> AbstractEvent { + // This surrenders memory management of the event! + AbstractEvent { + event: unsafe { cast::transmute(event) }, + } + } + + pub fn new(window: @mut Window, type_id: EventTypeId) -> AbstractEvent { + let ev = reflect_dom_object(@mut Event::new_inherited(type_id), window, + EventBinding::Wrap); + Event::as_abstract(ev) } pub fn EventPhase(&self) -> u16 { @@ -54,11 +180,11 @@ impl Event { Some(self.type_.clone()) } - pub fn GetTarget(&self) -> Option<@mut EventTarget> { + pub fn GetTarget(&self) -> Option<AbstractEventTarget> { None } - pub fn GetCurrentTarget(&self) -> Option<@mut EventTarget> { + pub fn GetCurrentTarget(&self) -> Option<AbstractEventTarget> { None } @@ -92,7 +218,7 @@ impl Event { type_: &DOMString, bubbles: bool, cancelable: bool) -> ErrorResult { - self.type_ = type_.to_str(); + self.type_ = null_str_as_word_null(type_); self.cancelable = cancelable; self.bubbles = bubbles; Ok(()) @@ -103,9 +229,11 @@ impl Event { } pub fn Constructor(global: @mut Window, - type_: &DOMString, - _init: &EventBinding::EventInit) -> Fallible<@mut Event> { - Ok(Event::new(global, type_)) + type_: &DOMString, + init: &EventBinding::EventInit) -> Fallible<AbstractEvent> { + let ev = Event::new(global, HTMLEventTypeId); + ev.mut_event().InitEvent(type_, init.bubbles, init.cancelable); + Ok(ev) } } diff --git a/src/components/script/dom/eventtarget.rs b/src/components/script/dom/eventtarget.rs index 834c1db767c..4a33b1eba2d 100644 --- a/src/components/script/dom/eventtarget.rs +++ b/src/components/script/dom/eventtarget.rs @@ -4,14 +4,19 @@ use dom::bindings::callback::eReportExceptions; use dom::bindings::codegen::EventTargetBinding; -use dom::bindings::utils::{Reflectable, Reflector, DOMString, Fallible}; +use dom::bindings::utils::{Reflectable, Reflector, DOMString, Fallible, DerivedWrapper}; +use dom::bindings::utils::null_str_as_word_null; use dom::bindings::codegen::EventListenerBinding::EventListener; -use dom::event::Event; +use dom::event::AbstractEvent; +use dom::node::{AbstractNode, ScriptView}; use script_task::page_from_context; -use js::jsapi::{JSObject, JSContext}; +use js::jsapi::{JSObject, JSContext, JSVal}; +use js::glue::RUST_OBJECT_TO_JSVAL; +use std::cast; use std::hashmap::HashMap; +use std::unstable::raw::Box; pub struct EventTarget { reflector_: Reflector, @@ -19,6 +24,80 @@ pub struct EventTarget { bubbling_handlers: HashMap<~str, ~[EventListener]> } +pub struct AbstractEventTarget { + eventtarget: *mut Box<EventTarget> +} + +impl AbstractEventTarget { + pub fn from_box(box: *mut Box<EventTarget>) -> AbstractEventTarget { + AbstractEventTarget { + eventtarget: box + } + } + + pub fn from_node(node: AbstractNode<ScriptView>) -> AbstractEventTarget { + unsafe { + cast::transmute(node) + } + } + + // + // Downcasting borrows + // + + fn transmute<'a, T>(&'a self) -> &'a T { + unsafe { + let box: *Box<T> = self.eventtarget as *Box<T>; + &(*box).data + } + } + + fn transmute_mut<'a, T>(&'a mut self) -> &'a mut T { + unsafe { + let box: *mut Box<T> = self.eventtarget as *mut Box<T>; + &mut (*box).data + } + } + + fn eventtarget<'a>(&'a self) -> &'a EventTarget { + self.transmute() + } + + fn mut_eventtarget<'a>(&'a mut self) -> &'a mut EventTarget { + self.transmute_mut() + } +} + +impl DerivedWrapper for AbstractEventTarget { + #[fixed_stack_segment] + fn wrap(&mut self, _cx: *JSContext, _scope: *JSObject, vp: *mut JSVal) -> i32 { + let wrapper = self.reflector().get_jsobject(); + if wrapper.is_not_null() { + unsafe { *vp = RUST_OBJECT_TO_JSVAL(wrapper) }; + return 1; + } + unreachable!() + } +} + +impl Reflectable for AbstractEventTarget { + fn reflector<'a>(&'a self) -> &'a Reflector { + self.eventtarget().reflector() + } + + fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector { + self.mut_eventtarget().mut_reflector() + } + + fn wrap_object_shared(@mut self, _cx: *JSContext, _scope: *JSObject) -> *JSObject { + unreachable!() + } + + fn GetParentObject(&self, cx: *JSContext) -> Option<@mut Reflectable> { + self.eventtarget().GetParentObject(cx) + } +} + impl EventTarget { pub fn new() -> EventTarget { EventTarget { @@ -46,7 +125,7 @@ impl EventTarget { } else { &mut self.bubbling_handlers }; - let entry = handlers.find_or_insert_with(ty.to_str(), |_| ~[]); + let entry = handlers.find_or_insert_with(null_str_as_word_null(ty), |_| ~[]); if entry.position_elem(listener).is_none() { entry.push((*listener).clone()); } @@ -63,7 +142,7 @@ impl EventTarget { } else { &mut self.bubbling_handlers }; - let mut entry = handlers.find_mut(&ty.to_str()); + let mut entry = handlers.find_mut(&null_str_as_word_null(ty)); for entry in entry.mut_iter() { let position = entry.position_elem(listener); for &position in position.iter() { @@ -73,24 +152,25 @@ impl EventTarget { } } - pub fn DispatchEvent(&self, event: @mut Event) -> Fallible<bool> { + pub fn DispatchEvent(&self, _abstract_self: AbstractEventTarget, event: AbstractEvent) -> Fallible<bool> { //FIXME: get proper |this| object - let maybe_handlers = self.capturing_handlers.find(&event.type_); + let type_ = event.event().type_.clone(); + let maybe_handlers = self.capturing_handlers.find(&type_); for handlers in maybe_handlers.iter() { for handler in handlers.iter() { handler.HandleEvent__(event, eReportExceptions); } } - if event.bubbles { - let maybe_handlers = self.bubbling_handlers.find(&event.type_); + if event.event().bubbles { + let maybe_handlers = self.bubbling_handlers.find(&type_); for handlers in maybe_handlers.iter() { for handler in handlers.iter() { handler.HandleEvent__(event, eReportExceptions); } } } - Ok(!event.DefaultPrevented()) + Ok(!event.event().DefaultPrevented()) } } diff --git a/src/components/script/dom/mouseevent.rs b/src/components/script/dom/mouseevent.rs index 70862d91904..e33bd485932 100644 --- a/src/components/script/dom/mouseevent.rs +++ b/src/components/script/dom/mouseevent.rs @@ -5,7 +5,8 @@ use dom::bindings::codegen::MouseEventBinding; use dom::bindings::utils::{ErrorResult, Fallible, DOMString}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; -use dom::eventtarget::EventTarget; +use dom::event::{AbstractEvent, Event, MouseEventTypeId}; +use dom::eventtarget::AbstractEventTarget; use dom::uievent::UIEvent; use dom::window::Window; use dom::windowproxy::WindowProxy; @@ -23,38 +24,42 @@ pub struct MouseEvent { alt_key: bool, meta_key: bool, button: u16, - related_target: Option<@mut EventTarget> + related_target: Option<AbstractEventTarget> } impl MouseEvent { - pub fn new(window: @mut Window, type_: &DOMString, can_bubble: bool, cancelable: bool, - view: Option<@mut WindowProxy>, detail: i32, screen_x: i32, - screen_y: i32, client_x: i32, client_y: i32, ctrl_key: bool, - shift_key: bool, alt_key: bool, meta_key: bool, button: u16, - _buttons: u16, related_target: Option<@mut EventTarget>) -> @mut MouseEvent { - let ev = @mut MouseEvent { - parent: UIEvent::new_inherited(type_, can_bubble, cancelable, view, detail), - screen_x: screen_x, - screen_y: screen_y, - client_x: client_x, - client_y: client_y, - ctrl_key: ctrl_key, - shift_key: shift_key, - alt_key: alt_key, - meta_key: meta_key, - button: button, - related_target: related_target - }; - reflect_dom_object(ev, window, MouseEventBinding::Wrap) + pub fn new_inherited() -> MouseEvent { + MouseEvent { + parent: UIEvent::new_inherited(MouseEventTypeId), + screen_x: 0, + screen_y: 0, + client_x: 0, + client_y: 0, + ctrl_key: false, + shift_key: false, + alt_key: false, + meta_key: false, + button: 0, + related_target: None + } + } + + pub fn new(window: @mut Window) -> AbstractEvent { + Event::as_abstract(reflect_dom_object(@mut MouseEvent::new_inherited(), + window, + MouseEventBinding::Wrap)) } pub fn Constructor(owner: @mut Window, type_: &DOMString, - init: &MouseEventBinding::MouseEventInit) -> Fallible<@mut MouseEvent> { - Ok(MouseEvent::new(owner, type_, init.bubbles, init.cancelable, init.view, init.detail, - init.screenX, init.screenY, init.clientX, init.clientY, - init.ctrlKey, init.shiftKey, init.altKey, init.metaKey, - init.button, init.buttons, init.relatedTarget)) + init: &MouseEventBinding::MouseEventInit) -> Fallible<AbstractEvent> { + let ev = MouseEvent::new(owner); + ev.mut_mouseevent().InitMouseEvent(type_, init.bubbles, init.cancelable, init.view, + init.detail, init.screenX, init.screenY, + init.clientX, init.clientY, init.ctrlKey, + init.altKey, init.shiftKey, init.metaKey, + init.button, init.relatedTarget); + Ok(ev) } pub fn ScreenX(&self) -> i32 { @@ -98,7 +103,7 @@ impl MouseEvent { 0 } - pub fn GetRelatedTarget(&self) -> Option<@mut EventTarget> { + pub fn GetRelatedTarget(&self) -> Option<AbstractEventTarget> { self.related_target } @@ -122,7 +127,7 @@ impl MouseEvent { shiftKeyArg: bool, metaKeyArg: bool, buttonArg: u16, - relatedTargetArg: Option<@mut EventTarget>) -> ErrorResult { + relatedTargetArg: Option<AbstractEventTarget>) -> ErrorResult { self.parent.InitUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, detailArg); self.screen_x = screenXArg; self.screen_y = screenYArg; diff --git a/src/components/script/dom/uievent.rs b/src/components/script/dom/uievent.rs index 8871ccafd92..86f84cf25b5 100644 --- a/src/components/script/dom/uievent.rs +++ b/src/components/script/dom/uievent.rs @@ -6,7 +6,7 @@ use dom::bindings::codegen::UIEventBinding; use dom::bindings::utils::{DOMString, Fallible}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::node::{AbstractNode, ScriptView}; -use dom::event::Event; +use dom::event::{AbstractEvent, Event, EventTypeId, UIEventTypeId}; use dom::window::Window; use dom::windowproxy::WindowProxy; @@ -14,36 +14,33 @@ use js::jsapi::{JSObject, JSContext}; pub struct UIEvent { parent: Event, - can_bubble: bool, - cancelable: bool, view: Option<@mut WindowProxy>, detail: i32 } impl UIEvent { - pub fn new_inherited(type_: &DOMString, can_bubble: bool, cancelable: bool, - view: Option<@mut WindowProxy>, detail: i32) -> UIEvent { + pub fn new_inherited(type_id: EventTypeId) -> UIEvent { UIEvent { - parent: Event::new_inherited(type_), - can_bubble: can_bubble, - cancelable: cancelable, - view: view, - detail: detail + parent: Event::new_inherited(type_id), + view: None, + detail: 0 } } - pub fn new(window: @mut Window, type_: &DOMString, can_bubble: bool, cancelable: bool, - view: Option<@mut WindowProxy>, detail: i32) -> @mut UIEvent { - reflect_dom_object(@mut UIEvent::new_inherited(type_, can_bubble, cancelable, view, detail), - window, - UIEventBinding::Wrap) + pub fn new(window: @mut Window, type_id: EventTypeId) -> AbstractEvent { + let ev = reflect_dom_object(@mut UIEvent::new_inherited(type_id), + window, + UIEventBinding::Wrap); + Event::as_abstract(ev) } pub fn Constructor(owner: @mut Window, type_: &DOMString, - init: &UIEventBinding::UIEventInit) -> Fallible<@mut UIEvent> { - Ok(UIEvent::new(owner, type_, init.parent.bubbles, init.parent.cancelable, - init.view, init.detail)) + init: &UIEventBinding::UIEventInit) -> Fallible<AbstractEvent> { + let ev = UIEvent::new(owner, UIEventTypeId); + ev.mut_uievent().InitUIEvent(type_, init.parent.bubbles, init.parent.cancelable, + init.view, init.detail); + Ok(ev) } pub fn GetView(&self) -> Option<@mut WindowProxy> { @@ -61,8 +58,6 @@ impl UIEvent { view: Option<@mut WindowProxy>, detail: i32) { self.parent.InitEvent(type_, can_bubble, cancelable); - self.can_bubble = can_bubble; - self.cancelable = cancelable; self.view = view; self.detail = detail; } diff --git a/src/test/html/content/test_event_listener.html b/src/test/html/content/test_event_listener.html index 5feeda8a374..414f8e8a156 100644 --- a/src/test/html/content/test_event_listener.html +++ b/src/test/html/content/test_event_listener.html @@ -4,14 +4,17 @@ </head> <body> <script> + var saw_event = false; function onFoopy() { window.removeEventListener('foopy', onFoopy); - finish(); + saw_event = true; } window.addEventListener('foopy', onFoopy); - var ev = document.createEvent('Event'); + var ev = document.createEvent('HTMLEvents'); ev.initEvent('foopy', true, true); window.dispatchEvent(ev); + is(saw_event, true); + finish(); </script> </body> </html> |