Skip to content

Commit

Permalink
Implement EventListenerOptions for EventTarget
Browse files Browse the repository at this point in the history
For now, only "capture" is supported.
  • Loading branch information
GuillaumeGomez authored and nox committed Sep 30, 2017
1 parent 8732f6d commit 3d0b7fb
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 41 deletions.
3 changes: 1 addition & 2 deletions components/script/dom/bindings/codegen/CodegenRust.py
Expand Up @@ -6142,8 +6142,7 @@ def memberInsert(memberInfo):
" } else if val.get().is_object() {\n"
" val.get().to_object()\n"
" } else {\n"
" throw_type_error(cx, \"Value not an object.\");\n"
" return Err(());\n"
" return Ok(ConversionResult::Failure(\"Value is not an object.\".into()));\n"
" };\n"
" rooted!(in(cx) let object = object);\n"
"${preInitial}"
Expand Down
87 changes: 74 additions & 13 deletions components/script/dom/eventtarget.rs
Expand Up @@ -12,8 +12,12 @@ use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::EventHandlerBinding::OnBeforeUnloadEventHandlerNonNull;
use dom::bindings::codegen::Bindings::EventHandlerBinding::OnErrorEventHandlerNonNull;
use dom::bindings::codegen::Bindings::EventListenerBinding::EventListener;
use dom::bindings::codegen::Bindings::EventTargetBinding::AddEventListenerOptions;
use dom::bindings::codegen::Bindings::EventTargetBinding::EventListenerOptions;
use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::codegen::UnionTypes::AddEventListenerOptionsOrBoolean;
use dom::bindings::codegen::UnionTypes::EventListenerOptionsOrBoolean;
use dom::bindings::codegen::UnionTypes::EventOrString;
use dom::bindings::error::{Error, Fallible, report_pending_exception};
use dom::bindings::inheritance::Castable;
Expand Down Expand Up @@ -543,14 +547,13 @@ impl EventTarget {
event.fire(self);
event
}
}

