mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Add Event and EventTarget hierarchy via gross AbstractFoo mechanism.
This commit is contained in:
parent
7ecf5abbbd
commit
bb97fd13f3
9 changed files with 327 additions and 86 deletions
|
@ -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': {
|
||||
|
|
|
@ -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 +
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue