Chromium Code Reviews| Index: Source/devtools/front_end/components/EventListenersView.js |
| diff --git a/Source/devtools/front_end/components/EventListenersView.js b/Source/devtools/front_end/components/EventListenersView.js |
| index 0a7abf6be8a35aeba01d567696c7eea0be0409d9..be03d01b69ff235da1be4d96e6a8ffcb15d3f921 100644 |
| --- a/Source/devtools/front_end/components/EventListenersView.js |
| +++ b/Source/devtools/front_end/components/EventListenersView.js |
| @@ -3,6 +3,11 @@ |
| // found in the LICENSE file. |
| /** |
| + * @typedef {Array<{object: !WebInspector.RemoteObject, eventListeners: ?Array<!WebInspector.EventListener>, frameworkEventListeners: ?Array<!WebInspector.EventListener>, frameworkInternalHandlers: ?WebInspector.RemoteSet, isInternal: ?Array<boolean>}>} |
| + */ |
| +WebInspector.EventListenersResult; |
| + |
| +/** |
| * @constructor |
| * @param {!Element} element |
| */ |
| @@ -30,34 +35,85 @@ WebInspector.EventListenersView.prototype = { |
| addObjects: function(objects) |
|
pfeldman
2015/08/27 01:30:38
I am trying to understand what it does and it is s
|
| { |
| var promises = []; |
| - for (var i = 0; i < objects.length; ++i) |
| - promises.push(objects[i].eventListeners()); |
| - return Promise.all(promises).then(listenersCallback.bind(this)); |
| + var results = []; |
| + for (var i = 0; i < objects.length; ++i) { |
| + var result = {object: objects[i]}; |
| + results.push(result); |
| + promises.push(objects[i].eventListeners().then(WebInspector.storeTo.bind(null, result, "eventListeners"))); |
|
pfeldman
2015/08/27 01:21:31
What's storeTo?
|
| + promises.push(objects[i].frameworkEventListeners(WebInspector.EventListenersView._frameworkEventListenersGetter) |
|
pfeldman
2015/08/27 01:30:38
In here we call remote objects' frameworkEventList
|
| + .then(WebInspector.storeTo.bind(null, result, "frameworkEventListeners"))); |
| + promises.push(objects[i].frameworkInternalHandlers(WebInspector.EventListenersView._frameworkInternalHandlersGetter) |
| + .then(WebInspector.storeTo.bind(null, result, "frameworkInternalHandlers"))); |
| + } |
| + return Promise.all(promises).then(listenersCallback.bind(this, results)); |
| /** |
| - * @param {!Array<?Array<!WebInspector.EventListener>>} listeners |
| + * @param {!WebInspector.EventListenersResult} results |
| * @this {WebInspector.EventListenersView} |
| */ |
| - function listenersCallback(listeners) |
| + function listenersCallback(results) |
| { |
| this.reset(); |
| - for (var i = 0; i < listeners.length; ++i) |
| - this._addObjectEventListeners(objects[i], listeners[i]); |
| + var promises = []; |
| + for (var i = 0; i < results.length; ++i) { |
| + results[i].isInternal = []; |
| + for (var j = 0; j < results[i].eventListeners.length; ++j) { |
| + var handler = results[i].eventListeners[j].handler(); |
| + if (handler) { |
| + promises.push(results[i].frameworkInternalHandlers.has(handler) |
| + .then(WebInspector.storeTo.bind(null, results[i].isInternal, j))); |
| + } |
| + } |
| + } |
| + return Promise.all(promises).then(addResults.bind(this, results)); |
| + } |
| + |
| + /** |
| + * @param {!WebInspector.EventListenersResult} results |
| + * @this {WebInspector.EventListenersView} |
| + */ |
| + function addResults(results) |
| + { |
| + for (var i = 0; i < results.length; ++i) { |
| + this._addObjectEventListeners(results[i].object, results[i].eventListeners, "normal", results[i].isInternal); |
| + this._addObjectEventListeners(results[i].object, results[i].frameworkEventListeners, "frameworkUser", null); |
| + } |
| this.addEmptyHolderIfNeeded(); |
| this._eventListenersArrivedForTest(); |
| } |
| }, |
| /** |
| + * @param {boolean} showFramework |
| + */ |
| + showFrameworkListeners: function(showFramework) |
| + { |
| + var eventTypes = this._treeOutline.rootElement().children(); |
| + for (var eventType of eventTypes) { |
| + for (var listenerElement of eventType.children()) { |
| + var listenerType = listenerElement.listenerType(); |
| + var hidden = false; |
| + if (listenerType === "frameworkUser" && !showFramework) |
| + hidden = true; |
| + if (listenerType === "frameworkInternal" && showFramework) |
| + hidden = true; |
| + listenerElement.hidden = hidden; |
| + } |
| + } |
| + }, |
| + |
| + /** |
| * @param {!WebInspector.RemoteObject} object |
| * @param {?Array<!WebInspector.EventListener>} eventListeners |
| + * @param {string} listenerType |
| + * @param {?Array<boolean>} isInternal |
| */ |
| - _addObjectEventListeners: function(object, eventListeners) |
| + _addObjectEventListeners: function(object, eventListeners, listenerType, isInternal) |
| { |
| if (!eventListeners) |
| return; |
| - for (var eventListener of eventListeners) { |
| - var treeItem = this._getOrCreateTreeElementForType(eventListener.type()); |
| - treeItem.addObjectEventListener(eventListener, object); |
| + for (var i = 0; i < eventListeners.length; ++i) { |
| + var treeItem = this._getOrCreateTreeElementForType(eventListeners[i].type()); |
| + treeItem.addObjectEventListener(eventListeners[i], object, isInternal && isInternal[i] ? "frameworkInternal" : listenerType); |
| } |
| }, |
| @@ -124,10 +180,11 @@ WebInspector.EventListenersTreeElement.prototype = { |
| /** |
| * @param {!WebInspector.EventListener} eventListener |
| * @param {!WebInspector.RemoteObject} object |
| + * @param {string} listenerType |
| */ |
| - addObjectEventListener: function(eventListener, object) |
| + addObjectEventListener: function(eventListener, object, listenerType) |
| { |
| - var treeElement = new WebInspector.ObjectEventListenerBar(eventListener, object, this._linkifier); |
| + var treeElement = new WebInspector.ObjectEventListenerBar(eventListener, object, this._linkifier, listenerType); |
| this.appendChild(/** @type {!TreeElement} */ (treeElement)); |
| }, |
| @@ -140,14 +197,16 @@ WebInspector.EventListenersTreeElement.prototype = { |
| * @param {!WebInspector.EventListener} eventListener |
| * @param {!WebInspector.RemoteObject} object |
| * @param {!WebInspector.Linkifier} linkifier |
| + * @param {string} listenerType |
| */ |
| -WebInspector.ObjectEventListenerBar = function(eventListener, object, linkifier) |
| +WebInspector.ObjectEventListenerBar = function(eventListener, object, linkifier, listenerType) |
| { |
| TreeElement.call(this, "", true); |
| this._eventListener = eventListener; |
| this.editable = false; |
| this.selectable = false; |
| this._setTitle(object, linkifier); |
| + this._listenerType = listenerType; |
| } |
| WebInspector.ObjectEventListenerBar.prototype = { |
| @@ -174,5 +233,168 @@ WebInspector.ObjectEventListenerBar.prototype = { |
| title.appendChild(WebInspector.ObjectPropertiesSection.createValueElement(object, false)); |
| }, |
| + /** |
| + * @return {string} |
| + */ |
| + listenerType: function() |
| + { |
| + return this._listenerType; |
| + }, |
| + |
| __proto__: TreeElement.prototype |
| -} |
| +} |
| + |
| +/** |
| + * @return {!Array<!{handler:function(), useCapture: boolean, type:string}>} |
| + * @this {Object} |
| + */ |
| +WebInspector.EventListenersView._frameworkEventListenersGetter = function() |
| +{ |
| + var listeners = []; |
| + var getters = [jQueryEventListeners]; |
| + try { |
| + if (self.devtoolsFrameworkEventListeners && isArrayLike(self.devtoolsFrameworkEventListeners)) |
| + getters = getters.concat(self.devtoolsFrameworkEventListeners); |
| + } catch (e) { |
| + } |
| + |
| + for (var i = 0; i < getters.length; ++i) { |
| + try { |
| + listeners = listeners.concat(getters[i](this)); |
| + } catch (e) { |
| + } |
| + } |
| + return listeners; |
| + |
| + /** |
| + * @param {?Object} obj |
| + * @return {boolean} |
| + */ |
| + function isArrayLike(obj) |
| + { |
| + if (!obj || typeof obj !== "object") |
| + return false; |
| + try { |
| + if (typeof obj.splice === "function") { |
| + var len = obj.length; |
| + return typeof len === "number" && (len >>> 0 === len && (len > 0 || 1 / len > 0)); |
| + } |
| + } catch (e) { |
| + } |
| + return false; |
| + } |
| + |
| + /** |
| + * @param {?Object} node |
| + * @return {!Array<!{handler:function(), useCapture: boolean, type:string}>} |
| + */ |
| + function jQueryEventListeners(node) |
| + { |
| + if (!node || !(node instanceof Node)) |
| + return []; |
| + var hasJQuery = (typeof jQuery !== 'undefined') && jQuery.fn; |
| + if (!hasJQuery) |
| + return []; |
| + var listeners = []; |
| + var data = jQuery._data || jQuery.data; |
| + if (typeof data === "function") { |
| + var events = data(node, "events"); |
| + for (var type in events) { |
| + for (var key in events[type]) { |
| + var frameworkListener = events[type][key]; |
| + if (typeof frameworkListener === "object" || typeof frameworkListener === "function") { |
| + var listener = { |
| + handler: frameworkListener.handler || frameworkListener, |
| + useCapture: true, |
| + type: type |
| + }; |
| + listeners.push(listener); |
| + } |
| + } |
| + } |
| + } |
| + var entry = jQuery(node)[0]; |
| + if (entry) { |
| + var entryEvents = entry["$events"]; |
| + for (var type in entryEvents) { |
| + var events = entryEvents[type]; |
| + for (var key in events) { |
| + if (typeof events[key] === "function") { |
| + var listener = { |
| + handler: events[key], |
| + useCapture: true, |
| + type: type |
| + }; |
| + listeners.push(listener); |
| + } |
| + } |
| + } |
| + } |
| + return listeners; |
| + } |
| +} |
| + |
| +/** |
| + * @return {!Array<function()>} |
| + * @this {Object} |
| + */ |
| +WebInspector.EventListenersView._frameworkInternalHandlersGetter = function() |
|
pfeldman
2015/08/27 01:30:38
Can we do these two in one pass and return the str
|
| +{ |
| + var handlers = []; |
| + var getters = [jQueryInternalHandlers]; |
| + try { |
| + if (self.devtoolsFrameworkInternalHandlers && isArrayLike(self.devtoolsFrameworkInternalHandlers)) |
| + getters = getters.concat(self.devtoolsFrameworkInternalHandlers); |
| + } catch (e) { |
| + } |
| + |
| + for (var i = 0; i < getters.length; ++i) { |
| + try { |
| + handlers = handlers.concat(getters[i](this)); |
| + } catch (e) { |
| + } |
| + } |
| + return handlers; |
| + |
| + /** |
| + * @param {?Object} obj |
| + * @return {boolean} |
| + */ |
| + function isArrayLike(obj) |
| + { |
| + if (!obj || typeof obj !== "object") |
| + return false; |
| + try { |
| + if (typeof obj.splice === "function") { |
| + var len = obj.length; |
| + return typeof len === "number" && (len >>> 0 === len && (len > 0 || 1 / len > 0)); |
| + } |
| + } catch (e) { |
| + } |
| + return false; |
| + } |
| + |
| + /** |
| + * @param {?Object} node |
| + * @return {!Array<function()>} |
| + */ |
| + function jQueryInternalHandlers(node) |
| + { |
| + if (!(node instanceof Node)) |
| + return []; |
| + var hasJQuery = (typeof jQuery !== 'undefined') && jQuery.fn; |
| + if (!hasJQuery) |
| + return []; |
| + var handlers = []; |
| + var data = jQuery._data || jQuery.data; |
| + if (typeof data === "function") { |
| + var nodeData = data(node); |
| + if (typeof nodeData.handle === "function") |
| + handlers.push(nodeData.handle); |
| + } |
| + var entry = jQuery(node)[0]; |
| + if (entry && entry["$handle"]) |
| + handlers.push(entry["$handle"]); |
| + return handlers; |
| + } |
| +} |