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

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 /** @typedef {{eventListeners:!Array<!WebInspector.EventListener>, internalHandl ers:?WebInspector.RemoteArray}} */
6 WebInspector.FrameworkEventListenersObject;
7
8 /** @typedef {{type: string, useCapture: boolean, handler: function()}} */
9 WebInspector.EventListenerObjectInInspectedPage;
10
11 /**
12 * @param {!WebInspector.RemoteObject} object
13 * @return {!Promise<!WebInspector.FrameworkEventListenersObject>}
14 */
15 WebInspector.EventListener.frameworkEventListeners = function(object)
16 {
17 var listenersResult = /** @type {!WebInspector.FrameworkEventListenersObject } */({eventListeners: []});
18 return object.callFunctionPromise(frameworkEventListeners, undefined)
19 .then(assertCallFunctionResult)
20 .then(getOwnProperties)
21 .then(createEventListeners)
22 .then(returnResult)
23 .catchException(listenersResult);
24
25 /**
26 * @param {!WebInspector.RemoteObject} object
27 * @return {!Promise<!{properties: ?Array.<!WebInspector.RemoteObjectPropert y>, internalProperties: ?Array.<!WebInspector.RemoteObjectProperty>}>}
28 */
29 function getOwnProperties(object)
30 {
31 return object.getOwnPropertiesPromise();
32 }
33
34 /**
35 * @param {!{properties: ?Array<!WebInspector.RemoteObjectProperty>, interna lProperties: ?Array<!WebInspector.RemoteObjectProperty>}} result
36 * @return {!Promise<undefined>}
37 */
38 function createEventListeners(result)
39 {
40 if (!result.properties)
41 throw new Error("Object properties is empty");
42 var promises = [];
43 for (var property of result.properties) {
44 if (property.name === "eventListeners" && property.value)
45 promises.push(convertToEventListeners(property.value).then(store EventListeners));
46 if (property.name === "internalHandlers" && property.value)
47 promises.push(convertToInternalHandlers(property.value).then(sto reInternalHandlers));
48 }
49 return /** @type {!Promise<undefined>} */(Promise.all(promises));
50 }
51
52 /**
53 * @param {!WebInspector.RemoteObject} pageEventListenersObject
54 * @return {!Promise<!Array<!WebInspector.EventListener>>}
55 */
56 function convertToEventListeners(pageEventListenersObject)
57 {
58 return WebInspector.RemoteArray.objectAsArray(pageEventListenersObject). map(toEventListener).then(filterOutEmptyObjects);
59
60 /**
61 * @param {!WebInspector.RemoteObject} listenerObject
62 * @return {!Promise<?WebInspector.EventListener>}
63 */
64 function toEventListener(listenerObject)
65 {
66 /** @type {string} */
67 var type;
68 /** @type {boolean} */
69 var useCapture;
70 /** @type {?WebInspector.RemoteObject} */
71 var handler = null;
72 /** @type {?WebInspector.DebuggerModel.Location} */
73 var location = null;
74
75 var promises = [];
76 promises.push(listenerObject.callFunctionJSONPromise(truncatePageEve ntListener, undefined).then(storeTrunkatedListener));
77
78 /**
79 * @suppressReceiverCheck
80 * @this {WebInspector.EventListenerObjectInInspectedPage}
81 * @return {!{type:string, useCapture:boolean}}
82 */
83 function truncatePageEventListener()
84 {
85 return {type: this.type, useCapture: this.useCapture};
86 }
87
88 /**
89 * @param {!{type:string, useCapture: boolean}} truncatedListener
90 */
91 function storeTrunkatedListener(truncatedListener)
92 {
93 type = truncatedListener.type;
94 useCapture = truncatedListener.useCapture;
95 }
96
97 promises.push(listenerObject.callFunctionPromise(handlerFunction).th en(assertCallFunctionResult).then(toTargetFunction).then(storeFunctionWithDetail s));
98
99 /**
100 * @suppressReceiverCheck
101 * @return {function()}
102 * @this {WebInspector.EventListenerObjectInInspectedPage}
103 */
104 function handlerFunction()
105 {
106 return this.handler;
107 }
108
109 /**
110 * @param {!WebInspector.RemoteObject} functionObject
111 * @return {!Promise<undefined>}
112 */
113 function storeFunctionWithDetails(functionObject)
114 {
115 handler = functionObject;
116 return /** @type {!Promise<undefined>} */(functionObject.functio nDetailsPromise().then(storeFunctionDetails));
117 }
118
119 /**
120 * @param {?WebInspector.DebuggerModel.FunctionDetails} functionDeta ils
121 */
122 function storeFunctionDetails(functionDetails)
123 {
124 location = functionDetails ? functionDetails.location : null;
125 }
126
127 return Promise.all(promises).then(createEventListener).catchExceptio n(/** @type {?WebInspector.EventListener} */(null));
128
129 /**
130 * @return {!WebInspector.EventListener}
131 */
132 function createEventListener()
133 {
134 if (!location)
135 throw new Error("Empty event listener's location");
136 return new WebInspector.EventListener(handler._target, type, use Capture, handler, location, "frameworkUser");
137 }
138 }
139 }
140
141 /**
142 * @param {!WebInspector.RemoteObject} pageInternalHandlersObject
143 * @return {!Promise<!WebInspector.RemoteArray>}
144 */
145 function convertToInternalHandlers(pageInternalHandlersObject)
146 {
147 return WebInspector.RemoteArray.objectAsArray(pageInternalHandlersObject ).map(toTargetFunction)
148 .then(WebInspector.RemoteArray.createFrom RemoteObjects);
149 }
150
151 /**
152 * @param {!WebInspector.RemoteObject} functionObject
153 * @return {!Promise<!WebInspector.RemoteObject>}
154 */
155 function toTargetFunction(functionObject)
156 {
157 return WebInspector.RemoteFunction.objectAsFunction(functionObject).targ etFunction();
158 }
159
160 /**
161 * @param {!Array<!WebInspector.EventListener>} eventListeners
162 */
163 function storeEventListeners(eventListeners)
164 {
165 listenersResult.eventListeners = eventListeners;
166 }
167
168 /**
169 * @param {!WebInspector.RemoteArray} internalHandlers
170 */
171 function storeInternalHandlers(internalHandlers)
172 {
173 listenersResult.internalHandlers = internalHandlers;
174 }
175
176 /**
177 * @return {!WebInspector.FrameworkEventListenersObject}
178 */
179 function returnResult()
180 {
181 return listenersResult;
182 }
183
184 /**
185 * @param {!WebInspector.CallFunctionResult} result
186 * @return {!WebInspector.RemoteObject}
187 */
188 function assertCallFunctionResult(result)
189 {
190 if (result.wasThrown || !result.object)
191 throw new Error("Exception in callFunction or empty result");
192 return result.object;
193 }
194
195 /**
196 * @param {!Array<?T>} objects
197 * @return {!Array<!T>}
198 * @template T
199 */
200 function filterOutEmptyObjects(objects)
201 {
202 return objects.filter(filterOutEmpty);
203
204 /**
205 * @param {?T} object
206 * @return {boolean}
207 * @template T
208 */
209 function filterOutEmpty(object)
210 {
211 return !!object;
212 }
213 }
214
215 /*
216 frameworkEventListeners fetcher functions should produce following output:
217 {
218 // framework event listeners
219 "eventListeners": [
220 {
221 "handler": function(),
222 "useCapture": true,
223 "type": "change"
224 },
225 ...
226 ],
227 // internal framework event handlers
228 "internalHandlers": [
229 function(),
230 function(),
231 ...
232 ]
233 }
234 */
235 /**
236 * @suppressReceiverCheck
237 * @return {!{eventListeners:!Array<!WebInspector.EventListenerObjectInInspe ctedPage>, internalHandlers:?Array<function()>}}
238 * @this {Object}
239 */
240 function frameworkEventListeners()
241 {
242 var eventListeners = [];
243 var internalHandlers = [];
244 var fetchers = [jQueryFetcher];
245 try {
246 if (self.devtoolsPageEventListeners && isArrayLike(self.devtoolsPage EventListeners))
247 fetchers = fetchers.concat(self.devtoolsPageEventListeners);
248 } catch (e) {
249 }
250
251 for (var i = 0; i < fetchers.length; ++i) {
252 try {
253 var fetcherResult = fetchers[i](this);
254 eventListeners = eventListeners.concat(fetcherResult.eventListen ers);
255 if (fetcherResult.internalHandlers)
256 internalHandlers = internalHandlers.concat(fetcherResult.int ernalHandlers);
257 } catch (e) {
258 }
259 }
260 var result = {eventListeners: eventListeners};
261 if (internalHandlers.length)
262 result.internalHandlers = internalHandlers;
263 return result;
264
265 /**
266 * @param {?Object} obj
267 * @return {boolean}
268 */
269 function isArrayLike(obj)
270 {
271 if (!obj || typeof obj !== "object")
272 return false;
273 try {
274 if (typeof obj.splice === "function") {
275 var len = obj.length;
276 return typeof len === "number" && (len >>> 0 === len && (len > 0 || 1 / len > 0));
277 }
278 } catch (e) {
279 }
280 return false;
281 }
282
283 function jQueryFetcher(node)
284 {
285 if (!node || !(node instanceof Node))
286 return {eventListeners: []};
287 var jQuery = /** @type {?{fn,data,_data}}*/(window["jQuery"]);
288 if (!jQuery || !jQuery.fn)
289 return {eventListeners: []};
290 var jQueryFunction = /** @type {function(!Node)} */(jQuery);
291 var data = jQuery._data || jQuery.data;
292
293 var eventListeners = [];
294 var internalHandlers = [];
295
296 if (typeof data === "function") {
297 var events = data(node, "events");
298 for (var type in events) {
299 for (var key in events[type]) {
300 var frameworkListener = events[type][key];
301 if (typeof frameworkListener === "object" || typeof fram eworkListener === "function") {
302 var listener = {
303 handler: frameworkListener.handler || frameworkL istener,
304 useCapture: true,
305 type: type
306 };
307 eventListeners.push(listener);
308 }
309 }
310 }
311 var nodeData = data(node);
312 if (typeof nodeData.handle === "function")
313 internalHandlers.push(nodeData.handle);
314 }
315 var entry = jQueryFunction(node)[0];
316 if (entry) {
317 var entryEvents = entry["$events"];
318 for (var type in entryEvents) {
319 var events = entryEvents[type];
320 for (var key in events) {
321 if (typeof events[key] === "function") {
322 var listener = {
323 handler: events[key],
324 useCapture: true,
325 type: type
326 };
327 eventListeners.push(listener);
328 }
329 }
330 }
331 if (entry && entry["$handle"])
332 internalHandlers.push(entry["$handle"]);
333 }
334 return {eventListeners: eventListeners, internalHandlers: internalHa ndlers};
335 }
336 }
337 }
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