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

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 * @param {function(this:Object):{eventListeners:!Array<!{type:string, handler:( function()|!Object), useCapture:boolean}>, internalHandlers:?Array<function()>}} getter
8 * @return {!Promise<!{eventListeners:!Array<!WebInspector.EventListener>, inter nalHandlers:?WebInspector.RemoteArray}>}
9 */
10 WebInspector.frameworkEventListeners = function(object, getter)
pfeldman 2015/09/02 02:58:52 Please don't put anything on the global WebInspect
pfeldman 2015/09/02 02:58:52 What is getter?
kozy 2015/09/02 17:34:13 Moved to WebInspector.EventListener
kozy 2015/09/02 17:34:13 Getter is moved into this function.
11 {
12 var listenersResult = {eventListeners: []};
13 return object.callFunctionPromise(getter, undefined)
14 .then(assertCallFunctionResult)
15 .then(getterCallback)
16 .then(propertiesCallback)
17 .then(returnResult);
18
19 /**
20 * @param {!WebInspector.RemoteObject} object
21 * @return {!Promise<!{properties: ?Array<!WebInspector.RemoteObjectProperty >, internalProperties: ?Array<!WebInspector.RemoteObjectProperty>}>}
22 */
23 function getterCallback(object)
24 {
25 return object.getOwnPropertiesPromise();
26 }
27
28 /**
29 * @param {!{properties: ?Array<!WebInspector.RemoteObjectProperty>, interna lProperties: ?Array<!WebInspector.RemoteObjectProperty>}} result
30 * @return {!Promise<void>}
31 */
32 function propertiesCallback(result)
33 {
34 if (!result.properties)
35 return Promise.resolve();
36 var promises = [];
37 for (var property of result.properties) {
38 if (property.name === "eventListeners" && property.value) {
pfeldman 2015/09/02 02:58:52 Could you explain the structure of the objects you
kozy 2015/09/02 17:34:13 Added before frameworkEventListenersGetter functio
39 promises.push(WebInspector.RemoteArray.createFromObject(property .value)
40 .map(toEventListener)
41 .then(nonEmptyObjects)
42 .then(storeResultTo.bind(n ull, listenersResult, "eventListeners")));
43 }
44 if (property.name === "internalHandlers" && property.value) {
45 promises.push(WebInspector.RemoteArray.createFromObject(property .value)
46 .map(toTargetFunction)
47 .then(WebInspector.RemoteA rray.createFromArray)
48 .then(storeResultTo.bind(n ull, listenersResult, "internalHandlers")));
49 }
50 }
51 return /** @type {!Promise<void>} */(Promise.all(promises));
52
53 /**
54 * @param {!WebInspector.RemoteObject} listenerObject
55 * @return {!Promise<?WebInspector.EventListener>}
56 */
57 function toEventListener(listenerObject)
58 {
59 /** @type {?} */
60 var eventListenerData = {};
61 var promises = [];
62
63 promises.push(listenerObject.callFunctionJSONPromise(identity, undef ined).then(storeResultTo.bind(null, eventListenerData, "jsonData")));
64 promises.push(listenerObject.callFunctionPromise(listenerEffectiveFu nction).then(assertCallFunctionResult)
65 .then(toTargetFunction)
66 .then(storeFunctionWithDetails));
67 return Promise.all(promises).then(createEventListener.bind(null, eve ntListenerData)).catchException(/** @type {?WebInspector.EventListener} */(null) );
68
69 /**
70 * @suppressReceiverCheck
71 * @this {T}
72 * @return {T}
73 * @template T
74 */
75 function identity()
76 {
77 return this;
78 }
79
80 /**
81 * @suppressReceiverCheck
82 * @return {function()}
83 * @this {Object}
84 */
85 function listenerEffectiveFunction()
86 {
87 if (typeof this.handler === "function")
88 return this.handler;
89 return typeof this.handler === "object" ? (this.handler.handlerE vent || this.handler.constructor) : null;
90 }
91
92 /**
93 * @param {!WebInspector.RemoteObject} functionObject
94 * @return {!Promise<void>}
95 */
96 function storeFunctionWithDetails(functionObject)
97 {
98 eventListenerData.handlerFunction = functionObject;
99 return /** @type {!Promise<void>} */(functionObject.functionDeta ilsPromise().then(storeResultTo.bind(null, eventListenerData, "handlerDetails")) );
100 }
101
102 /**
103 * @param {!{jsonData: {type:string, useCapture:boolean, handler:fun ction()}, handlerFunction: !WebInspector.RemoteObject, handlerDetails: !WebInspe ctor.DebuggerModel.FunctionDetails}} eventListenerData
104 * @return {!WebInspector.EventListener}
105 */
106 function createEventListener(eventListenerData)
107 {
108 return new WebInspector.EventListener(eventListenerData.handlerF unction._target,
109 eventListenerData.jsonData .type,
110 eventListenerData.jsonData .useCapture,
111 eventListenerData.handlerF unction,
112 /** @type {!WebInspector.D ebuggerModel.Location}} */ (eventListenerData.handlerDetails.location),
113 "frameworkUser");
114 }
115 }
116
117 /**
118 * @param {!WebInspector.RemoteObject} functionObject
119 * @return {!Promise<!WebInspector.RemoteObject>}
120 */
121 function toTargetFunction(functionObject)
122 {
123 return WebInspector.RemoteFunction.createFromObject(functionObject). targetFunction();
124 }
125
126 /**
127 * @param {!Array<?T>} objects
128 * @return {!Array<!T>}
129 * @template T
130 */
131 function nonEmptyObjects(objects)
132 {
133 return objects.filter(filterOutEmpty);
134
135 /**
136 * @param {?T} object
137 * @return {boolean}
138 * @template T
139 */
140 function filterOutEmpty(object)
141 {
142 return !!object;
143 }
144 }
145 }
146
147 /**
148 * @return {!{eventListeners:!Array<!WebInspector.EventListener>, internalHa ndlers:?WebInspector.RemoteArray}}
149 */
150 function returnResult()
151 {
152 return /**@type {!{eventListeners:!Array<!WebInspector.EventListener>, i nternalHandlers:?WebInspector.RemoteArray}} */(listenersResult);
153 }
154
155 /**
156 * @param {!WebInspector.CallFunctionResult} result
157 * @return {!WebInspector.RemoteObject}
158 */
159 function assertCallFunctionResult(result)
160 {
161 if (result.wasThrown || !result.object)
162 throw new Error("Exception in callFunction or empty result");
163 return result.object;
164 }
165 }
166
167 /**
168 * @this {Object}
169 */
170 WebInspector._frameworkEventListenersGetter = function()
pfeldman 2015/09/02 02:58:51 Where is this used?
kozy 2015/09/02 17:34:13 Moved to WebInspector.EventListener.frameworkEvent
171 {
172 var eventListeners = [];
173 var internalHandlers = [];
174 var getters = [jQueryGetter];
175 try {
176 if (self.devtoolsFrameworkEventListeners && isArrayLike(self.devtoolsFra meworkEventListeners))
177 getters = getters.concat(self.devtoolsFrameworkEventListeners);
178 } catch (e) {
179 }
180
181 for (var i = 0; i < getters.length; ++i) {
182 try {
183 var getterResult = getters[i](this);
184 eventListeners = eventListeners.concat(getterResult.eventListeners);
185 internalHandlers = internalHandlers.concat(getterResult.internalHand lers);
186 } catch (e) {
187 }
188 }
189 var result = {eventListeners: eventListeners};
190 if (internalHandlers.length)
191 result.internalHandlers = internalHandlers;
192 return result;
193
194 /**
195 * @param {?Object} obj
196 * @return {boolean}
197 */
198 function isArrayLike(obj)
199 {
200 if (!obj || typeof obj !== "object")
201 return false;
202 try {
203 if (typeof obj.splice === "function") {
204 var len = obj.length;
205 return typeof len === "number" && (len >>> 0 === len && (len > 0 || 1 / len > 0));
206 }
207 } catch (e) {
208 }
209 return false;
210 }
211
212 function jQueryGetter(node)
213 {
214 return {eventListeners: jQueryEventListeners(node), internalHandlers: jQ ueryInternalHandlers(node)};
215 }
216
217 /**
218 * @param {?Object} node
219 * @return {!Array<!{handler:function(), useCapture: boolean, type:string}>}
220 */
221 function jQueryEventListeners(node)
222 {
223 if (!node || !(node instanceof Node))
224 return [];
225 var hasJQuery = (typeof jQuery !== 'undefined') && jQuery.fn;
226 if (!hasJQuery)
227 return [];
228 var listeners = [];
229 var data = jQuery._data || jQuery.data;
230 if (typeof data === "function") {
231 var events = data(node, "events");
232 for (var type in events) {
233 for (var key in events[type]) {
234 var frameworkListener = events[type][key];
235 if (typeof frameworkListener === "object" || typeof framewor kListener === "function") {
236 var listener = {
237 handler: frameworkListener.handler || frameworkListe ner,
238 useCapture: true,
239 type: type
240 };
241 listeners.push(listener);
242 }
243 }
244 }
245 }
246 var entry = jQuery(node)[0];
247 if (entry) {
248 var entryEvents = entry["$events"];
249 for (var type in entryEvents) {
250 var events = entryEvents[type];
251 for (var key in events) {
252 if (typeof events[key] === "function") {
253 var listener = {
254 handler: events[key],
255 useCapture: true,
256 type: type
257 };
258 listeners.push(listener);
259 }
260 }
261 }
262 }
263 return listeners;
264 }
265
266 /**
267 * @param {?Object} node
268 * @return {!Array<function()>}
269 */
270 function jQueryInternalHandlers(node)
271 {
272 if (!(node instanceof Node))
273 return [];
274 var hasJQuery = (typeof jQuery !== 'undefined') && jQuery.fn;
275 if (!hasJQuery)
276 return [];
277 var handlers = [];
278 var data = jQuery._data || jQuery.data;
279 if (typeof data === "function") {
280 var nodeData = data(node);
281 if (typeof nodeData.handle === "function")
282 handlers.push(nodeData.handle);
283 }
284 var entry = jQuery(node)[0];
285 if (entry && entry["$handle"])
286 handlers.push(entry["$handle"]);
287 return handlers;
288 }
289 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698