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 { ...@@ -90,6 +90,56 @@ Common.Object = class {
for (var i = 0; i < listeners.length; ++i) for (var i = 0; i < listeners.length; ++i)
listeners[i].listener.call(listeners[i].thisObject, event); 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 { ...@@ -110,12 +160,15 @@ Common.Event = class {
Common.EventTarget = function() {}; Common.EventTarget = function() {};
/** /**
* @param {!Array<!Common.EventTarget.EventDescriptor>} eventList * @param {!Array<!Common.EventTarget.EventDescriptor|!Common.EventTarget.TypedEventDescriptor>} eventList
*/ */
Common.EventTarget.removeEventListeners = function(eventList) { Common.EventTarget.removeEventListeners = function(eventList) {
for (var i = 0; i < eventList.length; ++i) { for (var i = 0; i < eventList.length; ++i) {
var eventInfo = eventList[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. // Do not hold references on unused event descriptors.
eventList.splice(0, eventList.length); eventList.splice(0, eventList.length);
...@@ -148,6 +201,29 @@ Common.EventTarget.prototype = { ...@@ -148,6 +201,29 @@ Common.EventTarget.prototype = {
* @param {*=} eventData * @param {*=} eventData
*/ */
dispatchEventToListeners(eventType, 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 { ...@@ -167,3 +243,22 @@ Common.EventTarget.EventDescriptor = class {
this.method = method; 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 { ...@@ -164,7 +164,7 @@ Resources.DatabaseModel = class extends SDK.SDKModel {
this._enabled = false; this._enabled = false;
this._databases = []; this._databases = [];
this._agent.disable(); 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 { ...@@ -182,16 +182,21 @@ Resources.DatabaseModel = class extends SDK.SDKModel {
*/ */
_addDatabase(database) { _addDatabase(database) {
this._databases.push(database); this._databases.push(database);
this.dispatchEventToListeners(Resources.DatabaseModel.Events.DatabaseAdded, database); this.emit(new Resources.DatabaseModel.DatabaseAddedEvent(database));
} }
}; };
/** @enum {symbol} */ Resources.DatabaseModel.DatabaseAddedEvent = class {
Resources.DatabaseModel.Events = { /**
DatabaseAdded: Symbol('DatabaseAdded'), * @param {!Resources.Database} database
DatabasesRemoved: Symbol('DatabasesRemoved') */
constructor(database) {
this.database = database;
}
}; };
Resources.DatabaseModel.DatabasesRemovedEvent = class {};
/** /**
* @implements {Protocol.DatabaseDispatcher} * @implements {Protocol.DatabaseDispatcher}
* @unrestricted * @unrestricted
......
...@@ -134,8 +134,8 @@ Resources.ResourcesPanel = class extends UI.PanelWithSidebar { ...@@ -134,8 +134,8 @@ Resources.ResourcesPanel = class extends UI.PanelWithSidebar {
this._target = target; this._target = target;
this._databaseModel = Resources.DatabaseModel.fromTarget(target); this._databaseModel = Resources.DatabaseModel.fromTarget(target);
this._databaseModel.addEventListener(Resources.DatabaseModel.Events.DatabaseAdded, this._databaseAdded, this); this._databaseModel.on(Resources.DatabaseModel.DatabaseAddedEvent, this._databaseAdded, this);
this._databaseModel.addEventListener(Resources.DatabaseModel.Events.DatabasesRemoved, this._resetWebSQL, this); this._databaseModel.on(Resources.DatabaseModel.DatabasesRemovedEvent, this._resetWebSQL, this);
var resourceTreeModel = SDK.ResourceTreeModel.fromTarget(target); var resourceTreeModel = SDK.ResourceTreeModel.fromTarget(target);
if (!resourceTreeModel) if (!resourceTreeModel)
...@@ -164,8 +164,8 @@ Resources.ResourcesPanel = class extends UI.PanelWithSidebar { ...@@ -164,8 +164,8 @@ Resources.ResourcesPanel = class extends UI.PanelWithSidebar {
resourceTreeModel.removeEventListener( resourceTreeModel.removeEventListener(
SDK.ResourceTreeModel.Events.WillLoadCachedResources, this._resetWithFrames, this); SDK.ResourceTreeModel.Events.WillLoadCachedResources, this._resetWithFrames, this);
} }
this._databaseModel.removeEventListener(Resources.DatabaseModel.Events.DatabaseAdded, this._databaseAdded, this); this._databaseModel.off(Resources.DatabaseModel.DatabaseAddedEvent, this._databaseAdded, this);
this._databaseModel.removeEventListener(Resources.DatabaseModel.Events.DatabasesRemoved, this._resetWebSQL, this); this._databaseModel.off(Resources.DatabaseModel.DatabasesRemovedEvent, this._resetWebSQL, this);
this._resetWithFrames(); this._resetWithFrames();
} }
...@@ -382,19 +382,11 @@ Resources.ResourcesPanel = class extends UI.PanelWithSidebar { ...@@ -382,19 +382,11 @@ Resources.ResourcesPanel = class extends UI.PanelWithSidebar {
} }
/** /**
* @param {!Common.Event} event * @param {!Resources.DatabaseModel.DatabaseAddedEvent} event
*/ */
_databaseAdded(event) { _databaseAdded(event) {
var database = /** @type {!Resources.Database} */ (event.data); var databaseTreeElement = new Resources.DatabaseTreeElement(this, event.database);
this._addDatabase(database); this._databaseTreeElements.set(event.database, databaseTreeElement);
}
/**
* @param {!Resources.Database} database
*/
_addDatabase(database) {
var databaseTreeElement = new Resources.DatabaseTreeElement(this, database);
this._databaseTreeElements.set(database, databaseTreeElement);
this.databasesListTreeElement.appendChild(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