Note Web Inspector event listeners
Clone this wiki locally
Web Inspector uses two different event dispatch systems:
DOM event dispatch
This is the event dispatch used on normal webpages (MDN Docs). Event names are typically provided as a string. the last argument is whether it's a capturing handler (=true) or bubbling handler.
this.element.addEventListener("dblclick", this._onMiniviewDoubleClicked.bind(this), true);
In this case, you need not worry about removing the event listener from
this.element, because it will be removed by garbage collection when this.element is removed from the document and GC'd. (In old versions of IE, this was not GC'd, and was a horrible memory leak for everyone.)
Inspector event dispatch
This event dispatch system is homegrown for the inspector frontend. Instead of a tree-based dispatch algorithm, it uses a simple array of listeners for each
WebInspector.Object instance, and dispatches the event linearly to each listener. Here's an example:
this._model.addEventListener(eventNames.InputPaused, this._onInputPaused, this);
Several things are different:
- The first argument is usually a property of an object, which corresponds to a string. This provides better scoping.
- The third argument is the object to be used as the
thiscontext for the listener invocation. This is nicer because we don't have to store the
this-bound closure, but...
- Without further care,
thiswill leak memory even when unused, because the dispatching object (in this case,
this._model) will keep a reference to the
WebInspector.Object used a weak map to store
this-objects, then this wouldn't be a problem. But, they don't yet, so we must be careful to remove event listeners when they aren't needed any more. This is especially a problem for listeners registered with objects that rarely or never get GC'd by design. In Timelapse code, this is
WebInspector.TimelapseModel (singleton like much of Inspector code) and
WebInspector.TimelapseRecording (cleared when unloaded).