summaryrefslogtreecommitdiffstats
path: root/core/src/OC
diff options
context:
space:
mode:
authorChristoph Wurst <christoph@winzerhof-wurst.at>2019-01-29 09:23:38 +0100
committerChristoph Wurst <christoph@winzerhof-wurst.at>2019-01-29 09:33:16 +0100
commit3695d025755a69dbb4940eaa8de24ce3ca559c1b (patch)
tree35cdbaab674db911c7c1d58042f9094ba652c177 /core/src/OC
parent8e9d259074619de0f137d749fc94dd4e580d2ec9 (diff)
downloadnextcloud-server-3695d025755a69dbb4940eaa8de24ce3ca559c1b.tar.gz
nextcloud-server-3695d025755a69dbb4940eaa8de24ce3ca559c1b.zip
Move OC.EventSource to the server bundle
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
Diffstat (limited to 'core/src/OC')
-rw-r--r--core/src/OC/eventsource.js168
-rw-r--r--core/src/OC/index.js2
2 files changed, 170 insertions, 0 deletions
diff --git a/core/src/OC/eventsource.js b/core/src/OC/eventsource.js
new file mode 100644
index 00000000000..4851aa3816d
--- /dev/null
+++ b/core/src/OC/eventsource.js
@@ -0,0 +1,168 @@
+/**
+ * ownCloud
+ *
+ * @author Robin Appelman
+ * @copyright 2012 Robin Appelman icewind1991@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * Wrapper for server side events
+ * (http://en.wikipedia.org/wiki/Server-sent_events)
+ * includes a fallback for older browsers and IE
+ *
+ * use server side events with caution, too many open requests can hang the
+ * server
+ */
+
+/* global EventSource */
+
+import $ from 'jquery'
+
+/**
+ * Create a new event source
+ * @param {string} src
+ * @param {object} [data] to be send as GET
+ *
+ * @constructs OCEventSource
+ */
+const OCEventSource = function (src, data) {
+ var dataStr = '';
+ var name;
+ var joinChar;
+ this.typelessListeners = [];
+ this.closed = false;
+ this.listeners = {};
+ if (data) {
+ for (name in data) {
+ dataStr += name + '=' + encodeURIComponent(data[name]) + '&';
+ }
+ }
+ dataStr += 'requesttoken=' + encodeURIComponent(oc_requesttoken);
+ if (!this.useFallBack && typeof EventSource !== 'undefined') {
+ joinChar = '&';
+ if (src.indexOf('?') === -1) {
+ joinChar = '?';
+ }
+ this.source = new EventSource(src + joinChar + dataStr);
+ this.source.onmessage = function (e) {
+ for (var i = 0; i < this.typelessListeners.length; i++) {
+ this.typelessListeners[i](JSON.parse(e.data));
+ }
+ }.bind(this);
+ } else {
+ var iframeId = 'oc_eventsource_iframe_' + OCEventSource.iframeCount;
+ OCEventSource.fallBackSources[OCEventSource.iframeCount] = this;
+ this.iframe = $('<iframe/>');
+ this.iframe.attr('id', iframeId);
+ this.iframe.hide();
+
+ joinChar = '&';
+ if (src.indexOf('?') === -1) {
+ joinChar = '?';
+ }
+ this.iframe.attr('src', src + joinChar + 'fallback=true&fallback_id=' + OCEventSource.iframeCount + '&' + dataStr);
+ $('body').append(this.iframe);
+ this.useFallBack = true;
+ OCEventSource.iframeCount++;
+ }
+ //add close listener
+ this.listen('__internal__', function (data) {
+ if (data === 'close') {
+ this.close();
+ }
+ }.bind(this));
+};
+OCEventSource.fallBackSources = [];
+OCEventSource.iframeCount = 0;//number of fallback iframes
+OCEventSource.fallBackCallBack = function (id, type, data) {
+ OCEventSource.fallBackSources[id].fallBackCallBack(type, data);
+};
+OCEventSource.prototype = {
+ typelessListeners: [],
+ iframe: null,
+ listeners: {},//only for fallback
+ useFallBack: false,
+ /**
+ * Fallback callback for browsers that don't have the
+ * native EventSource object.
+ *
+ * Calls the registered listeners.
+ *
+ * @private
+ * @param {String} type event type
+ * @param {Object} data received data
+ */
+ fallBackCallBack: function (type, data) {
+ var i;
+ // ignore messages that might appear after closing
+ if (this.closed) {
+ return;
+ }
+ if (type) {
+ if (typeof this.listeners.done !== 'undefined') {
+ for (i = 0; i < this.listeners[type].length; i++) {
+ this.listeners[type][i](data);
+ }
+ }
+ } else {
+ for (i = 0; i < this.typelessListeners.length; i++) {
+ this.typelessListeners[i](data);
+ }
+ }
+ },
+ lastLength: 0,//for fallback
+ /**
+ * Listen to a given type of events.
+ *
+ * @param {String} type event type
+ * @param {Function} callback event callback
+ */
+ listen: function (type, callback) {
+ if (callback && callback.call) {
+
+ if (type) {
+ if (this.useFallBack) {
+ if (!this.listeners[type]) {
+ this.listeners[type] = [];
+ }
+ this.listeners[type].push(callback);
+ } else {
+ this.source.addEventListener(type, function (e) {
+ if (typeof e.data !== 'undefined') {
+ callback(JSON.parse(e.data));
+ } else {
+ callback('');
+ }
+ }, false);
+ }
+ } else {
+ this.typelessListeners.push(callback);
+ }
+ }
+ },
+ /**
+ * Closes this event source.
+ */
+ close: function () {
+ this.closed = true;
+ if (typeof this.source !== 'undefined') {
+ this.source.close();
+ }
+ }
+};
+
+export default OCEventSource;
diff --git a/core/src/OC/index.js b/core/src/OC/index.js
index e7a975e0827..e988a76e273 100644
--- a/core/src/OC/index.js
+++ b/core/src/OC/index.js
@@ -24,6 +24,7 @@ import Backbone from 'backbone';
import Apps from './apps'
import AppConfig from './appconfig'
import ContactsMenu from './contactsmenu';
+import EventSource from './eventsource'
import {davCall, davSync} from './backbone-webdav';
// Patch Backbone for DAV
@@ -37,5 +38,6 @@ export default {
Apps,
AppConfig,
Backbone,
+ EventSource,
ContactsMenu,
};