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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/sdk/InspectorBackend.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month 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
1 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer 11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the 12 * in the documentation and/or other materials provided with the
13 * distribution. 13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its 14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from 15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission. 16 * this software without specific prior written permission.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30
31 /** 30 /**
32 * @constructor 31 * @unrestricted
33 */ 32 */
34 function InspectorBackendClass() 33 var InspectorBackendClass = class {
35 { 34 constructor() {
36 this._agentPrototypes = {}; 35 this._agentPrototypes = {};
37 this._dispatcherPrototypes = {}; 36 this._dispatcherPrototypes = {};
38 this._initialized = false; 37 this._initialized = false;
39 } 38 }
39
40 /**
41 * @param {string} error
42 * @param {!Object} messageObject
43 */
44 static reportProtocolError(error, messageObject) {
45 console.error(error + ': ' + JSON.stringify(messageObject));
46 }
47
48 /**
49 * @return {boolean}
50 */
51 isInitialized() {
52 return this._initialized;
53 }
54
55 /**
56 * @param {string} domain
57 */
58 _addAgentGetterMethodToProtocolTargetPrototype(domain) {
59 var upperCaseLength = 0;
60 while (upperCaseLength < domain.length && domain[upperCaseLength].toLowerCas e() !== domain[upperCaseLength])
61 ++upperCaseLength;
62
63 var methodName = domain.substr(0, upperCaseLength).toLowerCase() + domain.sl ice(upperCaseLength) + 'Agent';
64
65 /**
66 * @this {Protocol.Target}
67 */
68 function agentGetter() {
69 return this._agents[domain];
70 }
71
72 Protocol.Target.prototype[methodName] = agentGetter;
73
74 /**
75 * @this {Protocol.Target}
76 */
77 function registerDispatcher(dispatcher) {
78 this.registerDispatcher(domain, dispatcher);
79 }
80
81 Protocol.Target.prototype['register' + domain + 'Dispatcher'] = registerDisp atcher;
82 }
83
84 /**
85 * @param {string} domain
86 * @return {!InspectorBackendClass._AgentPrototype}
87 */
88 _agentPrototype(domain) {
89 if (!this._agentPrototypes[domain]) {
90 this._agentPrototypes[domain] = new InspectorBackendClass._AgentPrototype( domain);
91 this._addAgentGetterMethodToProtocolTargetPrototype(domain);
92 }
93
94 return this._agentPrototypes[domain];
95 }
96
97 /**
98 * @param {string} domain
99 * @return {!InspectorBackendClass._DispatcherPrototype}
100 */
101 _dispatcherPrototype(domain) {
102 if (!this._dispatcherPrototypes[domain])
103 this._dispatcherPrototypes[domain] = new InspectorBackendClass._Dispatcher Prototype();
104 return this._dispatcherPrototypes[domain];
105 }
106
107 /**
108 * @param {string} method
109 * @param {!Array.<!Object>} signature
110 * @param {!Array.<string>} replyArgs
111 * @param {boolean} hasErrorData
112 */
113 registerCommand(method, signature, replyArgs, hasErrorData) {
114 var domainAndMethod = method.split('.');
115 this._agentPrototype(domainAndMethod[0]).registerCommand(domainAndMethod[1], signature, replyArgs, hasErrorData);
116 this._initialized = true;
117 }
118
119 /**
120 * @param {string} type
121 * @param {!Object} values
122 */
123 registerEnum(type, values) {
124 var domainAndMethod = type.split('.');
125 var agentName = domainAndMethod[0] + 'Agent';
126 if (!window[agentName])
127 window[agentName] = {};
128
129 window[agentName][domainAndMethod[1]] = values;
130 this._initialized = true;
131 }
132
133 /**
134 * @param {string} eventName
135 * @param {!Object} params
136 */
137 registerEvent(eventName, params) {
138 var domain = eventName.split('.')[0];
139 this._dispatcherPrototype(domain).registerEvent(eventName, params);
140 this._initialized = true;
141 }
142
143 /**
144 * @param {function(T)} clientCallback
145 * @param {string} errorPrefix
146 * @param {function(new:T,S)=} constructor
147 * @param {T=} defaultValue
148 * @return {function(?string, S)}
149 * @template T,S
150 */
151 wrapClientCallback(clientCallback, errorPrefix, constructor, defaultValue) {
152 /**
153 * @param {?string} error
154 * @param {S} value
155 * @template S
156 */
157 function callbackWrapper(error, value) {
158 if (error) {
159 console.error(errorPrefix + error);
160 clientCallback(defaultValue);
161 return;
162 }
163 if (constructor)
164 clientCallback(new constructor(value));
165 else
166 clientCallback(value);
167 }
168 return callbackWrapper;
169 }
170 };
40 171
41 InspectorBackendClass._DevToolsErrorCode = -32000; 172 InspectorBackendClass._DevToolsErrorCode = -32000;
42 InspectorBackendClass.DevToolsStubErrorCode = -32015; 173 InspectorBackendClass.DevToolsStubErrorCode = -32015;
43 174
44 /**
45 * @param {string} error
46 * @param {!Object} messageObject
47 */
48 InspectorBackendClass.reportProtocolError = function(error, messageObject)
49 {
50 console.error(error + ": " + JSON.stringify(messageObject));
51 };
52
53 InspectorBackendClass.prototype = {
54 /**
55 * @return {boolean}
56 */
57 isInitialized: function()
58 {
59 return this._initialized;
60 },
61
62 /**
63 * @param {string} domain
64 */
65 _addAgentGetterMethodToProtocolTargetPrototype: function(domain)
66 {
67 var upperCaseLength = 0;
68 while (upperCaseLength < domain.length && domain[upperCaseLength].toLowe rCase() !== domain[upperCaseLength])
69 ++upperCaseLength;
70
71 var methodName = domain.substr(0, upperCaseLength).toLowerCase() + domai n.slice(upperCaseLength) + "Agent";
72
73 /**
74 * @this {Protocol.Target}
75 */
76 function agentGetter()
77 {
78 return this._agents[domain];
79 }
80
81 Protocol.Target.prototype[methodName] = agentGetter;
82
83 /**
84 * @this {Protocol.Target}
85 */
86 function registerDispatcher(dispatcher)
87 {
88 this.registerDispatcher(domain, dispatcher);
89 }
90
91 Protocol.Target.prototype["register" + domain + "Dispatcher"] = register Dispatcher;
92 },
93
94 /**
95 * @param {string} domain
96 * @return {!InspectorBackendClass._AgentPrototype}
97 */
98 _agentPrototype: function(domain)
99 {
100 if (!this._agentPrototypes[domain]) {
101 this._agentPrototypes[domain] = new InspectorBackendClass._AgentProt otype(domain);
102 this._addAgentGetterMethodToProtocolTargetPrototype(domain);
103 }
104
105 return this._agentPrototypes[domain];
106 },
107
108 /**
109 * @param {string} domain
110 * @return {!InspectorBackendClass._DispatcherPrototype}
111 */
112 _dispatcherPrototype: function(domain)
113 {
114 if (!this._dispatcherPrototypes[domain])
115 this._dispatcherPrototypes[domain] = new InspectorBackendClass._Disp atcherPrototype();
116 return this._dispatcherPrototypes[domain];
117 },
118
119 /**
120 * @param {string} method
121 * @param {!Array.<!Object>} signature
122 * @param {!Array.<string>} replyArgs
123 * @param {boolean} hasErrorData
124 */
125 registerCommand: function(method, signature, replyArgs, hasErrorData)
126 {
127 var domainAndMethod = method.split(".");
128 this._agentPrototype(domainAndMethod[0]).registerCommand(domainAndMethod [1], signature, replyArgs, hasErrorData);
129 this._initialized = true;
130 },
131
132 /**
133 * @param {string} type
134 * @param {!Object} values
135 */
136 registerEnum: function(type, values)
137 {
138 var domainAndMethod = type.split(".");
139 var agentName = domainAndMethod[0] + "Agent";
140 if (!window[agentName])
141 window[agentName] = {};
142
143 window[agentName][domainAndMethod[1]] = values;
144 this._initialized = true;
145 },
146
147 /**
148 * @param {string} eventName
149 * @param {!Object} params
150 */
151 registerEvent: function(eventName, params)
152 {
153 var domain = eventName.split(".")[0];
154 this._dispatcherPrototype(domain).registerEvent(eventName, params);
155 this._initialized = true;
156 },
157
158 /**
159 * @param {function(T)} clientCallback
160 * @param {string} errorPrefix
161 * @param {function(new:T,S)=} constructor
162 * @param {T=} defaultValue
163 * @return {function(?string, S)}
164 * @template T,S
165 */
166 wrapClientCallback: function(clientCallback, errorPrefix, constructor, defau ltValue)
167 {
168 /**
169 * @param {?string} error
170 * @param {S} value
171 * @template S
172 */
173 function callbackWrapper(error, value)
174 {
175 if (error) {
176 console.error(errorPrefix + error);
177 clientCallback(defaultValue);
178 return;
179 }
180 if (constructor)
181 clientCallback(new constructor(value));
182 else
183 clientCallback(value);
184 }
185 return callbackWrapper;
186 }
187 };
188 175
189 var InspectorBackend = new InspectorBackendClass(); 176 var InspectorBackend = new InspectorBackendClass();
190 177
191 /** 178 /**
192 * @interface 179 * @interface
193 */ 180 */
194 InspectorBackendClass.Connection = function() 181 InspectorBackendClass.Connection = function() {};
195 {
196 };
197 182
198 InspectorBackendClass.Connection.prototype = { 183 InspectorBackendClass.Connection.prototype = {
199 /** 184 /**
200 * @param {string} message 185 * @param {string} message
201 */ 186 */
202 sendMessage: function(message) { }, 187 sendMessage: function(message) {},
203 188
204 /** 189 /**
205 * @return {!Promise} 190 * @return {!Promise}
206 */ 191 */
207 disconnect: function() { }, 192 disconnect: function() {},
208 }; 193 };
209 194
210 /** 195 /**
211 * @typedef {!{ 196 * @typedef {!{
212 * onMessage: function((!Object|string)), 197 * onMessage: function((!Object|string)),
213 * onDisconnect: function(string) 198 * onDisconnect: function(string)
214 * }} 199 * }}
215 */ 200 */
216 InspectorBackendClass.Connection.Params; 201 InspectorBackendClass.Connection.Params;
217 202
218 /** 203 /**
219 * @typedef {function(!InspectorBackendClass.Connection.Params):!InspectorBacken dClass.Connection} 204 * @typedef {function(!InspectorBackendClass.Connection.Params):!InspectorBacken dClass.Connection}
220 */ 205 */
221 InspectorBackendClass.Connection.Factory; 206 InspectorBackendClass.Connection.Factory;
222 207
223 var Protocol = {}; 208 var Protocol = {};
224 209
225 /** @typedef {string} */ 210 /** @typedef {string} */
226 Protocol.Error; 211 Protocol.Error;
227 212
228 /** 213 /**
229 * @constructor 214 * @unrestricted
230 * @param {!InspectorBackendClass.Connection.Factory} connectionFactory
231 */ 215 */
232 Protocol.Target = function(connectionFactory) 216 Protocol.Target = class {
233 { 217 /**
234 this._connection = connectionFactory({onMessage: this._onMessage.bind(this), onDisconnect: this._onDisconnect.bind(this)}); 218 * @param {!InspectorBackendClass.Connection.Factory} connectionFactory
219 */
220 constructor(connectionFactory) {
221 this._connection =
222 connectionFactory({onMessage: this._onMessage.bind(this), onDisconnect: this._onDisconnect.bind(this)});
235 this._lastMessageId = 1; 223 this._lastMessageId = 1;
236 this._pendingResponsesCount = 0; 224 this._pendingResponsesCount = 0;
237 this._agents = {}; 225 this._agents = {};
238 this._dispatchers = {}; 226 this._dispatchers = {};
239 this._callbacks = {}; 227 this._callbacks = {};
240 this._initialize(InspectorBackend._agentPrototypes, InspectorBackend._dispat cherPrototypes); 228 this._initialize(InspectorBackend._agentPrototypes, InspectorBackend._dispat cherPrototypes);
241 if (!InspectorBackendClass.deprecatedRunAfterPendingDispatches) 229 if (!InspectorBackendClass.deprecatedRunAfterPendingDispatches)
242 InspectorBackendClass.deprecatedRunAfterPendingDispatches = this._deprec atedRunAfterPendingDispatches.bind(this); 230 InspectorBackendClass.deprecatedRunAfterPendingDispatches = this._deprecat edRunAfterPendingDispatches.bind(this);
243 if (!InspectorBackendClass.sendRawMessageForTesting) 231 if (!InspectorBackendClass.sendRawMessageForTesting)
244 InspectorBackendClass.sendRawMessageForTesting = this._sendRawMessageFor Testing.bind(this); 232 InspectorBackendClass.sendRawMessageForTesting = this._sendRawMessageForTe sting.bind(this);
233 }
234
235 /**
236 * @param {!Object.<string, !InspectorBackendClass._AgentPrototype>} agentProt otypes
237 * @param {!Object.<string, !InspectorBackendClass._DispatcherPrototype>} disp atcherPrototypes
238 */
239 _initialize(agentPrototypes, dispatcherPrototypes) {
240 for (var domain in agentPrototypes) {
241 this._agents[domain] = Object.create(agentPrototypes[domain]);
242 this._agents[domain].setTarget(this);
243 }
244
245 for (var domain in dispatcherPrototypes)
246 this._dispatchers[domain] = Object.create(dispatcherPrototypes[domain]);
247 }
248
249 /**
250 * @return {number}
251 */
252 _nextMessageId() {
253 return this._lastMessageId++;
254 }
255
256 /**
257 * @param {string} domain
258 * @return {!InspectorBackendClass._AgentPrototype}
259 */
260 _agent(domain) {
261 return this._agents[domain];
262 }
263
264 /**
265 * @param {string} domain
266 * @param {string} method
267 * @param {?Object} params
268 * @param {?function(*)} callback
269 */
270 _wrapCallbackAndSendMessageObject(domain, method, params, callback) {
271 if (!this._connection) {
272 if (callback)
273 this._dispatchConnectionErrorResponse(domain, method, callback);
274 return;
275 }
276
277 var messageObject = {};
278 var messageId = this._nextMessageId();
279 messageObject.id = messageId;
280 messageObject.method = method;
281 if (params)
282 messageObject.params = params;
283
284 var wrappedCallback = this._wrap(callback, domain, method);
285 var message = JSON.stringify(messageObject);
286
287 if (InspectorBackendClass.Options.dumpInspectorProtocolMessages)
288 this._dumpProtocolMessage('frontend: ' + message);
289
290 this._connection.sendMessage(message);
291 ++this._pendingResponsesCount;
292 this._callbacks[messageId] = wrappedCallback;
293 }
294
295 /**
296 * @param {?function(*)} callback
297 * @param {string} method
298 * @param {string} domain
299 * @return {function(*)}
300 */
301 _wrap(callback, domain, method) {
302 if (!callback)
303 callback = function() {};
304
305 callback.methodName = method;
306 callback.domain = domain;
307 if (InspectorBackendClass.Options.dumpInspectorTimeStats)
308 callback.sendRequestTime = Date.now();
309
310 return callback;
311 }
312
313 /**
314 * @param {string} method
315 * @param {?Object} params
316 * @param {?function(...*)} callback
317 */
318 _sendRawMessageForTesting(method, params, callback) {
319 var domain = method.split('.')[0];
320 this._wrapCallbackAndSendMessageObject(domain, method, params, callback);
321 }
322
323 /**
324 * @param {!Object|string} message
325 */
326 _onMessage(message) {
327 if (InspectorBackendClass.Options.dumpInspectorProtocolMessages)
328 this._dumpProtocolMessage('backend: ' + ((typeof message === 'string') ? m essage : JSON.stringify(message)));
329
330 var messageObject = /** @type {!Object} */ ((typeof message === 'string') ? JSON.parse(message) : message);
331
332 if ('id' in messageObject) { // just a response for some request
333 var callback = this._callbacks[messageObject.id];
334 if (!callback) {
335 InspectorBackendClass.reportProtocolError('Protocol Error: the message w ith wrong id', messageObject);
336 return;
337 }
338
339 var processingStartTime;
340 if (InspectorBackendClass.Options.dumpInspectorTimeStats)
341 processingStartTime = Date.now();
342
343 this._agent(callback.domain).dispatchResponse(messageObject, callback.meth odName, callback);
344 --this._pendingResponsesCount;
345 delete this._callbacks[messageObject.id];
346
347 if (InspectorBackendClass.Options.dumpInspectorTimeStats)
348 console.log(
349 'time-stats: ' + callback.methodName + ' = ' + (processingStartTime - callback.sendRequestTime) + ' + ' +
350 (Date.now() - processingStartTime));
351
352 if (this._scripts && !this._pendingResponsesCount)
353 this._deprecatedRunAfterPendingDispatches();
354 } else {
355 if (!('method' in messageObject)) {
356 InspectorBackendClass.reportProtocolError('Protocol Error: the message w ithout method', messageObject);
357 return;
358 }
359
360 var method = messageObject.method.split('.');
361 var domainName = method[0];
362 if (!(domainName in this._dispatchers)) {
363 InspectorBackendClass.reportProtocolError(
364 'Protocol Error: the message ' + messageObject.method + ' is for non -existing domain \'' + domainName +
365 '\'',
366 messageObject);
367 return;
368 }
369
370 this._dispatchers[domainName].dispatch(method[1], messageObject);
371 }
372 }
373
374 /**
375 * @param {string} domain
376 * @param {!Object} dispatcher
377 */
378 registerDispatcher(domain, dispatcher) {
379 if (!this._dispatchers[domain])
380 return;
381
382 this._dispatchers[domain].setDomainDispatcher(dispatcher);
383 }
384
385 /**
386 * @param {function()=} script
387 */
388 _deprecatedRunAfterPendingDispatches(script) {
389 if (!this._scripts)
390 this._scripts = [];
391
392 if (script)
393 this._scripts.push(script);
394
395 // Execute all promises.
396 setTimeout(function() {
397 if (!this._pendingResponsesCount)
398 this._executeAfterPendingDispatches();
399 else
400 this._deprecatedRunAfterPendingDispatches();
401 }.bind(this), 0);
402 }
403
404 _executeAfterPendingDispatches() {
405 if (!this._pendingResponsesCount) {
406 var scripts = this._scripts;
407 this._scripts = [];
408 for (var id = 0; id < scripts.length; ++id)
409 scripts[id].call(this);
410 }
411 }
412
413 /**
414 * @param {string} message
415 */
416 _dumpProtocolMessage(message) {
417 console.log(message);
418 }
419
420 /**
421 * @param {string} reason
422 */
423 _onDisconnect(reason) {
424 this._connection = null;
425 this._runPendingCallbacks();
426 this.dispose();
427 }
428
429 /**
430 * @protected
431 */
432 dispose() {
433 }
434
435 /**
436 * @return {boolean}
437 */
438 isDisposed() {
439 return !this._connection;
440 }
441
442 _runPendingCallbacks() {
443 var keys = Object.keys(this._callbacks).map(function(num) {
444 return parseInt(num, 10);
445 });
446 for (var i = 0; i < keys.length; ++i) {
447 var callback = this._callbacks[keys[i]];
448 this._dispatchConnectionErrorResponse(callback.domain, callback.methodName , callback);
449 }
450 this._callbacks = {};
451 }
452
453 /**
454 * @param {string} domain
455 * @param {string} methodName
456 * @param {function(*)} callback
457 */
458 _dispatchConnectionErrorResponse(domain, methodName, callback) {
459 var error = {
460 message: 'Connection is closed, can\'t dispatch pending ' + methodName,
461 code: InspectorBackendClass._DevToolsErrorCode,
462 data: null
463 };
464 var messageObject = {error: error};
465 setTimeout(
466 InspectorBackendClass._AgentPrototype.prototype.dispatchResponse.bind(
467 this._agent(domain), messageObject, methodName, callback),
468 0);
469 }
245 }; 470 };
246 471
247 Protocol.Target.prototype = { 472 /**
473 * @unrestricted
474 */
475 InspectorBackendClass._AgentPrototype = class {
476 /**
477 * @param {string} domain
478 */
479 constructor(domain) {
480 this._replyArgs = {};
481 this._hasErrorData = {};
482 this._domain = domain;
483 }
484
485 /**
486 * @param {!Protocol.Target} target
487 */
488 setTarget(target) {
489 this._target = target;
490 }
491
492 /**
493 * @param {string} methodName
494 * @param {!Array.<!Object>} signature
495 * @param {!Array.<string>} replyArgs
496 * @param {boolean} hasErrorData
497 */
498 registerCommand(methodName, signature, replyArgs, hasErrorData) {
499 var domainAndMethod = this._domain + '.' + methodName;
500
248 /** 501 /**
249 * @param {!Object.<string, !InspectorBackendClass._AgentPrototype>} agentPr ototypes 502 * @param {...*} vararg
250 * @param {!Object.<string, !InspectorBackendClass._DispatcherPrototype>} di spatcherPrototypes 503 * @this {InspectorBackendClass._AgentPrototype}
504 * @return {!Promise.<*>}
251 */ 505 */
252 _initialize: function(agentPrototypes, dispatcherPrototypes) 506 function sendMessagePromise(vararg) {
253 { 507 var params = Array.prototype.slice.call(arguments);
254 for (var domain in agentPrototypes) { 508 return InspectorBackendClass._AgentPrototype.prototype._sendMessageToBacke ndPromise.call(
255 this._agents[domain] = Object.create(agentPrototypes[domain]); 509 this, domainAndMethod, signature, params);
256 this._agents[domain].setTarget(this); 510 }
257 } 511
258 512 this[methodName] = sendMessagePromise;
259 for (var domain in dispatcherPrototypes)
260 this._dispatchers[domain] = Object.create(dispatcherPrototypes[domai n]);
261 },
262 513
263 /** 514 /**
264 * @return {number} 515 * @param {...*} vararg
516 * @this {InspectorBackendClass._AgentPrototype}
265 */ 517 */
266 _nextMessageId: function() 518 function invoke(vararg) {
267 { 519 var params = [domainAndMethod].concat(Array.prototype.slice.call(arguments ));
268 return this._lastMessageId++; 520 InspectorBackendClass._AgentPrototype.prototype._invoke.apply(this, params );
269 }, 521 }
270 522
271 /** 523 this['invoke_' + methodName] = invoke;
272 * @param {string} domain 524
273 * @return {!InspectorBackendClass._AgentPrototype} 525 this._replyArgs[domainAndMethod] = replyArgs;
274 */ 526 if (hasErrorData)
275 _agent: function(domain) 527 this._hasErrorData[domainAndMethod] = true;
276 { 528 }
277 return this._agents[domain]; 529
278 }, 530 /**
279 531 * @param {string} method
280 /** 532 * @param {!Array.<!Object>} signature
281 * @param {string} domain 533 * @param {!Array.<*>} args
282 * @param {string} method 534 * @param {boolean} allowExtraUndefinedArg
283 * @param {?Object} params 535 * @param {function(string)} errorCallback
284 * @param {?function(*)} callback 536 * @return {?Object}
285 */ 537 */
286 _wrapCallbackAndSendMessageObject: function(domain, method, params, callback ) 538 _prepareParameters(method, signature, args, allowExtraUndefinedArg, errorCallb ack) {
287 { 539 var params = {};
288 if (!this._connection) { 540 var hasParams = false;
289 if (callback) 541 for (var i = 0; i < signature.length; ++i) {
290 this._dispatchConnectionErrorResponse(domain, method, callback); 542 var param = signature[i];
291 return; 543 var paramName = param['name'];
292 } 544 var typeName = param['type'];
293 545 var optionalFlag = param['optional'];
294 var messageObject = {}; 546
295 var messageId = this._nextMessageId(); 547 if (!args.length && !optionalFlag) {
296 messageObject.id = messageId; 548 errorCallback(
297 messageObject.method = method; 549 'Protocol Error: Invalid number of arguments for method \'' + method +
298 if (params) 550 '\' call. It must have the following arguments \'' + JSON.stringify( signature) + '\'.');
299 messageObject.params = params; 551 return null;
300 552 }
301 var wrappedCallback = this._wrap(callback, domain, method); 553
302 var message = JSON.stringify(messageObject); 554 var value = args.shift();
303 555 if (optionalFlag && typeof value === 'undefined')
304 if (InspectorBackendClass.Options.dumpInspectorProtocolMessages) 556 continue;
305 this._dumpProtocolMessage("frontend: " + message); 557
306 558 if (typeof value !== typeName) {
307 this._connection.sendMessage(message); 559 errorCallback(
308 ++this._pendingResponsesCount; 560 'Protocol Error: Invalid type of argument \'' + paramName + '\' for method \'' + method +
309 this._callbacks[messageId] = wrappedCallback; 561 '\' call. It must be \'' + typeName + '\' but it is \'' + typeof val ue + '\'.');
310 }, 562 return null;
311 563 }
312 /** 564
313 * @param {?function(*)} callback 565 params[paramName] = value;
314 * @param {string} method 566 hasParams = true;
315 * @param {string} domain 567 }
316 * @return {function(*)} 568
317 */ 569 if (args.length === 1 && (!allowExtraUndefinedArg || (typeof args[0] !== 'un defined'))) {
318 _wrap: function(callback, domain, method) 570 errorCallback(
319 { 571 'Protocol Error: Optional callback argument for method \'' + method +
320 if (!callback) 572 '\' call must be a function but its type is \'' + typeof args[0] + '\' .');
321 callback = function() {}; 573 return null;
322 574 }
323 callback.methodName = method; 575
324 callback.domain = domain; 576 if (args.length > 1) {
325 if (InspectorBackendClass.Options.dumpInspectorTimeStats) 577 errorCallback('Protocol Error: Extra ' + args.length + ' arguments in a ca ll to method \'' + method + '\'.');
326 callback.sendRequestTime = Date.now(); 578 return null;
327 579 }
328 return callback; 580
329 }, 581 return hasParams ? params : null;
330 582 }
331 /** 583
332 * @param {string} method 584 /**
333 * @param {?Object} params 585 * @param {string} method
334 * @param {?function(...*)} callback 586 * @param {!Array.<!Object>} signature
335 */ 587 * @param {!Array.<*>} args
336 _sendRawMessageForTesting: function(method, params, callback) 588 * @return {!Promise.<*>}
337 { 589 */
338 var domain = method.split(".")[0]; 590 _sendMessageToBackendPromise(method, signature, args) {
339 this._wrapCallbackAndSendMessageObject(domain, method, params, callback) ; 591 var errorMessage;
340 },
341
342 /**
343 * @param {!Object|string} message
344 */
345 _onMessage: function(message)
346 {
347 if (InspectorBackendClass.Options.dumpInspectorProtocolMessages)
348 this._dumpProtocolMessage("backend: " + ((typeof message === "string ") ? message : JSON.stringify(message)));
349
350 var messageObject = /** @type {!Object} */ ((typeof message === "string" ) ? JSON.parse(message) : message);
351
352 if ("id" in messageObject) { // just a response for some request
353 var callback = this._callbacks[messageObject.id];
354 if (!callback) {
355 InspectorBackendClass.reportProtocolError("Protocol Error: the m essage with wrong id", messageObject);
356 return;
357 }
358
359 var processingStartTime;
360 if (InspectorBackendClass.Options.dumpInspectorTimeStats)
361 processingStartTime = Date.now();
362
363 this._agent(callback.domain).dispatchResponse(messageObject, callbac k.methodName, callback);
364 --this._pendingResponsesCount;
365 delete this._callbacks[messageObject.id];
366
367 if (InspectorBackendClass.Options.dumpInspectorTimeStats)
368 console.log("time-stats: " + callback.methodName + " = " + (proc essingStartTime - callback.sendRequestTime) + " + " + (Date.now() - processingSt artTime));
369
370 if (this._scripts && !this._pendingResponsesCount)
371 this._deprecatedRunAfterPendingDispatches();
372 } else {
373 if (!("method" in messageObject)) {
374 InspectorBackendClass.reportProtocolError("Protocol Error: the m essage without method", messageObject);
375 return;
376 }
377
378 var method = messageObject.method.split(".");
379 var domainName = method[0];
380 if (!(domainName in this._dispatchers)) {
381 InspectorBackendClass.reportProtocolError("Protocol Error: the m essage " + messageObject.method + " is for non-existing domain '" + domainName + "'", messageObject);
382 return;
383 }
384
385 this._dispatchers[domainName].dispatch(method[1], messageObject);
386 }
387 },
388
389 /**
390 * @param {string} domain
391 * @param {!Object} dispatcher
392 */
393 registerDispatcher: function(domain, dispatcher)
394 {
395 if (!this._dispatchers[domain])
396 return;
397
398 this._dispatchers[domain].setDomainDispatcher(dispatcher);
399 },
400
401 /**
402 * @param {function()=} script
403 */
404 _deprecatedRunAfterPendingDispatches: function(script)
405 {
406 if (!this._scripts)
407 this._scripts = [];
408
409 if (script)
410 this._scripts.push(script);
411
412 // Execute all promises.
413 setTimeout(function() {
414 if (!this._pendingResponsesCount)
415 this._executeAfterPendingDispatches();
416 else
417 this._deprecatedRunAfterPendingDispatches();
418 }.bind(this), 0);
419 },
420
421 _executeAfterPendingDispatches: function()
422 {
423 if (!this._pendingResponsesCount) {
424 var scripts = this._scripts;
425 this._scripts = [];
426 for (var id = 0; id < scripts.length; ++id)
427 scripts[id].call(this);
428 }
429 },
430
431 /** 592 /**
432 * @param {string} message 593 * @param {string} message
433 */ 594 */
434 _dumpProtocolMessage: function(message) 595 function onError(message) {
435 { 596 console.error(message);
436 console.log(message); 597 errorMessage = message;
437 }, 598 }
599 var userCallback = (args.length && typeof args.peekLast() === 'function') ? args.pop() : null;
600 var params = this._prepareParameters(method, signature, args, !userCallback, onError);
601 if (errorMessage)
602 return Promise.reject(new Error(errorMessage));
603 else
604 return new Promise(promiseAction.bind(this));
438 605
439 /** 606 /**
440 * @param {string} reason 607 * @param {function(?)} resolve
608 * @param {function(!Error)} reject
609 * @this {InspectorBackendClass._AgentPrototype}
441 */ 610 */
442 _onDisconnect: function(reason) 611 function promiseAction(resolve, reject) {
443 { 612 /**
444 this._connection = null; 613 * @param {...*} vararg
445 this._runPendingCallbacks(); 614 */
446 this.dispose(); 615 function callback(vararg) {
447 }, 616 var result = userCallback ? userCallback.apply(null, arguments) : undefi ned;
448 617 resolve(result);
449 /** 618 }
450 * @protected 619 this._target._wrapCallbackAndSendMessageObject(this._domain, method, param s, callback);
451 */ 620 }
452 dispose: function() 621 }
453 { 622
454 }, 623 /**
455 624 * @param {string} method
456 /** 625 * @param {?Object} args
457 * @return {boolean} 626 * @param {?function(*)} callback
458 */ 627 */
459 isDisposed: function() 628 _invoke(method, args, callback) {
460 { 629 this._target._wrapCallbackAndSendMessageObject(this._domain, method, args, c allback);
461 return !this._connection; 630 }
462 }, 631
463 632 /**
464 _runPendingCallbacks: function() 633 * @param {!Object} messageObject
465 { 634 * @param {string} methodName
466 var keys = Object.keys(this._callbacks).map(function(num) { return parse Int(num, 10); }); 635 * @param {function(*)|function(?Protocol.Error, ?Object)} callback
467 for (var i = 0; i < keys.length; ++i) { 636 */
468 var callback = this._callbacks[keys[i]]; 637 dispatchResponse(messageObject, methodName, callback) {
469 this._dispatchConnectionErrorResponse(callback.domain, callback.meth odName, callback); 638 if (messageObject.error && messageObject.error.code !== InspectorBackendClas s._DevToolsErrorCode &&
470 } 639 messageObject.error.code !== InspectorBackendClass.DevToolsStubErrorCode &&
471 this._callbacks = {}; 640 !InspectorBackendClass.Options.suppressRequestErrors) {
472 }, 641 var id = InspectorBackendClass.Options.dumpInspectorProtocolMessages ? ' w ith id = ' + messageObject.id : '';
473 642 console.error('Request ' + methodName + id + ' failed. ' + JSON.stringify( messageObject.error));
474 /** 643 }
475 * @param {string} domain 644
476 * @param {string} methodName 645 var argumentsArray = [];
477 * @param {function(*)} callback 646 argumentsArray[0] = messageObject.error ? messageObject.error.message : null ;
478 */ 647
479 _dispatchConnectionErrorResponse: function(domain, methodName, callback) 648 if (this._hasErrorData[methodName])
480 { 649 argumentsArray[1] = messageObject.error ? messageObject.error.data : null;
481 var error = { message: "Connection is closed, can't dispatch pending " + methodName, code: InspectorBackendClass._DevToolsErrorCode, data: null}; 650
482 var messageObject = {error: error}; 651 if (messageObject.result) {
483 setTimeout(InspectorBackendClass._AgentPrototype.prototype.dispatchRespo nse.bind(this._agent(domain), messageObject, methodName, callback), 0); 652 var paramNames = this._replyArgs[methodName] || [];
484 }, 653 for (var i = 0; i < paramNames.length; ++i)
654 argumentsArray.push(messageObject.result[paramNames[i]]);
655 }
656
657 callback.apply(null, argumentsArray);
658 }
485 }; 659 };
486 660
487 /** 661 /**
488 * @constructor 662 * @unrestricted
489 * @param {string} domain
490 */ 663 */
491 InspectorBackendClass._AgentPrototype = function(domain) 664 InspectorBackendClass._DispatcherPrototype = class {
492 { 665 constructor() {
493 this._replyArgs = {};
494 this._hasErrorData = {};
495 this._domain = domain;
496 };
497
498 InspectorBackendClass._AgentPrototype.prototype = {
499 /**
500 * @param {!Protocol.Target} target
501 */
502 setTarget: function(target)
503 {
504 this._target = target;
505 },
506
507 /**
508 * @param {string} methodName
509 * @param {!Array.<!Object>} signature
510 * @param {!Array.<string>} replyArgs
511 * @param {boolean} hasErrorData
512 */
513 registerCommand: function(methodName, signature, replyArgs, hasErrorData)
514 {
515 var domainAndMethod = this._domain + "." + methodName;
516
517 /**
518 * @param {...*} vararg
519 * @this {InspectorBackendClass._AgentPrototype}
520 * @return {!Promise.<*>}
521 */
522 function sendMessagePromise(vararg)
523 {
524 var params = Array.prototype.slice.call(arguments);
525 return InspectorBackendClass._AgentPrototype.prototype._sendMessageT oBackendPromise.call(this, domainAndMethod, signature, params);
526 }
527
528 this[methodName] = sendMessagePromise;
529
530 /**
531 * @param {...*} vararg
532 * @this {InspectorBackendClass._AgentPrototype}
533 */
534 function invoke(vararg)
535 {
536 var params = [domainAndMethod].concat(Array.prototype.slice.call(arg uments));
537 InspectorBackendClass._AgentPrototype.prototype._invoke.apply(this, params);
538 }
539
540 this["invoke_" + methodName] = invoke;
541
542 this._replyArgs[domainAndMethod] = replyArgs;
543 if (hasErrorData)
544 this._hasErrorData[domainAndMethod] = true;
545 },
546
547 /**
548 * @param {string} method
549 * @param {!Array.<!Object>} signature
550 * @param {!Array.<*>} args
551 * @param {boolean} allowExtraUndefinedArg
552 * @param {function(string)} errorCallback
553 * @return {?Object}
554 */
555 _prepareParameters: function(method, signature, args, allowExtraUndefinedArg , errorCallback)
556 {
557 var params = {};
558 var hasParams = false;
559 for (var i = 0; i < signature.length; ++i) {
560 var param = signature[i];
561 var paramName = param["name"];
562 var typeName = param["type"];
563 var optionalFlag = param["optional"];
564
565 if (!args.length && !optionalFlag) {
566 errorCallback("Protocol Error: Invalid number of arguments for m ethod '" + method + "' call. It must have the following arguments '" + JSON.stri ngify(signature) + "'.");
567 return null;
568 }
569
570 var value = args.shift();
571 if (optionalFlag && typeof value === "undefined")
572 continue;
573
574 if (typeof value !== typeName) {
575 errorCallback("Protocol Error: Invalid type of argument '" + par amName + "' for method '" + method + "' call. It must be '" + typeName + "' but it is '" + typeof value + "'.");
576 return null;
577 }
578
579 params[paramName] = value;
580 hasParams = true;
581 }
582
583 if (args.length === 1 && (!allowExtraUndefinedArg || (typeof args[0] !== "undefined"))) {
584 errorCallback("Protocol Error: Optional callback argument for method '" + method + "' call must be a function but its type is '" + typeof args[0] + "'.");
585 return null;
586 }
587
588 if (args.length > 1) {
589 errorCallback("Protocol Error: Extra " + args.length + " arguments i n a call to method '" + method + "'.");
590 return null;
591 }
592
593 return hasParams ? params : null;
594 },
595
596 /**
597 * @param {string} method
598 * @param {!Array.<!Object>} signature
599 * @param {!Array.<*>} args
600 * @return {!Promise.<*>}
601 */
602 _sendMessageToBackendPromise: function(method, signature, args)
603 {
604 var errorMessage;
605 /**
606 * @param {string} message
607 */
608 function onError(message)
609 {
610 console.error(message);
611 errorMessage = message;
612 }
613 var userCallback = (args.length && typeof args.peekLast() === "function" ) ? args.pop() : null;
614 var params = this._prepareParameters(method, signature, args, !userCallb ack, onError);
615 if (errorMessage)
616 return Promise.reject(new Error(errorMessage));
617 else
618 return new Promise(promiseAction.bind(this));
619
620 /**
621 * @param {function(?)} resolve
622 * @param {function(!Error)} reject
623 * @this {InspectorBackendClass._AgentPrototype}
624 */
625 function promiseAction(resolve, reject)
626 {
627 /**
628 * @param {...*} vararg
629 */
630 function callback(vararg)
631 {
632 var result = userCallback ? userCallback.apply(null, arguments) : undefined;
633 resolve(result);
634 }
635 this._target._wrapCallbackAndSendMessageObject(this._domain, method, params, callback);
636 }
637 },
638
639 /**
640 * @param {string} method
641 * @param {?Object} args
642 * @param {?function(*)} callback
643 */
644 _invoke: function(method, args, callback)
645 {
646 this._target._wrapCallbackAndSendMessageObject(this._domain, method, arg s, callback);
647 },
648
649 /**
650 * @param {!Object} messageObject
651 * @param {string} methodName
652 * @param {function(*)|function(?Protocol.Error, ?Object)} callback
653 */
654 dispatchResponse: function(messageObject, methodName, callback)
655 {
656 if (messageObject.error && messageObject.error.code !== InspectorBackend Class._DevToolsErrorCode && messageObject.error.code !== InspectorBackendClass.D evToolsStubErrorCode && !InspectorBackendClass.Options.suppressRequestErrors) {
657 var id = InspectorBackendClass.Options.dumpInspectorProtocolMessages ? " with id = " + messageObject.id : "";
658 console.error("Request " + methodName + id + " failed. " + JSON.stri ngify(messageObject.error));
659 }
660
661 var argumentsArray = [];
662 argumentsArray[0] = messageObject.error ? messageObject.error.message : null;
663
664 if (this._hasErrorData[methodName])
665 argumentsArray[1] = messageObject.error ? messageObject.error.data : null;
666
667 if (messageObject.result) {
668 var paramNames = this._replyArgs[methodName] || [];
669 for (var i = 0; i < paramNames.length; ++i)
670 argumentsArray.push(messageObject.result[paramNames[i]]);
671 }
672
673 callback.apply(null, argumentsArray);
674 },
675 };
676
677 /**
678 * @constructor
679 */
680 InspectorBackendClass._DispatcherPrototype = function()
681 {
682 this._eventArgs = {}; 666 this._eventArgs = {};
683 this._dispatcher = null; 667 this._dispatcher = null;
668 }
669
670 /**
671 * @param {string} eventName
672 * @param {!Object} params
673 */
674 registerEvent(eventName, params) {
675 this._eventArgs[eventName] = params;
676 }
677
678 /**
679 * @param {!Object} dispatcher
680 */
681 setDomainDispatcher(dispatcher) {
682 this._dispatcher = dispatcher;
683 }
684
685 /**
686 * @param {string} functionName
687 * @param {!Object} messageObject
688 */
689 dispatch(functionName, messageObject) {
690 if (!this._dispatcher)
691 return;
692
693 if (!(functionName in this._dispatcher)) {
694 InspectorBackendClass.reportProtocolError(
695 'Protocol Error: Attempted to dispatch an unimplemented method \'' + m essageObject.method + '\'',
696 messageObject);
697 return;
698 }
699
700 if (!this._eventArgs[messageObject.method]) {
701 InspectorBackendClass.reportProtocolError(
702 'Protocol Error: Attempted to dispatch an unspecified method \'' + mes sageObject.method + '\'',
703 messageObject);
704 return;
705 }
706
707 var params = [];
708 if (messageObject.params) {
709 var paramNames = this._eventArgs[messageObject.method];
710 for (var i = 0; i < paramNames.length; ++i)
711 params.push(messageObject.params[paramNames[i]]);
712 }
713
714 var processingStartTime;
715 if (InspectorBackendClass.Options.dumpInspectorTimeStats)
716 processingStartTime = Date.now();
717
718 this._dispatcher[functionName].apply(this._dispatcher, params);
719
720 if (InspectorBackendClass.Options.dumpInspectorTimeStats)
721 console.log('time-stats: ' + messageObject.method + ' = ' + (Date.now() - processingStartTime));
722 }
684 }; 723 };
685 724
686 InspectorBackendClass._DispatcherPrototype.prototype = { 725 InspectorBackendClass.Options = {
687 726 dumpInspectorTimeStats: false,
688 /** 727 dumpInspectorProtocolMessages: false,
689 * @param {string} eventName 728 suppressRequestErrors: false
690 * @param {!Object} params
691 */
692 registerEvent: function(eventName, params)
693 {
694 this._eventArgs[eventName] = params;
695 },
696
697 /**
698 * @param {!Object} dispatcher
699 */
700 setDomainDispatcher: function(dispatcher)
701 {
702 this._dispatcher = dispatcher;
703 },
704
705 /**
706 * @param {string} functionName
707 * @param {!Object} messageObject
708 */
709 dispatch: function(functionName, messageObject)
710 {
711 if (!this._dispatcher)
712 return;
713
714 if (!(functionName in this._dispatcher)) {
715 InspectorBackendClass.reportProtocolError("Protocol Error: Attempted to dispatch an unimplemented method '" + messageObject.method + "'", messageObj ect);
716 return;
717 }
718
719 if (!this._eventArgs[messageObject.method]) {
720 InspectorBackendClass.reportProtocolError("Protocol Error: Attempted to dispatch an unspecified method '" + messageObject.method + "'", messageObjec t);
721 return;
722 }
723
724 var params = [];
725 if (messageObject.params) {
726 var paramNames = this._eventArgs[messageObject.method];
727 for (var i = 0; i < paramNames.length; ++i)
728 params.push(messageObject.params[paramNames[i]]);
729 }
730
731 var processingStartTime;
732 if (InspectorBackendClass.Options.dumpInspectorTimeStats)
733 processingStartTime = Date.now();
734
735 this._dispatcher[functionName].apply(this._dispatcher, params);
736
737 if (InspectorBackendClass.Options.dumpInspectorTimeStats)
738 console.log("time-stats: " + messageObject.method + " = " + (Date.no w() - processingStartTime));
739 }
740 }; 729 };
741
742 InspectorBackendClass.Options = {
743 dumpInspectorTimeStats: false,
744 dumpInspectorProtocolMessages: false,
745 suppressRequestErrors: false
746 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698