Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js (167983 => 167984)
--- trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js 2014-04-30 05:42:57 UTC (rev 167983)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js 2014-04-30 05:52:04 UTC (rev 167984)
@@ -47,20 +47,37 @@
}
InspectorBackendClass.prototype = {
- _wrap: function(callback, method)
+ _registerPendingResponse: function(callback, methodName)
{
var callbackId = this._lastCallbackId++;
if (!callback)
callback = function() {};
this._callbacks[callbackId] = callback;
- callback.methodName = method;
+ callback.methodName = methodName;
if (this.dumpInspectorTimeStats)
callback.sendRequestTime = Date.now();
+ ++this._pendingResponsesCount;
+
return callbackId;
},
+ _invokeMethod: function(command, parameters, callback)
+ {
+ var messageObject = {};
+ messageObject["method"] = command.methodName;
+ if (parameters)
+ messageObject["params"] = parameters;
+ messageObject["id"] = this._registerPendingResponse(callback, command.methodName);
+
+ var stringifiedMessage = JSON.stringify(messageObject);
+ if (this.dumpInspectorProtocolMessages)
+ console.log("frontend: " + stringifiedMessage);
+
+ InspectorFrontendHost.sendMessageToBackend(stringifiedMessage);
+ },
+
_getAgent: function(domain)
{
var agentName = domain + "Agent";
@@ -73,11 +90,8 @@
{
var domainAndMethod = method.split(".");
var agent = this._getAgent(domainAndMethod[0]);
+ agent[domainAndMethod[1]] = InspectorBackendCommand.create(this, method, signature);
- agent[domainAndMethod[1]] = this._sendMessageToBackend.bind(this, method, signature);
- agent[domainAndMethod[1]]["invoke"] = this._invoke.bind(this, method, signature);
- agent[domainAndMethod[1]]["promise"] = this._promise.bind(this, method, signature);
- agent[domainAndMethod[1]]["supports"] = this._supports.bind(this, method, signature);
this._replyArgs[method] = replyArgs;
},
@@ -89,105 +103,11 @@
agent[domainAndMethod[1]] = values;
},
- registerEvent: function(eventName, params)
+ registerEvent: function(eventName, parameters)
{
- this._eventArgs[eventName] = params;
+ this._eventArgs[eventName] = parameters;
},
- _invoke: function(method, signature, args, callback)
- {
- this._wrapCallbackAndSendMessageObject(method, args, callback);
- },
-
- _promise: function(method, signature)
- {
- var backend = this;
- var promiseArguments = Array.prototype.slice.call(arguments);
- return new Promise(function(resolve, reject) {
- function convertToPromiseCallback(error, payload) {
- if (error)
- reject(error);
- else
- resolve(payload);
- }
- promiseArguments.push(convertToPromiseCallback);
- backend._sendMessageToBackend.apply(backend, promiseArguments);
- });
- },
-
- _supports: function(method, signature, paramName)
- {
- for (var i = 0; i < signature.length; ++i) {
- if (signature[i]["name"] === paramName)
- return true;
- }
-
- return false;
- },
-
- _sendMessageToBackend: function(method, signature, vararg)
- {
- var args = Array.prototype.slice.call(arguments, 2);
- var callback = typeof args.lastValue === "function" ? args.pop() : null;
-
- var params = {};
- var hasParams = false;
- for (var i = 0; i < signature.length; ++i) {
- var param = signature[i];
- var paramName = param["name"];
- var typeName = param["type"];
- var optionalFlag = param["optional"];
-
- if (!args.length && !optionalFlag) {
- console.error("Protocol Error: Invalid number of arguments for method '" + method + "' call. It must have the following arguments '" + JSON.stringify(signature) + "'.");
- return;
- }
-
- var value = args.shift();
- if (optionalFlag && typeof value === "undefined") {
- continue;
- }
-
- if (typeof value !== typeName) {
- console.error("Protocol Error: Invalid type of argument '" + paramName + "' for method '" + method + "' call. It must be '" + typeName + "' but it is '" + typeof value + "'.");
- return;
- }
-
- params[paramName] = value;
- hasParams = true;
- }
-
- if (args.length === 1 && !callback) {
- if (typeof args[0] !== "undefined") {
- console.error("Protocol Error: Optional callback argument for method '" + method + "' call must be a function but its type is '" + typeof args[0] + "'.");
- return;
- }
- }
-
- this._wrapCallbackAndSendMessageObject(method, hasParams ? params : null, callback);
- },
-
- _wrapCallbackAndSendMessageObject: function(method, params, callback)
- {
- var messageObject = {};
- messageObject.method = method;
- if (params)
- messageObject.params = params;
- messageObject.id = this._wrap(callback, method);
-
- if (this.dumpInspectorProtocolMessages)
- console.log("frontend: " + JSON.stringify(messageObject));
-
- ++this._pendingResponsesCount;
- this.sendMessageObjectToBackend(messageObject);
- },
-
- sendMessageObjectToBackend: function(messageObject)
- {
- var message = JSON.stringify(messageObject);
- InspectorFrontendHost.sendMessageToBackend(message);
- },
-
registerDomainDispatcher: function(domain, dispatcher)
{
this._domainDispatchers[domain] = dispatcher;
@@ -311,3 +231,96 @@
}
InspectorBackend = new InspectorBackendClass();
+
+InspectorBackendCommand = function(backend, methodName, callSignature)
+{
+ this._backend = backend;
+ this.methodName = methodName;
+ this._callSignature = callSignature;
+ this._instance = this;
+}
+
+InspectorBackendCommand.create = function(backend, methodName, callSignature)
+{
+ var instance = new InspectorBackendCommand(backend, methodName, callSignature);
+
+ function callable() {
+ instance._invokeWithArguments.apply(instance, arguments);
+ }
+ callable._instance = instance;
+ callable.__proto__ = InspectorBackendCommand.prototype;
+ return callable;
+}
+
+// As part of the workaround to make commands callable, these functions use |this._instance|.
+// |this| could refer to the callable trampoline, or the InspectorBackendCommand instance.
+InspectorBackendCommand.prototype = {
+ __proto__: Function.prototype,
+
+ invoke: function(args, callback)
+ {
+ var instance = this._instance;
+ instance._backend._invokeMethod(instance, args, callback);
+ },
+
+ promise: function()
+ {
+ var instance = this._instance;
+ var promiseArguments = Array.prototype.slice.call(arguments);
+ return new Promise(function(resolve, reject) {
+ function convertToPromiseCallback(error, payload) {
+ return error ? reject(error) : resolve(payload);
+ }
+ promiseArguments.push(convertToPromiseCallback);
+ instance._invokeWithArguments.apply(instance, promiseArguments);
+ });
+ },
+
+ supports: function(parameterName)
+ {
+ var instance = this._instance;
+ return instance._callSignature.any(function(parameter) {
+ return parameter["name"] === parameterName
+ });
+ },
+
+ _invokeWithArguments: function()
+ {
+ var instance = this._instance;
+ var args = Array.prototype.slice.call(arguments);
+ var callback = typeof args.lastValue === "function" ? args.pop() : null;
+
+ var parameters = {};
+ for (var i = 0; i < instance._callSignature.length; ++i) {
+ var parameter = instance._callSignature[i];
+ var parameterName = parameter["name"];
+ var typeName = parameter["type"];
+ var optionalFlag = parameter["optional"];
+
+ if (!args.length && !optionalFlag) {
+ console.error("Protocol Error: Invalid number of arguments for method '" + instance.methodName + "' call. It must have the following arguments '" + JSON.stringify(signature) + "'.");
+ return;
+ }
+
+ var value = args.shift();
+ if (optionalFlag && typeof value === "undefined")
+ continue;
+
+ if (typeof value !== typeName) {
+ console.error("Protocol Error: Invalid type of argument '" + parameterName + "' for method '" + instance.methodName + "' call. It must be '" + typeName + "' but it is '" + typeof value + "'.");
+ return;
+ }
+
+ parameters[parameterName] = value;
+ }
+
+ if (args.length === 1 && !callback) {
+ if (typeof args[0] !== "undefined") {
+ console.error("Protocol Error: Optional callback argument for method '" + instance.methodName + "' call must be a function but its type is '" + typeof args[0] + "'.");
+ return;
+ }
+ }
+
+ instance._backend._invokeMethod(instance, Object.keys(parameters).length ? parameters : null, callback);
+ },
+}