Commit 78b49dc9 authored by dgozman's avatar dgozman Committed by Commit bot

[DevTools] Introduce typed events.

These are now type-checked by compiler.

BUG=none

Review-Url: https://codereview.chromium.org/2580673002
Cr-Commit-Position: refs/heads/master@{#439054}
parent de5be95f
......@@ -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;
}
};
......@@ -164,7 +164,7 @@ Resources.DatabaseModel = class extends SDK.SDKModel {
this._enabled = false;
this._databases = [];
this._agent.disable();
this.dispatchEventToListeners(Resources.DatabaseModel.Events.DatabasesRemoved);
this.emit(new Resources.DatabaseModel.DatabasesRemovedEvent());
}
/**
......@@ -182,16 +182,21 @@ Resources.DatabaseModel = class extends SDK.SDKModel {
*/
_addDatabase(database) {
this._databases.push(database);
this.dispatchEventToListeners(Resources.DatabaseModel.Events.DatabaseAdded, database);
this.emit(new Resources.DatabaseModel.DatabaseAddedEvent(database));
}
};
/** @enum {symbol} */
Resources.DatabaseModel.Events = {
DatabaseAdded: Symbol('DatabaseAdded'),
DatabasesRemoved: Symbol('DatabasesRemoved')
Resources.DatabaseModel.DatabaseAddedEvent = class {
/**
* @param {!Resources.Database} database
*/
constructor(database) {
this.database = database;
}
};
Resources.DatabaseModel.DatabasesRemovedEvent = class {};
/**
* @implements {Protocol.DatabaseDispatcher}
* @unrestricted
......
......@@ -134,8 +134,8 @@ Resources.ResourcesPanel = class extends UI.PanelWithSidebar {
this._target = target;
this._databaseModel = Resources.DatabaseModel.fromTarget(target);
this._databaseModel.addEventListener(Resources.DatabaseModel.Events.DatabaseAdded, this._databaseAdded, this);
this._databaseModel.addEventListener(Resources.DatabaseModel.Events.DatabasesRemoved, this._resetWebSQL, this);
this._databaseModel.on(Resources.DatabaseModel.DatabaseAddedEvent, this._databaseAdded, this);
this._databaseModel.on(Resources.DatabaseModel.DatabasesRemovedEvent, this._resetWebSQL, this);
var resourceTreeModel = SDK.ResourceTreeModel.fromTarget(target);
if (!resourceTreeModel)
......@@ -164,8 +164,8 @@ Resources.ResourcesPanel = class extends UI.PanelWithSidebar {
resourceTreeModel.removeEventListener(
SDK.ResourceTreeModel.Events.WillLoadCachedResources, this._resetWithFrames, this);
}
this._databaseModel.removeEventListener(Resources.DatabaseModel.Events.DatabaseAdded, this._databaseAdded, this);
this._databaseModel.removeEventListener(Resources.DatabaseModel.Events.DatabasesRemoved, this._resetWebSQL, this);
this._databaseModel.off(Resources.DatabaseModel.DatabaseAddedEvent, this._databaseAdded, this);
this._databaseModel.off(Resources.DatabaseModel.DatabasesRemovedEvent, this._resetWebSQL, this);
this._resetWithFrames();
}
......@@ -382,19 +382,11 @@ Resources.ResourcesPanel = class extends UI.PanelWithSidebar {
}
/**
* @param {!Common.Event} event
* @param {!Resources.DatabaseModel.DatabaseAddedEvent} event
*/
_databaseAdded(event) {
var database = /** @type {!Resources.Database} */ (event.data);
this._addDatabase(database);
}
/**
* @param {!Resources.Database} database
*/
_addDatabase(database) {
var databaseTreeElement = new Resources.DatabaseTreeElement(this, database);
this._databaseTreeElements.set(database, databaseTreeElement);
var databaseTreeElement = new Resources.DatabaseTreeElement(this, event.database);
this._databaseTreeElements.set(event.database, databaseTreeElement);
this.databasesListTreeElement.appendChild(databaseTreeElement);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment