pusher-fake 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -13,7 +13,7 @@
13
13
  <ul></ul>
14
14
  </section>
15
15
 
16
- <script src="/javascripts/vendor/pusher-1.12.7.js"></script>
16
+ <script src="/javascripts/vendor/pusher-2.0.4.js"></script>
17
17
  <script>
18
18
  window.addEventListener("DOMContentLoaded", function() {
19
19
  // Use the PusherFake server.
data/lib/pusher-fake.rb CHANGED
@@ -16,7 +16,7 @@ require "pusher-fake/webhook"
16
16
 
17
17
  module PusherFake
18
18
  # The current version string.
19
- VERSION = "0.7.0"
19
+ VERSION = "0.8.0"
20
20
 
21
21
  # Call this method to modify the defaults.
22
22
  #
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pusher-fake
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-26 00:00:00.000000000 Z
12
+ date: 2013-05-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: em-http-request
@@ -34,7 +34,7 @@ dependencies:
34
34
  requirements:
35
35
  - - '='
36
36
  - !ruby/object:Gem::Version
37
- version: 0.4.0
37
+ version: 0.5.0
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,7 +42,7 @@ dependencies:
42
42
  requirements:
43
43
  - - '='
44
44
  - !ruby/object:Gem::Version
45
- version: 0.4.0
45
+ version: 0.5.0
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: thin
48
48
  requirement: !ruby/object:Gem::Requirement
@@ -50,7 +50,7 @@ dependencies:
50
50
  requirements:
51
51
  - - '='
52
52
  - !ruby/object:Gem::Version
53
- version: 1.5.0
53
+ version: 1.5.1
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
@@ -58,7 +58,7 @@ dependencies:
58
58
  requirements:
59
59
  - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: 1.5.0
61
+ version: 1.5.1
62
62
  - !ruby/object:Gem::Dependency
63
63
  name: multi_json
64
64
  requirement: !ruby/object:Gem::Requirement
@@ -66,7 +66,7 @@ dependencies:
66
66
  requirements:
67
67
  - - '='
68
68
  - !ruby/object:Gem::Version
69
- version: 1.6.1
69
+ version: 1.7.3
70
70
  type: :runtime
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
@@ -74,7 +74,7 @@ dependencies:
74
74
  requirements:
75
75
  - - '='
76
76
  - !ruby/object:Gem::Version
77
- version: 1.6.1
77
+ version: 1.7.3
78
78
  - !ruby/object:Gem::Dependency
79
79
  name: bourne
80
80
  requirement: !ruby/object:Gem::Requirement
@@ -82,7 +82,7 @@ dependencies:
82
82
  requirements:
83
83
  - - '='
84
84
  - !ruby/object:Gem::Version
85
- version: 1.3.2
85
+ version: 1.4.0
86
86
  type: :development
87
87
  prerelease: false
88
88
  version_requirements: !ruby/object:Gem::Requirement
@@ -90,7 +90,7 @@ dependencies:
90
90
  requirements:
91
91
  - - '='
92
92
  - !ruby/object:Gem::Version
93
- version: 1.3.2
93
+ version: 1.4.0
94
94
  - !ruby/object:Gem::Dependency
95
95
  name: capybara-webkit
96
96
  requirement: !ruby/object:Gem::Requirement
@@ -114,7 +114,7 @@ dependencies:
114
114
  requirements:
115
115
  - - '='
116
116
  - !ruby/object:Gem::Version
117
- version: 1.2.1
117
+ version: 1.3.1
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
@@ -122,7 +122,7 @@ dependencies:
122
122
  requirements:
123
123
  - - '='
124
124
  - !ruby/object:Gem::Version
125
- version: 1.2.1
125
+ version: 1.3.1
126
126
  - !ruby/object:Gem::Dependency
127
127
  name: pusher
128
128
  requirement: !ruby/object:Gem::Requirement
@@ -146,7 +146,7 @@ dependencies:
146
146
  requirements:
147
147
  - - '='
148
148
  - !ruby/object:Gem::Version
149
- version: 10.0.3
149
+ version: 10.0.4
150
150
  type: :development
151
151
  prerelease: false
152
152
  version_requirements: !ruby/object:Gem::Requirement
@@ -154,7 +154,7 @@ dependencies:
154
154
  requirements:
155
155
  - - '='
156
156
  - !ruby/object:Gem::Version
157
- version: 10.0.3
157
+ version: 10.0.4
158
158
  - !ruby/object:Gem::Dependency
159
159
  name: redcarpet
160
160
  requirement: !ruby/object:Gem::Requirement
@@ -194,7 +194,7 @@ dependencies:
194
194
  requirements:
195
195
  - - '='
196
196
  - !ruby/object:Gem::Version
197
- version: 1.3.5
197
+ version: 1.4.2
198
198
  type: :development
199
199
  prerelease: false
200
200
  version_requirements: !ruby/object:Gem::Requirement
@@ -202,7 +202,7 @@ dependencies:
202
202
  requirements:
203
203
  - - '='
204
204
  - !ruby/object:Gem::Version
205
- version: 1.3.5
205
+ version: 1.4.2
206
206
  - !ruby/object:Gem::Dependency
207
207
  name: yard
208
208
  requirement: !ruby/object:Gem::Requirement
@@ -210,7 +210,7 @@ dependencies:
210
210
  requirements:
211
211
  - - '='
212
212
  - !ruby/object:Gem::Version
213
- version: 0.8.5
213
+ version: 0.8.6.1
214
214
  type: :development
215
215
  prerelease: false
216
216
  version_requirements: !ruby/object:Gem::Requirement
@@ -218,7 +218,7 @@ dependencies:
218
218
  requirements:
219
219
  - - '='
220
220
  - !ruby/object:Gem::Version
221
- version: 0.8.5
221
+ version: 0.8.6.1
222
222
  description: A fake Pusher server for development and testing.
223
223
  email: hello@tristandunn.com
224
224
  executables: []
@@ -249,7 +249,7 @@ files:
249
249
  - features/step_definitions/navigation_steps.rb
250
250
  - features/step_definitions/presence_steps.rb
251
251
  - features/step_definitions/webhook_steps.rb
252
- - features/support/application/public/javascripts/vendor/pusher-1.12.7.js
252
+ - features/support/application/public/javascripts/vendor/pusher-2.0.4.js
253
253
  - features/support/application/views/index.erb
254
254
  - features/support/application.rb
255
255
  - features/support/environment.rb
@@ -284,7 +284,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
284
284
  version: '0'
285
285
  segments:
286
286
  - 0
287
- hash: -3011704484738286884
287
+ hash: -4438089056312273430
288
288
  required_rubygems_version: !ruby/object:Gem::Requirement
289
289
  none: false
290
290
  requirements:
@@ -293,7 +293,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
293
293
  version: '0'
294
294
  segments:
295
295
  - 0
296
- hash: -3011704484738286884
296
+ hash: -4438089056312273430
297
297
  requirements: []
298
298
  rubyforge_project:
299
299
  rubygems_version: 1.8.23
@@ -314,7 +314,7 @@ test_files:
314
314
  - features/step_definitions/navigation_steps.rb
315
315
  - features/step_definitions/presence_steps.rb
316
316
  - features/step_definitions/webhook_steps.rb
317
- - features/support/application/public/javascripts/vendor/pusher-1.12.7.js
317
+ - features/support/application/public/javascripts/vendor/pusher-2.0.4.js
318
318
  - features/support/application/views/index.erb
319
319
  - features/support/application.rb
320
320
  - features/support/environment.rb
@@ -1,1319 +0,0 @@
1
- /*!
2
- * Pusher JavaScript Library v1.12.7
3
- * http://pusherapp.com/
4
- *
5
- * Copyright 2011, Pusher
6
- * Released under the MIT licence.
7
- */
8
-
9
- ;(function() {
10
- if (Function.prototype.scopedTo === undefined) {
11
- Function.prototype.scopedTo = function(context, args) {
12
- var f = this;
13
- return function() {
14
- return f.apply(context, Array.prototype.slice.call(args || [])
15
- .concat(Array.prototype.slice.call(arguments)));
16
- };
17
- };
18
- }
19
-
20
- var Pusher = function(app_key, options) {
21
- this.options = options || {};
22
- this.key = app_key;
23
- this.channels = new Pusher.Channels();
24
- this.global_emitter = new Pusher.EventsDispatcher()
25
-
26
- var self = this;
27
-
28
- this.checkAppKey();
29
-
30
- this.connection = new Pusher.Connection(this.key, this.options);
31
-
32
- // Setup / teardown connection
33
- this.connection
34
- .bind('connected', function() {
35
- self.subscribeAll();
36
- })
37
- .bind('message', function(params) {
38
- var internal = (params.event.indexOf('pusher_internal:') === 0);
39
- if (params.channel) {
40
- var channel;
41
- if (channel = self.channel(params.channel)) {
42
- channel.emit(params.event, params.data);
43
- }
44
- }
45
- // Emit globaly [deprecated]
46
- if (!internal) self.global_emitter.emit(params.event, params.data);
47
- })
48
- .bind('disconnected', function() {
49
- self.channels.disconnect();
50
- })
51
- .bind('error', function(err) {
52
- Pusher.warn('Error', err);
53
- });
54
-
55
- Pusher.instances.push(this);
56
-
57
- if (Pusher.isReady) self.connect();
58
- };
59
- Pusher.instances = [];
60
- Pusher.prototype = {
61
- channel: function(name) {
62
- return this.channels.find(name);
63
- },
64
-
65
- connect: function() {
66
- this.connection.connect();
67
- },
68
-
69
- disconnect: function() {
70
- this.connection.disconnect();
71
- },
72
-
73
- bind: function(event_name, callback) {
74
- this.global_emitter.bind(event_name, callback);
75
- return this;
76
- },
77
-
78
- bind_all: function(callback) {
79
- this.global_emitter.bind_all(callback);
80
- return this;
81
- },
82
-
83
- subscribeAll: function() {
84
- var channelName;
85
- for (channelName in this.channels.channels) {
86
- if (this.channels.channels.hasOwnProperty(channelName)) {
87
- this.subscribe(channelName);
88
- }
89
- }
90
- },
91
-
92
- subscribe: function(channel_name) {
93
- var self = this;
94
- var channel = this.channels.add(channel_name, this);
95
-
96
- if (this.connection.state === 'connected') {
97
- channel.authorize(this.connection.socket_id, this.options, function(err, data) {
98
- if (err) {
99
- channel.emit('pusher:subscription_error', data);
100
- } else {
101
- self.send_event('pusher:subscribe', {
102
- channel: channel_name,
103
- auth: data.auth,
104
- channel_data: data.channel_data
105
- });
106
- }
107
- });
108
- }
109
- return channel;
110
- },
111
-
112
- unsubscribe: function(channel_name) {
113
- this.channels.remove(channel_name);
114
- if (this.connection.state === 'connected') {
115
- this.send_event('pusher:unsubscribe', {
116
- channel: channel_name
117
- });
118
- }
119
- },
120
-
121
- send_event: function(event_name, data, channel) {
122
- return this.connection.send_event(event_name, data, channel);
123
- },
124
-
125
- checkAppKey: function() {
126
- if (!this.key) {
127
- // do not allow undefined, null or empty string
128
- Pusher.warn('Warning', 'You must pass your app key when you instantiate Pusher.');
129
- }
130
- }
131
- };
132
-
133
- Pusher.Util = {
134
- extend: function extend(target, extensions) {
135
- for (var property in extensions) {
136
- if (extensions[property] && extensions[property].constructor &&
137
- extensions[property].constructor === Object) {
138
- target[property] = extend(target[property] || {}, extensions[property]);
139
- } else {
140
- target[property] = extensions[property];
141
- }
142
- }
143
- return target;
144
- },
145
-
146
- stringify: function stringify() {
147
- var m = ["Pusher"]
148
- for (var i = 0; i < arguments.length; i++){
149
- if (typeof arguments[i] === "string") {
150
- m.push(arguments[i])
151
- } else {
152
- if (window['JSON'] == undefined) {
153
- m.push(arguments[i].toString());
154
- } else {
155
- m.push(JSON.stringify(arguments[i]))
156
- }
157
- }
158
- };
159
- return m.join(" : ")
160
- },
161
-
162
- arrayIndexOf: function(array, item) { // MSIE doesn't have array.indexOf
163
- var nativeIndexOf = Array.prototype.indexOf;
164
- if (array == null) return -1;
165
- if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
166
- for (i = 0, l = array.length; i < l; i++) if (array[i] === item) return i;
167
- return -1;
168
- }
169
- };
170
-
171
- // To receive log output provide a Pusher.log function, for example
172
- // Pusher.log = function(m){console.log(m)}
173
- Pusher.debug = function() {
174
- if (!Pusher.log) return
175
- Pusher.log(Pusher.Util.stringify.apply(this, arguments))
176
- }
177
- Pusher.warn = function() {
178
- if (window.console && window.console.warn) {
179
- window.console.warn(Pusher.Util.stringify.apply(this, arguments));
180
- } else {
181
- if (!Pusher.log) return
182
- Pusher.log(Pusher.Util.stringify.apply(this, arguments));
183
- }
184
- };
185
-
186
- // Pusher defaults
187
- Pusher.VERSION = '1.12.7';
188
- // WS connection parameters
189
- Pusher.host = 'ws.pusherapp.com';
190
- Pusher.ws_port = 80;
191
- Pusher.wss_port = 443;
192
- // SockJS fallback parameters
193
- Pusher.sockjs_host = 'sockjs.pusher.com';
194
- Pusher.sockjs_http_port = 80
195
- Pusher.sockjs_https_port = 443
196
- Pusher.sockjs_path = "/pusher"
197
- // Other settings
198
- Pusher.channel_auth_endpoint = '/pusher/auth';
199
- Pusher.cdn_http = 'http://js.pusher.com/'
200
- Pusher.cdn_https = 'https://d3dy5gmtp8yhk7.cloudfront.net/'
201
- Pusher.dependency_suffix = '';
202
- Pusher.channel_auth_transport = 'ajax';
203
- Pusher.activity_timeout = 120000;
204
- Pusher.pong_timeout = 30000;
205
-
206
- Pusher.isReady = false;
207
- Pusher.ready = function() {
208
- Pusher.isReady = true;
209
- for (var i = 0, l = Pusher.instances.length; i < l; i++) {
210
- Pusher.instances[i].connect();
211
- }
212
- };
213
-
214
- this.Pusher = Pusher;
215
- }).call(this);
216
-
217
- ;(function() {
218
- /* Abstract event binding
219
- Example:
220
-
221
- var MyEventEmitter = function(){};
222
- MyEventEmitter.prototype = new Pusher.EventsDispatcher;
223
-
224
- var emitter = new MyEventEmitter();
225
-
226
- // Bind to single event
227
- emitter.bind('foo_event', function(data){ alert(data)} );
228
-
229
- // Bind to all
230
- emitter.bind_all(function(eventName, data){ alert(data) });
231
-
232
- --------------------------------------------------------*/
233
-
234
- function CallbackRegistry() {
235
- this._callbacks = {};
236
- };
237
-
238
- CallbackRegistry.prototype.get = function(eventName) {
239
- return this._callbacks[this._prefix(eventName)];
240
- };
241
-
242
- CallbackRegistry.prototype.add = function(eventName, callback) {
243
- var prefixedEventName = this._prefix(eventName);
244
- this._callbacks[prefixedEventName] = this._callbacks[prefixedEventName] || [];
245
- this._callbacks[prefixedEventName].push(callback);
246
- };
247
-
248
- CallbackRegistry.prototype.remove = function(eventName, callback) {
249
- if(this.get(eventName)) {
250
- var index = Pusher.Util.arrayIndexOf(this.get(eventName), callback);
251
- this._callbacks[this._prefix(eventName)].splice(index, 1);
252
- }
253
- };
254
-
255
- CallbackRegistry.prototype._prefix = function(eventName) {
256
- return "_" + eventName;
257
- };
258
-
259
-
260
- function EventsDispatcher(failThrough) {
261
- this.callbacks = new CallbackRegistry();
262
- this.global_callbacks = [];
263
- // Run this function when dispatching an event when no callbacks defined
264
- this.failThrough = failThrough;
265
- }
266
-
267
- EventsDispatcher.prototype.bind = function(eventName, callback) {
268
- this.callbacks.add(eventName, callback);
269
- return this;// chainable
270
- };
271
-
272
- EventsDispatcher.prototype.unbind = function(eventName, callback) {
273
- this.callbacks.remove(eventName, callback);
274
- return this;
275
- };
276
-
277
- EventsDispatcher.prototype.emit = function(eventName, data) {
278
- // Global callbacks
279
- for (var i = 0; i < this.global_callbacks.length; i++) {
280
- this.global_callbacks[i](eventName, data);
281
- }
282
-
283
- // Event callbacks
284
- var callbacks = this.callbacks.get(eventName);
285
- if (callbacks) {
286
- for (var i = 0; i < callbacks.length; i++) {
287
- callbacks[i](data);
288
- }
289
- } else if (this.failThrough) {
290
- this.failThrough(eventName, data)
291
- }
292
-
293
- return this;
294
- };
295
-
296
- EventsDispatcher.prototype.bind_all = function(callback) {
297
- this.global_callbacks.push(callback);
298
- return this;
299
- };
300
-
301
- this.Pusher.EventsDispatcher = EventsDispatcher;
302
- }).call(this);
303
-
304
- ;(function() {
305
- var Pusher = this.Pusher;
306
-
307
- /*-----------------------------------------------
308
- Helpers:
309
- -----------------------------------------------*/
310
-
311
- function capitalize(str) {
312
- return str.substr(0, 1).toUpperCase() + str.substr(1);
313
- }
314
-
315
-
316
- function safeCall(method, obj, data) {
317
- if (obj[method] !== undefined) {
318
- obj[method](data);
319
- }
320
- }
321
-
322
- /*-----------------------------------------------
323
- The State Machine
324
- -----------------------------------------------*/
325
- function Machine(initialState, transitions, stateActions) {
326
- Pusher.EventsDispatcher.call(this);
327
-
328
- this.state = undefined;
329
- this.errors = [];
330
-
331
- // functions for each state
332
- this.stateActions = stateActions;
333
-
334
- // set up the transitions
335
- this.transitions = transitions;
336
-
337
- this.transition(initialState);
338
- };
339
-
340
- Machine.prototype.transition = function(nextState, data) {
341
- var prevState = this.state;
342
- var stateCallbacks = this.stateActions;
343
-
344
- if (prevState && (Pusher.Util.arrayIndexOf(this.transitions[prevState], nextState) == -1)) {
345
- this.emit('invalid_transition_attempt', {
346
- oldState: prevState,
347
- newState: nextState
348
- });
349
-
350
- throw new Error('Invalid transition [' + prevState + ' to ' + nextState + ']');
351
- }
352
-
353
- // exit
354
- safeCall(prevState + 'Exit', stateCallbacks, data);
355
-
356
- // tween
357
- safeCall(prevState + 'To' + capitalize(nextState), stateCallbacks, data);
358
-
359
- // pre
360
- safeCall(nextState + 'Pre', stateCallbacks, data);
361
-
362
- // change state:
363
- this.state = nextState;
364
-
365
- // handy to bind to
366
- this.emit('state_change', {
367
- oldState: prevState,
368
- newState: nextState
369
- });
370
-
371
- // Post:
372
- safeCall(nextState + 'Post', stateCallbacks, data);
373
- };
374
-
375
- Machine.prototype.is = function(state) {
376
- return this.state === state;
377
- };
378
-
379
- Machine.prototype.isNot = function(state) {
380
- return this.state !== state;
381
- };
382
-
383
- Pusher.Util.extend(Machine.prototype, Pusher.EventsDispatcher.prototype);
384
-
385
- this.Pusher.Machine = Machine;
386
- }).call(this);
387
-
388
- ;(function() {
389
- /*
390
- A little bauble to interface with window.navigator.onLine,
391
- window.ononline and window.onoffline. Easier to mock.
392
- */
393
-
394
- var NetInfo = function() {
395
- var self = this;
396
- Pusher.EventsDispatcher.call(this);
397
- // This is okay, as IE doesn't support this stuff anyway.
398
- if (window.addEventListener !== undefined) {
399
- window.addEventListener("online", function() {
400
- self.emit('online', null);
401
- }, false);
402
- window.addEventListener("offline", function() {
403
- self.emit('offline', null);
404
- }, false);
405
- }
406
- };
407
-
408
- // Offline means definitely offline (no connection to router).
409
- // Inverse does NOT mean definitely online (only currently supported in Safari
410
- // and even there only means the device has a connection to the router).
411
- NetInfo.prototype.isOnLine = function() {
412
- if (window.navigator.onLine === undefined) {
413
- return true;
414
- } else {
415
- return window.navigator.onLine;
416
- }
417
- };
418
-
419
- Pusher.Util.extend(NetInfo.prototype, Pusher.EventsDispatcher.prototype);
420
-
421
- this.Pusher.NetInfo = NetInfo;
422
- }).call(this);
423
-
424
- ;(function() {
425
- var Pusher = this.Pusher;
426
-
427
- var machineTransitions = {
428
- 'initialized': ['waiting', 'failed'],
429
- 'waiting': ['connecting', 'permanentlyClosed'],
430
- 'connecting': ['open', 'permanentlyClosing', 'impermanentlyClosing', 'waiting'],
431
- 'open': ['connected', 'permanentlyClosing', 'impermanentlyClosing', 'waiting'],
432
- 'connected': ['permanentlyClosing', 'waiting'],
433
- 'impermanentlyClosing': ['waiting', 'permanentlyClosing'],
434
- 'permanentlyClosing': ['permanentlyClosed'],
435
- 'permanentlyClosed': ['waiting', 'failed'],
436
- 'failed': ['permanentlyClosed']
437
- };
438
-
439
-
440
- var OPEN_TIMEOUT_INCREMENT = 2000;
441
- var CONNECTED_TIMEOUT_INCREMENT = 2000;
442
-
443
- var MAX_OPEN_TIMEOUT = 10000;
444
- var MAX_CONNECTED_TIMEOUT = 10000;
445
-
446
- function resetConnectionParameters(connection) {
447
- connection.connectionWait = 0;
448
-
449
- if (Pusher.TransportType === 'native') {
450
- connection.openTimeout = 4000;
451
- } else if (Pusher.TransportType === 'flash') {
452
- connection.openTimeout = 7000;
453
- } else { // SockJS
454
- connection.openTimeout = 6000;
455
- }
456
- connection.connectedTimeout = 2000;
457
- connection.connectionSecure = connection.compulsorySecure;
458
- connection.failedAttempts = 0;
459
- }
460
-
461
- function Connection(key, options) {
462
- var self = this;
463
-
464
- Pusher.EventsDispatcher.call(this);
465
-
466
- this.ping = true
467
- this.options = Pusher.Util.extend({encrypted: false}, options);
468
-
469
- this.netInfo = new Pusher.NetInfo();
470
-
471
- this.netInfo.bind('online', function(){
472
- if (self._machine.is('waiting')) {
473
- self._machine.transition('connecting');
474
- updateState('connecting');
475
- }
476
- });
477
-
478
- this.netInfo.bind('offline', function() {
479
- if (self._machine.is('connected')) {
480
- // These are for Chrome 15, which ends up
481
- // having two sockets hanging around.
482
- self.socket.onclose = undefined;
483
- self.socket.onmessage = undefined;
484
- self.socket.onerror = undefined;
485
- self.socket.onopen = undefined;
486
-
487
- self.socket.close();
488
- self.socket = undefined;
489
- self._machine.transition('waiting');
490
- }
491
- });
492
-
493
- // define the state machine that runs the connection
494
- this._machine = new Pusher.Machine('initialized', machineTransitions, {
495
- initializedPre: function() {
496
- self.compulsorySecure = self.options.encrypted;
497
-
498
- self.key = key;
499
- self.socket = null;
500
- self.socket_id = null;
501
-
502
- self.state = 'initialized';
503
- },
504
-
505
- waitingPre: function() {
506
- if (self.netInfo.isOnLine()) {
507
- if (self.failedAttempts < 2) {
508
- updateState('connecting');
509
- } else {
510
- updateState('unavailable');
511
- // Delay 10s between connection attempts on entering unavailable
512
- self.connectionWait = 10000;
513
- }
514
-
515
- if (self.connectionWait > 0) {
516
- self.emit('connecting_in', connectionDelay());
517
- }
518
-
519
- self._waitingTimer = setTimeout(function() {
520
- // Even when unavailable we try connecting (not changing state)
521
- self._machine.transition('connecting');
522
- }, connectionDelay());
523
- } else {
524
- updateState('unavailable');
525
- }
526
- },
527
-
528
- waitingExit: function() {
529
- clearTimeout(self._waitingTimer);
530
- },
531
-
532
- connectingPre: function() {
533
- // Case that a user manages to get to the connecting
534
- // state even when offline.
535
- if (self.netInfo.isOnLine() === false) {
536
- self._machine.transition('waiting');
537
- updateState('unavailable');
538
-
539
- return;
540
- }
541
-
542
- var path = connectPath(self.key);
543
- if (Pusher.TransportType === 'sockjs') {
544
- Pusher.debug('Connecting to sockjs', Pusher.sockjs);
545
- var url = buildSockJSURL(self.connectionSecure);
546
-
547
- self.ping = false
548
- self.socket = new SockJS(url);
549
- self.socket.onopen = function() {
550
- // SockJS does not yet support custom paths and query params
551
- self.socket.send(JSON.stringify({path: path}));
552
- self._machine.transition('open');
553
- }
554
- } else {
555
- var url = connectBaseURL(self.connectionSecure) + path;
556
- Pusher.debug('Connecting', url);
557
- self.socket = new Pusher.Transport(url);
558
- self.socket.onopen = function() {
559
- self._machine.transition('open');
560
- }
561
- }
562
-
563
- self.socket.onclose = transitionToWaiting;
564
- self.socket.onerror = ws_onError;
565
-
566
- // allow time to get ws_onOpen, otherwise close socket and try again
567
- self._connectingTimer = setTimeout(TransitionToImpermanentlyClosing, self.openTimeout);
568
- },
569
-
570
- connectingExit: function() {
571
- clearTimeout(self._connectingTimer);
572
- self.socket.onopen = undefined; // unbind to avoid open events that are no longer relevant
573
- },
574
-
575
- connectingToWaiting: function() {
576
- updateConnectionParameters();
577
-
578
- // FUTURE: update only ssl
579
- },
580
-
581
- connectingToImpermanentlyClosing: function() {
582
- updateConnectionParameters();
583
-
584
- // FUTURE: update only timeout
585
- },
586
-
587
- openPre: function() {
588
- self.socket.onmessage = ws_onMessageOpen;
589
- self.socket.onerror = ws_onError;
590
- self.socket.onclose = transitionToWaiting;
591
-
592
- // allow time to get connected-to-Pusher message, otherwise close socket, try again
593
- self._openTimer = setTimeout(TransitionToImpermanentlyClosing, self.connectedTimeout);
594
- },
595
-
596
- openExit: function() {
597
- clearTimeout(self._openTimer);
598
- self.socket.onmessage = undefined; // unbind to avoid messages that are no longer relevant
599
- },
600
-
601
- openToWaiting: function() {
602
- updateConnectionParameters();
603
- },
604
-
605
- openToImpermanentlyClosing: function() {
606
- updateConnectionParameters();
607
- },
608
-
609
- connectedPre: function(socket_id) {
610
- self.socket_id = socket_id;
611
-
612
- self.socket.onmessage = ws_onMessageConnected;
613
- self.socket.onerror = ws_onError;
614
- self.socket.onclose = transitionToWaiting;
615
-
616
- resetConnectionParameters(self);
617
- self.connectedAt = new Date().getTime();
618
-
619
- resetActivityCheck();
620
- },
621
-
622
- connectedPost: function() {
623
- updateState('connected');
624
- },
625
-
626
- connectedExit: function() {
627
- stopActivityCheck();
628
- updateState('disconnected');
629
- },
630
-
631
- impermanentlyClosingPost: function() {
632
- if (self.socket) {
633
- self.socket.onclose = transitionToWaiting;
634
- self.socket.close();
635
- }
636
- },
637
-
638
- permanentlyClosingPost: function() {
639
- if (self.socket) {
640
- self.socket.onclose = function() {
641
- resetConnectionParameters(self);
642
- self._machine.transition('permanentlyClosed');
643
- };
644
-
645
- self.socket.close();
646
- } else {
647
- resetConnectionParameters(self);
648
- self._machine.transition('permanentlyClosed');
649
- }
650
- },
651
-
652
- failedPre: function() {
653
- updateState('failed');
654
- Pusher.debug('WebSockets are not available in this browser.');
655
- },
656
-
657
- permanentlyClosedPost: function() {
658
- updateState('disconnected');
659
- }
660
- });
661
-
662
- /*-----------------------------------------------
663
- -----------------------------------------------*/
664
-
665
- function updateConnectionParameters() {
666
- if (self.openTimeout < MAX_OPEN_TIMEOUT) {
667
- self.openTimeout += OPEN_TIMEOUT_INCREMENT;
668
- }
669
-
670
- if (self.connectedTimeout < MAX_CONNECTED_TIMEOUT) {
671
- self.connectedTimeout += CONNECTED_TIMEOUT_INCREMENT;
672
- }
673
-
674
- // Toggle between ws & wss
675
- if (self.compulsorySecure !== true) {
676
- self.connectionSecure = !self.connectionSecure;
677
- }
678
-
679
- self.failedAttempts++;
680
- }
681
-
682
- function connectBaseURL(isSecure) {
683
- // Always connect with SSL if the current page served over https
684
- var ssl = (isSecure || document.location.protocol === 'https:');
685
- var port = ssl ? Pusher.wss_port : Pusher.ws_port;
686
- var scheme = ssl ? 'wss://' : 'ws://';
687
-
688
- return scheme + Pusher.host + ':' + port;
689
- }
690
-
691
- function connectPath(key) {
692
- var flash = (Pusher.TransportType === "flash") ? "true" : "false";
693
- var path = '/app/' + key + '?protocol=5&client=js'
694
- + '&version=' + Pusher.VERSION
695
- + '&flash=' + flash;
696
- return path;
697
- }
698
-
699
- function buildSockJSURL(isSecure) {
700
- var ssl = (isSecure || document.location.protocol === 'https:');
701
- var port = ssl ? Pusher.sockjs_https_port : Pusher.sockjs_http_port;
702
- var scheme = ssl ? 'https://' : 'http://';
703
-
704
- return scheme + Pusher.sockjs_host + ':' + port + Pusher.sockjs_path;
705
- }
706
-
707
- // callback for close and retry. Used on timeouts.
708
- function TransitionToImpermanentlyClosing() {
709
- self._machine.transition('impermanentlyClosing');
710
- }
711
-
712
- function resetActivityCheck() {
713
- if (self._activityTimer) { clearTimeout(self._activityTimer); }
714
- // Send ping after inactivity
715
- if (self.ping) {
716
- self._activityTimer = setTimeout(function() {
717
- self.send_event('pusher:ping', {})
718
- // Wait for pong response
719
- self._activityTimer = setTimeout(function() {
720
- self.socket.close();
721
- }, (self.options.pong_timeout || Pusher.pong_timeout))
722
- }, (self.options.activity_timeout || Pusher.activity_timeout))
723
- }
724
- }
725
-
726
- function stopActivityCheck() {
727
- if (self._activityTimer) { clearTimeout(self._activityTimer); }
728
- }
729
-
730
- // Returns the delay before the next connection attempt should be made
731
- //
732
- // This function guards against attempting to connect more frequently than
733
- // once every second
734
- //
735
- function connectionDelay() {
736
- var delay = self.connectionWait;
737
- if (delay === 0) {
738
- if (self.connectedAt) {
739
- var t = 1000;
740
- var connectedFor = new Date().getTime() - self.connectedAt;
741
- if (connectedFor < t) {
742
- delay = t - connectedFor;
743
- }
744
- }
745
- }
746
- return delay;
747
- }
748
-
749
- /*-----------------------------------------------
750
- WebSocket Callbacks
751
- -----------------------------------------------*/
752
-
753
- function handleCloseCode(code, message) {
754
- // first inform the end-developer of this error
755
- self.emit('error', {type: 'PusherError', data: {code: code, message: message}});
756
-
757
- if (code === 4000) {
758
- // SSL only app
759
- self.compulsorySecure = true;
760
- self.connectionSecure = true;
761
- self.options.encrypted = true;
762
-
763
- TransitionToImpermanentlyClosing();
764
- } else if (code < 4100) {
765
- // Permentently close connection
766
- self._machine.transition('permanentlyClosing')
767
- } else if (code < 4200) {
768
- // Backoff before reconnecting
769
- self.connectionWait = 1000;
770
- self._machine.transition('waiting')
771
- } else if (code < 4300) {
772
- // Reconnect immediately
773
- TransitionToImpermanentlyClosing();
774
- } else {
775
- // Unknown error
776
- self._machine.transition('permanentlyClosing')
777
- }
778
- }
779
-
780
- function ws_onMessageOpen(event) {
781
- var params = parseWebSocketEvent(event);
782
- if (params !== undefined) {
783
- if (params.event === 'pusher:connection_established') {
784
- self._machine.transition('connected', params.data.socket_id);
785
- } else if (params.event === 'pusher:error') {
786
- handleCloseCode(params.data.code, params.data.message)
787
- }
788
- }
789
- }
790
-
791
- function ws_onMessageConnected(event) {
792
- resetActivityCheck();
793
-
794
- var params = parseWebSocketEvent(event);
795
- if (params !== undefined) {
796
- Pusher.debug('Event recd', params);
797
-
798
- switch (params.event) {
799
- case 'pusher:error':
800
- self.emit('error', {type: 'PusherError', data: params.data});
801
- break;
802
- case 'pusher:ping':
803
- self.send_event('pusher:pong', {})
804
- break;
805
- }
806
-
807
- self.emit('message', params);
808
- }
809
- }
810
-
811
-
812
- /**
813
- * Parses an event from the WebSocket to get
814
- * the JSON payload that we require
815
- *
816
- * @param {MessageEvent} event The event from the WebSocket.onmessage handler.
817
- **/
818
- function parseWebSocketEvent(event) {
819
- try {
820
- var params = JSON.parse(event.data);
821
-
822
- if (typeof params.data === 'string') {
823
- try {
824
- params.data = JSON.parse(params.data);
825
- } catch (e) {
826
- if (!(e instanceof SyntaxError)) {
827
- throw e;
828
- }
829
- }
830
- }
831
-
832
- return params;
833
- } catch (e) {
834
- self.emit('error', {type: 'MessageParseError', error: e, data: event.data});
835
- }
836
- }
837
-
838
- function transitionToWaiting() {
839
- self._machine.transition('waiting');
840
- }
841
-
842
- function ws_onError(error) {
843
- // just emit error to user - socket will already be closed by browser
844
- self.emit('error', { type: 'WebSocketError', error: error });
845
- }
846
-
847
- // Updates the public state information exposed by connection
848
- //
849
- // This is distinct from the internal state information used by _machine
850
- // to manage the connection
851
- //
852
- function updateState(newState, data) {
853
- var prevState = self.state;
854
- self.state = newState;
855
-
856
- // Only emit when the state changes
857
- if (prevState !== newState) {
858
- Pusher.debug('State changed', prevState + ' -> ' + newState);
859
- self.emit('state_change', {previous: prevState, current: newState});
860
- self.emit(newState, data);
861
- }
862
- }
863
- };
864
-
865
- Connection.prototype.connect = function() {
866
- // no WebSockets
867
- if (!this._machine.is('failed') && !Pusher.Transport) {
868
- this._machine.transition('failed');
869
- }
870
- // initial open of connection
871
- else if(this._machine.is('initialized')) {
872
- resetConnectionParameters(this);
873
- this._machine.transition('waiting');
874
- }
875
- // user skipping connection wait
876
- else if (this._machine.is('waiting') && this.netInfo.isOnLine() === true) {
877
- this._machine.transition('connecting');
878
- }
879
- // user re-opening connection after closing it
880
- else if(this._machine.is("permanentlyClosed")) {
881
- resetConnectionParameters(this);
882
- this._machine.transition('waiting');
883
- }
884
- };
885
-
886
- Connection.prototype.send = function(data) {
887
- if (this._machine.is('connected')) {
888
- // Workaround for MobileSafari bug (see https://gist.github.com/2052006)
889
- var self = this;
890
- setTimeout(function() {
891
- self.socket.send(data);
892
- }, 0);
893
- return true;
894
- } else {
895
- return false;
896
- }
897
- };
898
-
899
- Connection.prototype.send_event = function(event_name, data, channel) {
900
- var payload = {
901
- event: event_name,
902
- data: data
903
- };
904
- if (channel) payload['channel'] = channel;
905
-
906
- Pusher.debug('Event sent', payload);
907
- return this.send(JSON.stringify(payload));
908
- }
909
-
910
- Connection.prototype.disconnect = function() {
911
- if (this._machine.is('permanentlyClosed')) return;
912
-
913
- if (this._machine.is('waiting') || this._machine.is('failed')) {
914
- this._machine.transition('permanentlyClosed');
915
- } else {
916
- this._machine.transition('permanentlyClosing');
917
- }
918
- };
919
-
920
- Pusher.Util.extend(Connection.prototype, Pusher.EventsDispatcher.prototype);
921
- this.Pusher.Connection = Connection;
922
- }).call(this);
923
-
924
- ;(function() {
925
- Pusher.Channels = function() {
926
- this.channels = {};
927
- };
928
-
929
- Pusher.Channels.prototype = {
930
- add: function(channel_name, pusher) {
931
- var existing_channel = this.find(channel_name);
932
- if (!existing_channel) {
933
- var channel = Pusher.Channel.factory(channel_name, pusher);
934
- this.channels[channel_name] = channel;
935
- return channel;
936
- } else {
937
- return existing_channel;
938
- }
939
- },
940
-
941
- find: function(channel_name) {
942
- return this.channels[channel_name];
943
- },
944
-
945
- remove: function(channel_name) {
946
- delete this.channels[channel_name];
947
- },
948
-
949
- disconnect: function () {
950
- for(var channel_name in this.channels){
951
- this.channels[channel_name].disconnect()
952
- }
953
- }
954
- };
955
-
956
- Pusher.Channel = function(channel_name, pusher) {
957
- var self = this;
958
- Pusher.EventsDispatcher.call(this, function(event_name, event_data) {
959
- Pusher.debug('No callbacks on ' + channel_name + ' for ' + event_name);
960
- });
961
-
962
- this.pusher = pusher;
963
- this.name = channel_name;
964
- this.subscribed = false;
965
-
966
- this.bind('pusher_internal:subscription_succeeded', function(data) {
967
- self.onSubscriptionSucceeded(data);
968
- });
969
- };
970
-
971
- Pusher.Channel.prototype = {
972
- // inheritable constructor
973
- init: function() {},
974
- disconnect: function() {
975
- this.subscribed = false;
976
- this.emit("pusher_internal:disconnected");
977
- },
978
-
979
- onSubscriptionSucceeded: function(data) {
980
- this.subscribed = true;
981
- this.emit('pusher:subscription_succeeded');
982
- },
983
-
984
- authorize: function(socketId, options, callback){
985
- return callback(false, {}); // normal channels don't require auth
986
- },
987
-
988
- trigger: function(event, data) {
989
- return this.pusher.send_event(event, data, this.name);
990
- }
991
- };
992
-
993
- Pusher.Util.extend(Pusher.Channel.prototype, Pusher.EventsDispatcher.prototype);
994
-
995
- Pusher.Channel.PrivateChannel = {
996
- authorize: function(socketId, options, callback){
997
- var self = this;
998
- var authorizer = new Pusher.Channel.Authorizer(this, Pusher.channel_auth_transport, options);
999
- return authorizer.authorize(socketId, function(err, authData) {
1000
- if(!err) {
1001
- self.emit('pusher_internal:authorized', authData);
1002
- }
1003
-
1004
- callback(err, authData);
1005
- });
1006
- }
1007
- };
1008
-
1009
- Pusher.Channel.PresenceChannel = {
1010
- init: function(){
1011
- this.members = new Members(this); // leeches off channel events
1012
- },
1013
-
1014
- onSubscriptionSucceeded: function(data) {
1015
- this.subscribed = true;
1016
- // We override this because we want the Members obj to be responsible for
1017
- // emitting the pusher:subscription_succeeded. It will do this after it has done its work.
1018
- }
1019
- };
1020
-
1021
- var Members = function(channel) {
1022
- var self = this;
1023
- var channelData = null;
1024
-
1025
- var reset = function() {
1026
- self._members_map = {};
1027
- self.count = 0;
1028
- self.me = null;
1029
- channelData = null;
1030
- };
1031
- reset();
1032
-
1033
- var subscriptionSucceeded = function(subscriptionData) {
1034
- self._members_map = subscriptionData.presence.hash;
1035
- self.count = subscriptionData.presence.count;
1036
- self.me = self.get(channelData.user_id);
1037
- channel.emit('pusher:subscription_succeeded', self);
1038
- };
1039
-
1040
- channel.bind('pusher_internal:authorized', function(authorizedData) {
1041
- channelData = JSON.parse(authorizedData.channel_data);
1042
- channel.bind("pusher_internal:subscription_succeeded", subscriptionSucceeded);
1043
- });
1044
-
1045
- channel.bind('pusher_internal:member_added', function(data) {
1046
- if(self.get(data.user_id) === null) { // only incr if user_id does not already exist
1047
- self.count++;
1048
- }
1049
-
1050
- self._members_map[data.user_id] = data.user_info;
1051
- channel.emit('pusher:member_added', self.get(data.user_id));
1052
- });
1053
-
1054
- channel.bind('pusher_internal:member_removed', function(data) {
1055
- var member = self.get(data.user_id);
1056
- if(member) {
1057
- delete self._members_map[data.user_id];
1058
- self.count--;
1059
- channel.emit('pusher:member_removed', member);
1060
- }
1061
- });
1062
-
1063
- channel.bind('pusher_internal:disconnected', function() {
1064
- reset();
1065
- channel.unbind("pusher_internal:subscription_succeeded", subscriptionSucceeded);
1066
- });
1067
- };
1068
-
1069
- Members.prototype = {
1070
- each: function(callback) {
1071
- for(var i in this._members_map) {
1072
- callback(this.get(i));
1073
- }
1074
- },
1075
-
1076
- get: function(user_id) {
1077
- if (this._members_map.hasOwnProperty(user_id)) { // have heard of this user user_id
1078
- return {
1079
- id: user_id,
1080
- info: this._members_map[user_id]
1081
- }
1082
- } else { // have never heard of this user
1083
- return null;
1084
- }
1085
- }
1086
- };
1087
-
1088
- Pusher.Channel.factory = function(channel_name, pusher){
1089
- var channel = new Pusher.Channel(channel_name, pusher);
1090
- if (channel_name.indexOf('private-') === 0) {
1091
- Pusher.Util.extend(channel, Pusher.Channel.PrivateChannel);
1092
- } else if (channel_name.indexOf('presence-') === 0) {
1093
- Pusher.Util.extend(channel, Pusher.Channel.PrivateChannel);
1094
- Pusher.Util.extend(channel, Pusher.Channel.PresenceChannel);
1095
- };
1096
- channel.init();
1097
- return channel;
1098
- };
1099
- }).call(this);
1100
-
1101
- ;(function() {
1102
- Pusher.Channel.Authorizer = function(channel, type, options) {
1103
- this.channel = channel;
1104
- this.type = type;
1105
-
1106
- this.authOptions = (options || {}).auth || {};
1107
- };
1108
-
1109
- Pusher.Channel.Authorizer.prototype = {
1110
- composeQuery: function(socketId) {
1111
- var query = '&socket_id=' + encodeURIComponent(socketId)
1112
- + '&channel_name=' + encodeURIComponent(this.channel.name);
1113
-
1114
- for(var i in this.authOptions.params) {
1115
- query += "&" + encodeURIComponent(i) + "=" + encodeURIComponent(this.authOptions.params[i]);
1116
- }
1117
-
1118
- return query;
1119
- },
1120
-
1121
- authorize: function(socketId, callback) {
1122
- return Pusher.authorizers[this.type].call(this, socketId, callback);
1123
- }
1124
- };
1125
-
1126
-
1127
- Pusher.auth_callbacks = {};
1128
- Pusher.authorizers = {
1129
- ajax: function(socketId, callback){
1130
- var self = this, xhr;
1131
-
1132
- if (Pusher.XHR) {
1133
- xhr = new Pusher.XHR();
1134
- } else {
1135
- xhr = (window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));
1136
- }
1137
-
1138
- xhr.open("POST", Pusher.channel_auth_endpoint, true);
1139
-
1140
- // add request headers
1141
- xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
1142
- for(var headerName in this.authOptions.headers) {
1143
- xhr.setRequestHeader(headerName, this.authOptions.headers[headerName]);
1144
- }
1145
-
1146
- xhr.onreadystatechange = function() {
1147
- if (xhr.readyState == 4) {
1148
- if (xhr.status == 200) {
1149
- var data, parsed = false;
1150
-
1151
- try {
1152
- data = JSON.parse(xhr.responseText);
1153
- parsed = true;
1154
- } catch (e) {
1155
- callback(true, 'JSON returned from webapp was invalid, yet status code was 200. Data was: ' + xhr.responseText);
1156
- }
1157
-
1158
- if (parsed) { // prevents double execution.
1159
- callback(false, data);
1160
- }
1161
- } else {
1162
- Pusher.warn("Couldn't get auth info from your webapp", xhr.status);
1163
- callback(true, xhr.status);
1164
- }
1165
- }
1166
- };
1167
-
1168
- xhr.send(this.composeQuery(socketId));
1169
- return xhr;
1170
- },
1171
-
1172
- jsonp: function(socketId, callback){
1173
- if(this.authOptions.headers !== undefined) {
1174
- Pusher.warn("Warn", "To send headers with the auth request, you must use AJAX, rather than JSONP.");
1175
- }
1176
-
1177
- var script = document.createElement("script");
1178
- // Hacked wrapper.
1179
- Pusher.auth_callbacks[this.channel.name] = function(data) {
1180
- callback(false, data);
1181
- };
1182
-
1183
- var callback_name = "Pusher.auth_callbacks['" + this.channel.name + "']";
1184
- script.src = Pusher.channel_auth_endpoint
1185
- + '?callback='
1186
- + encodeURIComponent(callback_name)
1187
- + this.composeQuery(socketId);
1188
-
1189
- var head = document.getElementsByTagName("head")[0] || document.documentElement;
1190
- head.insertBefore( script, head.firstChild );
1191
- }
1192
- };
1193
- }).call(this);
1194
- // _require(dependencies, callback) takes an array of dependency urls and a
1195
- // callback to call when all the dependecies have finished loading
1196
- var _require = (function() {
1197
- function handleScriptLoaded(elem, callback) {
1198
- if (document.addEventListener) {
1199
- elem.addEventListener('load', callback, false);
1200
- } else {
1201
- elem.attachEvent('onreadystatechange', function () {
1202
- if (elem.readyState == 'loaded' || elem.readyState == 'complete') {
1203
- callback();
1204
- }
1205
- });
1206
- }
1207
- }
1208
-
1209
- function addScript(src, callback) {
1210
- var head = document.getElementsByTagName('head')[0];
1211
- var script = document.createElement('script');
1212
- script.setAttribute('src', src);
1213
- script.setAttribute("type","text/javascript");
1214
- script.setAttribute('async', true);
1215
-
1216
- handleScriptLoaded(script, function() {
1217
- callback();
1218
- });
1219
-
1220
- head.appendChild(script);
1221
- }
1222
-
1223
- return function(deps, callback) {
1224
- var deps_loaded = 0;
1225
- for (var i = 0; i < deps.length; i++) {
1226
- addScript(deps[i], function() {
1227
- if (deps.length == ++deps_loaded) {
1228
- // This setTimeout is a workaround for an Opera issue
1229
- setTimeout(callback, 0);
1230
- }
1231
- });
1232
- }
1233
- }
1234
- })();
1235
-
1236
- ;(function() {
1237
- // Support Firefox versions which prefix WebSocket
1238
- if (!window['WebSocket'] && window['MozWebSocket']) {
1239
- window['WebSocket'] = window['MozWebSocket']
1240
- }
1241
-
1242
- if (window['WebSocket']) {
1243
- Pusher.Transport = window['WebSocket'];
1244
- Pusher.TransportType = 'native';
1245
- }
1246
-
1247
- var cdn = (document.location.protocol == 'http:') ? Pusher.cdn_http : Pusher.cdn_https;
1248
- var root = cdn + Pusher.VERSION;
1249
- var deps = [];
1250
-
1251
- if (!window['JSON']) {
1252
- deps.push(root + '/json2' + Pusher.dependency_suffix + '.js');
1253
- }
1254
- if (!window['WebSocket']) {
1255
- var flashSupported;
1256
- try {
1257
- flashSupported = Boolean(new ActiveXObject('ShockwaveFlash.ShockwaveFlash'));
1258
- } catch (e) {
1259
- flashSupported = navigator.mimeTypes["application/x-shockwave-flash"] !== undefined;
1260
- }
1261
-
1262
- if (flashSupported) {
1263
- // Try to use web-socket-js (flash WebSocket emulation)
1264
- window.WEB_SOCKET_DISABLE_AUTO_INITIALIZATION = true;
1265
- window.WEB_SOCKET_SUPPRESS_CROSS_DOMAIN_SWF_ERROR = true;
1266
- deps.push(root + '/flashfallback' + Pusher.dependency_suffix + '.js');
1267
- } else {
1268
- // Use SockJS when Flash is not available
1269
- deps.push(root + '/sockjs' + Pusher.dependency_suffix + '.js');
1270
- }
1271
- }
1272
-
1273
- var initialize = function() {
1274
- if (window['WebSocket']) {
1275
- // Initialize function in the case that we have native WebSocket support
1276
- return function() {
1277
- Pusher.ready();
1278
- }
1279
- } else {
1280
- // Initialize function for fallback case
1281
- return function() {
1282
- if (window['WebSocket']) {
1283
- // window['WebSocket'] is a flash emulation of WebSocket
1284
- Pusher.Transport = window['WebSocket'];
1285
- Pusher.TransportType = 'flash';
1286
-
1287
- window.WEB_SOCKET_SWF_LOCATION = root + "/WebSocketMain.swf";
1288
- WebSocket.__addTask(function() {
1289
- Pusher.ready();
1290
- })
1291
- WebSocket.__initialize();
1292
- } else {
1293
- // Flash fallback was not loaded, using SockJS
1294
- Pusher.Transport = window.SockJS;
1295
- Pusher.TransportType = 'sockjs';
1296
- Pusher.ready();
1297
- }
1298
- }
1299
- }
1300
- }();
1301
-
1302
- // Allows calling a function when the document body is available
1303
- var ondocumentbody = function(callback) {
1304
- var load_body = function() {
1305
- document.body ? callback() : setTimeout(load_body, 0);
1306
- }
1307
- load_body();
1308
- };
1309
-
1310
- var initializeOnDocumentBody = function() {
1311
- ondocumentbody(initialize);
1312
- }
1313
-
1314
- if (deps.length > 0) {
1315
- _require(deps, initializeOnDocumentBody);
1316
- } else {
1317
- initializeOnDocumentBody();
1318
- }
1319
- })();