script: Clear all associated event listeners when removing an event listener content attribute. (#39011)

This change allows callers of `remove_event_listener` to specify `None`
for the `options` argument to skip phase (bubble/capture) checking (and
remove either type of listener).

Notably, this changes the HTMLElement `attribute_mutated` code to remove
all event listeners rather than ones with just `capture: false`, which
should be [correct
behavior](https://html.spec.whatwg.org/multipage/webappapis.html#deactivate-an-event-handler).

Testing: `mach try linux-wpt`:
https://github.com/kotx/servo/actions/runs/17313405730
Fixes: https://github.com/servo/servo/issues/38742

---------

Signed-off-by: Kot <kot@kot.pink>
This commit is contained in:
Kot 2025-08-29 22:38:32 -07:00 committed by GitHub
parent 4a4a615eb7
commit 2e1b2e7260
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 5 additions and 17 deletions

View file

@ -1000,14 +1000,10 @@ impl EventTarget {
} else { } else {
ListenerPhase::Bubbling ListenerPhase::Bubbling
}; };
let old_entry = Rc::new(RefCell::new(EventListenerEntry { if let Some(position) = entries.iter().position(|e| {
phase, e.borrow().listener == EventListenerType::Additive(listener.clone()) &&
listener: EventListenerType::Additive(listener.clone()), e.borrow().phase == phase
once: false, }) {
passive: None,
removed: false,
}));
if let Some(position) = entries.iter().position(|e| *e == old_entry) {
entries.remove(position).borrow_mut().removed = true; entries.remove(position).borrow_mut().removed = true;
} }
} }

View file

@ -20,7 +20,6 @@ use crate::dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterData
use crate::dom::bindings::codegen::Bindings::EventHandlerBinding::{ use crate::dom::bindings::codegen::Bindings::EventHandlerBinding::{
EventHandlerNonNull, OnErrorEventHandlerNonNull, EventHandlerNonNull, OnErrorEventHandlerNonNull,
}; };
use crate::dom::bindings::codegen::Bindings::EventTargetBinding::EventListenerOptions;
use crate::dom::bindings::codegen::Bindings::HTMLElementBinding::HTMLElementMethods; use crate::dom::bindings::codegen::Bindings::HTMLElementBinding::HTMLElementMethods;
use crate::dom::bindings::codegen::Bindings::HTMLLabelElementBinding::HTMLLabelElementMethods; use crate::dom::bindings::codegen::Bindings::HTMLLabelElementBinding::HTMLLabelElementMethods;
use crate::dom::bindings::codegen::Bindings::HTMLOrSVGElementBinding::FocusOptions; use crate::dom::bindings::codegen::Bindings::HTMLOrSVGElementBinding::FocusOptions;
@ -1132,11 +1131,7 @@ impl VirtualMethods for HTMLElement {
}, },
// https://html.spec.whatwg.org/multipage/#deactivate-an-event-handler // https://html.spec.whatwg.org/multipage/#deactivate-an-event-handler
AttributeMutation::Removed => { AttributeMutation::Removed => {
evtarget.remove_event_listener( evtarget.set_event_handler_common::<EventHandlerNonNull>(event_name, None);
event_name.into(),
evtarget.get_event_handler_common(event_name, can_gc),
EventListenerOptions { capture: false },
);
}, },
} }
}, },

View file

@ -1,3 +0,0 @@
[event-handler-removal.window.html]
[Event handler set through content attribute should be deactivated when the content attribute is removed.]
expected: FAIL