rev-websocket 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ /* SWFObject v2.2 <http://code.google.com/p/swfobject/>
2
+ is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
3
+ */
4
+ var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y<X;Y++){U[Y]()}}function K(X){if(J){X()}else{U[U.length]=X}}function s(Y){if(typeof O.addEventListener!=D){O.addEventListener("load",Y,false)}else{if(typeof j.addEventListener!=D){j.addEventListener("load",Y,false)}else{if(typeof O.attachEvent!=D){i(O,"onload",Y)}else{if(typeof O.onload=="function"){var X=O.onload;O.onload=function(){X();Y()}}else{O.onload=Y}}}}}function h(){if(T){V()}else{H()}}function V(){var X=j.getElementsByTagName("body")[0];var aa=C(r);aa.setAttribute("type",q);var Z=X.appendChild(aa);if(Z){var Y=0;(function(){if(typeof Z.GetVariable!=D){var ab=Z.GetVariable("$version");if(ab){ab=ab.split(" ")[1].split(",");M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}else{if(Y<10){Y++;setTimeout(arguments.callee,10);return}}X.removeChild(aa);Z=null;H()})()}else{H()}}function H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[af].id;var ab=o[af].callbackFn;var aa={success:false,id:Y};if(M.pv[0]>0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad<ac;ad++){if(X[ad].getAttribute("name").toLowerCase()!="movie"){ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value")}}P(ai,ah,Y,ab)}else{p(ae);if(ab){ab(aa)}}}}}else{w(Y,true);if(ab){var Z=z(Y);if(Z&&typeof Z.SetVariable!=D){aa.success=true;aa.ref=Z}ab(aa)}}}}}function z(aa){var X=null;var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typeof Y.SetVariable!=D){X=Y}else{var Z=Y.getElementsByTagName(r)[0];if(Z){X=Z}}}return X}function A(){return !a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}function P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var ae=c(X);if(ae){if(ae.nodeName=="OBJECT"){l=g(ae);Q=null}else{l=ae;Q=X}aa.id=R;if(typeof aa.width==D||(!/%$/.test(aa.width)&&parseInt(aa.width,10)<310)){aa.width="310"}if(typeof aa.height==D||(!/%$/.test(aa.height)&&parseInt(aa.height,10)<137)){aa.height="137"}j.title=j.title.slice(0,47)+" - Flash Player Installation";var ad=M.ie&&M.win?"ActiveX":"PlugIn",ac="MMredirectURL="+O.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;if(typeof ab.flashvars!=D){ab.flashvars+="&"+ac}else{ab.flashvars=ac}if(M.ie&&M.win&&ae.readyState!=4){var Y=C("div");X+="SWFObjectNew";Y.setAttribute("id",X);ae.parentNode.insertBefore(Y,ae);ae.style.display="none";(function(){if(ae.readyState==4){ae.parentNode.removeChild(ae)}else{setTimeout(arguments.callee,10)}})()}u(aa,ab,X)}}function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");Y.parentNode.insertBefore(X,Y);X.parentNode.replaceChild(g(Y),X);Y.style.display="none";(function(){if(Y.readyState==4){Y.parentNode.removeChild(Y)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.replaceChild(g(Y),Y)}}function g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML}else{var Y=ab.getElementsByTagName(r)[0];if(Y){var ad=Y.childNodes;if(ad){var X=ad.length;for(var Z=0;Z<X;Z++){if(!(ad[Z].nodeType==1&&ad[Z].nodeName=="PARAM")&&!(ad[Z].nodeType==8)){aa.appendChild(ad[Z].cloneNode(true))}}}}}return aa}function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return X}if(aa){if(typeof ai.id==D){ai.id=Y}if(M.ie&&M.win){var ah="";for(var ae in ai){if(ai[ae]!=Object.prototype[ae]){if(ae.toLowerCase()=="data"){ag.movie=ai[ae]}else{if(ae.toLowerCase()=="styleclass"){ah+=' class="'+ai[ae]+'"'}else{if(ae.toLowerCase()!="classid"){ah+=" "+ae+'="'+ai[ae]+'"'}}}}}var af="";for(var ad in ag){if(ag[ad]!=Object.prototype[ad]){af+='<param name="'+ad+'" value="'+ag[ad]+'" />'}}aa.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab<ac;ab++){I[ab][0].detachEvent(I[ab][1],I[ab][2])}var Z=N.length;for(var aa=0;aa<Z;aa++){y(N[aa])}for(var Y in M){M[Y]=null}M=null;for(var X in swfobject){swfobject[X]=null}swfobject=null})}}();return{registerObject:function(ab,X,aa,Z){if(M.w3&&ab&&X){var Y={};Y.id=ab;Y.swfVersion=X;Y.expressInstall=aa;Y.callbackFn=Z;o[o.length]=Y;w(ab,false)}else{if(Z){Z({success:false,id:ab})}}},getObjectById:function(X){if(M.w3){return z(X)}},embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){var X={success:false,id:ah};if(M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y){w(ah,false);K(function(){ae+="";ag+="";var aj={};if(af&&typeof af===r){for(var al in af){aj[al]=af[al]}}aj.data=ab;aj.width=ae;aj.height=ag;var am={};if(ad&&typeof ad===r){for(var ak in ad){am[ak]=ad[ak]}}if(Z&&typeof Z===r){for(var ai in Z){if(typeof am.flashvars!=D){am.flashvars+="&"+ai+"="+Z[ai]}else{am.flashvars=ai+"="+Z[ai]}}}if(F(Y)){var an=u(aj,am,ah);if(aj.id==ah){w(ah,true)}X.success=true;X.ref=an}else{if(aa&&A()){aj.data=aa;P(aj,am,ah,ac);return}else{w(ah,true)}}if(ac){ac(X)}})}else{if(ac){ac(X)}}},switchOffAutoHideShow:function(){m=false},ua:M,getFlashPlayerVersion:function(){return{major:M.pv[0],minor:M.pv[1],release:M.pv[2]}},hasFlashPlayerVersion:F,createSWF:function(Z,Y,X){if(M.w3){return u(Z,Y,X)}else{return undefined}},showExpressInstall:function(Z,aa,X,Y){if(M.w3&&A()){P(Z,aa,X,Y)}},removeSWF:function(X){if(M.w3){y(X)}},createCSS:function(aa,Z,Y,X){if(M.w3){v(aa,Z,Y,X)}},addDomLoadEvent:K,addLoadEvent:s,getQueryParamValue:function(aa){var Z=j.location.search||j.location.hash;if(Z){if(/\?/.test(Z)){Z=Z.split("?")[1]}if(aa==null){return L(Z)}var Y=Z.split("&");for(var X=0;X<Y.length;X++){if(Y[X].substring(0,Y[X].indexOf("="))==aa){return L(Y[X].substring((Y[X].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(a){var X=c(R);if(X&&l){X.parentNode.replaceChild(l,X);if(Q){w(Q,true);if(M.ie&&M.win){l.style.display="block"}}if(E){E(B)}}a=false}}}}();
@@ -0,0 +1,371 @@
1
+ // Copyright: Hiroshi Ichikawa <http://gimite.net/en/>
2
+ // License: New BSD License
3
+ // Reference: http://dev.w3.org/html5/websockets/
4
+ // Reference: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol
5
+
6
+ (function() {
7
+
8
+ if (window.WebSocket) return;
9
+
10
+ var console = window.console;
11
+ if (!console) console = {log: function(){ }, error: function(){ }};
12
+
13
+ function hasFlash() {
14
+ if ('navigator' in window && 'plugins' in navigator && navigator.plugins['Shockwave Flash']) {
15
+ return !!navigator.plugins['Shockwave Flash'].description;
16
+ }
17
+ if ('ActiveXObject' in window) {
18
+ try {
19
+ return !!new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
20
+ } catch (e) {}
21
+ }
22
+ return false;
23
+ }
24
+
25
+ if (!hasFlash()) {
26
+ console.error("Flash Player is not installed.");
27
+ return;
28
+ }
29
+ console.log(location.protocol);
30
+ if (location.protocol == "file:") {
31
+ console.error(
32
+ "web-socket-js doesn't work in file:///... URL (without special configuration). " +
33
+ "Open the page via Web server i.e. http://...");
34
+ }
35
+
36
+ WebSocket = function(url, protocol, proxyHost, proxyPort, headers) {
37
+ var self = this;
38
+ self.readyState = WebSocket.CONNECTING;
39
+ self.bufferedAmount = 0;
40
+ // Uses setTimeout() to make sure __createFlash() runs after the caller sets ws.onopen etc.
41
+ // Otherwise, when onopen fires immediately, onopen is called before it is set.
42
+ setTimeout(function() {
43
+ WebSocket.__addTask(function() {
44
+ self.__createFlash(url, protocol, proxyHost, proxyPort, headers);
45
+ });
46
+ }, 1);
47
+ }
48
+
49
+ WebSocket.prototype.__createFlash = function(url, protocol, proxyHost, proxyPort, headers) {
50
+ var self = this;
51
+ self.__flash =
52
+ WebSocket.__flash.create(url, protocol, proxyHost || null, proxyPort || 0, headers || null);
53
+
54
+ self.__flash.addEventListener("open", function(fe) {
55
+ try {
56
+ self.readyState = self.__flash.getReadyState();
57
+ if (self.__timer) clearInterval(self.__timer);
58
+ if (window.opera) {
59
+ // Workaround for weird behavior of Opera which sometimes drops events.
60
+ self.__timer = setInterval(function () {
61
+ self.__handleMessages();
62
+ }, 500);
63
+ }
64
+ if (self.onopen) self.onopen();
65
+ } catch (e) {
66
+ console.error(e.toString());
67
+ }
68
+ });
69
+
70
+ self.__flash.addEventListener("close", function(fe) {
71
+ try {
72
+ self.readyState = self.__flash.getReadyState();
73
+ if (self.__timer) clearInterval(self.__timer);
74
+ if (self.onclose) self.onclose();
75
+ } catch (e) {
76
+ console.error(e.toString());
77
+ }
78
+ });
79
+
80
+ self.__flash.addEventListener("message", function() {
81
+ try {
82
+ self.__handleMessages();
83
+ } catch (e) {
84
+ console.error(e.toString());
85
+ }
86
+ });
87
+
88
+ self.__flash.addEventListener("error", function(fe) {
89
+ try {
90
+ if (self.__timer) clearInterval(self.__timer);
91
+ if (self.onerror) self.onerror();
92
+ } catch (e) {
93
+ console.error(e.toString());
94
+ }
95
+ });
96
+
97
+ self.__flash.addEventListener("stateChange", function(fe) {
98
+ try {
99
+ self.readyState = self.__flash.getReadyState();
100
+ self.bufferedAmount = fe.getBufferedAmount();
101
+ } catch (e) {
102
+ console.error(e.toString());
103
+ }
104
+ });
105
+
106
+ //console.log("[WebSocket] Flash object is ready");
107
+ };
108
+
109
+ WebSocket.prototype.send = function(data) {
110
+ if (this.__flash) {
111
+ this.readyState = this.__flash.getReadyState();
112
+ }
113
+ if (!this.__flash || this.readyState == WebSocket.CONNECTING) {
114
+ throw "INVALID_STATE_ERR: Web Socket connection has not been established";
115
+ }
116
+ var result = this.__flash.send(encodeURIComponent(data));
117
+ if (result < 0) { // success
118
+ return true;
119
+ } else {
120
+ this.bufferedAmount = result;
121
+ return false;
122
+ }
123
+ };
124
+
125
+ WebSocket.prototype.close = function() {
126
+ if (!this.__flash) return;
127
+ this.readyState = this.__flash.getReadyState();
128
+ if (this.readyState != WebSocket.OPEN) return;
129
+ this.__flash.close();
130
+ // Sets/calls them manually here because Flash WebSocketConnection.close cannot fire events
131
+ // which causes weird error:
132
+ // > You are trying to call recursively into the Flash Player which is not allowed.
133
+ this.readyState = WebSocket.CLOSED;
134
+ if (this.__timer) clearInterval(this.__timer);
135
+ if (this.onclose) this.onclose();
136
+ };
137
+
138
+ /**
139
+ * Implementation of {@link <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration">DOM 2 EventTarget Interface</a>}
140
+ *
141
+ * @param {string} type
142
+ * @param {function} listener
143
+ * @param {boolean} useCapture !NB Not implemented yet
144
+ * @return void
145
+ */
146
+ WebSocket.prototype.addEventListener = function(type, listener, useCapture) {
147
+ if (!('__events' in this)) {
148
+ this.__events = {};
149
+ }
150
+ if (!(type in this.__events)) {
151
+ this.__events[type] = [];
152
+ if ('function' == typeof this['on' + type]) {
153
+ this.__events[type].defaultHandler = this['on' + type];
154
+ this['on' + type] = this.__createEventHandler(this, type);
155
+ }
156
+ }
157
+ this.__events[type].push(listener);
158
+ };
159
+
160
+ /**
161
+ * Implementation of {@link <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration">DOM 2 EventTarget Interface</a>}
162
+ *
163
+ * @param {string} type
164
+ * @param {function} listener
165
+ * @param {boolean} useCapture NB! Not implemented yet
166
+ * @return void
167
+ */
168
+ WebSocket.prototype.removeEventListener = function(type, listener, useCapture) {
169
+ if (!('__events' in this)) {
170
+ this.__events = {};
171
+ }
172
+ if (!(type in this.__events)) return;
173
+ for (var i = this.__events.length; i > -1; --i) {
174
+ if (listener === this.__events[type][i]) {
175
+ this.__events[type].splice(i, 1);
176
+ break;
177
+ }
178
+ }
179
+ };
180
+
181
+ /**
182
+ * Implementation of {@link <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration">DOM 2 EventTarget Interface</a>}
183
+ *
184
+ * @param {WebSocketEvent} event
185
+ * @return void
186
+ */
187
+ WebSocket.prototype.dispatchEvent = function(event) {
188
+ if (!('__events' in this)) throw 'UNSPECIFIED_EVENT_TYPE_ERR';
189
+ if (!(event.type in this.__events)) throw 'UNSPECIFIED_EVENT_TYPE_ERR';
190
+
191
+ for (var i = 0, l = this.__events[event.type].length; i < l; ++ i) {
192
+ this.__events[event.type][i](event);
193
+ if (event.cancelBubble) break;
194
+ }
195
+
196
+ if (false !== event.returnValue &&
197
+ 'function' == typeof this.__events[event.type].defaultHandler)
198
+ {
199
+ this.__events[event.type].defaultHandler(event);
200
+ }
201
+ };
202
+
203
+ WebSocket.prototype.__handleMessages = function() {
204
+ // Gets data using readSocketData() instead of getting it from event object
205
+ // of Flash event. This is to make sure to keep message order.
206
+ // It seems sometimes Flash events don't arrive in the same order as they are sent.
207
+ var arr = this.__flash.readSocketData();
208
+ for (var i = 0; i < arr.length; i++) {
209
+ var data = decodeURIComponent(arr[i]);
210
+ try {
211
+ if (this.onmessage) {
212
+ var e;
213
+ if (window.MessageEvent) {
214
+ e = document.createEvent("MessageEvent");
215
+ e.initMessageEvent("message", false, false, data, null, null, window, null);
216
+ } else { // IE
217
+ e = {data: data};
218
+ }
219
+ this.onmessage(e);
220
+ }
221
+ } catch (e) {
222
+ console.error(e.toString());
223
+ }
224
+ }
225
+ };
226
+
227
+ /**
228
+ * @param {object} object
229
+ * @param {string} type
230
+ */
231
+ WebSocket.prototype.__createEventHandler = function(object, type) {
232
+ return function(data) {
233
+ var event = new WebSocketEvent();
234
+ event.initEvent(type, true, true);
235
+ event.target = event.currentTarget = object;
236
+ for (var key in data) {
237
+ event[key] = data[key];
238
+ }
239
+ object.dispatchEvent(event, arguments);
240
+ };
241
+ }
242
+
243
+ /**
244
+ * Basic implementation of {@link <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-interface">DOM 2 EventInterface</a>}
245
+ *
246
+ * @class
247
+ * @constructor
248
+ */
249
+ function WebSocketEvent(){}
250
+
251
+ /**
252
+ *
253
+ * @type boolean
254
+ */
255
+ WebSocketEvent.prototype.cancelable = true;
256
+
257
+ /**
258
+ *
259
+ * @type boolean
260
+ */
261
+ WebSocketEvent.prototype.cancelBubble = false;
262
+
263
+ /**
264
+ *
265
+ * @return void
266
+ */
267
+ WebSocketEvent.prototype.preventDefault = function() {
268
+ if (this.cancelable) {
269
+ this.returnValue = false;
270
+ }
271
+ };
272
+
273
+ /**
274
+ *
275
+ * @return void
276
+ */
277
+ WebSocketEvent.prototype.stopPropagation = function() {
278
+ this.cancelBubble = true;
279
+ };
280
+
281
+ /**
282
+ *
283
+ * @param {string} eventTypeArg
284
+ * @param {boolean} canBubbleArg
285
+ * @param {boolean} cancelableArg
286
+ * @return void
287
+ */
288
+ WebSocketEvent.prototype.initEvent = function(eventTypeArg, canBubbleArg, cancelableArg) {
289
+ this.type = eventTypeArg;
290
+ this.cancelable = cancelableArg;
291
+ this.timeStamp = new Date();
292
+ };
293
+
294
+
295
+ WebSocket.CONNECTING = 0;
296
+ WebSocket.OPEN = 1;
297
+ WebSocket.CLOSING = 2;
298
+ WebSocket.CLOSED = 3;
299
+
300
+ WebSocket.__tasks = [];
301
+
302
+ WebSocket.__initialize = function() {
303
+ if (WebSocket.__swfLocation) {
304
+ // For backword compatibility.
305
+ window.WEB_SOCKET_SWF_LOCATION = WebSocket.__swfLocation;
306
+ }
307
+ if (!window.WEB_SOCKET_SWF_LOCATION) {
308
+ console.error("[WebSocket] set WEB_SOCKET_SWF_LOCATION to location of WebSocketMain.swf");
309
+ return;
310
+ }
311
+ var container = document.createElement("div");
312
+ container.id = "webSocketContainer";
313
+ // Puts the Flash out of the window. Note that we cannot use display: none or visibility: hidden
314
+ // here because it prevents Flash from loading at least in IE.
315
+ container.style.position = "absolute";
316
+ container.style.left = "-100px";
317
+ container.style.top = "-100px";
318
+ var holder = document.createElement("div");
319
+ holder.id = "webSocketFlash";
320
+ container.appendChild(holder);
321
+ document.body.appendChild(container);
322
+ swfobject.embedSWF(
323
+ WEB_SOCKET_SWF_LOCATION, "webSocketFlash", "8", "8", "9.0.0",
324
+ null, {bridgeName: "webSocket"}, null, null,
325
+ function(e) {
326
+ if (!e.success) console.error("[WebSocket] swfobject.embedSWF failed");
327
+ }
328
+ );
329
+ FABridge.addInitializationCallback("webSocket", function() {
330
+ try {
331
+ //console.log("[WebSocket] FABridge initializad");
332
+ WebSocket.__flash = FABridge.webSocket.root();
333
+ WebSocket.__flash.setCallerUrl(location.href);
334
+ WebSocket.__flash.setDebug(!!window.WEB_SOCKET_DEBUG);
335
+ for (var i = 0; i < WebSocket.__tasks.length; ++i) {
336
+ WebSocket.__tasks[i]();
337
+ }
338
+ WebSocket.__tasks = [];
339
+ } catch (e) {
340
+ console.error("[WebSocket] " + e.toString());
341
+ }
342
+ });
343
+ };
344
+
345
+ WebSocket.__addTask = function(task) {
346
+ if (WebSocket.__flash) {
347
+ task();
348
+ } else {
349
+ WebSocket.__tasks.push(task);
350
+ }
351
+ }
352
+
353
+ // called from Flash
354
+ window.webSocketLog = function(message) {
355
+ console.log(decodeURIComponent(message));
356
+ };
357
+
358
+ // called from Flash
359
+ window.webSocketError = function(message) {
360
+ console.error(decodeURIComponent(message));
361
+ };
362
+
363
+ if (!window.WEB_SOCKET_DISABLE_AUTO_INITIALIZATION) {
364
+ if (window.addEventListener) {
365
+ window.addEventListener("load", WebSocket.__initialize, false);
366
+ } else {
367
+ window.attachEvent("onload", WebSocket.__initialize);
368
+ }
369
+ }
370
+
371
+ })();
@@ -0,0 +1,63 @@
1
+
2
+ body {
3
+ overflow: hidden;
4
+ padding: 7px;
5
+ margin: 0;
6
+ font-family: serif;
7
+ }
8
+
9
+ #screen {
10
+ margin: 0;
11
+ padding: 0;
12
+ }
13
+
14
+ #screen li {
15
+ padding: 0;
16
+ margin: 0;
17
+ font-weight: bold;
18
+ list-style-type: none;
19
+ }
20
+
21
+ #control {
22
+ width: 14em;
23
+ border: 2px solid #f09090;
24
+ background-color: #fffcf9;
25
+ padding: 0.9em 1em 0.4em 1em;
26
+ font-family: sans-serif;
27
+ }
28
+
29
+ #input {
30
+ width: 10em;
31
+ font-size: 130%;
32
+ font-weight: bold;
33
+ margin: 0.3em 0.2em 0.9em -0.1em;
34
+ padding: 0 0 0 0.2em;
35
+ height: 1.5em;
36
+ }
37
+
38
+ #control p {
39
+ font-size: 85%;
40
+ margin: 0 0 1em 0;
41
+ line-height: 100%;
42
+ }
43
+
44
+ #control p a {
45
+ margin-right: 0.5em;
46
+ }
47
+
48
+ a {
49
+ color: red;
50
+ }
51
+
52
+ a:hover {
53
+ text-decoration: none;
54
+ }
55
+
56
+ #users:before {
57
+ content: "user: ";
58
+ }
59
+
60
+ #status:before {
61
+ content: "status: ";
62
+ }
63
+
@@ -0,0 +1,148 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta content="text/css" http-equiv="content-style-type" />
6
+ <meta content="text/javascript" http-equiv="content-script-type" />
7
+
8
+ <script type="text/javascript" src='js/jquery.min.js'></script>
9
+ <script type="text/javascript" src='js/swfobject.js'></script>
10
+ <script type="text/javascript" src='js/FABridge.js'></script>
11
+ <script type="text/javascript" src='js/web_socket.js'></script>
12
+ <script type="text/javascript" src='js/json2.js'></script>
13
+ <link rel="stylesheet" type="text/css" href="shoutchat.css" />
14
+
15
+ <title>Rev-WebSocket Demo: ShoutChat</title>
16
+
17
+ <script>
18
+ WS_URL = "ws://localhost:8081";
19
+ WEB_SOCKET_SWF_LOCATION = "js/WebSocketMain.swf";
20
+
21
+ var global = this;
22
+
23
+ $(document).ready(function(){
24
+
25
+ function setStatus(message) {
26
+ $("#status").text(message);
27
+ }
28
+
29
+ setStatus("connecting...");
30
+ ws = new WebSocket(WS_URL);
31
+
32
+ ws.onopen = function() {
33
+ setStatus("connected.");
34
+ }
35
+
36
+ ws.onclose = function() {
37
+ setStatus("disconnected...");
38
+ }
39
+
40
+ ws.onerror = function(msg) {
41
+ setStatus("failed to connect:"+msg);
42
+ }
43
+
44
+ ws.onmessage = function(event) {
45
+ obj = JSON.parse(event.data);
46
+ data = obj[1];
47
+ switch(obj[0]) {
48
+ case "count":
49
+ setCount(data);
50
+ break;
51
+ case "message":
52
+ renderMessage(data);
53
+ break;
54
+ }
55
+ }
56
+
57
+ function sendMessage(method, data) {
58
+ ws.send(JSON.stringify([method, data]));
59
+ }
60
+
61
+ function setCount(count) {
62
+ $("#users").html(count);
63
+ }
64
+
65
+ function renderMessage(params) {
66
+ var text = params.message;
67
+
68
+ var size = Math.floor(20 * text.length / params.tsec);
69
+ if(size > 1500) { size = 1500; }
70
+ else if(size < 70) { size = 70; }
71
+
72
+ var dh = $(window).height();
73
+ var dw = $(window).width();
74
+ var tw = text.length * size / 25;
75
+ var th = size / 30;
76
+ var x = dw * params.randX - tw/2;
77
+ var y = dh * params.randY - th/2;
78
+ if(x < 0) { x = 0; } else if(x > dw - tw) { x -= tw; }
79
+ if(y < 0) { y = 0; } else if(y > dh - th) { y -= th; }
80
+
81
+ var screen = $("#screen");
82
+
83
+ screen.append(
84
+ $('<li>')
85
+ .css('position', 'absolute')
86
+ .css('left', ''+Math.floor(x)+'px')
87
+ .css('top', ''+Math.floor(y)+'px')
88
+ .css('font-size', ''+size+'%')
89
+ .text(text));
90
+
91
+ var children = screen.children();
92
+
93
+ while(children.size() > 20) {
94
+ children.first().remove();
95
+ children = screen.children();
96
+ }
97
+
98
+ var size = children.size();
99
+ var step = 255.0 / size;
100
+ for(var i=0; i < size; i++) {
101
+ var base = Math.floor(step*(size-i-1));
102
+ function c() {
103
+ var s = (1.0 + Math.random() / 2.0) * base;
104
+ if(s > 255) { s = 255; }
105
+ return Math.floor(s);
106
+ }
107
+ var e = children.eq(i);
108
+ e.css("color", "rgb("+c()+","+c()+","+c()+")");
109
+ e.css("opacity", ''+((i+1)/size));
110
+ }
111
+ }
112
+
113
+ var beforeTime = new Date();
114
+
115
+ global.submitMessage = function() {
116
+ var input = $("#input");
117
+ if(input.val() != "") {
118
+ currentTime = new Date();
119
+ var tsec = (currentTime - beforeTime) / 60 / 60;
120
+ beforeTime = currentTime;
121
+ sendMessage("message", {
122
+ message: input.val(),
123
+ randX: Math.random(),
124
+ randY: Math.random(),
125
+ tsec: tsec
126
+ });
127
+ input.val("");
128
+ }
129
+ return false;
130
+ }
131
+ });
132
+ </script>
133
+ </head>
134
+ <body>
135
+ <div id="control">
136
+ <form action="#" onsubmit="return submitMessage();">
137
+ <input type="text" name="input" id="input" value="ShoutChat!" />
138
+ </form>
139
+ <p id="users"></p>
140
+ <p id="status"></p>
141
+ <p>
142
+ <a href="/shoutchat.html" target="_blank">Open new tab</a>
143
+ <a href="http://github.com/frsyuki/rev-websocket">Source</a>
144
+ </p>
145
+ </div>
146
+
147
+ <ul id="screen"></ul>
148
+ </body>