Updated Branches: refs/heads/wicket-6.x 6189a89d0 -> 3239c8d00
Upgrade atmosphere to 2.0.4 and js to 2.0.8 Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/3239c8d0 Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/3239c8d0 Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/3239c8d0 Branch: refs/heads/wicket-6.x Commit: 3239c8d0096045c3d3faeab724ec9b4769e829aa Parents: 4e161cb Author: Emond Papegaaij <[email protected]> Authored: Tue Nov 26 09:08:59 2013 +0100 Committer: Emond Papegaaij <[email protected]> Committed: Tue Nov 26 09:09:16 2013 +0100 ---------------------------------------------------------------------- wicket-experimental/wicket-atmosphere/pom.xml | 2 +- .../wicket/atmosphere/jquery.atmosphere.js | 134 ++++++++++++++----- 2 files changed, 99 insertions(+), 37 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/wicket/blob/3239c8d0/wicket-experimental/wicket-atmosphere/pom.xml ---------------------------------------------------------------------- diff --git a/wicket-experimental/wicket-atmosphere/pom.xml b/wicket-experimental/wicket-atmosphere/pom.xml index 2be87d5..fb412e7 100644 --- a/wicket-experimental/wicket-atmosphere/pom.xml +++ b/wicket-experimental/wicket-atmosphere/pom.xml @@ -27,7 +27,7 @@ <version>0.16-SNAPSHOT</version> <packaging>jar</packaging> <properties> - <atmosphere.version>2.0.0</atmosphere.version> + <atmosphere.version>2.0.4</atmosphere.version> </properties> <name>Wicket-Atmosphere</name> <description>Wicket-Atmosphere provides integration of the Atmosphere Framework in Wicket.</description> http://git-wip-us.apache.org/repos/asf/wicket/blob/3239c8d0/wicket-experimental/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/jquery.atmosphere.js ---------------------------------------------------------------------- diff --git a/wicket-experimental/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/jquery.atmosphere.js b/wicket-experimental/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/jquery.atmosphere.js index b909609..701a586 100644 --- a/wicket-experimental/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/jquery.atmosphere.js +++ b/wicket-experimental/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/jquery.atmosphere.js @@ -1,5 +1,5 @@ /** - * Copyright 2012 Jeanfrancois Arcand + * Copyright 2013 Jeanfrancois Arcand * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,7 +54,8 @@ jQuery.atmosphere = function () { }; return { - version: "2.0.3-jquery", + version: "2.0.8-jquery", + uuid : 0, requests: [], callbacks: [], @@ -166,7 +167,7 @@ jQuery.atmosphere = function () { request: null, partialMessage: "", errorHandled: false, - id: 0 + closedByClientTimeout: false }; /** @@ -256,6 +257,9 @@ jQuery.atmosphere = function () { /** Trace time */ var _traceTimer; + /** Key for connection sharing */ + var _sharingKey; + // Automatic call to subscribe _subscribe(options); @@ -352,9 +356,11 @@ jQuery.atmosphere = function () { } // Protocol - _request.firstMessage = true; + _request.firstMessage = jQuery.atmosphere.uuid == 0 ? true : false; _request.isOpen = false; _request.ctime = jQuery.now(); + _request.uuid = jQuery.atmosphere.uuid; + _request.closedByClientTimeout = false; if (_request.transport !== 'websocket' && _request.transport !== 'sse') { _executeRequest(_request); @@ -679,13 +685,13 @@ jQuery.atmosphere = function () { }; function leaveTrace() { - document.cookie = encodeURIComponent(name) + "=" + + 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(jQuery.stringifyJSON({ ts: jQuery.now() + 1, heir: (storageService.get("children") || [])[0] - })); + })) + "; path=/"; } // Chooses a storageService @@ -704,6 +710,7 @@ jQuery.atmosphere = function () { storageService.set("opened", false); } // Leaves traces + _sharingKey = encodeURIComponent(name); leaveTrace(); _traceTimer = setInterval(leaveTrace, 1000); @@ -780,8 +787,17 @@ jQuery.atmosphere = function () { dataType: "jsonp", error: function (jqXHR, textStatus, errorThrown) { _response.error = true; - if (jqXHR.status < 300) { - _reconnect(_jqxhr, rq, 0); + + if (rq.openId) { + clearTimeout(rq.openId); + } + + if (rq.reconnect && _requestCount++ < rq.maxReconnectOnClose) { + _open('re-connecting', rq.transport, rq); + _reconnect(_jqxhr, rq, rq.reconnectInterval); + rq.openId = setTimeout(function() { + _triggerOpen(rq); + }, rq.reconnectInterval + 1000); } else { _onError(jqXHR.status, errorThrown); } @@ -994,6 +1010,9 @@ jQuery.atmosphere = function () { } else { _open('re-opening', "sse", _request); } + } else if (_request.isReopen) { + _request.isReopen = false; + _open('re-opening', _request.transport, _request); } sseOpened = true; @@ -1025,7 +1044,7 @@ jQuery.atmosphere = function () { _sse.onerror = function (message) { clearTimeout(_request.id); - if (_response.state === 'closedByClient') return; + if (_response.closedByClientTimeout) return; _invokeClose(sseOpened); _clearState(); @@ -1038,7 +1057,7 @@ jQuery.atmosphere = function () { if (_requestCount++ < _request.maxReconnectOnClose) { _open('re-connecting', _request.transport, _request); if (_request.reconnectInterval > 0) { - _request.id = setTimeout(function () { + _request.reconnectId = setTimeout(function () { _executeSSE(true); }, _request.reconnectInterval); } else { @@ -1113,18 +1132,22 @@ jQuery.atmosphere = function () { jQuery.atmosphere.debug("Websocket successfully opened"); } + var reopening = webSocketOpened; + + webSocketOpened = true; + if(_websocket != null) { + _websocket.webSocketOpened = webSocketOpened; + } + if (!_request.enableProtocol) { - if (!webSocketOpened) { - _open('opening', "websocket", _request); - } else { + if (reopening) { _open('re-opening', "websocket", _request); + } else { + _open('opening', "websocket", _request); } } - webSocketOpened = true; if (_websocket != null) { - _websocket.webSocketOpened = webSocketOpened; - if (_request.method === 'POST') { _response.state = "messageReceived"; _websocket.send(_request.data); @@ -1200,7 +1223,7 @@ jQuery.atmosphere = function () { jQuery.atmosphere.warn("Websocket closed, wasClean: " + message.wasClean); } - if (_response.state === 'closedByClient') { + if (_response.closedByClientTimeout) { return; } @@ -1218,7 +1241,7 @@ jQuery.atmosphere = function () { if (_requestCount++ < _request.maxReconnectOnClose) { _open('re-connecting', _request.transport, _request); if (_request.reconnectInterval > 0) { - _request.id = setTimeout(function () { + _request.reconnectId = setTimeout(function () { _response.responseBody = ""; _response.messages = []; _executeWebSocket(true); @@ -1250,6 +1273,9 @@ jQuery.atmosphere = function () { function _handleProtocol(request, message) { // The first messages is always the uuid. var b = true; + + if (request.transport === 'polling') return b; + if (jQuery.trim(message).length !== 0 && request.enableProtocol && request.firstMessage) { request.firstMessage = false; var messages = message.split(request.messageDelimiter); @@ -1260,6 +1286,8 @@ jQuery.atmosphere = function () { if (request.transport !== 'long-polling') { _triggerOpen(request); } + + jQuery.atmosphere.uuid = request.uuid; } else if (request.enableProtocol && request.firstMessage) { // In case we are getting some junk from IE b = false; @@ -1281,6 +1309,7 @@ jQuery.atmosphere = function () { } function _onClientTimeout(_request) { + _response.closedByClientTimeout = true; _response.state = 'closedByClient'; _response.responseBody = ""; _response.status = 408; @@ -1307,7 +1336,7 @@ jQuery.atmosphere = function () { * @param response */ function _trackMessageSize(message, request, response) { - if (!_handleProtocol(_request, message)) + if (!_handleProtocol(request, message)) return true; if (message.length === 0) return true; @@ -1376,7 +1405,7 @@ jQuery.atmosphere = function () { _response.transport = _request.fallbackTransport; _request.fallbackTransport = 'none'; if (reconnectInterval > 0) { - _request.id = setTimeout(function () { + _request.reconnectId = setTimeout(function () { _execute(); }, reconnectInterval); } else { @@ -1537,8 +1566,8 @@ jQuery.atmosphere = function () { if (!_response.status) { _response.status = 500; } - _clearState(); if (!_response.errorHandled) { + _clearState(); reconnectF(); } }; @@ -1569,12 +1598,9 @@ jQuery.atmosphere = function () { _timeout(_request); if (rq.transport !== 'polling') { - if ((!rq.enableProtocol || !request.firstMessage) && ajaxRequest.readyState === 2) { - _triggerOpen(rq); - } // MSIE 9 and lower status can be higher than 1000, Chrome can be 0 var status = 200; - if (ajaxRequest.readyState > 1) { + if (ajaxRequest.readyState === 4) { status = ajaxRequest.status > 1000 ? 0 : ajaxRequest.status; } @@ -1585,6 +1611,13 @@ jQuery.atmosphere = function () { 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) { @@ -1662,7 +1695,7 @@ jQuery.atmosphere = function () { _response.state = "messagePublished"; } - var isAllowedToReconnect = request.transport !== 'streaming'; + var isAllowedToReconnect = request.transport !== 'streaming' && request.transport !== 'polling';; if (isAllowedToReconnect && !rq.executeCallbackBeforeReconnect) { _reconnect(ajaxRequest, rq, 0); } @@ -1760,9 +1793,13 @@ jQuery.atmosphere = function () { // Reconnect immedialtely clearTimeout(request.id); + if (request.reconnectId) { + clearTimeout(request.reconnectId); + } + if (reconnectInterval > 0) { - request.id = setTimeout(function () { - _executeRequest(request); + setTimeout(function () { + _request.reconnectId = _executeRequest(request); }, reconnectInterval); } else { _executeRequest(request); @@ -1827,7 +1864,7 @@ jQuery.atmosphere = function () { _clearState(); if (_requestCount++ < rq.maxReconnectOnClose) { if (rq.reconnectInterval > 0) { - rq.id = setTimeout(function () { + rq.reconnectId = setTimeout(function () { _open('re-connecting', request.transport, request); _ieXDR(rq); }, rq.reconnectInterval); @@ -2024,7 +2061,7 @@ jQuery.atmosphere = function () { _invokeClose(true); _open('re-connecting', rq.transport, rq); if (rq.reconnectInterval > 0) { - rq.id = setTimeout(function () { + rq.reconnectId = setTimeout(function () { _ieStreaming(rq); }, rq.reconnectInterval); } else { @@ -2040,7 +2077,7 @@ jQuery.atmosphere = function () { _open('re-connecting', rq.transport, rq); if (_requestCount++ < rq.maxReconnectOnClose) { if (rq.reconnectInterval > 0) { - rq.id = setTimeout(function () { + rq.reconnectId = setTimeout(function () { _ieStreaming(rq); }, rq.reconnectInterval); } else { @@ -2086,6 +2123,9 @@ jQuery.atmosphere = function () { _pushJsonp(message); } else if (_websocket != null) { _pushWebSocket(message); + } else { + _onError(0, "No suspended connection available"); + jQuery.atmosphere.error("No suspended connection available. Make sure atmosphere.subscribe has been called and request.onOpen invoked before invoking this method"); } } @@ -2214,7 +2254,7 @@ jQuery.atmosphere = function () { * */ function _pushWebSocket(message) { - var msg = _getStringMessage(message); + var msg = jQuery.atmosphere.isBinary(message) ? message : _getStringMessage(message); var data; try { if (_request.dispatchUrl != null) { @@ -2310,6 +2350,7 @@ jQuery.atmosphere = function () { f.onError(response); break; case "opening": + delete _request.closed; if (typeof (f.onOpen) !== 'undefined') f.onOpen(response); break; @@ -2326,6 +2367,7 @@ jQuery.atmosphere = function () { f.onClientTimeout(_request); break; case "re-opening": + delete _request.closed; if (typeof (f.onReopen) !== 'undefined') f.onReopen(_request, response); break; @@ -2453,13 +2495,15 @@ jQuery.atmosphere = function () { if (_request.connectTimeout > 0) { jQuery.ajax({ url: url, - async: false, - timeout: _request.connectTimeout + async: true, + timeout: _request.connectTimeout, + cache: false }); } else { jQuery.ajax({ url: url, - async: false + async: true, + cache: false }); } } @@ -2471,6 +2515,9 @@ jQuery.atmosphere = function () { * @private */ function _close() { + if (_request.reconnectId) { + clearTimeout(_request.reconnectId); + } _request.reconnect = false; _abordingConnection = true; _response.request = _request; @@ -2520,7 +2567,7 @@ jQuery.atmosphere = function () { // Clears trace timer clearInterval(_traceTimer); // Removes the trace - document.cookie = encodeURIComponent("atmosphere-" + _request.url) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT"; + document.cookie = _sharingKey + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; // The heir is the parent unless unloading _storageService.signal("close", { reason: "", @@ -2667,6 +2714,15 @@ jQuery.atmosphere = function () { return true; } + // KreaTV 4.1 -> 4.4 + else if (jQuery.trim(navigator.userAgent).slice(0, 16) === "KreaTVWebKit/531") { + return true; + } + // KreaTV 3.8 + else if (jQuery.trim(navigator.userAgent).slice(-7).toLowerCase() === "kreatel") { + return true; + } + // Force Android to use CORS as some version like 2.2.3 fail otherwise var ua = navigator.userAgent.toLowerCase(); var isAndroid = ua.indexOf("android") > -1; @@ -2759,6 +2815,12 @@ jQuery.atmosphere = function () { error: function () { jQuery.atmosphere.log('error', arguments); + }, + + // TODO extract to utils or something + isBinary: function (data) { + // True if data is an instance of Blob, ArrayBuffer or ArrayBufferView + return /^\[object\s(?:Blob|ArrayBuffer|.+Array)\]$/.test(Object.prototype.toString.call(data)); } }; }();
