Diff
Modified: trunk/LayoutTests/ChangeLog (172395 => 172396)
--- trunk/LayoutTests/ChangeLog 2014-08-11 17:52:15 UTC (rev 172395)
+++ trunk/LayoutTests/ChangeLog 2014-08-11 18:10:25 UTC (rev 172396)
@@ -1,3 +1,15 @@
+2014-08-11 Brian J. Burg <[email protected]>
+
+ Web Inspector: Add a helper to avoid leaking single-fire event listeners in Promise chains
+ https://bugs.webkit.org/show_bug.cgi?id=135772
+
+ Reviewed by Timothy Hatcher.
+
+ * inspector/event-listener-expected.txt: Added.
+ * inspector/event-listener-set-expected.txt: Added.
+ * inspector/event-listener-set.html: Added.
+ * inspector/event-listener.html: Added.
+
2014-08-10 Oliver Hunt <[email protected]>
Destructuring assignment in a var declaration list incorrectly consumes subsequent variable initialisers
Added: trunk/LayoutTests/inspector/event-listener-expected.txt (0 => 172396)
--- trunk/LayoutTests/inspector/event-listener-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/event-listener-expected.txt 2014-08-11 18:10:25 UTC (rev 172396)
@@ -0,0 +1,16 @@
+Testing basic functionality of WebInspector.EventListener.
+
+Connecting the listener.
+Invoked callback for kaboom event.
+Invoked callback for kaboom event.
+Disconnecting the listener.
+Connecting the listener.
+Invoked callback for kaboom event.
+Disconnecting the listener.
+Connecting the listener.
+Disconnecting the listener.
+Connecting the single-fire listener.
+Invoked callback for kaboom event.
+Disconnecting the single-fire listener.
+Invoked callback for kaboom event.
+
Added: trunk/LayoutTests/inspector/event-listener-set-expected.txt (0 => 172396)
--- trunk/LayoutTests/inspector/event-listener-set-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/event-listener-set-expected.txt 2014-08-11 18:10:25 UTC (rev 172396)
@@ -0,0 +1,25 @@
+Testing basic functionality of WebInspector.EventListenerSet.
+
+Registering listeners.
+Installing listeners.
+Dispatching events.
+Invoked callback for foo event.
+Invoked callback for bar event.
+Invoked callback for baz event.
+Uninstalling and disconnecting listeners.
+Registering listeners.
+Dispatching events.
+Invoked callback for foo event.
+Invoked callback for bar event.
+Invoked callback for baz event.
+Uninstalling listeners.
+Installing listeners.
+Dispatching events.
+Invoked callback for foo event.
+Invoked callback for bar event.
+Invoked callback for baz event.
+Unregistering everything.
+Dispatching events.
+Unintalling and disconnecting listeners.
+Dispatching events.
+
Added: trunk/LayoutTests/inspector/event-listener-set.html (0 => 172396)
--- trunk/LayoutTests/inspector/event-listener-set.html (rev 0)
+++ trunk/LayoutTests/inspector/event-listener-set.html 2014-08-11 18:10:25 UTC (rev 172396)
@@ -0,0 +1,117 @@
+<!doctype html>
+<html>
+<head>
+<script type="text/_javascript_" src=""
+<script>
+function test()
+{
+ const FooEvent = "foo";
+ const BarEvent = "bar";
+ const BazEvent = "baz";
+ var emitter1 = new WebInspector.Object();
+ var emitter2 = new WebInspector.Object();
+ var context1 = new WebInspector.Object();
+ var context2 = new WebInspector.Object();
+ var data1 = [1, 2, 3];
+ var data2 = [4, 6, 8];
+
+ function fooCallback(event)
+ {
+ InspectorTest.assert(this === context1, "Callback invoked with wrong |this| binding.");
+ InspectorTest.assert(event.target === emitter1, "Callback invoked with wrong event emitter.");
+ InspectorTest.assert(event.data ="" data1, "Callback invoked with wrong event data.");
+
+ InspectorTest.log("Invoked callback for foo event.");
+ }
+
+ function barCallback(event)
+ {
+ InspectorTest.assert(this === context1, "Callback invoked with wrong |this| binding.");
+ InspectorTest.assert(event.target === emitter1, "Callback invoked with wrong event emitter.");
+ InspectorTest.assert(event.data ="" data2, "Callback invoked with wrong event data.");
+
+ InspectorTest.log("Invoked callback for bar event.");
+ }
+
+ function bazCallback(event)
+ {
+ InspectorTest.assert(this === context2, "Callback invoked with wrong |this| binding.");
+ InspectorTest.assert(event.target === emitter2, "Callback invoked with wrong event emitter.");
+ InspectorTest.assert(event.data ="" data2, "Callback invoked with wrong event data.");
+
+ InspectorTest.log("Invoked callback for baz event.");
+ }
+
+ // Test for multiple firings of listeners in the set.
+
+ var listenerSet = new WebInspector.EventListenerSet(context1);
+ InspectorTest.assert(!emitter1.hasEventListeners(FooEvent), "Emitter should not have any listeners.");
+ emitter1.dispatchEventToListeners(FooEvent, data1); // Should not fire anything.
+
+ InspectorTest.log("Registering listeners.");
+ listenerSet.register(emitter1, FooEvent, fooCallback);
+ listenerSet.register(emitter1, BarEvent, barCallback);
+ listenerSet.register(emitter2, BazEvent, bazCallback, context2);
+ InspectorTest.assert(!emitter1.hasEventListeners(FooEvent), "Emitter should not have a listener.");
+ InspectorTest.assert(!emitter1.hasEventListeners(BarEvent), "Emitter should not have a listener.");
+ InspectorTest.assert(!emitter2.hasEventListeners(BazEvent), "Emitter should not have a listener.");
+
+ InspectorTest.log("Installing listeners.");
+ listenerSet.install();
+ InspectorTest.assert(emitter1.hasEventListeners(FooEvent), "Emitter should have a listener.");
+ InspectorTest.assert(emitter1.hasEventListeners(BarEvent), "Emitter should have a listener.");
+ InspectorTest.assert(emitter2.hasEventListeners(BazEvent), "Emitter should have a listener.");
+
+ InspectorTest.log("Dispatching events.");
+ emitter1.dispatchEventToListeners(FooEvent, data1); // Should fire.
+ emitter1.dispatchEventToListeners(BarEvent, data2); // Should fire.
+ emitter2.dispatchEventToListeners(BazEvent, data2); // Should fire.
+ InspectorTest.log("Uninstalling and disconnecting listeners.");
+ listenerSet.uninstall(true);
+
+ InspectorTest.log("Registering listeners.");
+ listenerSet.register(emitter1, FooEvent, fooCallback);
+ listenerSet.register(emitter1, BarEvent, barCallback);
+ listenerSet.register(emitter2, BazEvent, bazCallback, context2);
+
+ listenerSet.install();
+ InspectorTest.log("Dispatching events.");
+ emitter1.dispatchEventToListeners(FooEvent, data1); // Should fire.
+ emitter1.dispatchEventToListeners(BarEvent, data2); // Should fire.
+ emitter2.dispatchEventToListeners(BazEvent, data2); // Should fire.
+ InspectorTest.log("Uninstalling listeners.");
+ listenerSet.uninstall();
+
+ InspectorTest.log("Installing listeners.");
+ listenerSet.install();
+ InspectorTest.log("Dispatching events.");
+ emitter1.dispatchEventToListeners(FooEvent, data1); // Should fire.
+ emitter1.dispatchEventToListeners(BarEvent, data2); // Should fire.
+ emitter2.dispatchEventToListeners(BazEvent, data2); // Should fire.
+
+ InspectorTest.log("Unregistering everything.");
+ listenerSet.unregister();
+ InspectorTest.log("Dispatching events.");
+ emitter1.dispatchEventToListeners(FooEvent, data1); // Should not fire.
+ emitter1.dispatchEventToListeners(BarEvent, data2); // Should not fire.
+ emitter2.dispatchEventToListeners(BazEvent, data2); // Should not fire.
+
+ InspectorTest.log("Unintalling and disconnecting listeners.");
+ listenerSet.uninstall(true);
+ InspectorTest.log("Dispatching events.");
+ emitter1.dispatchEventToListeners(FooEvent, data1); // Should not fire.
+ emitter1.dispatchEventToListeners(BarEvent, data2); // Should not fire.
+ emitter2.dispatchEventToListeners(BazEvent, data2); // Should not fire.
+
+ InspectorTest.assert(!emitter1.hasEventListeners(FooEvent), "Emitter should not have a listener.");
+ InspectorTest.assert(!emitter1.hasEventListeners(BarEvent), "Emitter should not have a listener.");
+ InspectorTest.assert(!emitter2.hasEventListeners(BazEvent), "Emitter should not have a listener.");
+
+ InspectorTest.completeTest();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+ <p>Testing basic functionality of WebInspector.EventListenerSet.</p>
+</body>
+</html>
Added: trunk/LayoutTests/inspector/event-listener.html (0 => 172396)
--- trunk/LayoutTests/inspector/event-listener.html (rev 0)
+++ trunk/LayoutTests/inspector/event-listener.html 2014-08-11 18:10:25 UTC (rev 172396)
@@ -0,0 +1,93 @@
+<!doctype html>
+<html>
+<head>
+<script type="text/_javascript_" src=""
+<script>
+function test()
+{
+ const KaboomEvent = "kaboom";
+ var emitter = new WebInspector.Object();
+ var context = new WebInspector.Object();
+ var data = "" 2, 3];
+
+ function kaboomCallback(event) {
+ InspectorTest.assert(this === context, "Callback invoked with wrong |this| binding.");
+ InspectorTest.assert(event.target === emitter, "Callback invoked with wrong event emitter.");
+ InspectorTest.assert(event.data ="" data, "Callback invoked with wrong event data.");
+
+ InspectorTest.log("Invoked callback for kaboom event.");
+ }
+
+ // Test for multiple firings of the listener.
+
+ var listener = new WebInspector.EventListener(context);
+ InspectorTest.assert(!emitter.hasEventListeners(KaboomEvent), "Emitter should not have any listeners.");
+ emitter.dispatchEventToListeners(KaboomEvent, data); // Should not fire anything.
+
+ InspectorTest.log("Connecting the listener.");
+ listener.connect(emitter, KaboomEvent, kaboomCallback);
+ InspectorTest.assert(emitter.hasEventListeners(KaboomEvent), "Emitter should have a listener.");
+ emitter.dispatchEventToListeners(KaboomEvent, data); // Should fire.
+ emitter.dispatchEventToListeners(KaboomEvent, data); // Should fire.
+ InspectorTest.log("Disconnecting the listener.");
+ listener.disconnect();
+
+ emitter.dispatchEventToListeners(KaboomEvent, data); // Should not fire anything.
+ InspectorTest.assert(!emitter.hasEventListeners(KaboomEvent), "Emitter should not have any listeners.");
+
+ // Test reconnection.
+
+ InspectorTest.log("Connecting the listener.");
+ listener.connect(emitter, KaboomEvent, kaboomCallback);
+ emitter.dispatchEventToListeners(KaboomEvent, data); // Should fire.
+ InspectorTest.log("Disconnecting the listener.");
+ listener.disconnect();
+
+ // Test unused listener.
+
+ InspectorTest.log("Connecting the listener.");
+ listener.connect(emitter, KaboomEvent, kaboomCallback);
+ InspectorTest.log("Disconnecting the listener.");
+ listener.disconnect();
+
+ // Test for single firing of the listener.
+
+ var singleListener = new WebInspector.EventListener(context, true);
+ InspectorTest.assert(!emitter.hasEventListeners(KaboomEvent), "Emitter should not have any listeners.");
+ emitter.dispatchEventToListeners(KaboomEvent, data); // Should not fire anything.
+
+ InspectorTest.log("Connecting the single-fire listener.");
+ singleListener.connect(emitter, KaboomEvent, kaboomCallback);
+ InspectorTest.assert(emitter.hasEventListeners(KaboomEvent), "Emitter should have a listener.");
+ emitter.dispatchEventToListeners(KaboomEvent, data); // Should fire.
+ InspectorTest.assert(!emitter.hasEventListeners(KaboomEvent), "Emitter should not have any listeners.");
+ emitter.dispatchEventToListeners(KaboomEvent, data); // Should not fire.
+ InspectorTest.log("Disconnecting the single-fire listener.");
+ singleListener.disconnect(); // Should cause an error.
+ emitter.dispatchEventToListeners(KaboomEvent, data); // Should not fire.
+
+ // Test for various error cases and abuse.
+
+ var badListener = new WebInspector.EventListener(context);
+ badListener.connect(data, data, data); // Should complain about non-callable callback.
+ badListener.connect(null, KaboomEvent, kaboomCallback); // Should complain about non-callable callback.
+ badListener.connect(emitter, KaboomEvent, null); // Should complain about non-callable callback.
+ badListener.connect(emitter, null, kaboomCallback); // Should complain about null event.
+
+ var badListener2 = new WebInspector.EventListener(context);
+ badListener2.disconnect(); // Should complain about already disconnected.
+ badListener2.connect(emitter, KaboomEvent, kaboomCallback);
+ badListener2.connect(emitter, KaboomEvent, kaboomCallback); // Should complain about already connected.
+ emitter.dispatchEventToListeners(KaboomEvent, data); // Should fire.
+ badListener2.connect(emitter, KaboomEvent, kaboomCallback); // Should complain about already connected.
+ badListener2.disconnect();
+ badListener2.disconnect(); // Should complain about already disconnected.
+
+ InspectorTest.completeTest();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+ <p>Testing basic functionality of WebInspector.EventListener.</p>
+</body>
+</html>
Modified: trunk/Source/WebInspectorUI/ChangeLog (172395 => 172396)
--- trunk/Source/WebInspectorUI/ChangeLog 2014-08-11 17:52:15 UTC (rev 172395)
+++ trunk/Source/WebInspectorUI/ChangeLog 2014-08-11 18:10:25 UTC (rev 172396)
@@ -1,3 +1,38 @@
+2014-08-11 Brian J. Burg <[email protected]>
+
+ Web Inspector: Add a helper to avoid leaking single-fire event listeners in Promise chains
+ https://bugs.webkit.org/show_bug.cgi?id=135772
+
+ Reviewed by Timothy Hatcher.
+
+ A common pattern when working with promise chains is to convert an event
+ handler into a promise by using a single-fire event listener with the
+ resolve continuation as the callback. This is fine if the event fires;
+ if it doesn't fire, then the event emitter permanently keeps a reference to the
+ this-object and the callback.
+
+ This patch adds EventListener, a proxy object for events that can be manipulated
+ from multiple promise callback functions. If a promise is rejected, the catch
+ block can disconnect any event listeners set up earlier in the promise chain.
+
+ This patch also reimplements EventListenerSet to use multiple EventListeners,
+ since they share the same logic to uniformly handle Inspector and DOM events.
+
+ Test: inspector/event-listener.html
+ Test: inspector/event-listener-set.html
+
+ * UserInterface/Base/EventListener.js: Added.
+ (WebInspector.EventListener):
+ (WebInspector.EventListener.prototype.this._callback):
+ (WebInspector.EventListener.prototype.connect):
+ (WebInspector.EventListener.prototype.disconnect):
+ * UserInterface/Base/EventListenerSet.js: Update license block.
+ (WebInspector.EventListenerSet.prototype.register):
+ (WebInspector.EventListenerSet.prototype.install):
+ (WebInspector.EventListenerSet.prototype.uninstall):
+ * UserInterface/Main.html: Include EventListener.
+ * UserInterface/Test.html: Include EventListener and EventListenerSet.
+
2014-08-10 Timothy Hatcher <[email protected]>
Web Inspector: new glyphs are visible on OS X 10.9 builds
Added: trunk/Source/WebInspectorUI/UserInterface/Base/EventListener.js (0 => 172396)
--- trunk/Source/WebInspectorUI/UserInterface/Base/EventListener.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/EventListener.js 2014-08-11 18:10:25 UTC (rev 172396)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2013, 2014 University of Washington. All rights reserved.
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.EventListener = function(thisObject, fireOnce)
+{
+ this._thisObject = thisObject;
+ this._emitter = null;
+ this._callback = null;
+ this._fireOnce = fireOnce;
+}
+
+WebInspector.EventListener.prototype = {
+ connect: function(emitter, type, callback, usesCapture)
+ {
+ console.assert(!this._emitter && !this._callback, "EventListener already bound to a callback.", this);
+ console.assert(callback, "Missing callback for event: " + type);
+ console.assert(emitter, "Missing event emitter for event: " + type);
+ var emitterIsValid = emitter && (emitter instanceof WebInspector.Object || emitter instanceof Node || (typeof emitter.addEventListener === "function"));
+ console.assert(emitterIsValid, "Event emitter ", emitter, " (type:" + type + ") is null or does not implement Node or WebInspector.Object!");
+
+ if (!emitterIsValid || !type || !callback)
+ return;
+
+ this._emitter = emitter;
+ this._type = type;
+ this._usesCapture = !!usesCapture;
+
+ if (emitter instanceof Node)
+ callback = callback.bind(this._thisObject);
+
+ if (this._fireOnce) {
+ var listener = this;
+ this._callback = function() {
+ listener.disconnect();
+ callback.apply(this, arguments);
+ }
+ } else
+ this._callback = callback;
+
+ if (this._emitter instanceof Node)
+ this._emitter.addEventListener(this._type, this._callback, this._usesCapture);
+ else
+ this._emitter.addEventListener(this._type, this._callback, this._thisObject);
+ },
+
+ disconnect: function()
+ {
+ console.assert(this._emitter && this._callback, "EventListener is not bound to a callback.", this);
+
+ if (!this._emitter || !this._callback)
+ return;
+
+ if (this._emitter instanceof Node)
+ this._emitter.removeEventListener(this._type, this._callback, this._usesCapture);
+ else
+ this._emitter.removeEventListener(this._type, this._callback, this._thisObject);
+
+ if (this._fireOnce)
+ delete this._thisObject;
+ delete this._emitter;
+ delete this._type;
+ delete this._callback;
+ }
+};
Modified: trunk/Source/WebInspectorUI/UserInterface/Base/EventListenerSet.js (172395 => 172396)
--- trunk/Source/WebInspectorUI/UserInterface/Base/EventListenerSet.js 2014-08-11 17:52:15 UTC (rev 172395)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/EventListenerSet.js 2014-08-11 18:10:25 UTC (rev 172396)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 University of Washington. All rights reserved.
+ * Copyright (C) 2013, 2014 University of Washington. All rights reserved.
* Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -11,15 +11,15 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
@@ -38,16 +38,17 @@
}
WebInspector.EventListenerSet.prototype = {
- register: function(emitter, type, listener, thisObject, useCapture)
+ register: function(emitter, type, callback, thisObject, usesCapture)
{
- console.assert(listener, "Missing listener for event: " + type);
- console.assert(emitter, "Missing event emitter for event: " + type);
- console.assert(emitter instanceof WebInspector.Object || emitter instanceof Node || (typeof emitter.addEventListener === "function"), "Event emitter", emitter, " (type:" + type + ") does not implement Node or WebInspector.Object!");
+ console.assert(callback, "Missing callback for event: " + type);
+ console.assert(type, "Tried to register listener for unknown event: " + type);
+ var emitterIsValid = emitter && (emitter instanceof WebInspector.Object || emitter instanceof Node || (typeof emitter.addEventListener === "function"));
+ console.assert(emitterIsValid, "Event emitter ", emitter, " (type:" + type + ") is null or does not implement Node or WebInspector.Object!");
- if (emitter instanceof Node)
- listener = listener.bind(thisObject || this._defaultThisObject);
+ if (!emitterIsValid || !type || !callback)
+ return;
- this._listeners.push({emitter: emitter, type: type, listener: listener, thisObject: thisObject, useCapture: useCapture});
+ this._listeners.push({listener: new WebInspector.EventListener(thisObject || this._defaultThisObject), emitter: emitter, type: type, callback: callback, usesCapture: usesCapture});
},
unregister: function()
@@ -60,33 +61,27 @@
install: function()
{
console.assert(!this._installed, "Already installed listener group: " + this.name);
+ if (this._installed)
+ return;
this._installed = true;
- for (var listenerData of this._listeners) {
- if (listenerData.emitter instanceof Node)
- listenerData.emitter.addEventListener(listenerData.type, listenerData.listener, listenerData.useCapture);
- else
- listenerData.emitter.addEventListener(listenerData.type, listenerData.listener, listenerData.thisObject || this._defaultThisObject);
- }
+ for (var data of this._listeners)
+ data.listener.connect(data.emitter, data.type, data.callback, data.usesCapture);
},
uninstall: function(unregisterListeners)
{
console.assert(this._installed, "Trying to uninstall listener group " + this.name + ", but it isn't installed.");
+ if (!this._installed)
+ return;
this._installed = false;
- for (var listenerData of this._listeners) {
- if (listenerData.emitter instanceof Node)
- listenerData.emitter.removeEventListener(listenerData.type, listenerData.listener, listenerData.useCapture);
- else
- listenerData.emitter.removeEventListener(listenerData.type, listenerData.listener, listenerData.thisObject || this._defaultThisObject);
- }
+ for (var data of this._listeners)
+ data.listener.disconnect();
- if (unregisterListeners) {
+ if (unregisterListeners)
this._listeners = [];
- delete this._defaultThisObject;
- }
},
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (172395 => 172396)
--- trunk/Source/WebInspectorUI/UserInterface/Main.html 2014-08-11 17:52:15 UTC (rev 172395)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html 2014-08-11 18:10:25 UTC (rev 172396)
@@ -165,6 +165,7 @@
<script src=""
<script src=""
+ <script src=""
<script src=""
<script src=""
<script src=""
Modified: trunk/Source/WebInspectorUI/UserInterface/Test.html (172395 => 172396)
--- trunk/Source/WebInspectorUI/UserInterface/Test.html 2014-08-11 17:52:15 UTC (rev 172395)
+++ trunk/Source/WebInspectorUI/UserInterface/Test.html 2014-08-11 18:10:25 UTC (rev 172396)
@@ -35,6 +35,8 @@
<script src=""
<script src=""
+ <script src=""
+ <script src=""
<script src=""
<script src=""