mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
parent
f3ca48206e
commit
50c832762f
5 changed files with 27 additions and 15 deletions
|
@ -525,7 +525,10 @@ fn inner_invoke(
|
|||
// Step 2.2.
|
||||
found = true;
|
||||
|
||||
// TODO: step 2.5.
|
||||
// Step 2.5.
|
||||
if let CompiledEventListener::Listener(event_listener) = listener {
|
||||
object.remove_listener_if_once(&event.type_(), &event_listener);
|
||||
}
|
||||
|
||||
// Step 2.6.
|
||||
let marker = TimelineMarker::start("DOMEvent".to_owned());
|
||||
|
|
|
@ -244,11 +244,18 @@ impl CompiledEventListener {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, DenyPublicFields, JSTraceable, MallocSizeOf, PartialEq)]
|
||||
#[derive(Clone, DenyPublicFields, JSTraceable, MallocSizeOf)]
|
||||
/// A listener in a collection of event listeners.
|
||||
struct EventListenerEntry {
|
||||
phase: ListenerPhase,
|
||||
listener: EventListenerType,
|
||||
once: bool,
|
||||
}
|
||||
|
||||
impl std::cmp::PartialEq for EventListenerEntry {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.phase == other.phase && self.listener == other.listener
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(JSTraceable, MallocSizeOf)]
|
||||
|
@ -401,12 +408,22 @@ impl EventTarget {
|
|||
entries.push(EventListenerEntry {
|
||||
phase: ListenerPhase::Bubbling,
|
||||
listener: EventListenerType::Inline(listener),
|
||||
once: false,
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove_listener_if_once(&self, ty: &Atom, listener: &Rc<EventListener>) {
|
||||
let mut handlers = self.handlers.borrow_mut();
|
||||
|
||||
let listener = EventListenerType::Additive(listener.clone());
|
||||
for entries in handlers.get_mut(ty) {
|
||||
entries.drain_filter(|e| e.listener == listener && e.once);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_inline_event_listener(&self, ty: &Atom) -> Option<CommonEventHandler> {
|
||||
let mut handlers = self.handlers.borrow_mut();
|
||||
handlers
|
||||
|
@ -662,6 +679,7 @@ impl EventTarget {
|
|||
let new_entry = EventListenerEntry {
|
||||
phase: phase,
|
||||
listener: EventListenerType::Additive(listener),
|
||||
once: options.once,
|
||||
};
|
||||
if !entry.contains(&new_entry) {
|
||||
entry.push(new_entry);
|
||||
|
@ -690,6 +708,7 @@ impl EventTarget {
|
|||
let old_entry = EventListenerEntry {
|
||||
phase: phase,
|
||||
listener: EventListenerType::Additive(listener.clone()),
|
||||
once: false,
|
||||
};
|
||||
if let Some(position) = entry.iter().position(|e| *e == old_entry) {
|
||||
entry.remove(position);
|
||||
|
@ -744,6 +763,7 @@ impl From<AddEventListenerOptionsOrBoolean> for AddEventListenerOptions {
|
|||
AddEventListenerOptionsOrBoolean::AddEventListenerOptions(options) => options,
|
||||
AddEventListenerOptionsOrBoolean::Boolean(capture) => Self {
|
||||
parent: EventListenerOptions { capture },
|
||||
once: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,6 +95,7 @@ impl MediaQueryListMethods for MediaQueryList {
|
|||
listener,
|
||||
AddEventListenerOptions {
|
||||
parent: EventListenerOptions { capture: false },
|
||||
once: false,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -29,5 +29,5 @@ dictionary EventListenerOptions {
|
|||
|
||||
dictionary AddEventListenerOptions : EventListenerOptions {
|
||||
// boolean passive = false;
|
||||
// boolean once = false;
|
||||
boolean once = false;
|
||||
};
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
[AddEventListenerOptions-once.html]
|
||||
type: testharness
|
||||
bug: https://github.com/servo/servo/issues/13242
|
||||
[Once listener should be invoked only once]
|
||||
expected: FAIL
|
||||
|
||||
[Once listener should be invoked only once even if the event is nested]
|
||||
expected: FAIL
|
||||
|
||||
[Once listener should be added / removed like normal listeners]
|
||||
expected: FAIL
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue