Index: third_party/WebKit/Source/devtools/front_end/common/Object.js |
diff --git a/third_party/WebKit/Source/devtools/front_end/common/Object.js b/third_party/WebKit/Source/devtools/front_end/common/Object.js |
index cf053942051630186538752c734f6ee4ea6fcb5d..6f5d793c827a6d14ee94043e1b8a9248b4074a63 100644 |
--- a/third_party/WebKit/Source/devtools/front_end/common/Object.js |
+++ b/third_party/WebKit/Source/devtools/front_end/common/Object.js |
@@ -90,6 +90,56 @@ Common.Object = class { |
for (var i = 0; i < listeners.length; ++i) |
listeners[i].listener.call(listeners[i].thisObject, event); |
} |
+ |
+ /** |
+ * @template T |
+ * @override |
+ * @param {function(new:T, ...)} eventType |
+ * @param {function(!T)} listener |
+ * @param {!Object=} thisObject |
+ * @return {!Common.EventTarget.TypedEventDescriptor} |
+ */ |
+ on(eventType, listener, thisObject) { |
+ if (!this._listeners) |
+ this._listeners = new Map(); |
+ if (!this._listeners.has(eventType)) |
+ this._listeners.set(eventType, []); |
+ this._listeners.get(eventType).push({thisObject: thisObject, listener: listener}); |
+ return new Common.EventTarget.TypedEventDescriptor(this, eventType, thisObject, listener); |
+ } |
+ |
+ /** |
+ * @template T |
+ * @override |
+ * @param {function(new:T, ...)} eventType |
+ * @param {function(!T)} listener |
+ * @param {!Object=} thisObject |
+ */ |
+ off(eventType, listener, thisObject) { |
+ if (!this._listeners || !this._listeners.has(eventType)) |
+ return; |
+ var listeners = this._listeners.get(eventType); |
+ for (var i = 0; i < listeners.length; ++i) { |
+ if (listeners[i].listener === listener && listeners[i].thisObject === thisObject) |
+ listeners.splice(i--, 1); |
+ } |
+ if (!listeners.length) |
+ this._listeners.delete(eventType); |
+ } |
+ |
+ /** |
+ * @template T |
+ * @override |
+ * @param {!T} event |
+ */ |
+ emit(event) { |
+ var eventType = event.constructor; |
+ if (!this._listeners || !this._listeners.has(eventType)) |
+ return; |
+ var listeners = this._listeners.get(eventType).slice(0); |
+ for (var i = 0; i < listeners.length; ++i) |
+ listeners[i].listener.call(listeners[i].thisObject, event); |
+ } |
}; |
/** |
@@ -110,12 +160,15 @@ Common.Event = class { |
Common.EventTarget = function() {}; |
/** |
- * @param {!Array<!Common.EventTarget.EventDescriptor>} eventList |
+ * @param {!Array<!Common.EventTarget.EventDescriptor|!Common.EventTarget.TypedEventDescriptor>} eventList |
*/ |
Common.EventTarget.removeEventListeners = function(eventList) { |
for (var i = 0; i < eventList.length; ++i) { |
var eventInfo = eventList[i]; |
- eventInfo.eventTarget.removeEventListener(eventInfo.eventType, eventInfo.method, eventInfo.receiver); |
+ if (eventInfo instanceof Common.EventTarget.EventDescriptor) |
+ eventInfo.eventTarget.removeEventListener(eventInfo.eventType, eventInfo.method, eventInfo.receiver); |
+ else |
+ eventInfo.eventTarget.off(eventInfo.eventType, eventInfo.method, eventInfo.receiver); |
} |
// Do not hold references on unused event descriptors. |
eventList.splice(0, eventList.length); |
@@ -148,6 +201,29 @@ Common.EventTarget.prototype = { |
* @param {*=} eventData |
*/ |
dispatchEventToListeners(eventType, eventData) {}, |
+ |
+ /** |
+ * @template T |
+ * @param {function(new:T, ...)} eventType |
+ * @param {function(!T)} listener |
+ * @param {!Object=} thisObject |
+ * @return {!Common.EventTarget.TypedEventDescriptor} |
+ */ |
+ on(eventType, listener, thisObject) {}, |
+ |
+ /** |
+ * @template T |
+ * @param {function(new:T, ...)} eventType |
+ * @param {function(!T)} listener |
+ * @param {!Object=} thisObject |
+ */ |
+ off(eventType, listener, thisObject) {}, |
+ |
+ /** |
+ * @template T |
+ * @param {!T} event |
+ */ |
+ emit(event) {}, |
}; |
/** |
@@ -167,3 +243,22 @@ Common.EventTarget.EventDescriptor = class { |
this.method = method; |
} |
}; |
+ |
+/** |
+ * @template T |
+ * @unrestricted |
+ */ |
+Common.EventTarget.TypedEventDescriptor = class { |
+ /** |
+ * @param {!Common.EventTarget} eventTarget |
+ * @param {function(new:T, ...)} eventType |
+ * @param {(!Object|undefined)} receiver |
+ * @param {function(!T)} method |
+ */ |
+ constructor(eventTarget, eventType, receiver, method) { |
+ this.eventTarget = eventTarget; |
+ this.eventType = eventType; |
+ this.receiver = receiver; |
+ this.method = method; |
+ } |
+}; |