Open Bug 890505 Opened 13 years ago Updated 3 years ago

The capability of listing event listeners on an element in order to be able to unbind them

Categories

(Core :: DOM: Events, defect, P5)

22 Branch
defect

Tracking

()

UNCONFIRMED

People

(Reporter: laszlo, Unassigned)

Details

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1502.0 Safari/537.36 Steps to reproduce: This is more like a design flaw, related to https://bugzilla.mozilla.org/show_bug.cgi?id=890504 . I tried to unbind all beforeunload events on all browser's document object, to avoid the confirm dialog when force-quitting firefox. I created a small addon code which lists all the <browser> and <xul:browser> elements under <tabbrowser>, and tries to unbind all beforeupload event handlers. Actual results: The events which were bound by specifying window.onbeforeunload, could be unbound. The ones which were added by document.addEventListener, could not be unbound, because according to https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIEventListenerService, the event listeners bound to a given element cannot be listed! Expected results: I think this is a serious design flaw, which should be resolved by adding a getEventListeners function call to nsIEventListenerService, or extending the return value of getListenerInfoFor with an array of nsIDOMEventListener instances, which later can be passed as a parameter for removeSystemEventListener.
OS: Mac OS X → All
Hardware: x86 → All
Summary: The capability to list event listeners on an element on order to be able to unbind them → The capability of listing event listeners on an element in order to be able to unbind them
Component: Untriaged → DOM: Events
Product: Firefox → Core
I've noticed that firebug does have a getEventListeners function, and if I'm not mistaken it's driven by the old JSD API... Do you know by any chance what are the plans for this post JSD? Does the new Debugger give some similar support, or do we plan to support this in some other way?
Flags: needinfo?(odvarko)
Do you know about any other request for an API like this / do you know about any solution we have or plan to have for this?
Flags: needinfo?(bugs)
FWIW I strongly oppose exposing this capability to the web. I don't see a problem with providing it internally though.
(In reply to Kyle Huey [:khuey] (khuey@mozilla.com) from comment #3) > FWIW I strongly oppose exposing this capability to the web. I don't see a > problem with providing it internally though. Absolutely. But at tooling level it perfectly makes sense, for addons or for devtools. I think the Debugger will need something like this for sure.
I guess we can add something to EventListenerService. When the service was added, I explicitly didn't want to give the listeners to the caller, since it was too easy way to cause security bugs, but these days security check happen differently and it should be ok to expose the listener. Though, perhaps even nicer option would be to add .remove() to the nsIEventListenerInfo object.
Flags: needinfo?(bugs)
(In reply to Gabor Krizsanits [:krizsa :gabor] from comment #1) > I've noticed that firebug does have a getEventListeners function, and if I'm > not mistaken it's driven by the old JSD API... Do you know by any chance > what are the plans for this post JSD? Does the new Debugger give some > similar support, or do we plan to support this in some other way? Firebug has recently implemented a new Command Line API: getEventListeners() - Returns the event listeners registered on the specified object. The return value is an object that contains an array for each registered event type. This command (runnable within the Console panel on the command line) is based on nsIEventListenerService.getListenerInfoFor(), you can see the source code: https://github.com/firebug/firebug/blob/master/extension/content/firebug/lib/events.js#L525 Note that Firebug is also using nsIEventListenerInfo.getDebugObject() that is returning JSD object representing the function (Firefox 22). I guess this report is about bypassing the getDebugObject() and get the listeners directly, correct? (and yes it would make the API simpler) > Though, perhaps even nicer option would be to add .remove() to the > nsIEventListenerInfo object. This sounds good. Note that one feature Firebug wants to implement in the future is "disabling/enabling" existing event listeners. Just like designers can do it for CSS Properties in Firebug. So, it should be simple to remove the listener and also add it back. Honza
Flags: needinfo?(odvarko)
(In reply to Olli Pettay [:smaug] from comment #5) > Though, perhaps even nicer option would be to add .remove() to the > nsIEventListenerInfo object. Thanks, this sounds like a very clean version, I like it. (In reply to Jan Honza Odvarko from comment #6) > > Though, perhaps even nicer option would be to add .remove() to the > > nsIEventListenerInfo object. > This sounds good. Note that one feature Firebug wants to implement in the > future is "disabling/enabling" existing event listeners. Just like designers > can do it for CSS Properties in Firebug. > > So, it should be simple to remove the listener and also add it back. Thanks for the reply. So it would be remove()/(re-)add() then. Or maybe we should call them enable/disable. How about ToSource? Won't you need that too at some point? Not that it could not be added later... I'm just thinking whether handing out the actual reference to the function is the better approach or this. Currently I prefer this enable/disable version. I guess what I'm trying to ask if you will need to get the actual direct (well, security wrapped...) references to the actual function objects those serve as listeners, or this enable/disable is enough?
(In reply to Gabor Krizsanits [:krizsa :gabor] from comment #7) > I guess what I'm trying to ask if you will need to get the actual direct (well, > security wrapped...) references to the actual function objects those serve as > listeners(In reply to Gabor Krizsanits [:krizsa :gabor] from comment #7) Yes. Having the function object that represent the actual listener is important (it's the reason why getDebugObject exists). By having the func object, Firebug (and other tools) can support direct relation with the debugger. E.g. the user can be navigated to the Script panel (debugger) by clicking on a event-listener link, the user could directly create a breakpoint for the event-listener (to break if the listener func is executed, etc. Honza
I can't get removeEventListener work neither with getDebugObject nor without it. I tried the following (in extension code): var listeners = eventListenerService.getListenerInfoFor(elem, {}); for (var i=0; i<listeners.length; i++){ var listener = listeners[i]; var listenerFunc = ...; elem.removeEventListener(listener.type, listenerFunc, listener.capturing); } It doesn't work for these definitions of listenerFunc: * listener.listenerObject * listener.getDebugObject() * listener.getDebugObject().QueryInterface(Components.interfaces.jsdIValue) * listener.getDebugObject().QueryInterface(Components.interfaces.jsdIValue).getWrappedValue() Of course, a simple way to remove the listener would be good. Bus is there any way to do it now?
it was a pseudo-code; I'm also checking for !listener.inSystemEventGroup && listener.listenerObject before calling removeEventListener
https://bugzilla.mozilla.org/show_bug.cgi?id=1472046 Move all DOM bugs that haven’t been updated in more than 3 years and has no one currently assigned to P5. If you have questions, please contact :mdaly.
Priority: -- → P5
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.