http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/dependencies/compile/runtime/javascript-2.1.5/javascript/atmosphere.js ---------------------------------------------------------------------- diff --git a/wave/dependencies/compile/runtime/javascript-2.1.5/javascript/atmosphere.js b/wave/dependencies/compile/runtime/javascript-2.1.5/javascript/atmosphere.js deleted file mode 100644 index d8b0317..0000000 --- a/wave/dependencies/compile/runtime/javascript-2.1.5/javascript/atmosphere.js +++ /dev/null @@ -1,3081 +0,0 @@ -/* - * Copyright 2014 Jeanfrancois Arcand - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Atmosphere.js - * https://github.com/Atmosphere/atmosphere-javascript - * - * API reference - * https://github.com/Atmosphere/atmosphere/wiki/jQuery.atmosphere.js-API - * - * Highly inspired by - * - Portal by Donghwan Kim http://flowersinthesand.github.io/portal/ - */ -(function(root, factory) { - if (typeof define === "function" && define.amd) { - // AMD - define(factory); - } else { - // Browser globals, Window - root.atmosphere = factory(); - } -}(this, function() { - - "use strict"; - - var version = "2.1.5-javascript", - atmosphere = {}, - guid, - requests = [], - callbacks = [], - uuid = 0, - hasOwn = Object.prototype.hasOwnProperty; - - atmosphere = { - - onError: function (response) { - }, - onClose: function (response) { - }, - onOpen: function (response) { - }, - onReopen: function (response) { - }, - onMessage: function (response) { - }, - onReconnect: function (request, response) { - }, - onMessagePublished: function (response) { - }, - onTransportFailure: function (errorMessage, _request) { - }, - onLocalMessage: function (response) { - }, - onFailureToReconnect: function (request, response) { - }, - onClientTimeout: function(request){ - }, - - AtmosphereRequest: function (options) { - - /** - * {Object} Request parameters. - * - * @private - */ - var _request = { - timeout: 300000, - method: 'GET', - headers: {}, - contentType: '', - callback: null, - url: '', - data: '', - suspend: true, - maxRequest: -1, - reconnect: true, - maxStreamingLength: 10000000, - lastIndex: 0, - logLevel: 'info', - requestCount: 0, - fallbackMethod: 'GET', - fallbackTransport: 'streaming', - transport: 'long-polling', - webSocketImpl: null, - webSocketBinaryType: null, - dispatchUrl: null, - webSocketPathDelimiter: "@@", - enableXDR: false, - rewriteURL: false, - attachHeadersAsQueryString: true, - executeCallbackBeforeReconnect: false, - readyState: 0, - lastTimestamp: 0, - withCredentials: false, - trackMessageLength: false, - messageDelimiter: '|', - connectTimeout: -1, - reconnectInterval: 0, - dropHeaders: true, - uuid: 0, - async: true, - shared: false, - readResponsesHeaders: false, - maxReconnectOnClose: 5, - enableProtocol: true, - pollingInterval : 0, - onError: function (response) { - }, - onClose: function (response) { - }, - onOpen: function (response) { - }, - onMessage: function (response) { - }, - onReopen: function (request, response) { - }, - onReconnect: function (request, response) { - }, - onMessagePublished: function (response) { - }, - onTransportFailure: function (reason, request) { - }, - onLocalMessage: function (request) { - }, - onFailureToReconnect: function (request, response) { - }, - onClientTimeout: function(request){ - } - }; - - /** - * {Object} Request's last response. - * - * @private - */ - var _response = { - status: 200, - reasonPhrase: "OK", - responseBody: '', - messages: [], - headers: [], - state: "messageReceived", - transport: "polling", - error: null, - request: null, - partialMessage: "", - errorHandled: false, - closedByClientTimeout: false - }; - - /** - * {websocket} Opened web socket. - * - * @private - */ - var _websocket = null; - - /** - * {SSE} Opened SSE. - * - * @private - */ - var _sse = null; - - /** - * {XMLHttpRequest, ActiveXObject} Opened ajax request (in case of http-streaming or long-polling) - * - * @private - */ - var _activeRequest = null; - - /** - * {Object} Object use for streaming with IE. - * - * @private - */ - var _ieStream = null; - - /** - * {Object} Object use for jsonp transport. - * - * @private - */ - var _jqxhr = null; - - /** - * {boolean} If request has been subscribed or not. - * - * @private - */ - var _subscribed = true; - - /** - * {number} Number of test reconnection. - * - * @private - */ - var _requestCount = 0; - - /** - * {boolean} If request is currently aborded. - * - * @private - */ - var _abordingConnection = false; - - /** - * A local "channel' of communication. - * - * @private - */ - var _localSocketF = null; - - /** - * The storage used. - * - * @private - */ - var _storageService; - - /** - * Local communication - * - * @private - */ - var _localStorageService = null; - - /** - * A Unique ID - * - * @private - */ - var guid = atmosphere.util.now(); - - /** Trace time */ - var _traceTimer; - - /** Key for connection sharing */ - var _sharingKey; - - // Automatic call to subscribe - _subscribe(options); - - /** - * Initialize atmosphere request object. - * - * @private - */ - function _init() { - _subscribed = true; - _abordingConnection = false; - _requestCount = 0; - - _websocket = null; - _sse = null; - _activeRequest = null; - _ieStream = null; - } - - /** - * Re-initialize atmosphere object. - * - * @private - */ - function _reinit() { - _clearState(); - _init(); - } - - /** - * - * @private - */ - function _verifyStreamingLength(ajaxRequest, rq) { - // Wait to be sure we have the full message before closing. - if (_response.partialMessage === "" && (rq.transport === 'streaming') && (ajaxRequest.responseText.length > rq.maxStreamingLength)) { - _response.messages = []; - rq.reconnectingOnLength = true; - rq.isReopen = true; - _invokeClose(true); - _disconnect(); - _clearState(); - _reconnect(ajaxRequest, rq, rq.pollingInterval); - } - } - - /** - * Disconnect - * - * @private - */ - function _disconnect() { - if (_request.enableProtocol && !_request.firstMessage) { - var query = "X-Atmosphere-Transport=close&X-Atmosphere-tracking-id=" + _request.uuid; - - atmosphere.util.each(_request.headers, function (name, value) { - var h = atmosphere.util.isFunction(value) ? value.call(this, _request, _request, _response) : value; - if (h != null) { - query += "&" + encodeURIComponent(name) + "=" + encodeURIComponent(h); - } - }); - - var url = _request.url.replace(/([?&])_=[^&]*/, query); - url = url + (url === _request.url ? (/\?/.test(_request.url) ? "&" : "?") + query : ""); - - var rq = { - connected: false - }; - var closeR = new atmosphere.AtmosphereRequest(rq); - closeR.attachHeadersAsQueryString = false; - closeR.dropHeaders = true; - closeR.url = url; - closeR.contentType = "text/plain"; - closeR.transport = 'polling'; - closeR.method = 'GET'; - closeR.data = ''; - closeR.async = false; - _pushOnClose("", closeR); - } - } - - /** - * Close request. - * - * @private - */ - function _close() { - if (_request.reconnectId) { - clearTimeout(_request.reconnectId); - delete _request.reconnectId; - } - _request.reconnect = false; - _abordingConnection = true; - _response.request = _request; - _response.state = 'unsubscribe'; - _response.responseBody = ""; - _response.status = 408; - _response.partialMessage = ""; - _invokeCallback(); - _disconnect(); - _clearState(); - } - - function _clearState() { - _response.partialMessage = ""; - if (_request.id) { - clearTimeout(_request.id); - } - - if (_ieStream != null) { - _ieStream.close(); - _ieStream = null; - } - if (_jqxhr != null) { - _jqxhr.abort(); - _jqxhr = null; - } - if (_activeRequest != null) { - _activeRequest.abort(); - _activeRequest = null; - } - if (_websocket != null) { - if (_websocket.canSendMessage) { - _websocket.close(); - } - _websocket = null; - } - if (_sse != null) { - _sse.close(); - _sse = null; - } - _clearStorage(); - } - - function _clearStorage() { - // Stop sharing a connection - if (_storageService != null) { - // Clears trace timer - clearInterval(_traceTimer); - // Removes the trace - document.cookie = _sharingKey + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; - // The heir is the parent unless unloading - _storageService.signal("close", { - reason: "", - heir: !_abordingConnection ? guid : (_storageService.get("children") || [])[0] - }); - _storageService.close(); - } - if (_localStorageService != null) { - _localStorageService.close(); - } - } - - /** - * Subscribe request using request transport. <br> - * If request is currently opened, this one will be closed. - * - * @param {Object} Request parameters. - * @private - */ - function _subscribe(options) { - _reinit(); - - _request = atmosphere.util.extend(_request, options); - // Allow at least 1 request - _request.mrequest = _request.reconnect; - if (!_request.reconnect) { - _request.reconnect = true; - } - } - - /** - * Check if web socket is supported (check for custom implementation provided by request object or browser implementation). - * - * @returns {boolean} True if web socket is supported, false otherwise. - * @private - */ - function _supportWebsocket() { - return _request.webSocketImpl != null || window.WebSocket || window.MozWebSocket; - } - - /** - * Check if server side events (SSE) is supported (check for custom implementation provided by request object or browser implementation). - * - * @returns {boolean} True if web socket is supported, false otherwise. - * @private - */ - function _supportSSE() { - return window.EventSource; - } - - /** - * Open request using request transport. <br> - * If request transport is 'websocket' but websocket can't be opened, request will automatically reconnect using fallback transport. - * - * @private - */ - function _execute() { - // Shared across multiple tabs/windows. - if (_request.shared) { - _localStorageService = _local(_request); - if (_localStorageService != null) { - if (_request.logLevel === 'debug') { - atmosphere.util.debug("Storage service available. All communication will be local"); - } - - if (_localStorageService.open(_request)) { - // Local connection. - return; - } - } - - if (_request.logLevel === 'debug') { - atmosphere.util.debug("No Storage service available."); - } - // Wasn't local or an error occurred - _localStorageService = null; - } - - // Protocol - _request.firstMessage = uuid == 0 ? true : false; - _request.isOpen = false; - _request.ctime = atmosphere.util.now(); - - // We carry any UUID set by the user or from a previous connection. - if (_request.uuid === 0) { - _request.uuid = uuid; - } - _response.closedByClientTimeout = false; - - if (_request.transport !== 'websocket' && _request.transport !== 'sse') { - _executeRequest(_request); - - } else if (_request.transport === 'websocket') { - if (!_supportWebsocket()) { - _reconnectWithFallbackTransport("Websocket is not supported, using request.fallbackTransport (" + _request.fallbackTransport - + ")"); - } else { - _executeWebSocket(false); - } - } else if (_request.transport === 'sse') { - if (!_supportSSE()) { - _reconnectWithFallbackTransport("Server Side Events(SSE) is not supported, using request.fallbackTransport (" - + _request.fallbackTransport + ")"); - } else { - _executeSSE(false); - } - } - } - - function _local(request) { - var trace, connector, orphan, name = "atmosphere-" + request.url, connectors = { - storage: function () { - function onstorage(event) { - if (event.key === name && event.newValue) { - listener(event.newValue); - } - } - - if (!atmosphere.util.storage) { - return; - } - - var storage = window.localStorage, - get = function (key) { - return atmosphere.util.parseJSON(storage.getItem(name + "-" + key)); - }, - set = function (key, value) { - storage.setItem(name + "-" + key, atmosphere.util.stringifyJSON(value)); - }; - - return { - init: function () { - set("children", get("children").concat([guid])); - atmosphere.util.on(window, "storage", onstorage); - return get("opened"); - }, - signal: function (type, data) { - storage.setItem(name, atmosphere.util.stringifyJSON({ - target: "p", - type: type, - data: data - })); - }, - close: function () { - var children = get("children"); - - atmosphere.util.off(window, "storage", onstorage); - if (children) { - if (removeFromArray(children, request.id)) { - set("children", children); - } - } - } - }; - }, - windowref: function () { - var win = window.open("", name.replace(/\W/g, "")); - - if (!win || win.closed || !win.callbacks) { - return; - } - - return { - init: function () { - win.callbacks.push(listener); - win.children.push(guid); - return win.opened; - }, - signal: function (type, data) { - if (!win.closed && win.fire) { - win.fire(atmosphere.util.stringifyJSON({ - target: "p", - type: type, - data: data - })); - } - }, - close: function () { - // Removes traces only if the parent is alive - if (!orphan) { - removeFromArray(win.callbacks, listener); - removeFromArray(win.children, guid); - } - } - - }; - } - }; - - function removeFromArray(array, val) { - var i, length = array.length; - - for (i = 0; i < length; i++) { - if (array[i] === val) { - array.splice(i, 1); - } - } - - return length !== array.length; - } - - // Receives open, close and message command from the parent - function listener(string) { - var command = atmosphere.util.parseJSON(string), data = command.data; - - if (command.target === "c") { - switch (command.type) { - case "open": - _open("opening", 'local', _request); - break; - case "close": - if (!orphan) { - orphan = true; - if (data.reason === "aborted") { - _close(); - } else { - // Gives the heir some time to reconnect - if (data.heir === guid) { - _execute(); - } else { - setTimeout(function () { - _execute(); - }, 100); - } - } - } - break; - case "message": - _prepareCallback(data, "messageReceived", 200, request.transport); - break; - case "localMessage": - _localMessage(data); - break; - } - } - } - - function findTrace() { - var matcher = new RegExp("(?:^|; )(" + encodeURIComponent(name) + ")=([^;]*)").exec(document.cookie); - if (matcher) { - return atmosphere.util.parseJSON(decodeURIComponent(matcher[2])); - } - } - - // Finds and validates the parent socket's trace from the cookie - trace = findTrace(); - if (!trace || atmosphere.util.now() - trace.ts > 1000) { - return; - } - - // Chooses a connector - connector = connectors.storage() || connectors.windowref(); - if (!connector) { - return; - } - - return { - open: function () { - var parentOpened; - - // Checks the shared one is alive - _traceTimer = setInterval(function () { - var oldTrace = trace; - trace = findTrace(); - if (!trace || oldTrace.ts === trace.ts) { - // Simulates a close signal - listener(atmosphere.util.stringifyJSON({ - target: "c", - type: "close", - data: { - reason: "error", - heir: oldTrace.heir - } - })); - } - }, 1000); - - parentOpened = connector.init(); - if (parentOpened) { - // Firing the open event without delay robs the user of the opportunity to bind connecting event handlers - setTimeout(function () { - _open("opening", 'local', request); - }, 50); - } - return parentOpened; - }, - send: function (event) { - connector.signal("send", event); - }, - localSend: function (event) { - connector.signal("localSend", atmosphere.util.stringifyJSON({ - id: guid, - event: event - })); - }, - close: function () { - // Do not signal the parent if this method is executed by the unload event handler - if (!_abordingConnection) { - clearInterval(_traceTimer); - connector.signal("close"); - connector.close(); - } - } - }; - } - - function share() { - var storageService, name = "atmosphere-" + _request.url, servers = { - // Powered by the storage event and the localStorage - // http://www.w3.org/TR/webstorage/#event-storage - storage: function () { - function onstorage(event) { - // When a deletion, newValue initialized to null - if (event.key === name && event.newValue) { - listener(event.newValue); - } - } - - if (!atmosphere.util.storage) { - return; - } - - var storage = window.localStorage; - - return { - init: function () { - // Handles the storage event - atmosphere.util.on(window, "storage", onstorage); - }, - signal: function (type, data) { - storage.setItem(name, atmosphere.util.stringifyJSON({ - target: "c", - type: type, - data: data - })); - }, - get: function (key) { - return atmosphere.util.parseJSON(storage.getItem(name + "-" + key)); - }, - set: function (key, value) { - storage.setItem(name + "-" + key, atmosphere.util.stringifyJSON(value)); - }, - close: function () { - atmosphere.util.off(window, "storage", onstorage); - storage.removeItem(name); - storage.removeItem(name + "-opened"); - storage.removeItem(name + "-children"); - } - - }; - }, - // Powered by the window.open method - // https://developer.mozilla.org/en/DOM/window.open - windowref: function () { - // Internet Explorer raises an invalid argument error - // when calling the window.open method with the name containing non-word characters - var neim = name.replace(/\W/g, ""), container = document.getElementById(neim), win; - - if (!container) { - container = document.createElement("div"); - container.id = neim; - container.style.display = "none"; - container.innerHTML = '<iframe name="' + neim + '" />'; - document.body.appendChild(container); - } - - win = container.firstChild.contentWindow; - - return { - init: function () { - // Callbacks from different windows - win.callbacks = [listener]; - // In IE 8 and less, only string argument can be safely passed to the function in other window - win.fire = function (string) { - var i; - - for (i = 0; i < win.callbacks.length; i++) { - win.callbacks[i](string); - } - }; - }, - signal: function (type, data) { - if (!win.closed && win.fire) { - win.fire(atmosphere.util.stringifyJSON({ - target: "c", - type: type, - data: data - })); - } - }, - get: function (key) { - return !win.closed ? win[key] : null; - }, - set: function (key, value) { - if (!win.closed) { - win[key] = value; - } - }, - close: function () { - } - }; - } - }; - - // Receives send and close command from the children - function listener(string) { - var command = atmosphere.util.parseJSON(string), data = command.data; - - if (command.target === "p") { - switch (command.type) { - case "send": - _push(data); - break; - case "localSend": - _localMessage(data); - break; - case "close": - _close(); - break; - } - } - } - - _localSocketF = function propagateMessageEvent(context) { - storageService.signal("message", context); - }; - - function leaveTrace() { - document.cookie = _sharingKey + "=" + - // Opera's JSON implementation ignores a number whose a last digit of 0 strangely - // but has no problem with a number whose a last digit of 9 + 1 - encodeURIComponent(atmosphere.util.stringifyJSON({ - ts: atmosphere.util.now() + 1, - heir: (storageService.get("children") || [])[0] - })) + "; path=/"; - } - - // Chooses a storageService - storageService = servers.storage() || servers.windowref(); - storageService.init(); - - if (_request.logLevel === 'debug') { - atmosphere.util.debug("Installed StorageService " + storageService); - } - - // List of children sockets - storageService.set("children", []); - - if (storageService.get("opened") != null && !storageService.get("opened")) { - // Flag indicating the parent socket is opened - storageService.set("opened", false); - } - // Leaves traces - _sharingKey = encodeURIComponent(name); - leaveTrace(); - _traceTimer = setInterval(leaveTrace, 1000); - - _storageService = storageService; - } - - /** - * @private - */ - function _open(state, transport, request) { - if (_request.shared && transport !== 'local') { - share(); - } - - if (_storageService != null) { - _storageService.set("opened", true); - } - - request.close = function () { - _close(); - }; - - if (_requestCount > 0 && state === 're-connecting') { - request.isReopen = true; - _tryingToReconnect(_response); - } else if (_response.error == null) { - _response.request = request; - var prevState = _response.state; - _response.state = state; - var prevTransport = _response.transport; - _response.transport = transport; - - var _body = _response.responseBody; - _invokeCallback(); - _response.responseBody = _body; - - _response.state = prevState; - _response.transport = prevTransport; - } - } - - /** - * Execute request using jsonp transport. - * - * @param request {Object} request Request parameters, if undefined _request object will be used. - * @private - */ - function _jsonp(request) { - // When CORS is enabled, make sure we force the proper transport. - request.transport = "jsonp"; - - var rq = _request, script; - if ((request != null) && (typeof (request) !== 'undefined')) { - rq = request; - } - - _jqxhr = { - open: function () { - var callback = "atmosphere" + (++guid); - - function poll() { - var url = rq.url; - if (rq.dispatchUrl != null) { - url += rq.dispatchUrl; - } - - var data = rq.data; - if (rq.attachHeadersAsQueryString) { - url = _attachHeaders(rq); - if (data !== '') { - url += "&X-Atmosphere-Post-Body=" + encodeURIComponent(data); - } - data = ''; - } - - var head = document.head || document.getElementsByTagName("head")[0] || document.documentElement; - - script = document.createElement("script"); - script.src = url + "&jsonpTransport=" + callback; - script.clean = function () { - script.clean = script.onerror = script.onload = script.onreadystatechange = null; - if (script.parentNode) { - script.parentNode.removeChild(script); - } - }; - script.onload = script.onreadystatechange = function () { - if (!script.readyState || /loaded|complete/.test(script.readyState)) { - script.clean(); - } - }; - script.onerror = function () { - script.clean(); - rq.lastIndex = 0; - - if (rq.openId) { - clearTimeout(rq.openId); - } - - if (rq.reconnect && _requestCount++ < rq.maxReconnectOnClose) { - _open('re-connecting', rq.transport, rq); - _reconnect(_jqxhr, rq, request.reconnectInterval); - rq.openId = setTimeout(function() { - _triggerOpen(rq); - }, rq.reconnectInterval + 1000); - } else { - _onError(0, "maxReconnectOnClose reached"); - } - }; - - head.insertBefore(script, head.firstChild); - } - - // Attaches callback - window[callback] = function (msg) { - if (rq.reconnect) { - if (rq.maxRequest === -1 || rq.requestCount++ < rq.maxRequest) { - // _readHeaders(_jqxhr, rq); - - if (!rq.executeCallbackBeforeReconnect) { - _reconnect(_jqxhr, rq, rq.pollingInterval); - } - - if (msg != null && typeof msg !== 'string') { - try { - msg = msg.message; - } catch (err) { - // The message was partial - } - } - - var skipCallbackInvocation = _trackMessageSize(msg, rq, _response); - if (!skipCallbackInvocation) { - _prepareCallback(_response.responseBody, "messageReceived", 200, rq.transport); - } - - if (rq.executeCallbackBeforeReconnect) { - _reconnect(_jqxhr, rq, rq.pollingInterval); - } - } else { - atmosphere.util.log(_request.logLevel, ["JSONP reconnect maximum try reached " + _request.requestCount]); - _onError(0, "maxRequest reached"); - } - } - }; - setTimeout(function () { - poll(); - }, 50); - }, - abort: function () { - if (script && script.clean) { - script.clean(); - } - } - }; - - _jqxhr.open(); - } - - /** - * Build websocket object. - * - * @param location {string} Web socket url. - * @returns {websocket} Web socket object. - * @private - */ - function _getWebSocket(location) { - if (_request.webSocketImpl != null) { - return _request.webSocketImpl; - } else { - if (window.WebSocket) { - return new WebSocket(location); - } else { - return new MozWebSocket(location); - } - } - } - - /** - * Build web socket url from request url. - * - * @return {string} Web socket url (start with "ws" or "wss" for secure web socket). - * @private - */ - function _buildWebSocketUrl() { - return _attachHeaders(_request, atmosphere.util.getAbsoluteURL(_request.url)).replace(/^http/, "ws"); - } - - /** - * Build SSE url from request url. - * - * @return a url with Atmosphere's headers - * @private - */ - function _buildSSEUrl() { - var url = _attachHeaders(_request); - return url; - } - - /** - * Open SSE. <br> - * Automatically use fallback transport if SSE can't be opened. - * - * @private - */ - function _executeSSE(sseOpened) { - - _response.transport = "sse"; - - var location = _buildSSEUrl(); - - if (_request.logLevel === 'debug') { - atmosphere.util.debug("Invoking executeSSE"); - atmosphere.util.debug("Using URL: " + location); - } - - if (_request.enableProtocol && sseOpened) { - var time = atmosphere.util.now() - _request.ctime; - _request.lastTimestamp = Number(_request.stime) + Number(time); - } - - if (sseOpened && !_request.reconnect) { - if (_sse != null) { - _clearState(); - } - return; - } - - try { - _sse = new EventSource(location, { - withCredentials: _request.withCredentials - }); - } catch (e) { - _onError(0, e); - _reconnectWithFallbackTransport("SSE failed. Downgrading to fallback transport and resending"); - return; - } - - if (_request.connectTimeout > 0) { - _request.id = setTimeout(function () { - if (!sseOpened) { - _clearState(); - } - }, _request.connectTimeout); - } - - _sse.onopen = function (event) { - _timeout(_request); - if (_request.logLevel === 'debug') { - atmosphere.util.debug("SSE successfully opened"); - } - - if (!_request.enableProtocol) { - if (!sseOpened) { - _open('opening', "sse", _request); - } else { - _open('re-opening', "sse", _request); - } - } else if (_request.isReopen) { - _request.isReopen = false; - _open('re-opening', _request.transport, _request); - } - - sseOpened = true; - - if (_request.method === 'POST') { - _response.state = "messageReceived"; - _sse.send(_request.data); - } - }; - - _sse.onmessage = function (message) { - _timeout(_request); - - if (!_request.enableXDR && message.origin && message.origin !== window.location.protocol + "//" + window.location.host) { - atmosphere.util.log(_request.logLevel, ["Origin was not " + window.location.protocol + "//" + window.location.host]); - return; - } - - _response.state = 'messageReceived'; - _response.status = 200; - - message = message.data; - var skipCallbackInvocation = _trackMessageSize(message, _request, _response); - - // https://github.com/remy/polyfills/blob/master/EventSource.js - // Since we polling. - /* if (_sse.URL) { - _sse.interval = 100; - _sse.URL = _buildSSEUrl(); - } */ - - if (!skipCallbackInvocation) { - _invokeCallback(); - _response.responseBody = ''; - _response.messages = []; - } - }; - - _sse.onerror = function (message) { - clearTimeout(_request.id); - - if (_response.closedByClientTimeout) return; - - _invokeClose(sseOpened); - _clearState(); - - if (_abordingConnection) { - atmosphere.util.log(_request.logLevel, ["SSE closed normally"]); - } else if (!sseOpened) { - _reconnectWithFallbackTransport("SSE failed. Downgrading to fallback transport and resending"); - } else if (_request.reconnect && (_response.transport === 'sse')) { - if (_requestCount++ < _request.maxReconnectOnClose) { - _open('re-connecting', _request.transport, _request); - if (_request.reconnectInterval > 0) { - _request.reconnectId = setTimeout(function () { - _executeSSE(true); - }, _request.reconnectInterval); - } else { - _executeSSE(true); - } - _response.responseBody = ""; - _response.messages = []; - } else { - atmosphere.util.log(_request.logLevel, ["SSE reconnect maximum try reached " + _requestCount]); - _onError(0, "maxReconnectOnClose reached"); - } - } - }; - } - - /** - * Open web socket. <br> - * Automatically use fallback transport if web socket can't be opened. - * - * @private - */ - function _executeWebSocket(webSocketOpened) { - - _response.transport = "websocket"; - - if (_request.enableProtocol && webSocketOpened) { - var time = atmosphere.util.now() - _request.ctime; - _request.lastTimestamp = Number(_request.stime) + Number(time); - } - - var location = _buildWebSocketUrl(_request.url); - if (_request.logLevel === 'debug') { - atmosphere.util.debug("Invoking executeWebSocket"); - atmosphere.util.debug("Using URL: " + location); - } - - if (webSocketOpened && !_request.reconnect) { - if (_websocket != null) { - _clearState(); - } - return; - } - - _websocket = _getWebSocket(location); - if (_request.webSocketBinaryType != null) { - _websocket.binaryType = _request.webSocketBinaryType; - } - - if (_request.connectTimeout > 0) { - _request.id = setTimeout(function () { - if (!webSocketOpened) { - var _message = { - code: 1002, - reason: "", - wasClean: false - }; - _websocket.onclose(_message); - // Close it anyway - try { - _clearState(); - } catch (e) { - } - return; - } - - }, _request.connectTimeout); - } - - _websocket.onopen = function (message) { - _timeout(_request); - - if (_request.logLevel === 'debug') { - atmosphere.util.debug("Websocket successfully opened"); - } - - var reopening = webSocketOpened; - - if(_websocket != null) { - _websocket.canSendMessage = true; - } - - if (!_request.enableProtocol) { - webSocketOpened = true; - if (reopening) { - _open('re-opening', "websocket", _request); - } else { - _open('opening', "websocket", _request); - } - } - - if (_websocket != null) { - if (_request.method === 'POST') { - _response.state = "messageReceived"; - _websocket.send(_request.data); - } - } - }; - - _websocket.onmessage = function (message) { - _timeout(_request); - - // We only consider it opened if we get the handshake data - // https://github.com/Atmosphere/atmosphere-javascript/issues/74 - if (_request.enableProtocol) { - webSocketOpened = true; - } - - _response.state = 'messageReceived'; - _response.status = 200; - - message = message.data; - var isString = typeof (message) === 'string'; - if (isString) { - var skipCallbackInvocation = _trackMessageSize(message, _request, _response); - if (!skipCallbackInvocation) { - _invokeCallback(); - _response.responseBody = ''; - _response.messages = []; - } - } else { - if (!_handleProtocol(_request, message)) - return; - - _response.responseBody = message; - _invokeCallback(); - _response.responseBody = null; - } - }; - - _websocket.onerror = function (message) { - clearTimeout(_request.id); - }; - - _websocket.onclose = function (message) { - clearTimeout(_request.id); - if (_response.state === 'closed') - return; - - var reason = message.reason; - if (reason === "") { - switch (message.code) { - case 1000: - reason = "Normal closure; the connection successfully completed whatever purpose for which " + "it was created."; - break; - case 1001: - reason = "The endpoint is going away, either because of a server failure or because the " - + "browser is navigating away from the page that opened the connection."; - break; - case 1002: - reason = "The endpoint is terminating the connection due to a protocol error."; - break; - case 1003: - reason = "The connection is being terminated because the endpoint received data of a type it " - + "cannot accept (for example, a text-only endpoint received binary data)."; - break; - case 1004: - reason = "The endpoint is terminating the connection because a data frame was received that " + "is too large."; - break; - case 1005: - reason = "Unknown: no status code was provided even though one was expected."; - break; - case 1006: - reason = "Connection was closed abnormally (that is, with no close frame being sent)."; - break; - } - } - - if (_request.logLevel === 'warn') { - atmosphere.util.warn("Websocket closed, reason: " + reason); - atmosphere.util.warn("Websocket closed, wasClean: " + message.wasClean); - } - - if (_response.closedByClientTimeout) { - return; - } - - _invokeClose(webSocketOpened); - - _response.state = 'closed'; - - if (_abordingConnection) { - atmosphere.util.log(_request.logLevel, ["Websocket closed normally"]); - } else if (!webSocketOpened) { - _reconnectWithFallbackTransport("Websocket failed. Downgrading to Comet and resending"); - - } else if (_request.reconnect && _response.transport === 'websocket') { - _clearState(); - if (_requestCount++ < _request.maxReconnectOnClose) { - _open('re-connecting', _request.transport, _request); - if (_request.reconnectInterval > 0) { - _request.reconnectId = setTimeout(function () { - _response.responseBody = ""; - _response.messages = []; - _executeWebSocket(true); - }, _request.reconnectInterval); - } else { - _response.responseBody = ""; - _response.messages = []; - _executeWebSocket(true); - } - } else { - atmosphere.util.log(_request.logLevel, ["Websocket reconnect maximum try reached " + _request.requestCount]); - if (_request.logLevel === 'warn') { - atmosphere.util.warn("Websocket error, reason: " + message.reason); - } - _onError(0, "maxReconnectOnClose reached"); - } - } - }; - - var ua = navigator.userAgent.toLowerCase(); - var isAndroid = ua.indexOf("android") > -1; - if (isAndroid && _websocket.url === undefined) { - // Android 4.1 does not really support websockets and fails silently - _websocket.onclose({ - reason: "Android 4.1 does not support websockets.", - wasClean: false - }); - } - } - - function _handleProtocol(request, message) { - - // The first messages is always the uuid. - var b = true; - - if (request.transport === 'polling') return b; - - if (atmosphere.util.trim(message).length !== 0 && request.enableProtocol && request.firstMessage) { - request.firstMessage = false; - var messages = message.split(request.messageDelimiter); - var pos = messages.length === 2 ? 0 : 1; - request.uuid = atmosphere.util.trim(messages[pos]); - request.stime = atmosphere.util.trim(messages[pos + 1]); - b = false; - if (request.transport !== 'long-polling') { - _triggerOpen(request); - } - uuid = request.uuid; - } else if (request.enableProtocol && request.firstMessage) { - // In case we are getting some junk from IE - b = false; - } else { - _triggerOpen(request); - } - return b; - } - - function _timeout(_request) { - clearTimeout(_request.id); - if (_request.timeout > 0 && _request.transport !== 'polling') { - _request.id = setTimeout(function () { - _onClientTimeout(_request); - _disconnect(); - _clearState(); - }, _request.timeout); - } - } - - function _onClientTimeout(_request) { - _response.closedByClientTimeout = true; - _response.state = 'closedByClient'; - _response.responseBody = ""; - _response.status = 408; - _response.messages = []; - _invokeCallback(); - } - - function _onError(code, reason) { - _clearState(); - clearTimeout(_request.id); - _response.state = 'error'; - _response.reasonPhrase = reason; - _response.responseBody = ""; - _response.status = code; - _response.messages = []; - _invokeCallback(); - } - - /** - * Track received message and make sure callbacks/functions are only invoked when the complete message has been received. - * - * @param message - * @param request - * @param response - */ - function _trackMessageSize(message, request, response) { - if (!_handleProtocol(request, message)) - return true; - if (message.length === 0) - return true; - - if (request.trackMessageLength) { - // prepend partialMessage if any - message = response.partialMessage + message; - - var messages = []; - var messageStart = message.indexOf(request.messageDelimiter); - while (messageStart !== -1) { - var str = atmosphere.util.trim(message.substring(0, messageStart)); - var messageLength = +str; - if (isNaN(messageLength)) - throw new Error('message length "' + str + '" is not a number'); - messageStart += request.messageDelimiter.length; - if (messageStart + messageLength > message.length) { - // message not complete, so there is no trailing messageDelimiter - messageStart = -1; - } else { - // message complete, so add it - messages.push(message.substring(messageStart, messageStart + messageLength)); - // remove consumed characters - message = message.substring(messageStart + messageLength, message.length); - messageStart = message.indexOf(request.messageDelimiter); - } - } - - /* keep any remaining data */ - response.partialMessage = message; - - if (messages.length !== 0) { - response.responseBody = messages.join(request.messageDelimiter); - response.messages = messages; - return false; - } else { - response.responseBody = ""; - response.messages = []; - return true; - } - } else { - response.responseBody = message; - } - return false; - } - - /** - * Reconnect request with fallback transport. <br> - * Used in case websocket can't be opened. - * - * @private - */ - function _reconnectWithFallbackTransport(errorMessage) { - atmosphere.util.log(_request.logLevel, [errorMessage]); - - if (typeof (_request.onTransportFailure) !== 'undefined') { - _request.onTransportFailure(errorMessage, _request); - } else if (typeof (atmosphere.util.onTransportFailure) !== 'undefined') { - atmosphere.util.onTransportFailure(errorMessage, _request); - } - - _request.transport = _request.fallbackTransport; - var reconnectInterval = _request.connectTimeout === -1 ? 0 : _request.connectTimeout; - if (_request.reconnect && _request.transport !== 'none' || _request.transport == null) { - _request.method = _request.fallbackMethod; - _response.transport = _request.fallbackTransport; - _request.fallbackTransport = 'none'; - if (reconnectInterval > 0) { - _request.reconnectId = setTimeout(function () { - _execute(); - }, reconnectInterval); - } else { - _execute(); - } - } else { - _onError(500, "Unable to reconnect with fallback transport"); - } - } - - /** - * Get url from request and attach headers to it. - * - * @param request {Object} request Request parameters, if undefined _request object will be used. - * - * @returns {Object} Request object, if undefined, _request object will be used. - * @private - */ - function _attachHeaders(request, url) { - var rq = _request; - if ((request != null) && (typeof (request) !== 'undefined')) { - rq = request; - } - - if (url == null) { - url = rq.url; - } - - // If not enabled - if (!rq.attachHeadersAsQueryString) - return url; - - // If already added - if (url.indexOf("X-Atmosphere-Framework") !== -1) { - return url; - } - - url += (url.indexOf('?') !== -1) ? '&' : '?'; - url += "X-Atmosphere-tracking-id=" + rq.uuid; - url += "&X-Atmosphere-Framework=" + version; - url += "&X-Atmosphere-Transport=" + rq.transport; - - if (rq.trackMessageLength) { - url += "&X-Atmosphere-TrackMessageSize=" + "true"; - } - - if (rq.lastTimestamp != null) { - url += "&X-Cache-Date=" + rq.lastTimestamp; - } else { - url += "&X-Cache-Date=" + 0; - } - - if (rq.contentType !== '') { - //Eurk! - url += "&Content-Type=" + (rq.transport === 'websocket' ? rq.contentType : encodeURIComponent(rq.contentType)); - } - - if (rq.enableProtocol) { - url += "&X-atmo-protocol=true"; - } - - atmosphere.util.each(rq.headers, function (name, value) { - var h = atmosphere.util.isFunction(value) ? value.call(this, rq, request, _response) : value; - if (h != null) { - url += "&" + encodeURIComponent(name) + "=" + encodeURIComponent(h); - } - }); - - return url; - } - - function _triggerOpen(rq) { - if (!rq.isOpen) { - rq.isOpen = true; - _open('opening', rq.transport, rq); - } else if (rq.isReopen) { - rq.isReopen = false; - _open('re-opening', rq.transport, rq); - } - } - - /** - * Execute ajax request. <br> - * - * @param request {Object} request Request parameters, if undefined _request object will be used. - * @private - */ - function _executeRequest(request) { - var rq = _request; - if ((request != null) || (typeof (request) !== 'undefined')) { - rq = request; - } - - rq.lastIndex = 0; - rq.readyState = 0; - - // CORS fake using JSONP - if ((rq.transport === 'jsonp') || ((rq.enableXDR) && (atmosphere.util.checkCORSSupport()))) { - _jsonp(rq); - return; - } - - if (atmosphere.util.browser.msie && +atmosphere.util.browser.version.split(".")[0] < 10) { - if ((rq.transport === 'streaming')) { - if (rq.enableXDR && window.XDomainRequest) { - _ieXDR(rq); - } else { - _ieStreaming(rq); - } - return; - } - - if ((rq.enableXDR) && (window.XDomainRequest)) { - _ieXDR(rq); - return; - } - } - - var reconnectF = function () { - rq.lastIndex = 0; - if (rq.reconnect && _requestCount++ < rq.maxReconnectOnClose) { - _open('re-connecting', request.transport, request); - _reconnect(ajaxRequest, rq, request.reconnectInterval); - } else { - _onError(0, "maxReconnectOnClose reached"); - } - }; - - if (rq.force || (rq.reconnect && (rq.maxRequest === -1 || rq.requestCount++ < rq.maxRequest))) { - rq.force = false; - - var ajaxRequest = atmosphere.util.xhr(); - ajaxRequest.hasData = false; - - _doRequest(ajaxRequest, rq, true); - - if (rq.suspend) { - _activeRequest = ajaxRequest; - } - - if (rq.transport !== 'polling') { - _response.transport = rq.transport; - - ajaxRequest.onabort = function () { - _invokeClose(true); - }; - - ajaxRequest.onerror = function () { - _response.error = true; - try { - _response.status = XMLHttpRequest.status; - } catch (e) { - _response.status = 500; - } - - if (!_response.status) { - _response.status = 500; - } - if (!_response.errorHandled) { - _clearState(); - reconnectF(); - } - }; - } - - ajaxRequest.onreadystatechange = function () { - if (_abordingConnection) { - return; - } - - _response.error = null; - var skipCallbackInvocation = false; - var update = false; - - if (rq.transport === 'streaming' && rq.readyState > 2 && ajaxRequest.readyState === 4) { - if (rq.reconnectingOnLength) { - return; - } - _clearState(); - reconnectF(); - return; - } - - rq.readyState = ajaxRequest.readyState; - - if (rq.transport === 'streaming' && ajaxRequest.readyState >= 3) { - update = true; - } else if (rq.transport === 'long-polling' && ajaxRequest.readyState === 4) { - update = true; - } - _timeout(_request); - - if (rq.transport !== 'polling') { - // MSIE 9 and lower status can be higher than 1000, Chrome can be 0 - var status = 200; - if (ajaxRequest.readyState === 4) { - status = ajaxRequest.status > 1000 ? 0 : ajaxRequest.status; - } - - if (status >= 300 || status === 0) { - // Prevent onerror callback to be called - _response.errorHandled = true; - _clearState(); - reconnectF(); - return; - } - - // Firefox incorrectly send statechange 0->2 when a reconnect attempt fails. The above checks ensure that onopen is not called for these - if ((!rq.enableProtocol || !request.firstMessage) && ajaxRequest.readyState === 2) { - _triggerOpen(rq); - } - - } else if (ajaxRequest.readyState === 4) { - update = true; - } - - if (update) { - var responseText = ajaxRequest.responseText; - - if (atmosphere.util.trim(responseText).length === 0 && rq.transport === 'long-polling') { - // For browser that aren't support onabort - if (!ajaxRequest.hasData) { - _reconnect(ajaxRequest, rq, rq.pollingInterval); - } else { - ajaxRequest.hasData = false; - } - return; - } - ajaxRequest.hasData = true; - - _readHeaders(ajaxRequest, _request); - - if (rq.transport === 'streaming') { - if (!atmosphere.util.browser.opera) { - var message = responseText.substring(rq.lastIndex, responseText.length); - skipCallbackInvocation = _trackMessageSize(message, rq, _response); - - rq.lastIndex = responseText.length; - if (skipCallbackInvocation) { - return; - } - } else { - atmosphere.util.iterate(function () { - if (_response.status !== 500 && ajaxRequest.responseText.length > rq.lastIndex) { - try { - _response.status = ajaxRequest.status; - _response.headers = atmosphere.util.parseHeaders(ajaxRequest.getAllResponseHeaders()); - - _readHeaders(ajaxRequest, _request); - - } catch (e) { - _response.status = 404; - } - _timeout(_request); - - _response.state = "messageReceived"; - var message = ajaxRequest.responseText.substring(rq.lastIndex); - rq.lastIndex = ajaxRequest.responseText.length; - - skipCallbackInvocation = _trackMessageSize(message, rq, _response); - if (!skipCallbackInvocation) { - _invokeCallback(); - } - - _verifyStreamingLength(ajaxRequest, rq); - } else if (_response.status > 400) { - // Prevent replaying the last message. - rq.lastIndex = ajaxRequest.responseText.length; - return false; - } - }, 0); - } - } else { - skipCallbackInvocation = _trackMessageSize(responseText, rq, _response); - } - - try { - _response.status = ajaxRequest.status; - _response.headers = atmosphere.util.parseHeaders(ajaxRequest.getAllResponseHeaders()); - - _readHeaders(ajaxRequest, rq); - } catch (e) { - _response.status = 404; - } - - if (rq.suspend) { - _response.state = _response.status === 0 ? "closed" : "messageReceived"; - } else { - _response.state = "messagePublished"; - } - - var isAllowedToReconnect = request.transport !== 'streaming' && request.transport !== 'polling'; - if (isAllowedToReconnect && !rq.executeCallbackBeforeReconnect) { - _reconnect(ajaxRequest, rq, rq.pollingInterval); - } - - if (_response.responseBody.length !== 0 && !skipCallbackInvocation) - _invokeCallback(); - - if (isAllowedToReconnect && rq.executeCallbackBeforeReconnect) { - _reconnect(ajaxRequest, rq, rq.pollingInterval); - } - - _verifyStreamingLength(ajaxRequest, rq); - } - }; - - try { - ajaxRequest.send(rq.data); - _subscribed = true; - } catch (e) { - atmosphere.util.log(rq.logLevel, ["Unable to connect to " + rq.url]); - _onError(0, e); - } - - } else { - if (rq.logLevel === 'debug') { - atmosphere.util.log(rq.logLevel, ["Max re-connection reached."]); - } - _onError(0, "maxRequest reached"); - } - } - - /** - * Do ajax request. - * - * @param ajaxRequest Ajax request. - * @param request Request parameters. - * @param create If ajax request has to be open. - */ - function _doRequest(ajaxRequest, request, create) { - // Prevent Android to cache request - var url = request.url; - if (request.dispatchUrl != null && request.method === 'POST') { - url += request.dispatchUrl; - } - url = _attachHeaders(request, url); - url = atmosphere.util.prepareURL(url); - - if (create) { - ajaxRequest.open(request.method, url, request.async); - if (request.connectTimeout > 0) { - request.id = setTimeout(function () { - if (request.requestCount === 0) { - _clearState(); - _prepareCallback("Connect timeout", "closed", 200, request.transport); - } - }, request.connectTimeout); - } - } - - if (_request.withCredentials) { - if ("withCredentials" in ajaxRequest) { - ajaxRequest.withCredentials = true; - } - } - - if (!_request.dropHeaders) { - ajaxRequest.setRequestHeader("X-Atmosphere-Framework", atmosphere.util.version); - ajaxRequest.setRequestHeader("X-Atmosphere-Transport", request.transport); - if (request.lastTimestamp != null) { - ajaxRequest.setRequestHeader("X-Cache-Date", request.lastTimestamp); - } else { - ajaxRequest.setRequestHeader("X-Cache-Date", 0); - } - - if (request.trackMessageLength) { - ajaxRequest.setRequestHeader("X-Atmosphere-TrackMessageSize", "true"); - } - ajaxRequest.setRequestHeader("X-Atmosphere-tracking-id", request.uuid); - - atmosphere.util.each(request.headers, function (name, value) { - var h = atmosphere.util.isFunction(value) ? value.call(this, ajaxRequest, request, create, _response) : value; - if (h != null) { - ajaxRequest.setRequestHeader(name, h); - } - }); - } - - if (request.contentType !== '') { - ajaxRequest.setRequestHeader("Content-Type", request.contentType); - } - } - - function _reconnect(ajaxRequest, request, reconnectInterval) { - if (request.reconnect || (request.suspend && _subscribed)) { - var status = 0; - if (ajaxRequest && ajaxRequest.readyState > 1) { - status = ajaxRequest.status > 1000 ? 0 : ajaxRequest.status; - } - _response.status = status === 0 ? 204 : status; - _response.reason = status === 0 ? "Server resumed the connection or down." : "OK"; - - clearTimeout(request.id); - if (request.reconnectId) { - clearTimeout(request.reconnectId); - delete request.reconnectId; - } - - if (reconnectInterval > 0) { - // For whatever reason, never cancel a reconnect timeout as it is mandatory to reconnect. - _request.reconnectId = setTimeout(function () { - _executeRequest(request); - }, reconnectInterval); - } else { - _executeRequest(request); - } - } - } - - function _tryingToReconnect(response) { - response.state = 're-connecting'; - _invokeFunction(response); - } - - function _ieXDR(request) { - if (request.transport !== "polling") { - _ieStream = _configureXDR(request); - _ieStream.open(); - } else { - _configureXDR(request).open(); - } - } - - function _configureXDR(request) { - var rq = _request; - if ((request != null) && (typeof (request) !== 'undefined')) { - rq = request; - } - - var transport = rq.transport; - var lastIndex = 0; - var xdr = new window.XDomainRequest(); - - var reconnect = function () { - if (rq.transport === "long-polling" && (rq.reconnect && (rq.maxRequest === -1 || rq.requestCount++ < rq.maxRequest))) { - xdr.status = 200; - _ieXDR(rq); - } - }; - - var rewriteURL = rq.rewriteURL || function (url) { - // Maintaining session by rewriting URL - // http://stackoverflow.com/questions/6453779/maintaining-session-by-rewriting-url - var match = /(?:^|;\s*)(JSESSIONID|PHPSESSID)=([^;]*)/.exec(document.cookie); - - switch (match && match[1]) { - case "JSESSIONID": - return url.replace(/;jsessionid=[^\?]*|(\?)|$/, ";jsessionid=" + match[2] + "$1"); - case "PHPSESSID": - return url.replace(/\?PHPSESSID=[^&]*&?|\?|$/, "?PHPSESSID=" + match[2] + "&").replace(/&$/, ""); - } - return url; - }; - - // Handles open and message event - xdr.onprogress = function () { - handle(xdr); - }; - // Handles error event - xdr.onerror = function () { - // If the server doesn't send anything back to XDR will fail with polling - if (rq.transport !== 'polling') { - _clearState(); - if (_requestCount++ < rq.maxReconnectOnClose) { - if (rq.reconnectInterval > 0) { - rq.reconnectId = setTimeout(function () { - _open('re-connecting', request.transport, request); - _ieXDR(rq); - }, rq.reconnectInterval); - } else { - _open('re-connecting', request.transport, request); - _ieXDR(rq); - } - } else { - _onError(0, "maxReconnectOnClose reached"); - } - } - }; - - // Handles close event - xdr.onload = function () { - }; - - var handle = function (xdr) { - clearTimeout(rq.id); - var message = xdr.responseText; - - message = message.substring(lastIndex); - lastIndex += message.length; - - if (transport !== 'polling') { - _timeout(rq); - - var skipCallbackInvocation = _trackMessageSize(message, rq, _response); - - if (transport === 'long-polling' && atmosphere.util.trim(message).length === 0) - return; - - if (rq.executeCallbackBeforeReconnect) { - reconnect(); - } - - if (!skipCallbackInvocation) { - _prepareCallback(_response.responseBody, "messageReceived", 200, transport); - } - - if (!rq.executeCallbackBeforeReconnect) { - reconnect(); - } - } - }; - - return { - open: function () { - var url = rq.url; - if (rq.dispatchUrl != null) { - url += rq.dispatchUrl; - } - url = _attachHeaders(rq, url); - xdr.open(rq.method, rewriteURL(url)); - if (rq.method === 'GET') { - xdr.send(); - } else { - xdr.send(rq.data); - } - - if (rq.connectTimeout > 0) { - rq.id = setTimeout(function () { - if (rq.requestCount === 0) { - _clearState(); - _prepareCallback("Connect timeout", "closed", 200, rq.transport); - } - }, rq.connectTimeout); - } - }, - close: function () { - xdr.abort(); - } - }; - } - - function _ieStreaming(request) { - _ieStream = _configureIE(request); - _ieStream.open(); - } - - function _configureIE(request) { - var rq = _request; - if ((request != null) && (typeof (request) !== 'undefined')) { - rq = request; - } - - var stop; - var doc = new window.ActiveXObject("htmlfile"); - - doc.open(); - doc.close(); - - var url = rq.url; - if (rq.dispatchUrl != null) { - url += rq.dispatchUrl; - } - - if (rq.transport !== 'polling') { - _response.transport = rq.transport; - } - - return { - open: function () { - var iframe = doc.createElement("iframe"); - - url = _attachHeaders(rq); - if (rq.data !== '') { - url += "&X-Atmosphere-Post-Body=" + encodeURIComponent(rq.data); - } - - // Finally attach a timestamp to prevent Android and IE caching. - url = atmosphere.util.prepareURL(url); - - iframe.src = url; - doc.body.appendChild(iframe); - - // For the server to respond in a consistent format regardless of user agent, we polls response text - var cdoc = iframe.contentDocument || iframe.contentWindow.document; - - stop = atmosphere.util.iterate(function () { - try { - if (!cdoc.firstChild) {
<TRUNCATED>