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