Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1205)

Side by Side Diff: Source/devtools/front_end/components/EventListenersUtils.js

Issue 1268353005: [DevTools] Support JQuery event listeners (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 * @typedef {{type: string, useCapture: boolean, handler: function()}}
7 */
8 WebInspector.FrameworkEventListener;
pfeldman 2015/09/02 22:55:34 What is the difference between all of these types?
kozy 2015/09/03 16:27:52 Rename page types to Page*
9
10 /**
11 * @typedef {{type:string, useCapture:boolean, handler:!WebInspector.RemoteObjec t, location:!WebInspector.DebuggerModel.Location}}
12 */
13 WebInspector.EventListenerData;
14
15 /**
16 * @typedef {{eventListeners:!Array<!{type:string, handler:function(), useCaptur e:boolean}>, internalHandlers:?Array<function()>}}
17 */
18 WebInspector.FrameworkEventListenerRawResult;
19
20 /**
21 * @typedef {{eventListeners:!Array<!WebInspector.EventListener>, internalHandle rs:?WebInspector.RemoteArray}}
22 */
23 WebInspector.FrameworkEventListenersResult;
24
25 /**
26 * @param {!WebInspector.RemoteObject} object
27 * @return {!Promise<!WebInspector.FrameworkEventListenersResult>}
28 */
29 WebInspector.EventListener.frameworkEventListeners = function(object)
30 {
31 var listenersResult = /** @type {!WebInspector.FrameworkEventListenersResult } */({eventListeners: []});
32 return object.callFunctionPromise(frameworkEventListeners, undefined)
33 .then(assertCallFunctionResult)
34 .then(frameworkEventListenersCallback)
35 .then(returnResult)
36 .catchException(listenersResult);
37
38 /**
39 * @param {!WebInspector.RemoteObject} object
40 * @return {!Promise<undefined>}
41 */
42 function frameworkEventListenersCallback(object)
pfeldman 2015/09/02 22:55:34 You should call them based on what they do, not wh
kozy 2015/09/03 16:27:52 Done.
43 {
44 return object.getOwnPropertiesPromise().then(propertiesCallback);
pfeldman 2015/09/02 22:55:34 Why is propertiesCallback now here? Stack it above
kozy 2015/09/03 16:27:52 Done.
45 }
46
47 /**
48 * @param {!{properties: ?Array<!WebInspector.RemoteObjectProperty>, interna lProperties: ?Array<!WebInspector.RemoteObjectProperty>}} result
49 * @return {!Promise<undefined>}
50 */
51 function propertiesCallback(result)
52 {
53 if (!result.properties)
54 throw new Error("Object properties is empty");
55 var promises = [];
56 for (var property of result.properties) {
57 if (property.name === "eventListeners" && property.value) {
58 promises.push(WebInspector.RemoteArray.objectAsArray(property.va lue)
pfeldman 2015/09/02 22:55:34 Extract this into the method that returns eventLis
kozy 2015/09/03 16:27:52 Done.
59 .map(toEventListener)
60 .then(nonEmptyObjects)
61 .then(eventListenersCallba ck));
pfeldman 2015/09/02 22:55:34 Promise<eventListeners>
kozy 2015/09/03 16:27:52 Done.
62 }
63 if (property.name === "internalHandlers" && property.value) {
64 promises.push(WebInspector.RemoteArray.objectAsArray(property.va lue)
pfeldman 2015/09/02 22:55:34 Extract this into the method that returns Promise<
kozy 2015/09/03 16:27:52 Done.
65 .map(toTargetFunction)
66 .then(WebInspector.RemoteA rray.createFromRemoteObjects)
67 .then(internalHandlersCall back));
68 }
69 }
70 return /** @type {!Promise<undefined>} */(Promise.all(promises));
71
72 /**
73 * @param {!WebInspector.RemoteObject} listenerObject
74 * @return {!Promise<?WebInspector.EventListener>}
75 */
76 function toEventListener(listenerObject)
77 {
78 var eventListenerData = /** @type {!WebInspector.EventListenerData} */({});
79 var promises = [];
80
81 promises.push(listenerObject.callFunctionJSONPromise(truncateFramewo rkEventListener, undefined).then(truncateFrameworkEventListenerCallback));
82
83 /**
84 * @suppressReceiverCheck
85 * @this {WebInspector.FrameworkEventListener}
86 * @return {!{type:string, useCapture:boolean}}
87 */
88 function truncateFrameworkEventListener()
89 {
90 return {type: this.type, useCapture: this.useCapture};
91 }
92
93 /**
94 * @param {!{type:string, useCapture: boolean}} truncatedListener
95 * @return {undefined}
96 */
97 function truncateFrameworkEventListenerCallback(truncatedListener)
pfeldman 2015/09/02 22:55:34 strip the Callback suffixes in all over the place,
kozy 2015/09/03 16:27:52 Done.
98 {
99 eventListenerData.type = truncatedListener.type;
100 eventListenerData.useCapture = truncatedListener.useCapture;
101 return undefined;
102 }
103
104 promises.push(listenerObject.callFunctionPromise(handlerFunction).th en(assertCallFunctionResult)
105 .then(toTargetFunction)
106 .then(toTargetFunctionCallback));
107
108 /**
109 * @suppressReceiverCheck
110 * @return {function()}
111 * @this {WebInspector.FrameworkEventListener}
112 */
113 function handlerFunction()
114 {
115 return this.handler;
116 }
117
118 /**
119 * @param {!WebInspector.RemoteObject} functionObject
120 * @return {!Promise<undefined>}
121 */
122 function toTargetFunctionCallback(functionObject)
123 {
124 eventListenerData.handler = functionObject;
125 return /** @type {!Promise<undefined>} */(functionObject.functio nDetailsPromise().then(targetFunctionDetailsCallback));
126 }
127
128 /**
129 * @param {?WebInspector.DebuggerModel.FunctionDetails} functionDeta ils
130 */
131 function targetFunctionDetailsCallback(functionDetails)
132 {
133 if (!functionDetails || !functionDetails.location)
134 throw new Error("Empty function details or function details location");
135 eventListenerData.location = functionDetails.location;
136 }
137
138 return Promise.all(promises).then(createEventListener).catchExceptio n(/** @type {?WebInspector.EventListener} */(null));
139
140 /**
141 * @return {!WebInspector.EventListener}
142 */
143 function createEventListener()
144 {
145 return new WebInspector.EventListener(eventListenerData.handler. _target,
146 eventListenerData.type,
147 eventListenerData.useCaptu re,
148 eventListenerData.handler,
149 eventListenerData.location ,
150 "frameworkUser");
151 }
152 }
153
154 /**
155 * @param {!WebInspector.RemoteObject} functionObject
156 * @return {!Promise<!WebInspector.RemoteObject>}
157 */
158 function toTargetFunction(functionObject)
159 {
160 return WebInspector.RemoteFunction.objectAsFunction(functionObject). targetFunction();
161 }
162
163 /**
164 * @param {!Array<?T>} objects
165 * @return {!Array<!T>}
166 * @template T
167 */
168 function nonEmptyObjects(objects)
169 {
170 return objects.filter(filterOutEmpty);
171
172 /**
173 * @param {?T} object
174 * @return {boolean}
175 * @template T
176 */
177 function filterOutEmpty(object)
178 {
179 return !!object;
180 }
181 }
182 }
183
184 /**
185 * @param {!Array<!WebInspector.EventListener>} eventListeners
186 */
187 function eventListenersCallback(eventListeners)
188 {
189 listenersResult.eventListeners = eventListeners;
190 }
191
192 /**
193 * @param {!WebInspector.RemoteArray} internalHandlers
194 */
195 function internalHandlersCallback(internalHandlers)
196 {
197 listenersResult.internalHandlers = internalHandlers;
198 }
199
200 /**
201 * @return {!WebInspector.FrameworkEventListenersResult}
202 */
203 function returnResult()
204 {
205 return listenersResult;
206 }
207
208 /**
209 * @param {!WebInspector.CallFunctionResult} result
210 * @return {!WebInspector.RemoteObject}
211 */
212 function assertCallFunctionResult(result)
213 {
214 if (result.wasThrown || !result.object)
215 throw new Error("Exception in callFunction or empty result");
216 return result.object;
217 }
218
219 /*
220 frameworkEventListeners fetcher functions should produce following output:
221 {
222 // framework event listeners
223 "eventListeners": [
224 {
225 "handler": function(),
226 "useCapture": true,
227 "type": "change"
228 },
229 ...
230 ],
231 // internal framework event handlers
232 "internalHandlers": [
233 function(),
234 function(),
235 ...
236 ]
237 }
238 */
239 /**
240 * @suppressReceiverCheck
241 * @return {!WebInspector.FrameworkEventListenerRawResult}
242 * @this {Object}
243 */
244 function frameworkEventListeners()
245 {
246 var eventListeners = [];
247 var internalHandlers = [];
248 var fetchers = [jQueryFetcher];
249 try {
250 if (self.devtoolsFrameworkEventListeners && isArrayLike(self.devtool sFrameworkEventListeners))
251 fetchers = fetchers.concat(self.devtoolsFrameworkEventListeners) ;
252 } catch (e) {
253 }
254
255 for (var i = 0; i < fetchers.length; ++i) {
256 try {
257 var fetcherResult = fetchers[i](this);
258 eventListeners = eventListeners.concat(fetcherResult.eventListen ers);
259 if (fetcherResult.internalHandlers)
260 internalHandlers = internalHandlers.concat(fetcherResult.int ernalHandlers);
261 } catch (e) {
262 }
263 }
264 var result = {eventListeners: eventListeners};
265 if (internalHandlers.length)
266 result.internalHandlers = internalHandlers;
267 return result;
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 function jQueryFetcher(node)
288 {
289 if (!node || !(node instanceof Node))
290 return {eventListeners: []};
291 var jQuery = /** @type {?{fn,data,_data}}*/(window["jQuery"]);
292 if (!jQuery || !jQuery.fn)
293 return {eventListeners: []};
294 var jQueryFunction = /** @type {function(!Node)} */(jQuery);
295 var data = jQuery._data || jQuery.data;
296
297 var eventListeners = [];
298 var internalHandlers = [];
299
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 fram eworkListener === "function") {
306 var listener = {
307 handler: frameworkListener.handler || frameworkL istener,
308 useCapture: true,
309 type: type
310 };
311 eventListeners.push(listener);
312 }
313 }
314 }
315 var nodeData = data(node);
316 if (typeof nodeData.handle === "function")
317 internalHandlers.push(nodeData.handle);
318 }
319 var entry = jQueryFunction(node)[0];
320 if (entry) {
321 var entryEvents = entry["$events"];
322 for (var type in entryEvents) {
323 var events = entryEvents[type];
324 for (var key in events) {
325 if (typeof events[key] === "function") {
326 var listener = {
327 handler: events[key],
328 useCapture: true,
329 type: type
330 };
331 eventListeners.push(listener);
332 }
333 }
334 }
335 if (entry && entry["$handle"])
336 internalHandlers.push(entry["$handle"]);
337 }
338 return {eventListeners: eventListeners, internalHandlers: internalHa ndlers};
339 }
340 }
341 }
OLDNEW
« no previous file with comments | « Source/devtools/devtools.gypi ('k') | Source/devtools/front_end/components/EventListenersView.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698