;modjewel.define("weinre/common/MessageDispatcher", function(require, exports, module) { // Generated by CoffeeScript 1.8.0 var Binding, Callback, Ex, IDLTools, InspectorBackend, MessageDispatcher, Verbose, WebSocketXhr, Weinre, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; Weinre = require('./Weinre'); WebSocketXhr = require('./WebSocketXhr'); IDLTools = require('./IDLTools'); Binding = require('./Binding'); Ex = require('./Ex'); Callback = require('./Callback'); Verbose = false; InspectorBackend = null; module.exports = MessageDispatcher = (function() { function MessageDispatcher(url, id) { if (!id) { id = "anonymous"; } this._url = url; this._id = id; this.error = null; this._opening = false; this._opened = false; this._closed = false; this._interfaces = {}; this._open(); } MessageDispatcher.setInspectorBackend = function(inspectorBackend) { return InspectorBackend = inspectorBackend; }; MessageDispatcher.verbose = function(value) { if (arguments.length >= 1) { Verbose = !!value; } return Verbose; }; MessageDispatcher.prototype._open = function() { if (this._opened || this._opening) { return; } if (this._closed) { throw new Ex(arguments, "socket has already been closed"); } this._opening = true; this._socket = new WebSocketXhr(this._url, this._id); this._socket.addEventListener("open", Binding(this, "_handleOpen")); this._socket.addEventListener("error", Binding(this, "_handleError")); this._socket.addEventListener("message", Binding(this, "_handleMessage")); return this._socket.addEventListener("close", Binding(this, "_handleClose")); }; MessageDispatcher.prototype.close = function() { if (this._closed) { return; } this._opened = false; this._closed = true; return this._socket.close(); }; MessageDispatcher.prototype.send = function(data) { return this._socket.send(data); }; MessageDispatcher.prototype.getWebSocket = function() { return this._socket; }; MessageDispatcher.prototype.registerInterface = function(intfName, intf, validate) { if (validate) { IDLTools.validateAgainstIDL(intf.constructor, intfName); } if (this._interfaces[intfName]) { throw new Ex(arguments, "interface " + intfName + " has already been registered"); } return this._interfaces[intfName] = intf; }; MessageDispatcher.prototype.createProxy = function(intfName) { var proxy, self, __invoke; proxy = {}; IDLTools.buildProxyForIDL(proxy, intfName); self = this; proxy.__invoke = __invoke = function(intfName, methodName, args) { return self._sendMethodInvocation(intfName, methodName, args); }; return proxy; }; MessageDispatcher.prototype._sendMethodInvocation = function(intfName, methodName, args) { var data; if (typeof intfName !== "string") { throw new Ex(arguments, "expecting intf parameter to be a string"); } if (typeof methodName !== "string") { throw new Ex(arguments, "expecting method parameter to be a string"); } data = { "interface": intfName, method: methodName, args: args }; data = JSON.stringify(data); this._socket.send(data); if (Verbose) { return Weinre.logDebug(this.constructor.name + ("[" + this._url + "]: send " + intfName + "." + methodName + "(" + (JSON.stringify(args)) + ")")); } }; MessageDispatcher.prototype.getState = function() { if (this._opening) { return "opening"; } if (this._opened) { return "opened"; } if (this._closed) { return "closed"; } return "unknown"; }; MessageDispatcher.prototype.isOpen = function() { return this._opened === true; }; MessageDispatcher.prototype._handleOpen = function(event) { this._opening = false; this._opened = true; this.channel = event.channel; Callback.setConnectorChannel(this.channel); if (Verbose) { return Weinre.logDebug(this.constructor.name + ("[" + this._url + "]: opened")); } }; MessageDispatcher.prototype._handleError = function(message) { this.error = message; this.close(); if (Verbose) { return Weinre.logDebug(this.constructor.name + ("[" + this._url + "]: error: ") + message); } }; MessageDispatcher.prototype._handleMessage = function(message) { var args, data, e, intf, intfName, method, methodName, methodSignature, skipErrorForMethods; skipErrorForMethods = ['domContentEventFired', 'loadEventFired', 'childNodeRemoved']; try { data = JSON.parse(message.data); } catch (_error) { e = _error; throw new Ex(arguments, "invalid JSON data received: " + e + ": '" + message.data + "'"); } intfName = data["interface"]; methodName = data.method; args = data.args; methodSignature = "" + intfName + "." + methodName + "()"; intf = this._interfaces.hasOwnProperty(intfName) && this._interfaces[intfName]; if (!intf && InspectorBackend && intfName.match(/.*Notify/)) { intf = InspectorBackend.getRegisteredDomainDispatcher(intfName.substr(0, intfName.length - 6)); } if (!intf) { Weinre.notImplemented("weinre: request for non-registered interface: " + methodSignature); return; } methodSignature = intf.constructor.name + ("." + methodName + "()"); method = intf[methodName]; if (typeof method !== "function") { Weinre.notImplemented(methodSignature); return; } try { method.apply(intf, args); } catch (_error) { e = _error; if (__indexOf.call(skipErrorForMethods, methodName) < 0) { Weinre.logError(("weinre: invocation exception on " + methodSignature + ": ") + e); } } if (Verbose) { return Weinre.logDebug(this.constructor.name + ("[" + this._url + "]: recv " + intfName + "." + methodName + "(" + (JSON.stringify(args)) + ")")); } }; MessageDispatcher.prototype._handleClose = function() { this._reallyClosed = true; if (Verbose) { return Weinre.logDebug(this.constructor.name + ("[" + this._url + "]: closed")); } }; return MessageDispatcher; })(); require("../common/MethodNamer").setNamesForClass(module.exports); });