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

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 * @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 }
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