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 |