;modjewel.define("weinre/common/WebSocketXhr", function(require, exports, module) { // Generated by CoffeeScript 1.8.0 var EventListeners, Ex, HookLib, WebSocketXhr, Weinre, _xhrEventHandler; Ex = require('./Ex'); Weinre = require('./Weinre'); HookLib = require('./HookLib'); EventListeners = require('./EventListeners'); module.exports = WebSocketXhr = (function() { WebSocketXhr.CONNECTING = 0; WebSocketXhr.OPEN = 1; WebSocketXhr.CLOSING = 2; WebSocketXhr.CLOSED = 3; function WebSocketXhr(url, id) { this.initialize(url, id); } WebSocketXhr.prototype.initialize = function(url, id) { if (!id) { id = "anonymous"; } this.readyState = WebSocketXhr.CONNECTING; this._url = url; this._id = id; this._urlChannel = null; this._queuedSends = []; this._sendInProgress = true; this._listeners = { open: new EventListeners(), message: new EventListeners(), error: new EventListeners(), close: new EventListeners() }; return this._getChannel(); }; WebSocketXhr.prototype._getChannel = function() { var body; body = JSON.stringify({ id: this._id }); return this._xhr(this._url, "POST", body, this._handleXhrResponseGetChannel); }; WebSocketXhr.prototype._handleXhrResponseGetChannel = function(xhr) { var e, object; if (xhr.status !== 200) { return this._handleXhrResponseError(xhr); } try { object = JSON.parse(xhr.responseText); } catch (_error) { e = _error; this._fireEventListeners("error", { message: "non-JSON response from channel open request" }); this.close(); return; } if (!object.channel) { this._fireEventListeners("error", { message: "channel open request did not include a channel" }); this.close(); return; } this._urlChannel = this._url + "/" + object.channel; this.readyState = WebSocketXhr.OPEN; this._fireEventListeners("open", { message: "open", channel: object.channel }); this._sendInProgress = false; this._sendQueued(); return this._readLoop(); }; WebSocketXhr.prototype._readLoop = function() { if (this.readyState === WebSocketXhr.CLOSED) { return; } if (this.readyState === WebSocketXhr.CLOSING) { return; } return this._xhr(this._urlChannel, "GET", "", this._handleXhrResponseGet); }; WebSocketXhr.prototype._handleXhrResponseGet = function(xhr) { var data, datum, e, self, _i, _len, _results; self = this; if (xhr.status !== 200) { return this._handleXhrResponseError(xhr); } try { datum = JSON.parse(xhr.responseText); } catch (_error) { e = _error; this.readyState = WebSocketXhr.CLOSED; this._fireEventListeners("error", { message: "non-JSON response from read request" }); return; } HookLib.ignoreHooks(function() { return setTimeout((function() { return self._readLoop(); }), 0); }); _results = []; for (_i = 0, _len = datum.length; _i < _len; _i++) { data = datum[_i]; _results.push(self._fireEventListeners("message", { data: data })); } return _results; }; WebSocketXhr.prototype.send = function(data) { if (typeof data !== "string") { throw new Ex(arguments, this.constructor.name + ".send"); } this._queuedSends.push(data); if (this._sendInProgress) { return; } return this._sendQueued(); }; WebSocketXhr.prototype._sendQueued = function() { var datum; if (this._queuedSends.length === 0) { return; } if (this.readyState === WebSocketXhr.CLOSED) { return; } if (this.readyState === WebSocketXhr.CLOSING) { return; } datum = JSON.stringify(this._queuedSends); this._queuedSends = []; this._sendInProgress = true; return this._xhr(this._urlChannel, "POST", datum, this._handleXhrResponseSend); }; WebSocketXhr.prototype._handleXhrResponseSend = function(xhr) { var httpSocket; httpSocket = this; if (xhr.status !== 200) { return this._handleXhrResponseError(xhr); } this._sendInProgress = false; return HookLib.ignoreHooks(function() { return setTimeout((function() { return httpSocket._sendQueued(); }), 0); }); }; WebSocketXhr.prototype.close = function() { this._sendInProgress = true; this.readyState = WebSocketXhr.CLOSING; this._fireEventListeners("close", { message: "closing", wasClean: true }); return this.readyState = WebSocketXhr.CLOSED; }; WebSocketXhr.prototype.addEventListener = function(type, listener, useCapture) { return this._getListeners(type).add(listener, useCapture); }; WebSocketXhr.prototype.removeEventListener = function(type, listener, useCapture) { return this._getListeners(type).remove(listener, useCapture); }; WebSocketXhr.prototype._fireEventListeners = function(type, event) { if (this.readyState === WebSocketXhr.CLOSED) { return; } event.target = this; return this._getListeners(type).fire(event); }; WebSocketXhr.prototype._getListeners = function(type) { var listeners; listeners = this._listeners[type]; if (null === listeners) { throw new Ex(arguments, "invalid event listener type: '" + type + "'"); } return listeners; }; WebSocketXhr.prototype._handleXhrResponseError = function(xhr) { if (xhr.status === 404) { this.close(); return; } this._fireEventListeners("error", { target: this, status: xhr.status, message: "error from XHR invocation: " + xhr.statusText }); return Weinre.logError(("error from XHR invocation: " + xhr.status + ": ") + xhr.statusText); }; WebSocketXhr.prototype._xhr = function(url, method, data, handler) { var xhr; if (null === handler) { throw new Ex(arguments, "handler must not be null"); } xhr = (XMLHttpRequest.noConflict ? new XMLHttpRequest.noConflict() : new XMLHttpRequest()); xhr.httpSocket = this; xhr.httpSocketHandler = handler; xhr.onreadystatechange = function() { return _xhrEventHandler(xhr); }; HookLib.ignoreHooks(function() { return xhr.open(method, url, true); }); xhr.setRequestHeader("Content-Type", "text/plain"); return HookLib.ignoreHooks(function() { return xhr.send(data); }); }; return WebSocketXhr; })(); _xhrEventHandler = function(xhr) { if (xhr.readyState !== 4) { return; } return xhr.httpSocketHandler.call(xhr.httpSocket, xhr); }; require("../common/MethodNamer").setNamesForClass(module.exports); });