1/** 2 * ownCloud 3 * 4 * @author Robin Appelman 5 * @copyright Copyright (c) 2012 Robin Appelman [email protected] 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE 9 * License as published by the Free Software Foundation; either 10 * version 3 of the License, or any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU AFFERO GENERAL PUBLIC LICENSE for more details. 16 * 17 * You should have received a copy of the GNU Affero General Public 18 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 19 * 20 */ 21 22/** 23 * Wrapper for server side events 24 * (http://en.wikipedia.org/wiki/Server-sent_events) 25 * includes a fallback for older browsers and IE 26 * 27 * use server side events with caution, too many open requests can hang the 28 * server 29 */ 30 31/* global EventSource */ 32 33/** 34 * Create a new event source 35 * @param {string} src 36 * @param {object} [data] to be send as GET 37 * 38 * @constructs OC.EventSource 39 */ 40OC.EventSource=function(src,data){ 41 var dataStr=''; 42 var name; 43 var joinChar; 44 this.typelessListeners=[]; 45 this.closed = false; 46 this.listeners={}; 47 if(data){ 48 for(name in data){ 49 dataStr+=name+'='+encodeURIComponent(data[name])+'&'; 50 } 51 } 52 dataStr+='requesttoken='+encodeURIComponent(oc_requesttoken); 53 if(!this.useFallBack && typeof EventSource !== 'undefined'){ 54 joinChar = '&'; 55 if(src.indexOf('?') === -1) { 56 joinChar = '?'; 57 } 58 this.source= new EventSource(src+joinChar+dataStr); 59 this.source.onmessage=function(e){ 60 for(var i=0;i<this.typelessListeners.length;i++){ 61 this.typelessListeners[i](JSON.parse(e.data)); 62 } 63 }.bind(this); 64 }else{ 65 var iframeId='oc_eventsource_iframe_'+OC.EventSource.iframeCount; 66 OC.EventSource.fallBackSources[OC.EventSource.iframeCount]=this; 67 this.iframe=$('<iframe/>'); 68 this.iframe.attr('id',iframeId); 69 this.iframe.hide(); 70 71 joinChar = '&'; 72 if(src.indexOf('?') === -1) { 73 joinChar = '?'; 74 } 75 this.iframe.attr('src',src+joinChar+'fallback=true&fallback_id='+OC.EventSource.iframeCount+'&'+dataStr); 76 $('body').append(this.iframe); 77 this.useFallBack=true; 78 OC.EventSource.iframeCount++; 79 } 80 //add close listener 81 this.listen('__internal__',function(data){ 82 if(data === 'close'){ 83 this.close(); 84 } 85 }.bind(this)); 86}; 87OC.EventSource.fallBackSources=[]; 88OC.EventSource.iframeCount=0;//number of fallback iframes 89OC.EventSource.fallBackCallBack=function(id,type,data){ 90 OC.EventSource.fallBackSources[id].fallBackCallBack(type,data); 91}; 92OC.EventSource.prototype={ 93 typelessListeners:[], 94 iframe:null, 95 listeners:{},//only for fallback 96 useFallBack:false, 97 /** 98 * Fallback callback for browsers that don't have the 99 * native EventSource object. 100 * 101 * Calls the registered listeners. 102 * 103 * @private 104 * @param {String} type event type 105 * @param {Object} data received data 106 */ 107 fallBackCallBack:function(type,data){ 108 var i; 109 // ignore messages that might appear after closing 110 if (this.closed) { 111 return; 112 } 113 if(type){ 114 if (typeof this.listeners.done !== 'undefined') { 115 for(i=0;i<this.listeners[type].length;i++){ 116 this.listeners[type][i](data); 117 } 118 } 119 }else{ 120 for(i=0;i<this.typelessListeners.length;i++){ 121 this.typelessListeners[i](data); 122 } 123 } 124 }, 125 lastLength:0,//for fallback 126 /** 127 * Listen to a given type of events. 128 * 129 * @param {String} type event type 130 * @param {Function} callback event callback 131 */ 132 listen:function(type,callback){ 133 if(callback && callback.call){ 134 135 if(type){ 136 if(this.useFallBack){ 137 if(!this.listeners[type]){ 138 this.listeners[type]=[]; 139 } 140 this.listeners[type].push(callback); 141 }else{ 142 this.source.addEventListener(type,function(e){ 143 if (typeof e.data !== 'undefined') { 144 callback(JSON.parse(e.data)); 145 } else { 146 callback(''); 147 } 148 },false); 149 } 150 }else{ 151 this.typelessListeners.push(callback); 152 } 153 } 154 }, 155 /** 156 * Closes this event source. 157 */ 158 close:function(){ 159 this.closed = true; 160 if (typeof this.source !== 'undefined') { 161 this.source.close(); 162 } 163 } 164};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.