impl EventTargetMethods for EventTarget {
// https://dom.spec.whatwg.org/#dom-eventtarget-addeventlistener
fn AddEventListener(&self,
ty: DOMString,
listener: Option<Rc<EventListener>>,
capture: bool) {
pub fn add_event_listener(
&self,
ty: DOMString,
listener: Option<Rc<EventListener>>,
options: AddEventListenerOptions,
) {
let listener = match listener {
Some(l) => l,
None => return,
Expand All @@ -561,7 +564,11 @@ impl EventTargetMethods for EventTarget {
Vacant(entry) => entry.insert(EventListeners(vec!())),
};

let phase = if capture { ListenerPhase::Capturing } else { ListenerPhase::Bubbling };
let phase = if options.parent.capture {
ListenerPhase::Capturing
} else {
ListenerPhase::Bubbling
};
let new_entry = EventListenerEntry {
phase: phase,
listener: EventListenerType::Additive(listener)
Expand All @@ -572,18 +579,24 @@ impl EventTargetMethods for EventTarget {
}

// https://dom.spec.whatwg.org/#dom-eventtarget-removeeventlistener
fn RemoveEventListener(&self,
ty: DOMString,
listener: Option<Rc<EventListener>>,
capture: bool) {
pub fn remove_event_listener(
&self,
ty: DOMString,
listener: Option<Rc<EventListener>>,
options: EventListenerOptions,
) {
let ref listener = match listener {
Some(l) => l,
None => return,
};
let mut handlers = self.handlers.borrow_mut();
let entry = handlers.get_mut(&Atom::from(ty));
for entry in entry {
let phase = if capture { ListenerPhase::Capturing } else { ListenerPhase::Bubbling };
let phase = if options.capture {
ListenerPhase::Capturing
} else {
ListenerPhase::Bubbling
};
let old_entry = EventListenerEntry {
phase: phase,
listener: EventListenerType::Additive(listener.clone())
Expand All @@ -593,6 +606,28 @@ impl EventTargetMethods for EventTarget {
}
}
}
}

impl EventTargetMethods for EventTarget {
// https://dom.spec.whatwg.org/#dom-eventtarget-addeventlistener
fn AddEventListener(
&self,
ty: DOMString,
listener: Option<Rc<EventListener>>,
options: AddEventListenerOptionsOrBoolean,
) {
self.add_event_listener(ty, listener, options.into())
}

// https://dom.spec.whatwg.org/#dom-eventtarget-removeeventlistener
fn RemoveEventListener(
&self,
ty: DOMString,
listener: Option<Rc<EventListener>>,
options: EventListenerOptionsOrBoolean,
) {
self.remove_event_listener(ty, listener, options.into())
}

// https://dom.spec.whatwg.org/#dom-eventtarget-dispatchevent
fn DispatchEvent(&self, event: &Event) -> Fallible<bool> {
Expand All @@ -612,3 +647,29 @@ impl VirtualMethods for EventTarget {
None
}
}

impl From<AddEventListenerOptionsOrBoolean> for AddEventListenerOptions {
fn from(options: AddEventListenerOptionsOrBoolean) -> Self {
match options {
AddEventListenerOptionsOrBoolean::AddEventListenerOptions(options) => {
options
},
AddEventListenerOptionsOrBoolean::Boolean(capture) => {
Self { parent: EventListenerOptions { capture } }
},
}
}
}

impl From<EventListenerOptionsOrBoolean> for EventListenerOptions {
fn from(options: EventListenerOptionsOrBoolean) -> Self {
match options {
EventListenerOptionsOrBoolean::EventListenerOptions(options) => {
options
},
EventListenerOptionsOrBoolean::Boolean(capture) => {
Self { capture }
},
}
}
}
17 changes: 12 additions & 5 deletions components/script/dom/mediaquerylist.rs
Expand Up @@ -4,7 +4,8 @@

use dom::bindings::cell::DomRefCell;
use dom::bindings::codegen::Bindings::EventListenerBinding::EventListener;
use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
use dom::bindings::codegen::Bindings::EventTargetBinding::AddEventListenerOptions;
use dom::bindings::codegen::Bindings::EventTargetBinding::EventListenerOptions;
use dom::bindings::codegen::Bindings::MediaQueryListBinding::{self, MediaQueryListMethods};
use dom::bindings::inheritance::Castable;
use dom::bindings::reflector::DomObject;
Expand Down Expand Up @@ -97,14 +98,20 @@ impl MediaQueryListMethods for MediaQueryList {

// https://drafts.csswg.org/cssom-view/#dom-mediaquerylist-addlistener
fn AddListener(&self, listener: Option<Rc<EventListener>>) {
self.upcast::<EventTarget>().AddEventListener(DOMString::from_string("change".to_owned()),
listener, false);
self.upcast::<EventTarget>().add_event_listener(
DOMString::from_string("change".to_owned()),
listener,
AddEventListenerOptions { parent: EventListenerOptions { capture: false } },
);
}

// https://drafts.csswg.org/cssom-view/#dom-mediaquerylist-removelistener
fn RemoveListener(&self, listener: Option<Rc<EventListener>>) {
self.upcast::<EventTarget>().RemoveEventListener(DOMString::from_string("change".to_owned()),
listener, false);
self.upcast::<EventTarget>().remove_event_listener(
DOMString::from_string("change".to_owned()),
listener,
EventListenerOptions { capture: false },
);
}

// https://drafts.csswg.org/cssom-view/#dom-mediaquerylist-onchange
Expand Down
27 changes: 21 additions & 6 deletions components/script/dom/webidls/EventTarget.webidl
Expand Up @@ -7,12 +7,27 @@

[Abstract, Exposed=(Window,Worker,Worklet)]
interface EventTarget {
void addEventListener(DOMString type,
EventListener? listener,
optional boolean capture = false);
void removeEventListener(DOMString type,
EventListener? listener,
optional boolean capture = false);
void addEventListener(
DOMString type,
EventListener? callback,
optional (AddEventListenerOptions or boolean) options
);

void removeEventListener(
DOMString type,
EventListener? callback,
optional (EventListenerOptions or boolean) options
);

[Throws]
boolean dispatchEvent(Event event);
};

dictionary EventListenerOptions {
boolean capture = false;
};

dictionary AddEventListenerOptions : EventListenerOptions {
// boolean passive = false;
// boolean once = false;
};
Expand Up @@ -11,6 +11,3 @@
[passive behavior of one listener should be unaffeted by the presence of other listeners]
expected: FAIL

[Equivalence of option values]
expected: FAIL

This file was deleted.

0 comments on commit 3d0b7fb

Please sign in to comment.