mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-10 21:54:47 +08:00
Move and rename files. NOAUTOREVERT=true NOPRESUBMIT=true NOTREECHECKS=true Bug: 768828 TBR=darin@chromium.org NOTRY=true Change-Id: I66d3b155808bc5bdbf237b80208e1e552bcf7f28 Reviewed-on: https://chromium-review.googlesource.com/1001153 Reviewed-by: Blink Reformat <blink-reformat@chromium.org> Commit-Queue: Blink Reformat <blink-reformat@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#549061} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: 0aee4434a4dba42a42abaea9bfbc0cd196a63bc1
735 lines
21 KiB
JavaScript
735 lines
21 KiB
JavaScript
/*
|
|
* Copyright (C) 2011 Google Inc. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the following disclaimer
|
|
* in the documentation and/or other materials provided with the
|
|
* distribution.
|
|
* * Neither the name of Google Inc. nor the names of its
|
|
* contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
/** @typedef {string} */
|
|
Protocol.Error = Symbol('Protocol.Error');
|
|
|
|
/**
|
|
* @unrestricted
|
|
*/
|
|
Protocol.InspectorBackend = class {
|
|
constructor() {
|
|
this._agentPrototypes = {};
|
|
this._dispatcherPrototypes = {};
|
|
this._initialized = false;
|
|
}
|
|
|
|
/**
|
|
* @param {string} error
|
|
* @param {!Object} messageObject
|
|
*/
|
|
static reportProtocolError(error, messageObject) {
|
|
console.error(error + ': ' + JSON.stringify(messageObject));
|
|
}
|
|
|
|
/**
|
|
* @return {boolean}
|
|
*/
|
|
isInitialized() {
|
|
return this._initialized;
|
|
}
|
|
|
|
/**
|
|
* @param {string} domain
|
|
*/
|
|
_addAgentGetterMethodToProtocolTargetPrototype(domain) {
|
|
let upperCaseLength = 0;
|
|
while (upperCaseLength < domain.length && domain[upperCaseLength].toLowerCase() !== domain[upperCaseLength])
|
|
++upperCaseLength;
|
|
|
|
const methodName = domain.substr(0, upperCaseLength).toLowerCase() + domain.slice(upperCaseLength) + 'Agent';
|
|
|
|
/**
|
|
* @this {Protocol.TargetBase}
|
|
*/
|
|
function agentGetter() {
|
|
return this._agents[domain];
|
|
}
|
|
|
|
Protocol.TargetBase.prototype[methodName] = agentGetter;
|
|
|
|
/**
|
|
* @this {Protocol.TargetBase}
|
|
*/
|
|
function registerDispatcher(dispatcher) {
|
|
this.registerDispatcher(domain, dispatcher);
|
|
}
|
|
|
|
Protocol.TargetBase.prototype['register' + domain + 'Dispatcher'] = registerDispatcher;
|
|
}
|
|
|
|
/**
|
|
* @param {string} domain
|
|
* @return {!Protocol.InspectorBackend._AgentPrototype}
|
|
*/
|
|
_agentPrototype(domain) {
|
|
if (!this._agentPrototypes[domain]) {
|
|
this._agentPrototypes[domain] = new Protocol.InspectorBackend._AgentPrototype(domain);
|
|
this._addAgentGetterMethodToProtocolTargetPrototype(domain);
|
|
}
|
|
|
|
return this._agentPrototypes[domain];
|
|
}
|
|
|
|
/**
|
|
* @param {string} domain
|
|
* @return {!Protocol.InspectorBackend._DispatcherPrototype}
|
|
*/
|
|
_dispatcherPrototype(domain) {
|
|
if (!this._dispatcherPrototypes[domain])
|
|
this._dispatcherPrototypes[domain] = new Protocol.InspectorBackend._DispatcherPrototype();
|
|
return this._dispatcherPrototypes[domain];
|
|
}
|
|
|
|
/**
|
|
* @param {string} method
|
|
* @param {!Array.<!Object>} signature
|
|
* @param {!Array.<string>} replyArgs
|
|
* @param {boolean} hasErrorData
|
|
*/
|
|
registerCommand(method, signature, replyArgs, hasErrorData) {
|
|
const domainAndMethod = method.split('.');
|
|
this._agentPrototype(domainAndMethod[0]).registerCommand(domainAndMethod[1], signature, replyArgs, hasErrorData);
|
|
this._initialized = true;
|
|
}
|
|
|
|
/**
|
|
* @param {string} type
|
|
* @param {!Object} values
|
|
*/
|
|
registerEnum(type, values) {
|
|
const domainAndName = type.split('.');
|
|
const domain = domainAndName[0];
|
|
if (!Protocol[domain])
|
|
Protocol[domain] = {};
|
|
|
|
Protocol[domain][domainAndName[1]] = values;
|
|
this._initialized = true;
|
|
}
|
|
|
|
/**
|
|
* @param {string} eventName
|
|
* @param {!Object} params
|
|
*/
|
|
registerEvent(eventName, params) {
|
|
const domain = eventName.split('.')[0];
|
|
this._dispatcherPrototype(domain).registerEvent(eventName, params);
|
|
this._initialized = true;
|
|
}
|
|
|
|
/**
|
|
* @param {function(T)} clientCallback
|
|
* @param {string} errorPrefix
|
|
* @param {function(new:T,S)=} constructor
|
|
* @param {T=} defaultValue
|
|
* @return {function(?string, S)}
|
|
* @template T,S
|
|
*/
|
|
wrapClientCallback(clientCallback, errorPrefix, constructor, defaultValue) {
|
|
/**
|
|
* @param {?string} error
|
|
* @param {S} value
|
|
* @template S
|
|
*/
|
|
function callbackWrapper(error, value) {
|
|
if (error) {
|
|
console.error(errorPrefix + error);
|
|
clientCallback(defaultValue);
|
|
return;
|
|
}
|
|
if (constructor)
|
|
clientCallback(new constructor(value));
|
|
else
|
|
clientCallback(value);
|
|
}
|
|
return callbackWrapper;
|
|
}
|
|
};
|
|
|
|
Protocol.InspectorBackend._ConnectionClosedErrorCode = -32000;
|
|
Protocol.InspectorBackend.DevToolsStubErrorCode = -32015;
|
|
|
|
|
|
Protocol.inspectorBackend = new Protocol.InspectorBackend();
|
|
|
|
/**
|
|
* @interface
|
|
*/
|
|
Protocol.InspectorBackend.Connection = function() {};
|
|
|
|
Protocol.InspectorBackend.Connection.prototype = {
|
|
/**
|
|
* @param {string} message
|
|
*/
|
|
sendMessage(message) {},
|
|
|
|
/**
|
|
* @return {!Promise}
|
|
*/
|
|
disconnect() {},
|
|
};
|
|
|
|
/**
|
|
* @typedef {!{
|
|
* onMessage: function((!Object|string)),
|
|
* onDisconnect: function(string)
|
|
* }}
|
|
*/
|
|
Protocol.InspectorBackend.Connection.Params;
|
|
|
|
/**
|
|
* @typedef {function(!Protocol.InspectorBackend.Connection.Params):!Protocol.InspectorBackend.Connection}
|
|
*/
|
|
Protocol.InspectorBackend.Connection.Factory;
|
|
|
|
/**
|
|
* @unrestricted
|
|
*/
|
|
Protocol.TargetBase = class extends Common.Object {
|
|
/**
|
|
* @param {!Protocol.InspectorBackend.Connection.Factory} connectionFactory
|
|
*/
|
|
constructor(connectionFactory) {
|
|
super();
|
|
this._connection =
|
|
connectionFactory({onMessage: this._onMessage.bind(this), onDisconnect: this._onDisconnect.bind(this)});
|
|
this._lastMessageId = 1;
|
|
this._pendingResponsesCount = 0;
|
|
this._agents = {};
|
|
this._dispatchers = {};
|
|
this._callbacks = {};
|
|
this._initialize(Protocol.inspectorBackend._agentPrototypes, Protocol.inspectorBackend._dispatcherPrototypes);
|
|
this._domainToLogger = new Map();
|
|
if (!Protocol.InspectorBackend.deprecatedRunAfterPendingDispatches) {
|
|
Protocol.InspectorBackend.deprecatedRunAfterPendingDispatches =
|
|
this._deprecatedRunAfterPendingDispatches.bind(this);
|
|
}
|
|
if (!Protocol.InspectorBackend.sendRawMessageForTesting)
|
|
Protocol.InspectorBackend.sendRawMessageForTesting = this._sendRawMessageForTesting.bind(this);
|
|
}
|
|
|
|
/**
|
|
* @param {!Object.<string, !Protocol.InspectorBackend._AgentPrototype>} agentPrototypes
|
|
* @param {!Object.<string, !Protocol.InspectorBackend._DispatcherPrototype>} dispatcherPrototypes
|
|
*/
|
|
_initialize(agentPrototypes, dispatcherPrototypes) {
|
|
for (const domain in agentPrototypes) {
|
|
this._agents[domain] = Object.create(agentPrototypes[domain]);
|
|
this._agents[domain].setTarget(this);
|
|
}
|
|
|
|
for (const domain in dispatcherPrototypes) {
|
|
this._dispatchers[domain] = Object.create(dispatcherPrototypes[domain]);
|
|
this._dispatchers[domain].initialize();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return {number}
|
|
*/
|
|
_nextMessageId() {
|
|
return this._lastMessageId++;
|
|
}
|
|
|
|
/**
|
|
* @param {string} domain
|
|
* @return {!Protocol.InspectorBackend._AgentPrototype}
|
|
*/
|
|
_agent(domain) {
|
|
return this._agents[domain];
|
|
}
|
|
|
|
/**
|
|
* @param {string} domain
|
|
* @param {string} method
|
|
* @param {?Object} params
|
|
* @param {?function(*)} callback
|
|
*/
|
|
_wrapCallbackAndSendMessageObject(domain, method, params, callback) {
|
|
if (!this._connection) {
|
|
if (callback)
|
|
this._dispatchConnectionErrorResponse(domain, method, callback);
|
|
return;
|
|
}
|
|
|
|
const messageObject = {};
|
|
const messageId = this._nextMessageId();
|
|
messageObject.id = messageId;
|
|
messageObject.method = method;
|
|
if (params)
|
|
messageObject.params = params;
|
|
|
|
const wrappedCallback = this._wrap(callback, domain, method);
|
|
const message = JSON.stringify(messageObject);
|
|
|
|
if (Protocol.InspectorBackend.Options.dumpInspectorProtocolMessages)
|
|
this._dumpProtocolMessage('frontend: ' + message, '[FE] ' + domain);
|
|
if (this.hasEventListeners(Protocol.TargetBase.Events.MessageSent)) {
|
|
this.dispatchEventToListeners(
|
|
Protocol.TargetBase.Events.MessageSent,
|
|
{domain, method, params: JSON.parse(JSON.stringify(params)), id: messageId});
|
|
}
|
|
|
|
this._connection.sendMessage(message);
|
|
++this._pendingResponsesCount;
|
|
this._callbacks[messageId] = wrappedCallback;
|
|
}
|
|
|
|
/**
|
|
* @param {?function(*)} callback
|
|
* @param {string} method
|
|
* @param {string} domain
|
|
* @return {function(*)}
|
|
*/
|
|
_wrap(callback, domain, method) {
|
|
if (!callback)
|
|
callback = function() {};
|
|
|
|
callback.methodName = method;
|
|
callback.domain = domain;
|
|
if (Protocol.InspectorBackend.Options.dumpInspectorTimeStats)
|
|
callback.sendRequestTime = Date.now();
|
|
|
|
return callback;
|
|
}
|
|
|
|
/**
|
|
* @param {string} method
|
|
* @param {?Object} params
|
|
* @param {?function(...*)} callback
|
|
*/
|
|
_sendRawMessageForTesting(method, params, callback) {
|
|
const domain = method.split('.')[0];
|
|
this._wrapCallbackAndSendMessageObject(domain, method, params, callback);
|
|
}
|
|
|
|
/**
|
|
* @param {!Object|string} message
|
|
*/
|
|
_onMessage(message) {
|
|
if (Protocol.InspectorBackend.Options.dumpInspectorProtocolMessages) {
|
|
this._dumpProtocolMessage(
|
|
'backend: ' + ((typeof message === 'string') ? message : JSON.stringify(message)), 'Backend');
|
|
}
|
|
if (this.hasEventListeners(Protocol.TargetBase.Events.MessageReceived)) {
|
|
this.dispatchEventToListeners(Protocol.TargetBase.Events.MessageReceived, {
|
|
message: JSON.parse((typeof message === 'string') ? message : JSON.stringify(message)),
|
|
});
|
|
}
|
|
|
|
|
|
const messageObject = /** @type {!Object} */ ((typeof message === 'string') ? JSON.parse(message) : message);
|
|
|
|
if ('id' in messageObject) { // just a response for some request
|
|
const callback = this._callbacks[messageObject.id];
|
|
if (!callback) {
|
|
Protocol.InspectorBackend.reportProtocolError('Protocol Error: the message with wrong id', messageObject);
|
|
return;
|
|
}
|
|
|
|
const timingLabel = 'time-stats: ' + callback.methodName;
|
|
if (Protocol.InspectorBackend.Options.dumpInspectorTimeStats)
|
|
Protocol.InspectorBackend._timeLogger.time(timingLabel);
|
|
|
|
this._agent(callback.domain).dispatchResponse(messageObject, callback.methodName, callback);
|
|
--this._pendingResponsesCount;
|
|
delete this._callbacks[messageObject.id];
|
|
|
|
if (Protocol.InspectorBackend.Options.dumpInspectorTimeStats)
|
|
Protocol.InspectorBackend._timeLogger.timeEnd(timingLabel);
|
|
|
|
if (this._scripts && !this._pendingResponsesCount)
|
|
this._deprecatedRunAfterPendingDispatches();
|
|
} else {
|
|
if (!('method' in messageObject)) {
|
|
Protocol.InspectorBackend.reportProtocolError('Protocol Error: the message without method', messageObject);
|
|
return;
|
|
}
|
|
|
|
const method = messageObject.method.split('.');
|
|
const domainName = method[0];
|
|
if (!(domainName in this._dispatchers)) {
|
|
Protocol.InspectorBackend.reportProtocolError(
|
|
`Protocol Error: the message ${messageObject.method} is for non-existing domain '${domainName}'`,
|
|
messageObject);
|
|
return;
|
|
}
|
|
|
|
this._dispatchers[domainName].dispatch(method[1], messageObject);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {string} domain
|
|
* @param {!Object} dispatcher
|
|
*/
|
|
registerDispatcher(domain, dispatcher) {
|
|
if (!this._dispatchers[domain])
|
|
return;
|
|
|
|
this._dispatchers[domain].addDomainDispatcher(dispatcher);
|
|
}
|
|
|
|
/**
|
|
* @param {function()=} script
|
|
*/
|
|
_deprecatedRunAfterPendingDispatches(script) {
|
|
if (!this._scripts)
|
|
this._scripts = [];
|
|
|
|
if (script)
|
|
this._scripts.push(script);
|
|
|
|
// Execute all promises.
|
|
setTimeout(function() {
|
|
if (!this._pendingResponsesCount)
|
|
this._executeAfterPendingDispatches();
|
|
else
|
|
this._deprecatedRunAfterPendingDispatches();
|
|
}.bind(this), 0);
|
|
}
|
|
|
|
_executeAfterPendingDispatches() {
|
|
if (!this._pendingResponsesCount) {
|
|
const scripts = this._scripts;
|
|
this._scripts = [];
|
|
for (let id = 0; id < scripts.length; ++id)
|
|
scripts[id].call(this);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {string} message
|
|
* @param {string} context
|
|
*/
|
|
_dumpProtocolMessage(message, context) {
|
|
if (!this._domainToLogger.get(context))
|
|
this._domainToLogger.set(context, console.context ? console.context(context) : console);
|
|
const logger = this._domainToLogger.get(context);
|
|
logger.log(message);
|
|
}
|
|
|
|
/**
|
|
* @param {string} reason
|
|
*/
|
|
_onDisconnect(reason) {
|
|
this._connection = null;
|
|
this._runPendingCallbacks();
|
|
this.dispose();
|
|
}
|
|
|
|
/**
|
|
* @protected
|
|
*/
|
|
dispose() {
|
|
}
|
|
|
|
/**
|
|
* @return {boolean}
|
|
*/
|
|
isDisposed() {
|
|
return !this._connection;
|
|
}
|
|
|
|
_runPendingCallbacks() {
|
|
const keys = Object.keys(this._callbacks).map(function(num) {
|
|
return parseInt(num, 10);
|
|
});
|
|
for (let i = 0; i < keys.length; ++i) {
|
|
const callback = this._callbacks[keys[i]];
|
|
this._dispatchConnectionErrorResponse(callback.domain, callback.methodName, callback);
|
|
}
|
|
this._callbacks = {};
|
|
}
|
|
|
|
/**
|
|
* @param {string} domain
|
|
* @param {string} methodName
|
|
* @param {function(*)} callback
|
|
*/
|
|
_dispatchConnectionErrorResponse(domain, methodName, callback) {
|
|
const error = {
|
|
message: 'Connection is closed, can\'t dispatch pending ' + methodName,
|
|
code: Protocol.InspectorBackend._ConnectionClosedErrorCode,
|
|
data: null
|
|
};
|
|
const messageObject = {error: error};
|
|
setTimeout(
|
|
Protocol.InspectorBackend._AgentPrototype.prototype.dispatchResponse.bind(
|
|
this._agent(domain), messageObject, methodName, callback),
|
|
0);
|
|
}
|
|
};
|
|
|
|
Protocol.TargetBase.Events = {
|
|
MessageSent: Symbol('MessageSent'),
|
|
MessageReceived: Symbol('MessageReceived')
|
|
};
|
|
|
|
/**
|
|
* @unrestricted
|
|
*/
|
|
Protocol.InspectorBackend._AgentPrototype = class {
|
|
/**
|
|
* @param {string} domain
|
|
*/
|
|
constructor(domain) {
|
|
this._replyArgs = {};
|
|
this._hasErrorData = {};
|
|
this._domain = domain;
|
|
}
|
|
|
|
/**
|
|
* @param {!Protocol.TargetBase} target
|
|
*/
|
|
setTarget(target) {
|
|
this._target = target;
|
|
}
|
|
|
|
/**
|
|
* @param {string} methodName
|
|
* @param {!Array.<!Object>} signature
|
|
* @param {!Array.<string>} replyArgs
|
|
* @param {boolean} hasErrorData
|
|
*/
|
|
registerCommand(methodName, signature, replyArgs, hasErrorData) {
|
|
const domainAndMethod = this._domain + '.' + methodName;
|
|
|
|
/**
|
|
* @param {...*} vararg
|
|
* @this {Protocol.InspectorBackend._AgentPrototype}
|
|
* @return {!Promise.<*>}
|
|
*/
|
|
function sendMessagePromise(vararg) {
|
|
const params = Array.prototype.slice.call(arguments);
|
|
return Protocol.InspectorBackend._AgentPrototype.prototype._sendMessageToBackendPromise.call(
|
|
this, domainAndMethod, signature, params);
|
|
}
|
|
|
|
this[methodName] = sendMessagePromise;
|
|
|
|
/**
|
|
* @param {!Object} request
|
|
* @return {!Promise}
|
|
* @this {Protocol.InspectorBackend._AgentPrototype}
|
|
*/
|
|
function invoke(request) {
|
|
return this._invoke(domainAndMethod, request);
|
|
}
|
|
|
|
this['invoke_' + methodName] = invoke;
|
|
|
|
this._replyArgs[domainAndMethod] = replyArgs;
|
|
if (hasErrorData)
|
|
this._hasErrorData[domainAndMethod] = true;
|
|
}
|
|
|
|
/**
|
|
* @param {string} method
|
|
* @param {!Array.<!Object>} signature
|
|
* @param {!Array.<*>} args
|
|
* @param {function(string)} errorCallback
|
|
* @return {?Object}
|
|
*/
|
|
_prepareParameters(method, signature, args, errorCallback) {
|
|
const params = {};
|
|
let hasParams = false;
|
|
|
|
for (const param of signature) {
|
|
const paramName = param['name'];
|
|
const typeName = param['type'];
|
|
const optionalFlag = param['optional'];
|
|
|
|
if (!args.length && !optionalFlag) {
|
|
errorCallback(
|
|
`Protocol Error: Invalid number of arguments for method '${method}' call. ` +
|
|
`It must have the following arguments ${JSON.stringify(signature)}'.`);
|
|
return null;
|
|
}
|
|
|
|
const value = args.shift();
|
|
if (optionalFlag && typeof value === 'undefined')
|
|
continue;
|
|
|
|
if (typeof value !== typeName) {
|
|
errorCallback(
|
|
`Protocol Error: Invalid type of argument '${paramName}' for method '${method}' call. ` +
|
|
`It must be '${typeName}' but it is '${typeof value}'.`);
|
|
return null;
|
|
}
|
|
|
|
params[paramName] = value;
|
|
hasParams = true;
|
|
}
|
|
|
|
if (args.length) {
|
|
errorCallback(`Protocol Error: Extra ${args.length} arguments in a call to method '${method}'.`);
|
|
return null;
|
|
}
|
|
|
|
return hasParams ? params : null;
|
|
}
|
|
|
|
/**
|
|
* @param {string} method
|
|
* @param {!Array<!Object>} signature
|
|
* @param {!Array<*>} args
|
|
* @return {!Promise<?>}
|
|
*/
|
|
_sendMessageToBackendPromise(method, signature, args) {
|
|
let errorMessage;
|
|
/**
|
|
* @param {string} message
|
|
*/
|
|
function onError(message) {
|
|
console.error(message);
|
|
errorMessage = message;
|
|
}
|
|
const params = this._prepareParameters(method, signature, args, onError);
|
|
if (errorMessage)
|
|
return Promise.resolve(null);
|
|
|
|
return new Promise(resolve => {
|
|
this._target._wrapCallbackAndSendMessageObject(this._domain, method, params, (error, result) => {
|
|
if (error) {
|
|
resolve(null);
|
|
return;
|
|
}
|
|
const args = this._replyArgs[method];
|
|
resolve(result && args.length ? result[args[0]] : undefined);
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @param {string} method
|
|
* @param {?Object} request
|
|
* @return {!Promise<!Object>}
|
|
*/
|
|
_invoke(method, request) {
|
|
return new Promise(fulfill => {
|
|
this._target._wrapCallbackAndSendMessageObject(this._domain, method, request, (error, result) => {
|
|
if (!result)
|
|
result = {};
|
|
if (error)
|
|
result[Protocol.Error] = error.message;
|
|
fulfill(result);
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @param {!Object} messageObject
|
|
* @param {string} methodName
|
|
* @param {function(?Protocol.Error, ?Object)} callback
|
|
*/
|
|
dispatchResponse(messageObject, methodName, callback) {
|
|
if (messageObject.error && messageObject.error.code !== Protocol.InspectorBackend._ConnectionClosedErrorCode &&
|
|
messageObject.error.code !== Protocol.InspectorBackend.DevToolsStubErrorCode &&
|
|
!Protocol.InspectorBackend.Options.suppressRequestErrors) {
|
|
const id =
|
|
Protocol.InspectorBackend.Options.dumpInspectorProtocolMessages ? ' with id = ' + messageObject.id : '';
|
|
console.error('Request ' + methodName + id + ' failed. ' + JSON.stringify(messageObject.error));
|
|
}
|
|
callback(messageObject.error, messageObject.result);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @unrestricted
|
|
*/
|
|
Protocol.InspectorBackend._DispatcherPrototype = class {
|
|
constructor() {
|
|
this._eventArgs = {};
|
|
}
|
|
|
|
/**
|
|
* @param {string} eventName
|
|
* @param {!Object} params
|
|
*/
|
|
registerEvent(eventName, params) {
|
|
this._eventArgs[eventName] = params;
|
|
}
|
|
|
|
initialize() {
|
|
this._dispatchers = [];
|
|
}
|
|
|
|
/**
|
|
* @param {!Object} dispatcher
|
|
*/
|
|
addDomainDispatcher(dispatcher) {
|
|
this._dispatchers.push(dispatcher);
|
|
}
|
|
|
|
/**
|
|
* @param {string} functionName
|
|
* @param {!Object} messageObject
|
|
*/
|
|
dispatch(functionName, messageObject) {
|
|
if (!this._dispatchers.length)
|
|
return;
|
|
|
|
if (!this._eventArgs[messageObject.method]) {
|
|
Protocol.InspectorBackend.reportProtocolError(
|
|
`Protocol Error: Attempted to dispatch an unspecified method '${messageObject.method}'`, messageObject);
|
|
return;
|
|
}
|
|
|
|
const params = [];
|
|
if (messageObject.params) {
|
|
const paramNames = this._eventArgs[messageObject.method];
|
|
for (let i = 0; i < paramNames.length; ++i)
|
|
params.push(messageObject.params[paramNames[i]]);
|
|
}
|
|
|
|
const timingLabel = 'time-stats: ' + messageObject.method;
|
|
if (Protocol.InspectorBackend.Options.dumpInspectorTimeStats)
|
|
Protocol.InspectorBackend._timeLogger.time(timingLabel);
|
|
|
|
for (let index = 0; index < this._dispatchers.length; ++index) {
|
|
const dispatcher = this._dispatchers[index];
|
|
if (functionName in dispatcher)
|
|
dispatcher[functionName].apply(dispatcher, params);
|
|
}
|
|
|
|
if (Protocol.InspectorBackend.Options.dumpInspectorTimeStats)
|
|
Protocol.InspectorBackend._timeLogger.timeEnd(timingLabel);
|
|
}
|
|
};
|
|
|
|
Protocol.InspectorBackend.Options = {
|
|
dumpInspectorTimeStats: false,
|
|
dumpInspectorProtocolMessages: false,
|
|
suppressRequestErrors: false
|
|
};
|
|
|
|
Protocol.InspectorBackend._timeLogger = console.context ? console.context('Protocol timing') : console;
|