Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * @param {!WebInspector.RemoteObject} object | |
| 7 * @return {!Promise<!{eventListeners:!Array<!WebInspector.EventListener>, inter nalHandlers:?WebInspector.RemoteArray}>} | |
| 8 */ | |
| 9 WebInspector.EventListener.frameworkEventListeners = function(object) | |
| 10 { | |
| 11 var listenersResult = {eventListeners: []}; | |
|
pfeldman
2015/09/02 21:13:25
use proper types, approach this as any other type
kozy
2015/09/02 22:40:20
Done.
| |
| 12 return object.callFunctionPromise(frameworkEventListenersGetter, undefined) | |
| 13 .then(assertCallFunctionResult) | |
| 14 .then(getterCallback) | |
| 15 .then(propertiesCallback) | |
| 16 .then(returnResult); | |
|
pfeldman
2015/09/02 21:13:26
catch()
kozy
2015/09/02 22:40:20
Done.
| |
| 17 | |
| 18 /** | |
| 19 * @param {!WebInspector.RemoteObject} object | |
| 20 * @return {!Promise<!{properties: ?Array<!WebInspector.RemoteObjectProperty >, internalProperties: ?Array<!WebInspector.RemoteObjectProperty>}>} | |
| 21 */ | |
| 22 function getterCallback(object) | |
| 23 { | |
| 24 return object.getOwnPropertiesPromise(); | |
| 25 } | |
| 26 | |
| 27 /** | |
| 28 * @param {!{properties: ?Array<!WebInspector.RemoteObjectProperty>, interna lProperties: ?Array<!WebInspector.RemoteObjectProperty>}} result | |
| 29 * @return {!Promise<void>} | |
|
pfeldman
2015/09/02 21:13:26
annotate properly
kozy
2015/09/02 22:40:20
Done.
| |
| 30 */ | |
| 31 function propertiesCallback(result) | |
| 32 { | |
| 33 if (!result.properties) | |
| 34 return Promise.resolve(); | |
|
pfeldman
2015/09/02 21:13:25
resolve(undefined)
kozy
2015/09/02 22:40:20
Done.
| |
| 35 var promises = []; | |
| 36 for (var property of result.properties) { | |
| 37 if (property.name === "eventListeners" && property.value) { | |
| 38 promises.push(WebInspector.RemoteArray.objectAsArray(property.va lue) | |
| 39 .map(toEventListener) | |
| 40 .then(nonEmptyObjects) | |
| 41 .then(storeResultTo.bind(n ull, listenersResult, "eventListeners"))); | |
|
pfeldman
2015/09/02 21:13:25
This is non-compiler-friendly.
kozy
2015/09/02 22:40:19
Replaced.
| |
| 42 } | |
| 43 if (property.name === "internalHandlers" && property.value) { | |
| 44 promises.push(WebInspector.RemoteArray.objectAsArray(property.va lue) | |
| 45 .map(toTargetFunction) | |
| 46 .then(WebInspector.RemoteA rray.createFromRemoteObjects) | |
| 47 .then(storeResultTo.bind(n ull, listenersResult, "internalHandlers"))); | |
| 48 } | |
| 49 } | |
| 50 return /** @type {!Promise<void>} */(Promise.all(promises)); | |
| 51 | |
| 52 /** | |
| 53 * @param {!WebInspector.RemoteObject} listenerObject | |
| 54 * @return {!Promise<?WebInspector.EventListener>} | |
| 55 */ | |
| 56 function toEventListener(listenerObject) | |
| 57 { | |
| 58 /** @type {?} */ | |
| 59 var eventListenerData = {}; | |
| 60 var promises = []; | |
| 61 | |
| 62 promises.push(listenerObject.callFunctionJSONPromise(identity, undef ined).then(storeResultTo.bind(null, eventListenerData, "jsonData"))); | |
|
pfeldman
2015/09/02 21:13:25
remove the storeResulTo
kozy
2015/09/02 22:40:20
Done.
| |
| 63 promises.push(listenerObject.callFunctionPromise(listenerEffectiveFu nction).then(assertCallFunctionResult) | |
| 64 .then(toTargetFunction) | |
| 65 .then(storeFunctionWithDetails)); | |
| 66 return Promise.all(promises).then(createEventListener.bind(null, eve ntListenerData)).catchException(/** @type {?WebInspector.EventListener} */(null) ); | |
| 67 | |
| 68 /** | |
| 69 * @suppressReceiverCheck | |
| 70 * @this {T} | |
| 71 * @return {T} | |
| 72 * @template T | |
| 73 */ | |
| 74 function identity() | |
|
pfeldman
2015/09/02 21:13:26
rename this to something meaningful.
kozy
2015/09/02 22:40:20
Done.
| |
| 75 { | |
| 76 return this; | |
|
pfeldman
2015/09/02 21:13:26
You should return what you need here:
{ type: thi
kozy
2015/09/02 22:40:20
Done.
| |
| 77 } | |
| 78 | |
| 79 /** | |
| 80 * @suppressReceiverCheck | |
| 81 * @return {function()} | |
| 82 * @this {Object} | |
| 83 */ | |
| 84 function listenerEffectiveFunction() | |
| 85 { | |
| 86 if (typeof this.handler === "function") | |
| 87 return this.handler; | |
| 88 return typeof this.handler === "object" ? (this.handler.handlerE vent || this.handler.constructor) : null; | |
|
pfeldman
2015/09/02 21:13:26
What is handlerEvent?
kozy
2015/09/02 22:40:19
Removed.
| |
| 89 } | |
| 90 | |
| 91 /** | |
| 92 * @param {!WebInspector.RemoteObject} functionObject | |
| 93 * @return {!Promise<void>} | |
| 94 */ | |
| 95 function storeFunctionWithDetails(functionObject) | |
| 96 { | |
| 97 eventListenerData.handlerFunction = functionObject; | |
| 98 return /** @type {!Promise<void>} */(functionObject.functionDeta ilsPromise().then(storeResultTo.bind(null, eventListenerData, "handlerDetails")) ); | |
|
pfeldman
2015/09/02 21:13:25
Remove all storeTo
kozy
2015/09/02 22:40:19
Done.
| |
| 99 } | |
| 100 | |
| 101 /** | |
| 102 * @param {!{jsonData: {type:string, useCapture:boolean, handler:fun ction()}, handlerFunction: !WebInspector.RemoteObject, handlerDetails: !WebInspe ctor.DebuggerModel.FunctionDetails}} eventListenerData | |
| 103 * @return {!WebInspector.EventListener} | |
| 104 */ | |
| 105 function createEventListener(eventListenerData) | |
| 106 { | |
| 107 return new WebInspector.EventListener(eventListenerData.handlerF unction._target, | |
| 108 eventListenerData.jsonData .type, | |
| 109 eventListenerData.jsonData .useCapture, | |
| 110 eventListenerData.handlerF unction, | |
| 111 /** @type {!WebInspector.D ebuggerModel.Location}} */ (eventListenerData.handlerDetails.location), | |
| 112 "frameworkUser"); | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 /** | |
| 117 * @param {!WebInspector.RemoteObject} functionObject | |
| 118 * @return {!Promise<!WebInspector.RemoteObject>} | |
| 119 */ | |
| 120 function toTargetFunction(functionObject) | |
| 121 { | |
| 122 return WebInspector.RemoteFunction.objectAsFunction(functionObject). targetFunction(); | |
| 123 } | |
| 124 | |
| 125 /** | |
| 126 * @param {!Array<?T>} objects | |
| 127 * @return {!Array<!T>} | |
| 128 * @template T | |
| 129 */ | |
| 130 function nonEmptyObjects(objects) | |
| 131 { | |
| 132 return objects.filter(filterOutEmpty); | |
| 133 | |
| 134 /** | |
| 135 * @param {?T} object | |
| 136 * @return {boolean} | |
| 137 * @template T | |
| 138 */ | |
| 139 function filterOutEmpty(object) | |
| 140 { | |
| 141 return !!object; | |
| 142 } | |
| 143 } | |
| 144 } | |
| 145 | |
| 146 /** | |
| 147 * @return {!{eventListeners:!Array<!WebInspector.EventListener>, internalHa ndlers:?WebInspector.RemoteArray}} | |
| 148 */ | |
| 149 function returnResult() | |
| 150 { | |
| 151 return /**@type {!{eventListeners:!Array<!WebInspector.EventListener>, i nternalHandlers:?WebInspector.RemoteArray}} */(listenersResult); | |
| 152 } | |
| 153 | |
| 154 /** | |
| 155 * @param {!WebInspector.CallFunctionResult} result | |
| 156 * @return {!WebInspector.RemoteObject} | |
| 157 */ | |
| 158 function assertCallFunctionResult(result) | |
| 159 { | |
| 160 if (result.wasThrown || !result.object) | |
| 161 throw new Error("Exception in callFunction or empty result"); | |
|
pfeldman
2015/09/02 21:13:25
We don't throw on expected / user errors.
kozy
2015/09/02 22:40:20
Errors are encapsulated in this file. Can I still
| |
| 162 return result.object; | |
| 163 } | |
| 164 | |
| 165 /* | |
| 166 frameworkEventListeners getter functions should produce following output: | |
| 167 { | |
| 168 // framework event listeners | |
| 169 "eventListeners": [ | |
| 170 { | |
| 171 "handler": function()|Object, | |
|
pfeldman
2015/09/02 21:13:26
Why handler is not a function?
kozy
2015/09/02 22:40:19
function()
| |
| 172 "useCapture": true, | |
| 173 "type": "change" | |
| 174 }, | |
| 175 ... | |
| 176 ], | |
| 177 // internal framework event handlers | |
| 178 "internalHandlers": [ | |
| 179 function(), | |
| 180 function(), | |
| 181 ... | |
| 182 ] | |
| 183 } | |
| 184 */ | |
| 185 /** | |
| 186 * @suppressReceiverCheck | |
| 187 * @return {!{eventListeners:!Array<!{type:string, handler:(function()|!Obje ct), useCapture:boolean}>, internalHandlers:?Array<function()>}} | |
| 188 * @this {Object} | |
| 189 */ | |
| 190 function frameworkEventListenersGetter() | |
|
pfeldman
2015/09/02 21:13:26
Could you typedef what it returns?
kozy
2015/09/02 22:40:19
Done.
| |
| 191 { | |
| 192 var eventListeners = []; | |
| 193 var internalHandlers = []; | |
| 194 var getters = [jQueryGetter]; | |
| 195 try { | |
| 196 if (self.devtoolsFrameworkEventListeners && isArrayLike(self.devtool sFrameworkEventListeners)) | |
| 197 getters = getters.concat(self.devtoolsFrameworkEventListeners); | |
| 198 } catch (e) { | |
| 199 } | |
| 200 | |
| 201 for (var i = 0; i < getters.length; ++i) { | |
| 202 try { | |
| 203 var getterResult = getters[i](this); | |
| 204 eventListeners = eventListeners.concat(getterResult.eventListene rs); | |
| 205 internalHandlers = internalHandlers.concat(getterResult.internal Handlers); | |
| 206 } catch (e) { | |
| 207 } | |
| 208 } | |
| 209 var result = {eventListeners: eventListeners}; | |
| 210 if (internalHandlers.length) | |
| 211 result.internalHandlers = internalHandlers; | |
| 212 return result; | |
| 213 | |
| 214 /** | |
| 215 * @param {?Object} obj | |
| 216 * @return {boolean} | |
| 217 */ | |
| 218 function isArrayLike(obj) | |
| 219 { | |
| 220 if (!obj || typeof obj !== "object") | |
| 221 return false; | |
| 222 try { | |
| 223 if (typeof obj.splice === "function") { | |
| 224 var len = obj.length; | |
| 225 return typeof len === "number" && (len >>> 0 === len && (len > 0 || 1 / len > 0)); | |
| 226 } | |
| 227 } catch (e) { | |
| 228 } | |
| 229 return false; | |
| 230 } | |
| 231 | |
| 232 function jQueryGetter(node) | |
| 233 { | |
| 234 return {eventListeners: jQueryEventListeners(node), internalHandlers : jQueryInternalHandlers(node)}; | |
| 235 } | |
| 236 | |
| 237 /** | |
| 238 * @param {?Object} node | |
| 239 * @return {!Array<!{handler:function(), useCapture: boolean, type:strin g}>} | |
| 240 * @suppress {missingProperties|undefinedVars} | |
| 241 */ | |
| 242 function jQueryEventListeners(node) | |
| 243 { | |
| 244 if (!node || !(node instanceof Node)) | |
| 245 return []; | |
| 246 var hasJQuery = (typeof jQuery !== 'undefined') && jQuery.fn; | |
|
pfeldman
2015/09/02 21:13:26
Should be window["jQuery"]
kozy
2015/09/02 22:40:20
Done.
| |
| 247 if (!hasJQuery) | |
| 248 return []; | |
| 249 var listeners = []; | |
| 250 var data = jQuery._data || jQuery.data; | |
| 251 if (typeof data === "function") { | |
| 252 var events = data(node, "events"); | |
| 253 for (var type in events) { | |
| 254 for (var key in events[type]) { | |
| 255 var frameworkListener = events[type][key]; | |
| 256 if (typeof frameworkListener === "object" || typeof fram eworkListener === "function") { | |
| 257 var listener = { | |
| 258 handler: frameworkListener.handler || frameworkL istener, | |
| 259 useCapture: true, | |
| 260 type: type | |
| 261 }; | |
| 262 listeners.push(listener); | |
| 263 } | |
| 264 } | |
| 265 } | |
| 266 } | |
| 267 var entry = jQuery(node)[0]; | |
| 268 if (entry) { | |
| 269 var entryEvents = entry["$events"]; | |
| 270 for (var type in entryEvents) { | |
| 271 var events = entryEvents[type]; | |
| 272 for (var key in events) { | |
| 273 if (typeof events[key] === "function") { | |
| 274 var listener = { | |
| 275 handler: events[key], | |
| 276 useCapture: true, | |
| 277 type: type | |
| 278 }; | |
| 279 listeners.push(listener); | |
| 280 } | |
| 281 } | |
| 282 } | |
| 283 } | |
| 284 return listeners; | |
| 285 } | |
| 286 | |
| 287 /** | |
| 288 * @param {?Object} node | |
| 289 * @return {!Array<function()>} | |
| 290 * @suppress {missingProperties|undefinedVars} | |
| 291 */ | |
| 292 function jQueryInternalHandlers(node) | |
|
pfeldman
2015/09/02 21:13:26
Embed into the one above.
kozy
2015/09/02 22:40:20
Done.
| |
| 293 { | |
| 294 if (!(node instanceof Node)) | |
| 295 return []; | |
| 296 var hasJQuery = (typeof jQuery !== 'undefined') && jQuery.fn; | |
| 297 if (!hasJQuery) | |
| 298 return []; | |
| 299 var handlers = []; | |
| 300 var data = jQuery._data || jQuery.data; | |
| 301 if (typeof data === "function") { | |
| 302 var nodeData = data(node); | |
| 303 if (typeof nodeData.handle === "function") | |
| 304 handlers.push(nodeData.handle); | |
| 305 } | |
| 306 var entry = jQuery(node)[0]; | |
| 307 if (entry && entry["$handle"]) | |
| 308 handlers.push(entry["$handle"]); | |
| 309 return handlers; | |
| 310 } | |
| 311 } | |
| 312 } | |
| OLD | NEW |