Commit 62338b62 authored by nextime's avatar nextime

update eventsource

parent b6239101
...@@ -35,7 +35,8 @@ foreach($panels as $panel) { ...@@ -35,7 +35,8 @@ foreach($panels as $panel) {
$buttonar_left=getPanelButtons($_DOMOTIKA['username'], $panel['panel_content'], $panel['panel_sections'], $panel['panel_websections'], $panel['panel_selector'],true,7); $buttonar_left=getPanelButtons($_DOMOTIKA['username'], $panel['panel_content'], $panel['panel_sections'], $panel['panel_websections'], $panel['panel_selector'],true,7);
break; break;
case 'gxv3175_center': case 'gxv3175_center':
$buttonar_center=getPanelButtons($_DOMOTIKA['username'], $panel['panel_content'], $panel['panel_sections'], $panel['panel_websections'], $panel['panel_selector'],true,7); $buttonar_center=DB::query("SELECT button_name,screenshot FROM mediasources
WHERE websection='citophone' AND active=1 ORDER BY position,id"); // AND DMDOMAIN(button_name, '".$panel['panel_content']."')=1
break; break;
case 'gxv3175_right': case 'gxv3175_right':
$buttonar_right=getPanelButtons($_DOMOTIKA['username'], $panel['panel_content'], $panel['panel_sections'], $panel['panel_websections'], $panel['panel_selector'],true,7); $buttonar_right=getPanelButtons($_DOMOTIKA['username'], $panel['panel_content'], $panel['panel_sections'], $panel['panel_websections'], $panel['panel_selector'],true,7);
...@@ -46,24 +47,40 @@ foreach($panels as $panel) { ...@@ -46,24 +47,40 @@ foreach($panels as $panel) {
//$buttonar_left=getPanelButtons($_DOMOTIKA['username'], "*","*","_grandstream_left", "dmdomain","true",7); //$buttonar_left=getPanelButtons($_DOMOTIKA['username'], "*","*","_grandstream_left", "dmdomain","true",7);
//$buttonar_right=getPanelButtons($_DOMOTIKA['username'], "*","*","_grandstream_right", "dmdomain","true",7); //$buttonar_right=getPanelButtons($_DOMOTIKA['username'], "*","*","_grandstream_right", "dmdomain","true",7);
//print_r($buttonar_left); //print_r($buttonar_left);
//print_r($buttonar_center);
?> ?>
<html> <html>
<head> <head>
<script type="text/javascript"
src="https://getfirebug.com/firebug-lite.js">
{
overrideConsole: false,
startInNewWindow: false,
startOpened: true,
enableTrace: true
}
</script>
<title>Domotika GMI Interface</title> <title>Domotika GMI Interface</title>
<link rel="stylesheet" href="/resources/pure/pure-nr-min.css"> <link rel="stylesheet" href="/resources/pure/pure-nr-min.css">
<link rel="stylesheet" href="/resources/fontawesome/css/font-awesome.min.css"> <link rel="stylesheet" href="/resources/fontawesome/css/font-awesome.min.css">
<link href='style.css' type='text/css' rel='stylesheet'> <link href='style.css' type='text/css' rel='stylesheet'>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate, max-age=-1, max-stale=0, post-check=0, pre-check=0">
<meta http-equiv="expires" content="-1">
<!-- <!--
<script src="/resources/js/sockjs-0.3.min.js" ></script> <script src="/resources/js/sockjs-0.3.min.js" ></script>
<script src="/resources/js/ajaxsocket.js" ></script> <script src="/resources/js/ajaxsocket.js" ></script>
<script type="text/javascript" src="https://getfirebug.com/firebug-lite.js"></script>
-->
<script src="/resources/js/jquery-1.9.0.min.js"></script> <script src="/resources/js/jquery-1.9.0.min.js"></script>
<script type="text/javascript" src="http://getfirebug.com/firebug-lite.js"></script>
-->
<script src="/resources/js/zepto.min.js"></script>
<script src="/resources/EventSource/eventsource.js"></script> <script src="/resources/EventSource/eventsource.js"></script>
<script language="javascript" src="simpleGMI.js"></script> <script language="javascript" src="simpleGMI.js"></script>
<script type="text/javascript"> <script type="text/javascript">
window.lastAction=new Date().getTime();
simpleGMI.fullScreen(); simpleGMI.fullScreen();
/** /**
...@@ -99,7 +116,7 @@ $.fn.alterClass = function ( removals, additions ) { ...@@ -99,7 +116,7 @@ $.fn.alterClass = function ( removals, additions ) {
}); });
return !additions ? self : self.addClass( additions ); return !additions ? self : self.addClass( additions );
}; };
})( jQuery ); })( window.jQuery || window.Zepto );
/* /*
function postreply(arg) function postreply(arg)
...@@ -119,15 +136,16 @@ function playClick(volume) { ...@@ -119,15 +136,16 @@ function playClick(volume) {
function butpushed(btype, bid) function butpushed(btype, bid)
{ {
window.lastAction=new Date().getTime();
//playClick(1); //playClick(1);
//simpleGMI.play('/domotika/gmi/beep.wav',0,0,function(data){alert(data)}); //simpleGMI.play('/domotika/gmi/beep.wav',0,0,function(data){alert(data)});
$.post("/rest/v1.2/"+btype+"/setbyid/"+bid+"/json"); $.post("/rest/v1.2/"+btype+"/setbyid/"+bid+"/json");
//simpleGMI.post("http://q.unixmedia.net/rest/v1.2/"+btype+"/setbyid/"+bid+"/json", 'gmi=true', postreply); //simpleGMI.post("http://q.unixmedia.net/rest/v1.2/"+btype+"/setbyid/"+bid+"/json", 'gmi=true', postreply);
} }
setInterval(function(){ //setInterval(function(){
simpleGMI.refresh(); // simpleGMI.refresh();
}, 3600000); //}, 3600000);
// simpleGMI.post('http://q.unixmedia.net/domotika/gmi/style.css', 'aaa=sarca', postreply); // simpleGMI.post('http://q.unixmedia.net/domotika/gmi/style.css', 'aaa=sarca', postreply);
//}, 5000); //}, 5000);
</script> </script>
...@@ -151,25 +169,21 @@ setInterval(function(){ ...@@ -151,25 +169,21 @@ setInterval(function(){
</div> </div>
<div class="pure-u-1-3" style="width:31%"> <div class="pure-u-1-3" style="width:31%">
<div style="padding:5px;"> <div style="padding:5px;">
<button class="pure-button pure-button-primary" style="width:100%;height:130px;" onclick="simpleGMI.refresh()">test</button> <? if(count($buttonar_center)<1) { ?>
<button class="pure-button pure-button-primary" style="width:100%;height:130px;" onclick="simpleGMI.refresh()">No Citophones</button>
<? } else { ?>
<select class="styled-select" id=camerasel name=camerasel style="width:100%;height:130px;">
<? foreach($buttonar_center as $cit) { ?>
<option value="<?=$cit['screenshot'];?>"><?=$cit['button_name']?></option>
<? } ?>
</select>
<? } ?>
</div> </div>
<div style="height:80px" onclick="simpleGMI.refresh()"> <div style="height:80px" onclick="simpleGMI.refresh()">
</div> </div>
<div style="padding:5px;display:none"> <div style="padding:5px;display:block">
<img src="https://192.168.4.45/enu/camera320x240.jpg" style="width:100%;height:190px" onclick="simpleGMI.refresh()"></img> <img id="camera" src="/domotika/gmi/img/camera.jpg" style="width:100%;height:190px" onclick="simpleGMI.refresh()"></img>
</div>
<div style="padding:5px;">
<div class="pure-g">
<div class="pure-u-1-3" >
<button class="pure-button"><h1>15</h1></button>
</div>
<div class="pure-u-1-3" style="width:28%">
<button class="pure-button"><h1>:</h1></button>
</div>
<div class="pure-u-1-3" >
<button class="pure-button"><h1>15</h1></button>
</div>
</div>
</div> </div>
...@@ -231,7 +245,29 @@ var syncReceived = function(event) { ...@@ -231,7 +245,29 @@ var syncReceived = function(event) {
} }
es.addEventListener("sync", syncReceived); es.addEventListener("sync", syncReceived);
setInterval(function(){ window.camimage = new Image();
window.camimage.src = "/domotika/gmi/img/camera.jpg";
function updateImage()
{
if(window.camimage.complete) {
$('#camera').attr('src', window.camimage.src);
window.camimage = new Image();
window.camimage.src = $('#camerasel').val() + "?time=" + new Date().getTime();
//alert($('#camerasel option:selected').text());
}
if(es!=null)
setTimeout(updateImage, 500);
}
window.camimagenum = <?=count($buttonar_center)?>;
if(window.camimagenum>0)
updateImage();
keepAlive = setInterval(function(){
$.get("/rest/v1.2/keepalive/json", $.get("/rest/v1.2/keepalive/json",
function(r){ function(r){
if(r.data=='SLOGGEDOUT') if(r.data=='SLOGGEDOUT')
...@@ -241,6 +277,29 @@ setInterval(function(){ ...@@ -241,6 +277,29 @@ setInterval(function(){
} }
}); });
},5000); },5000);
function endGMI()
{
clearInterval(keepAlive);
es.close();
es=null;
simpleGMI.exit();
}
function checkEnd()
{
window.checkAction=new Date().getTime();
if((window.checkAction-window.lastAction)>30000)
{
endGMI();
} else {
setTimeout(checkEnd, 1000);
}
}
setTimeout(checkEnd, 1000);
setTimeout(endGMI, 900000);
</script> </script>
</body> </body>
</html> </html>
...@@ -43,3 +43,4 @@ body { ...@@ -43,3 +43,4 @@ body {
button:active { button:active {
background: yellow; background: yellow;
} }
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*/ */
/*jslint indent: 2, vars: true, plusplus: true */ /*jslint indent: 2, vars: true, plusplus: true */
/*global setTimeout, clearTimeout, navigator */ /*global setTimeout, clearTimeout */
(function (global) { (function (global) {
"use strict"; "use strict";
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
EventTarget.prototype = { EventTarget.prototype = {
dispatchEvent: function (event) { dispatchEvent: function (event) {
event.target = this;
var type = String(event.type); var type = String(event.type);
var listeners = this.listeners; var listeners = this.listeners;
var typeListeners = listeners.get(type); var typeListeners = listeners.get(type);
...@@ -97,6 +98,7 @@ ...@@ -97,6 +98,7 @@
function Event(type) { function Event(type) {
this.type = type; this.type = type;
this.target = null;
} }
function MessageEvent(type, options) { function MessageEvent(type, options) {
...@@ -122,11 +124,8 @@ ...@@ -122,11 +124,8 @@
var VALUE_START = 6; var VALUE_START = 6;
var VALUE = 7; var VALUE = 7;
var contentTypeRegExp = /^text\/event\-stream;?(\s*charset\=utf\-8)?$/i; var contentTypeRegExp = /^text\/event\-stream;?(\s*charset\=utf\-8)?$/i;
var isWebKitBefore535 = /AppleWebKit\/5([0-2][0-9]|3[0-4])[\.\s\w]/.test(navigator.userAgent);
var isGecko = Boolean(XHR && ((new XHR()).sendAsBinary !== undefined));
var isPresto = Object.prototype.toString.call(global.opera) === "[object Opera]";
var MINIMUM_DURATION = 1; var MINIMUM_DURATION = 1000;
var MAXIMUM_DURATION = 18000000; var MAXIMUM_DURATION = 18000000;
function getDuration(value, def) { function getDuration(value, def) {
...@@ -149,7 +148,6 @@ ...@@ -149,7 +148,6 @@
var withCredentials = Boolean(isCORSSupported && options && options.withCredentials); var withCredentials = Boolean(isCORSSupported && options && options.withCredentials);
var initialRetry = getDuration(options ? options.retry : NaN, 1000); var initialRetry = getDuration(options ? options.retry : NaN, 1000);
var retryLimit = getDuration(options ? options.retryLimit : NaN, 300000);
var heartbeatTimeout = getDuration(options ? options.heartbeatTimeout : NaN, 45000); var heartbeatTimeout = getDuration(options ? options.heartbeatTimeout : NaN, 45000);
var lastEventId = (options && options.lastEventId && String(options.lastEventId)) || ""; var lastEventId = (options && options.lastEventId && String(options.lastEventId)) || "";
var that = this; var that = this;
...@@ -191,15 +189,20 @@ ...@@ -191,15 +189,20 @@
function onProgress(isLoadEnd) { function onProgress(isLoadEnd) {
var responseText = currentState === OPEN || currentState === CONNECTING ? xhr.responseText || "" : ""; var responseText = currentState === OPEN || currentState === CONNECTING ? xhr.responseText || "" : "";
var event = null; var event = null;
var isWrongStatusCodeOrContentType = false;
if (currentState === CONNECTING) { if (currentState === CONNECTING) {
var status = 0; var status = 0;
var statusText = "";
var contentType = ""; var contentType = "";
if (isXHR) { if (isXHR) {
try { try {
status = Number(xhr.status || 0); status = Number(xhr.status || 0);
statusText = String(xhr.statusText || "");
contentType = String(xhr.getResponseHeader("Content-Type") || ""); contentType = String(xhr.getResponseHeader("Content-Type") || "");
} catch (error) { } catch (error) {
// https://bugs.webkit.org/show_bug.cgi?id=29121
status = 0;
// FF < 14, WebKit // FF < 14, WebKit
// https://bugs.webkit.org/show_bug.cgi?id=29658 // https://bugs.webkit.org/show_bug.cgi?id=29658
// https://bugs.webkit.org/show_bug.cgi?id=77854 // https://bugs.webkit.org/show_bug.cgi?id=77854
...@@ -219,6 +222,19 @@ ...@@ -219,6 +222,19 @@
if (currentState === CLOSED) { if (currentState === CLOSED) {
return; return;
} }
} else {
if (status !== 0) {
var message = "";
if (status !== 200) {
message = "EventSource's response has a status " + status + " " + statusText.replace(/\s+/g, " ") + " that is not 200. Aborting the connection.";
} else {
message = "EventSource's response has a Content-Type specifying an unsupported type: " + contentType.replace(/\s+/g, " ") + ". Aborting the connection.";
}
setTimeout(function () {
throw new Error(message);
});
isWrongStatusCodeOrContentType = true;
}
} }
} }
...@@ -228,8 +244,9 @@ ...@@ -228,8 +244,9 @@
} }
var i = charOffset - 1; var i = charOffset - 1;
var length = responseText.length; var length = responseText.length;
var c = "\n";
while (++i < length) { while (++i < length) {
var c = responseText[i]; c = responseText[i];
if (state === AFTER_CR && c === "\n") { if (state === AFTER_CR && c === "\n") {
state = FIELD_START; state = FIELD_START;
} else { } else {
...@@ -246,11 +263,6 @@ ...@@ -246,11 +263,6 @@
} else if (field === "retry") { } else if (field === "retry") {
initialRetry = getDuration(value, initialRetry); initialRetry = getDuration(value, initialRetry);
retry = initialRetry; retry = initialRetry;
if (retryLimit < initialRetry) {
retryLimit = initialRetry;
}
} else if (field === "retryLimit") {//!
retryLimit = getDuration(value, retryLimit);
} else if (field === "heartbeatTimeout") {//! } else if (field === "heartbeatTimeout") {//!
heartbeatTimeout = getDuration(value, heartbeatTimeout); heartbeatTimeout = getDuration(value, heartbeatTimeout);
if (timeout !== 0) { if (timeout !== 0) {
...@@ -307,15 +319,18 @@ ...@@ -307,15 +319,18 @@
} }
if ((currentState === OPEN || currentState === CONNECTING) && if ((currentState === OPEN || currentState === CONNECTING) &&
(isLoadEnd || (charOffset > 1024 * 1024) || (timeout === 0 && !wasActivity))) { (isLoadEnd || isWrongStatusCodeOrContentType || (charOffset > 1024 * 1024) || (timeout === 0 && !wasActivity))) {
currentState = WAITING; currentState = WAITING;
xhr.abort(); xhr.abort();
if (timeout !== 0) { if (timeout !== 0) {
clearTimeout(timeout); clearTimeout(timeout);
timeout = 0; timeout = 0;
} }
if (retry > retryLimit) { if (retry > initialRetry * 16) {
retry = retryLimit; retry = initialRetry * 16;
}
if (retry > MAXIMUM_DURATION) {
retry = MAXIMUM_DURATION;
} }
timeout = setTimeout(onTimeout, retry); timeout = setTimeout(onTimeout, retry);
retry = retry * 2 + 1; retry = retry * 2 + 1;
...@@ -340,7 +355,7 @@ ...@@ -340,7 +355,7 @@
onProgress(true); onProgress(true);
} }
if (isPresto) { if (isXHR) {
// workaround for Opera issue with "progress" events // workaround for Opera issue with "progress" events
timeout0 = setTimeout(function f() { timeout0 = setTimeout(function f() {
if (xhr.readyState === 3) { if (xhr.readyState === 3) {
...@@ -356,36 +371,29 @@ ...@@ -356,36 +371,29 @@
onProgress(false); onProgress(false);
return; return;
} }
if (navigator.onLine === false) { // loading indicator in Safari, Chrome < 14, Firefox
// "online" event is not supported under Web Workers // https://bugzilla.mozilla.org/show_bug.cgi?id=736723
// https://bugs.webkit.org/show_bug.cgi?id=118832 if (isXHR && (xhr.sendAsBinary !== undefined || xhr.onloadend === undefined) && global.document && global.document.readyState && global.document.readyState !== "complete") {
timeout = setTimeout(onTimeout, 500); timeout = setTimeout(onTimeout, 4);
return;
}
// loading indicator in Safari, Chrome < 14
if (isWebKitBefore535 && global.document && global.document.readyState !== "complete") {
timeout = setTimeout(onTimeout, 100);
return; return;
} }
// XDomainRequest#abort removes onprogress, onerror, onload // XDomainRequest#abort removes onprogress, onerror, onload
xhr.onload = xhr.onerror = onLoadEnd; xhr.onload = xhr.onerror = onLoadEnd;
if (isXHR) {
// improper fix to match Firefox behaviour, but it is better than just ignore abort // improper fix to match Firefox behaviour, but it is better than just ignore abort
// see https://bugzilla.mozilla.org/show_bug.cgi?id=768596 // see https://bugzilla.mozilla.org/show_bug.cgi?id=768596
// https://bugzilla.mozilla.org/show_bug.cgi?id=880200 // https://bugzilla.mozilla.org/show_bug.cgi?id=880200
// https://code.google.com/p/chromium/issues/detail?id=153570 // https://code.google.com/p/chromium/issues/detail?id=153570
xhr.onabort = onLoadEnd; xhr.onabort = onLoadEnd;
if (isXHR) {
// Firefox 3.5 - 3.6 - ? < 9.0 // Firefox 3.5 - 3.6 - ? < 9.0
// onprogress is not fired sometimes or delayed // onprogress is not fired sometimes or delayed
xhr.onreadystatechange = onProgress2; xhr.onreadystatechange = onProgress2;
} }
if (!isGecko) {// Firefox (any version) shows loading indicator
xhr.onprogress = onProgress2; xhr.onprogress = onProgress2;
}
wasActivity = false; wasActivity = false;
timeout = setTimeout(onTimeout, heartbeatTimeout); timeout = setTimeout(onTimeout, heartbeatTimeout);
...@@ -407,12 +415,12 @@ ...@@ -407,12 +415,12 @@
} }
xhr.open("GET", s, true); xhr.open("GET", s, true);
if (isXHR) {
// withCredentials should be set after "open" for Safari and Chrome (< 19 ?) // withCredentials should be set after "open" for Safari and Chrome (< 19 ?)
xhr.withCredentials = withCredentials; xhr.withCredentials = withCredentials;
xhr.responseType = "text"; xhr.responseType = "text";
if (isXHR) {
// Request header field Cache-Control is not allowed by Access-Control-Allow-Headers. // Request header field Cache-Control is not allowed by Access-Control-Allow-Headers.
// "Cache-control: no-cache" are not honored in Chrome and Firefox // "Cache-control: no-cache" are not honored in Chrome and Firefox
// https://bugzilla.mozilla.org/show_bug.cgi?id=428916 // https://bugzilla.mozilla.org/show_bug.cgi?id=428916
...@@ -455,6 +463,7 @@ ...@@ -455,6 +463,7 @@
// https://code.google.com/p/chromium/issues/detail?id=260144 // https://code.google.com/p/chromium/issues/detail?id=260144
// https://code.google.com/p/chromium/issues/detail?id=225654 // https://code.google.com/p/chromium/issues/detail?id=225654
// ... // ...
global.NativeEventSource = global.EventSource;
global.EventSource = EventSource; global.EventSource = EventSource;
} }
......
/**
* eventsource.js
* Available under MIT License (MIT)
* https://github.com/Yaffle/EventSource/
*/
/*jslint indent: 2, vars: true, plusplus: true */
/*global setTimeout, clearTimeout, navigator */
(function (global) {
"use strict";
function Map() {
this.data = {};
}
Map.prototype = {
get: function (key) {
return this.data[key + "~"];
},
set: function (key, value) {
this.data[key + "~"] = value;
},
"delete": function (key) {
delete this.data[key + "~"];
}
};
function EventTarget() {
this.listeners = new Map();
}
function throwError(e) {
setTimeout(function () {
throw e;
}, 0);
}
EventTarget.prototype = {
dispatchEvent: function (event) {
var type = String(event.type);
var listeners = this.listeners;
var typeListeners = listeners.get(type);
if (!typeListeners) {
return;
}
var length = typeListeners.length;
var i = -1;
var listener = null;
while (++i < length) {
listener = typeListeners[i];
try {
listener.call(this, event);
} catch (e) {
throwError(e);
}
}
},
addEventListener: function (type, callback) {
type = String(type);
var listeners = this.listeners;
var typeListeners = listeners.get(type);
if (!typeListeners) {
typeListeners = [];
listeners.set(type, typeListeners);
}
var i = typeListeners.length;
while (--i >= 0) {
if (typeListeners[i] === callback) {
return;
}
}
typeListeners.push(callback);
},
removeEventListener: function (type, callback) {
type = String(type);
var listeners = this.listeners;
var typeListeners = listeners.get(type);
if (!typeListeners) {
return;
}
var length = typeListeners.length;
var filtered = [];
var i = -1;
while (++i < length) {
if (typeListeners[i] !== callback) {
filtered.push(typeListeners[i]);
}
}
if (filtered.length === 0) {
listeners["delete"](type);
} else {
listeners.set(type, filtered);
}
}
};
function Event(type) {
this.type = type;
}
function MessageEvent(type, options) {
Event.call(this, type);
this.data = options.data;
this.lastEventId = options.lastEventId;
}
MessageEvent.prototype = Event.prototype;
var XHR = global.XMLHttpRequest;
var XDR = global.XDomainRequest;
var isCORSSupported = Boolean(XHR && ((new XHR()).withCredentials !== undefined));
var isXHR = isCORSSupported;
var Transport = isCORSSupported ? XHR : XDR;
var WAITING = -1;
var CONNECTING = 0;
var OPEN = 1;
var CLOSED = 2;
var AFTER_CR = 3;
var FIELD_START = 4;
var FIELD = 5;
var VALUE_START = 6;
var VALUE = 7;
var contentTypeRegExp = /^text\/event\-stream;?(\s*charset\=utf\-8)?$/i;
var isWebKitBefore535 = /AppleWebKit\/5([0-2][0-9]|3[0-4])[\.\s\w]/.test(navigator.userAgent);
var isGecko = Boolean(XHR && ((new XHR()).sendAsBinary !== undefined));
var isPresto = Object.prototype.toString.call(global.opera) === "[object Opera]";
var MINIMUM_DURATION = 1;
var MAXIMUM_DURATION = 18000000;
function getDuration(value, def) {
var n = Number(value) || def;
return (n < MINIMUM_DURATION ? MINIMUM_DURATION : (n > MAXIMUM_DURATION ? MAXIMUM_DURATION : n));
}
function fire(that, f, event) {
try {
if (typeof f === "function") {
f.call(that, event);
}
} catch (e) {
throwError(e);
}
}
function EventSource(url, options) {
url = String(url);
var withCredentials = Boolean(isCORSSupported && options && options.withCredentials);
var initialRetry = getDuration(options ? options.retry : NaN, 1000);
var retryLimit = getDuration(options ? options.retryLimit : NaN, 300000);
var heartbeatTimeout = getDuration(options ? options.heartbeatTimeout : NaN, 45000);
var lastEventId = (options && options.lastEventId && String(options.lastEventId)) || "";
var that = this;
var retry = initialRetry;
var wasActivity = false;
var xhr = new Transport();
var timeout = 0;
var timeout0 = 0;
var charOffset = 0;
var currentState = WAITING;
var dataBuffer = [];
var lastEventIdBuffer = "";
var eventTypeBuffer = "";
var onTimeout = null;
var state = FIELD_START;
var field = "";
var value = "";
options = null;
function close() {
currentState = CLOSED;
if (xhr !== null) {
xhr.abort();
xhr = null;
}
if (timeout !== 0) {
clearTimeout(timeout);
timeout = 0;
}
if (timeout0 !== 0) {
clearTimeout(timeout0);
timeout0 = 0;
}
that.readyState = CLOSED;
}
function onProgress(isLoadEnd) {
var responseText = currentState === OPEN || currentState === CONNECTING ? xhr.responseText || "" : "";
var event = null;
if (currentState === CONNECTING) {
var status = 0;
var contentType = "";
if (isXHR) {
try {
status = Number(xhr.status || 0);
contentType = String(xhr.getResponseHeader("Content-Type") || "");
} catch (error) {
// FF < 14, WebKit
// https://bugs.webkit.org/show_bug.cgi?id=29658
// https://bugs.webkit.org/show_bug.cgi?id=77854
}
} else {
status = 200;
contentType = xhr.contentType;
}
if (status === 200 && contentTypeRegExp.test(contentType)) {
currentState = OPEN;
wasActivity = true;
retry = initialRetry;
that.readyState = OPEN;
event = new Event("open");
that.dispatchEvent(event);
fire(that, that.onopen, event);
if (currentState === CLOSED) {
return;
}
}
}
if (currentState === OPEN) {
if (responseText.length > charOffset) {
wasActivity = true;
}
var i = charOffset - 1;
var length = responseText.length;
while (++i < length) {
var c = responseText[i];
if (state === AFTER_CR && c === "\n") {
state = FIELD_START;
} else {
if (state === AFTER_CR) {
state = FIELD_START;
}
if (c === "\r" || c === "\n") {
if (field === "data") {
dataBuffer.push(value);
} else if (field === "id") {
lastEventIdBuffer = value;
} else if (field === "event") {
eventTypeBuffer = value;
} else if (field === "retry") {
initialRetry = getDuration(value, initialRetry);
retry = initialRetry;
if (retryLimit < initialRetry) {
retryLimit = initialRetry;
}
} else if (field === "retryLimit") {//!
retryLimit = getDuration(value, retryLimit);
} else if (field === "heartbeatTimeout") {//!
heartbeatTimeout = getDuration(value, heartbeatTimeout);
if (timeout !== 0) {
clearTimeout(timeout);
timeout = setTimeout(onTimeout, heartbeatTimeout);
}
}
value = "";
field = "";
if (state === FIELD_START) {
if (dataBuffer.length !== 0) {
lastEventId = lastEventIdBuffer;
if (eventTypeBuffer === "") {
eventTypeBuffer = "message";
}
event = new MessageEvent(eventTypeBuffer, {
data: dataBuffer.join("\n"),
lastEventId: lastEventIdBuffer
});
that.dispatchEvent(event);
if (eventTypeBuffer === "message") {
fire(that, that.onmessage, event);
}
if (currentState === CLOSED) {
return;
}
}
dataBuffer.length = 0;
eventTypeBuffer = "";
}
state = c === "\r" ? AFTER_CR : FIELD_START;
} else {
if (state === FIELD_START) {
state = FIELD;
}
if (state === FIELD) {
if (c === ":") {
state = VALUE_START;
} else {
field += c;
}
} else if (state === VALUE_START) {
if (c !== " ") {
value += c;
}
state = VALUE;
} else if (state === VALUE) {
value += c;
}
}
}
}
charOffset = length;
}
if ((currentState === OPEN || currentState === CONNECTING) &&
(isLoadEnd || (charOffset > 1024 * 1024) || (timeout === 0 && !wasActivity))) {
currentState = WAITING;
xhr.abort();
if (timeout !== 0) {
clearTimeout(timeout);
timeout = 0;
}
if (retry > retryLimit) {
retry = retryLimit;
}
timeout = setTimeout(onTimeout, retry);
retry = retry * 2 + 1;
that.readyState = CONNECTING;
event = new Event("error");
that.dispatchEvent(event);
fire(that, that.onerror, event);
} else {
if (timeout === 0) {
wasActivity = false;
timeout = setTimeout(onTimeout, heartbeatTimeout);
}
}
}
function onProgress2() {
onProgress(false);
}
function onLoadEnd() {
onProgress(true);
}
if (isPresto) {
// workaround for Opera issue with "progress" events
timeout0 = setTimeout(function f() {
if (xhr.readyState === 3) {
onProgress2();
}
timeout0 = setTimeout(f, 500);
}, 0);
}
onTimeout = function () {
timeout = 0;
if (currentState !== WAITING) {
onProgress(false);
return;
}
if (navigator.onLine === false) {
// "online" event is not supported under Web Workers
// https://bugs.webkit.org/show_bug.cgi?id=118832
timeout = setTimeout(onTimeout, 500);
return;
}
// loading indicator in Safari, Chrome < 14
if (isWebKitBefore535 && global.document && global.document.readyState !== "complete") {
timeout = setTimeout(onTimeout, 100);
return;
}
// XDomainRequest#abort removes onprogress, onerror, onload
xhr.onload = xhr.onerror = onLoadEnd;
// improper fix to match Firefox behaviour, but it is better than just ignore abort
// see https://bugzilla.mozilla.org/show_bug.cgi?id=768596
// https://bugzilla.mozilla.org/show_bug.cgi?id=880200
// https://code.google.com/p/chromium/issues/detail?id=153570
xhr.onabort = onLoadEnd;
if (isXHR) {
// Firefox 3.5 - 3.6 - ? < 9.0
// onprogress is not fired sometimes or delayed
xhr.onreadystatechange = onProgress2;
}
if (!isGecko) {// Firefox (any version) shows loading indicator
xhr.onprogress = onProgress2;
}
wasActivity = false;
timeout = setTimeout(onTimeout, heartbeatTimeout);
charOffset = 0;
currentState = CONNECTING;
dataBuffer.length = 0;
eventTypeBuffer = "";
lastEventIdBuffer = lastEventId;
value = "";
field = "";
state = FIELD_START;
var s = url.slice(0, 5);
if (s !== "data:" && s !== "blob:") {
s = url + ((url.indexOf("?", 0) === -1 ? "?" : "&") + "lastEventId=" + encodeURIComponent(lastEventId) + "&r=" + String(Math.random() + 1).slice(2));
} else {
s = url;
}
xhr.open("GET", s, true);
// withCredentials should be set after "open" for Safari and Chrome (< 19 ?)
xhr.withCredentials = withCredentials;
xhr.responseType = "text";
if (isXHR) {
// Request header field Cache-Control is not allowed by Access-Control-Allow-Headers.
// "Cache-control: no-cache" are not honored in Chrome and Firefox
// https://bugzilla.mozilla.org/show_bug.cgi?id=428916
//xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("Accept", "text/event-stream");
// Request header field Last-Event-ID is not allowed by Access-Control-Allow-Headers.
//xhr.setRequestHeader("Last-Event-ID", lastEventId);
}
xhr.send(null);
};
EventTarget.call(this);
this.close = close;
this.url = url;
this.readyState = CONNECTING;
this.withCredentials = withCredentials;
this.onopen = null;
this.onmessage = null;
this.onerror = null;
onTimeout();
}
function F() {
this.CONNECTING = CONNECTING;
this.OPEN = OPEN;
this.CLOSED = CLOSED;
}
F.prototype = EventTarget.prototype;
EventSource.prototype = new F();
F.call(EventSource);
if (Transport) {
// Why replace a native EventSource ?
// https://bugzilla.mozilla.org/show_bug.cgi?id=444328
// https://bugzilla.mozilla.org/show_bug.cgi?id=831392
// https://code.google.com/p/chromium/issues/detail?id=260144
// https://code.google.com/p/chromium/issues/detail?id=225654
// ...
global.EventSource = EventSource;
}
}(this));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment