Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @typedef {Array<{object: !WebInspector.RemoteObject, eventListeners: ?Array<! WebInspector.EventListener>, frameworkEventListeners: ?Array<!WebInspector.Event Listener>, frameworkInternalHandlers: ?WebInspector.RemoteSet, isInternal: ?Arra y<boolean>}>} | |
| 7 */ | |
| 8 WebInspector.EventListenersResult; | |
| 9 | |
| 10 /** | |
| 6 * @constructor | 11 * @constructor |
| 7 * @param {!Element} element | 12 * @param {!Element} element |
| 8 */ | 13 */ |
| 9 WebInspector.EventListenersView = function(element) | 14 WebInspector.EventListenersView = function(element) |
| 10 { | 15 { |
| 11 this._element = element; | 16 this._element = element; |
| 12 this._treeOutline = new TreeOutlineInShadow("event-listener-tree"); | 17 this._treeOutline = new TreeOutlineInShadow("event-listener-tree"); |
| 13 this._treeOutline.registerRequiredCSS("components/objectValue.css"); | 18 this._treeOutline.registerRequiredCSS("components/objectValue.css"); |
| 14 this._treeOutline.registerRequiredCSS("components/eventListenersView.css"); | 19 this._treeOutline.registerRequiredCSS("components/eventListenersView.css"); |
| 15 this._treeOutline.setComparator(WebInspector.EventListenersTreeElement.compa rator); | 20 this._treeOutline.setComparator(WebInspector.EventListenersTreeElement.compa rator); |
| 16 this._treeOutline.element.classList.add("monospace"); | 21 this._treeOutline.element.classList.add("monospace"); |
| 17 this._element.appendChild(this._treeOutline.element) | 22 this._element.appendChild(this._treeOutline.element) |
| 18 this._emptyHolder = createElementWithClass("div", "info"); | 23 this._emptyHolder = createElementWithClass("div", "info"); |
| 19 this._emptyHolder.textContent = WebInspector.UIString("No Event Listeners"); | 24 this._emptyHolder.textContent = WebInspector.UIString("No Event Listeners"); |
| 20 this._linkifier = new WebInspector.Linkifier(); | 25 this._linkifier = new WebInspector.Linkifier(); |
| 21 /** @type {!Map<string, !WebInspector.EventListenersTreeElement>} */ | 26 /** @type {!Map<string, !WebInspector.EventListenersTreeElement>} */ |
| 22 this._treeItemMap = new Map(); | 27 this._treeItemMap = new Map(); |
| 23 } | 28 } |
| 24 | 29 |
| 25 WebInspector.EventListenersView.prototype = { | 30 WebInspector.EventListenersView.prototype = { |
| 26 /** | 31 /** |
| 27 * @param {!Array<!WebInspector.RemoteObject>} objects | 32 * @param {!Array<!WebInspector.RemoteObject>} objects |
| 28 * @return {!Promise<undefined>} | 33 * @return {!Promise<undefined>} |
| 29 */ | 34 */ |
| 30 addObjects: function(objects) | 35 addObjects: function(objects) |
|
pfeldman
2015/08/27 01:30:38
I am trying to understand what it does and it is s
| |
| 31 { | 36 { |
| 32 var promises = []; | 37 var promises = []; |
| 33 for (var i = 0; i < objects.length; ++i) | 38 var results = []; |
| 34 promises.push(objects[i].eventListeners()); | 39 for (var i = 0; i < objects.length; ++i) { |
| 35 return Promise.all(promises).then(listenersCallback.bind(this)); | 40 var result = {object: objects[i]}; |
| 41 results.push(result); | |
| 42 promises.push(objects[i].eventListeners().then(WebInspector.storeTo. bind(null, result, "eventListeners"))); | |
|
pfeldman
2015/08/27 01:21:31
What's storeTo?
| |
| 43 promises.push(objects[i].frameworkEventListeners(WebInspector.EventL istenersView._frameworkEventListenersGetter) | |
|
pfeldman
2015/08/27 01:30:38
In here we call remote objects' frameworkEventList
| |
| 44 .then(WebInspector.storeTo.bind(null, result , "frameworkEventListeners"))); | |
| 45 promises.push(objects[i].frameworkInternalHandlers(WebInspector.Even tListenersView._frameworkInternalHandlersGetter) | |
| 46 .then(WebInspector.storeTo.bind(null, result , "frameworkInternalHandlers"))); | |
| 47 } | |
| 48 return Promise.all(promises).then(listenersCallback.bind(this, results)) ; | |
| 36 /** | 49 /** |
| 37 * @param {!Array<?Array<!WebInspector.EventListener>>} listeners | 50 * @param {!WebInspector.EventListenersResult} results |
| 38 * @this {WebInspector.EventListenersView} | 51 * @this {WebInspector.EventListenersView} |
| 39 */ | 52 */ |
| 40 function listenersCallback(listeners) | 53 function listenersCallback(results) |
| 41 { | 54 { |
| 42 this.reset(); | 55 this.reset(); |
| 43 for (var i = 0; i < listeners.length; ++i) | 56 var promises = []; |
| 44 this._addObjectEventListeners(objects[i], listeners[i]); | 57 for (var i = 0; i < results.length; ++i) { |
| 58 results[i].isInternal = []; | |
| 59 for (var j = 0; j < results[i].eventListeners.length; ++j) { | |
| 60 var handler = results[i].eventListeners[j].handler(); | |
| 61 if (handler) { | |
| 62 promises.push(results[i].frameworkInternalHandlers.has(h andler) | |
| 63 .then( WebInspector.storeTo.bind(null, results[i].isInternal, j))); | |
| 64 } | |
| 65 } | |
| 66 } | |
| 67 return Promise.all(promises).then(addResults.bind(this, results)); | |
| 68 } | |
| 69 | |
| 70 /** | |
| 71 * @param {!WebInspector.EventListenersResult} results | |
| 72 * @this {WebInspector.EventListenersView} | |
| 73 */ | |
| 74 function addResults(results) | |
| 75 { | |
| 76 for (var i = 0; i < results.length; ++i) { | |
| 77 this._addObjectEventListeners(results[i].object, results[i].even tListeners, "normal", results[i].isInternal); | |
| 78 this._addObjectEventListeners(results[i].object, results[i].fram eworkEventListeners, "frameworkUser", null); | |
| 79 } | |
| 45 this.addEmptyHolderIfNeeded(); | 80 this.addEmptyHolderIfNeeded(); |
| 46 this._eventListenersArrivedForTest(); | 81 this._eventListenersArrivedForTest(); |
| 47 } | 82 } |
| 48 }, | 83 }, |
| 49 | 84 |
| 50 /** | 85 /** |
| 86 * @param {boolean} showFramework | |
| 87 */ | |
| 88 showFrameworkListeners: function(showFramework) | |
| 89 { | |
| 90 var eventTypes = this._treeOutline.rootElement().children(); | |
| 91 for (var eventType of eventTypes) { | |
| 92 for (var listenerElement of eventType.children()) { | |
| 93 var listenerType = listenerElement.listenerType(); | |
| 94 var hidden = false; | |
| 95 if (listenerType === "frameworkUser" && !showFramework) | |
| 96 hidden = true; | |
| 97 if (listenerType === "frameworkInternal" && showFramework) | |
| 98 hidden = true; | |
| 99 listenerElement.hidden = hidden; | |
| 100 } | |
| 101 } | |
| 102 }, | |
| 103 | |
| 104 /** | |
| 51 * @param {!WebInspector.RemoteObject} object | 105 * @param {!WebInspector.RemoteObject} object |
| 52 * @param {?Array<!WebInspector.EventListener>} eventListeners | 106 * @param {?Array<!WebInspector.EventListener>} eventListeners |
| 107 * @param {string} listenerType | |
| 108 * @param {?Array<boolean>} isInternal | |
| 53 */ | 109 */ |
| 54 _addObjectEventListeners: function(object, eventListeners) | 110 _addObjectEventListeners: function(object, eventListeners, listenerType, isI nternal) |
| 55 { | 111 { |
| 56 if (!eventListeners) | 112 if (!eventListeners) |
| 57 return; | 113 return; |
| 58 for (var eventListener of eventListeners) { | 114 for (var i = 0; i < eventListeners.length; ++i) { |
| 59 var treeItem = this._getOrCreateTreeElementForType(eventListener.typ e()); | 115 var treeItem = this._getOrCreateTreeElementForType(eventListeners[i] .type()); |
| 60 treeItem.addObjectEventListener(eventListener, object); | 116 treeItem.addObjectEventListener(eventListeners[i], object, isInterna l && isInternal[i] ? "frameworkInternal" : listenerType); |
| 61 } | 117 } |
| 62 }, | 118 }, |
| 63 | 119 |
| 64 /** | 120 /** |
| 65 * @param {string} type | 121 * @param {string} type |
| 66 * @return {!WebInspector.EventListenersTreeElement} | 122 * @return {!WebInspector.EventListenersTreeElement} |
| 67 */ | 123 */ |
| 68 _getOrCreateTreeElementForType: function(type) | 124 _getOrCreateTreeElementForType: function(type) |
| 69 { | 125 { |
| 70 var treeItem = this._treeItemMap.get(type); | 126 var treeItem = this._treeItemMap.get(type); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 117 WebInspector.EventListenersTreeElement.comparator = function(element1, element2) { | 173 WebInspector.EventListenersTreeElement.comparator = function(element1, element2) { |
| 118 if (element1.title === element2.title) | 174 if (element1.title === element2.title) |
| 119 return 0; | 175 return 0; |
| 120 return element1.title > element2.title ? 1 : -1; | 176 return element1.title > element2.title ? 1 : -1; |
| 121 } | 177 } |
| 122 | 178 |
| 123 WebInspector.EventListenersTreeElement.prototype = { | 179 WebInspector.EventListenersTreeElement.prototype = { |
| 124 /** | 180 /** |
| 125 * @param {!WebInspector.EventListener} eventListener | 181 * @param {!WebInspector.EventListener} eventListener |
| 126 * @param {!WebInspector.RemoteObject} object | 182 * @param {!WebInspector.RemoteObject} object |
| 183 * @param {string} listenerType | |
| 127 */ | 184 */ |
| 128 addObjectEventListener: function(eventListener, object) | 185 addObjectEventListener: function(eventListener, object, listenerType) |
| 129 { | 186 { |
| 130 var treeElement = new WebInspector.ObjectEventListenerBar(eventListener, object, this._linkifier); | 187 var treeElement = new WebInspector.ObjectEventListenerBar(eventListener, object, this._linkifier, listenerType); |
| 131 this.appendChild(/** @type {!TreeElement} */ (treeElement)); | 188 this.appendChild(/** @type {!TreeElement} */ (treeElement)); |
| 132 }, | 189 }, |
| 133 | 190 |
| 134 __proto__: TreeElement.prototype | 191 __proto__: TreeElement.prototype |
| 135 } | 192 } |
| 136 | 193 |
| 137 /** | 194 /** |
| 138 * @constructor | 195 * @constructor |
| 139 * @extends {TreeElement} | 196 * @extends {TreeElement} |
| 140 * @param {!WebInspector.EventListener} eventListener | 197 * @param {!WebInspector.EventListener} eventListener |
| 141 * @param {!WebInspector.RemoteObject} object | 198 * @param {!WebInspector.RemoteObject} object |
| 142 * @param {!WebInspector.Linkifier} linkifier | 199 * @param {!WebInspector.Linkifier} linkifier |
| 200 * @param {string} listenerType | |
| 143 */ | 201 */ |
| 144 WebInspector.ObjectEventListenerBar = function(eventListener, object, linkifier) | 202 WebInspector.ObjectEventListenerBar = function(eventListener, object, linkifier, listenerType) |
| 145 { | 203 { |
| 146 TreeElement.call(this, "", true); | 204 TreeElement.call(this, "", true); |
| 147 this._eventListener = eventListener; | 205 this._eventListener = eventListener; |
| 148 this.editable = false; | 206 this.editable = false; |
| 149 this.selectable = false; | 207 this.selectable = false; |
| 150 this._setTitle(object, linkifier); | 208 this._setTitle(object, linkifier); |
| 209 this._listenerType = listenerType; | |
| 151 } | 210 } |
| 152 | 211 |
| 153 WebInspector.ObjectEventListenerBar.prototype = { | 212 WebInspector.ObjectEventListenerBar.prototype = { |
| 154 onpopulate: function() | 213 onpopulate: function() |
| 155 { | 214 { |
| 156 var properties = []; | 215 var properties = []; |
| 157 var eventListener = this._eventListener; | 216 var eventListener = this._eventListener; |
| 158 var runtimeModel = eventListener.target().runtimeModel; | 217 var runtimeModel = eventListener.target().runtimeModel; |
| 159 properties.push(runtimeModel.createRemotePropertyFromPrimitiveValue("use Capture", eventListener.useCapture())); | 218 properties.push(runtimeModel.createRemotePropertyFromPrimitiveValue("use Capture", eventListener.useCapture())); |
| 160 if (typeof eventListener.handler() !== "undefined") | 219 if (typeof eventListener.handler() !== "undefined") |
| 161 properties.push(new WebInspector.RemoteObjectProperty("handler", eve ntListener.handler())); | 220 properties.push(new WebInspector.RemoteObjectProperty("handler", eve ntListener.handler())); |
| 162 WebInspector.ObjectPropertyTreeElement.populateWithProperties(this, prop erties, [], true, null); | 221 WebInspector.ObjectPropertyTreeElement.populateWithProperties(this, prop erties, [], true, null); |
| 163 }, | 222 }, |
| 164 | 223 |
| 165 /** | 224 /** |
| 166 * @param {!WebInspector.RemoteObject} object | 225 * @param {!WebInspector.RemoteObject} object |
| 167 * @param {!WebInspector.Linkifier} linkifier | 226 * @param {!WebInspector.Linkifier} linkifier |
| 168 */ | 227 */ |
| 169 _setTitle: function(object, linkifier) | 228 _setTitle: function(object, linkifier) |
| 170 { | 229 { |
| 171 var title = this.listItemElement.createChild("span"); | 230 var title = this.listItemElement.createChild("span"); |
| 172 var subtitle = this.listItemElement.createChild("span", "event-listener- tree-subtitle"); | 231 var subtitle = this.listItemElement.createChild("span", "event-listener- tree-subtitle"); |
| 173 subtitle.appendChild(linkifier.linkifyRawLocation(this._eventListener.lo cation(), this._eventListener.sourceURL())); | 232 subtitle.appendChild(linkifier.linkifyRawLocation(this._eventListener.lo cation(), this._eventListener.sourceURL())); |
| 174 title.appendChild(WebInspector.ObjectPropertiesSection.createValueElemen t(object, false)); | 233 title.appendChild(WebInspector.ObjectPropertiesSection.createValueElemen t(object, false)); |
| 175 }, | 234 }, |
| 176 | 235 |
| 236 /** | |
| 237 * @return {string} | |
| 238 */ | |
| 239 listenerType: function() | |
| 240 { | |
| 241 return this._listenerType; | |
| 242 }, | |
| 243 | |
| 177 __proto__: TreeElement.prototype | 244 __proto__: TreeElement.prototype |
| 178 } | 245 } |
| 246 | |
| 247 /** | |
| 248 * @return {!Array<!{handler:function(), useCapture: boolean, type:string}>} | |
| 249 * @this {Object} | |
| 250 */ | |
| 251 WebInspector.EventListenersView._frameworkEventListenersGetter = function() | |
| 252 { | |
| 253 var listeners = []; | |
| 254 var getters = [jQueryEventListeners]; | |
| 255 try { | |
| 256 if (self.devtoolsFrameworkEventListeners && isArrayLike(self.devtoolsFra meworkEventListeners)) | |
| 257 getters = getters.concat(self.devtoolsFrameworkEventListeners); | |
| 258 } catch (e) { | |
| 259 } | |
| 260 | |
| 261 for (var i = 0; i < getters.length; ++i) { | |
| 262 try { | |
| 263 listeners = listeners.concat(getters[i](this)); | |
| 264 } catch (e) { | |
| 265 } | |
| 266 } | |
| 267 return listeners; | |
| 268 | |
| 269 /** | |
| 270 * @param {?Object} obj | |
| 271 * @return {boolean} | |
| 272 */ | |
| 273 function isArrayLike(obj) | |
| 274 { | |
| 275 if (!obj || typeof obj !== "object") | |
| 276 return false; | |
| 277 try { | |
| 278 if (typeof obj.splice === "function") { | |
| 279 var len = obj.length; | |
| 280 return typeof len === "number" && (len >>> 0 === len && (len > 0 || 1 / len > 0)); | |
| 281 } | |
| 282 } catch (e) { | |
| 283 } | |
| 284 return false; | |
| 285 } | |
| 286 | |
| 287 /** | |
| 288 * @param {?Object} node | |
| 289 * @return {!Array<!{handler:function(), useCapture: boolean, type:string}>} | |
| 290 */ | |
| 291 function jQueryEventListeners(node) | |
| 292 { | |
| 293 if (!node || !(node instanceof Node)) | |
| 294 return []; | |
| 295 var hasJQuery = (typeof jQuery !== 'undefined') && jQuery.fn; | |
| 296 if (!hasJQuery) | |
| 297 return []; | |
| 298 var listeners = []; | |
| 299 var data = jQuery._data || jQuery.data; | |
| 300 if (typeof data === "function") { | |
| 301 var events = data(node, "events"); | |
| 302 for (var type in events) { | |
| 303 for (var key in events[type]) { | |
| 304 var frameworkListener = events[type][key]; | |
| 305 if (typeof frameworkListener === "object" || typeof framewor kListener === "function") { | |
| 306 var listener = { | |
| 307 handler: frameworkListener.handler || frameworkListe ner, | |
| 308 useCapture: true, | |
| 309 type: type | |
| 310 }; | |
| 311 listeners.push(listener); | |
| 312 } | |
| 313 } | |
| 314 } | |
| 315 } | |
| 316 var entry = jQuery(node)[0]; | |
| 317 if (entry) { | |
| 318 var entryEvents = entry["$events"]; | |
| 319 for (var type in entryEvents) { | |
| 320 var events = entryEvents[type]; | |
| 321 for (var key in events) { | |
| 322 if (typeof events[key] === "function") { | |
| 323 var listener = { | |
| 324 handler: events[key], | |
| 325 useCapture: true, | |
| 326 type: type | |
| 327 }; | |
| 328 listeners.push(listener); | |
| 329 } | |
| 330 } | |
| 331 } | |
| 332 } | |
| 333 return listeners; | |
| 334 } | |
| 335 } | |
| 336 | |
| 337 /** | |
| 338 * @return {!Array<function()>} | |
| 339 * @this {Object} | |
| 340 */ | |
| 341 WebInspector.EventListenersView._frameworkInternalHandlersGetter = function() | |
|
pfeldman
2015/08/27 01:30:38
Can we do these two in one pass and return the str
| |
| 342 { | |
| 343 var handlers = []; | |
| 344 var getters = [jQueryInternalHandlers]; | |
| 345 try { | |
| 346 if (self.devtoolsFrameworkInternalHandlers && isArrayLike(self.devtoolsF rameworkInternalHandlers)) | |
| 347 getters = getters.concat(self.devtoolsFrameworkInternalHandlers); | |
| 348 } catch (e) { | |
| 349 } | |
| 350 | |
| 351 for (var i = 0; i < getters.length; ++i) { | |
| 352 try { | |
| 353 handlers = handlers.concat(getters[i](this)); | |
| 354 } catch (e) { | |
| 355 } | |
| 356 } | |
| 357 return handlers; | |
| 358 | |
| 359 /** | |
| 360 * @param {?Object} obj | |
| 361 * @return {boolean} | |
| 362 */ | |
| 363 function isArrayLike(obj) | |
| 364 { | |
| 365 if (!obj || typeof obj !== "object") | |
| 366 return false; | |
| 367 try { | |
| 368 if (typeof obj.splice === "function") { | |
| 369 var len = obj.length; | |
| 370 return typeof len === "number" && (len >>> 0 === len && (len > 0 || 1 / len > 0)); | |
| 371 } | |
| 372 } catch (e) { | |
| 373 } | |
| 374 return false; | |
| 375 } | |
| 376 | |
| 377 /** | |
| 378 * @param {?Object} node | |
| 379 * @return {!Array<function()>} | |
| 380 */ | |
| 381 function jQueryInternalHandlers(node) | |
| 382 { | |
| 383 if (!(node instanceof Node)) | |
| 384 return []; | |
| 385 var hasJQuery = (typeof jQuery !== 'undefined') && jQuery.fn; | |
| 386 if (!hasJQuery) | |
| 387 return []; | |
| 388 var handlers = []; | |
| 389 var data = jQuery._data || jQuery.data; | |
| 390 if (typeof data === "function") { | |
| 391 var nodeData = data(node); | |
| 392 if (typeof nodeData.handle === "function") | |
| 393 handlers.push(nodeData.handle); | |
| 394 } | |
| 395 var entry = jQuery(node)[0]; | |
| 396 if (entry && entry["$handle"]) | |
| 397 handlers.push(entry["$handle"]); | |
| 398 return handlers; | |
| 399 } | |
| 400 } | |
| OLD | NEW |