websocket-rails-js 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/Gemfile +11 -0
  4. data/Guardfile +6 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +13 -0
  7. data/Rakefile +36 -0
  8. data/app/assets/javascripts/websocket_rails/abstract_connection.js.coffee +45 -0
  9. data/app/assets/javascripts/websocket_rails/channel.js.coffee +66 -0
  10. data/app/assets/javascripts/websocket_rails/connection.js.coffee +62 -0
  11. data/app/assets/javascripts/websocket_rails/event.js.coffee +43 -0
  12. data/app/assets/javascripts/websocket_rails/http_connection.js.coffee +56 -0
  13. data/app/assets/javascripts/websocket_rails/main.js +6 -0
  14. data/app/assets/javascripts/websocket_rails/websocket_connection.js.coffee +29 -0
  15. data/app/assets/javascripts/websocket_rails/websocket_rails.js.coffee +148 -0
  16. data/lib/websocket-rails-js.rb +1 -0
  17. data/lib/websocket_rails/js/engine.rb +8 -0
  18. data/lib/websocket_rails/js/version.rb +5 -0
  19. data/spec/javascripts/helpers/.gitkeep +0 -0
  20. data/spec/javascripts/helpers/helpers.coffee +7 -0
  21. data/spec/javascripts/support/jasmine.yml +139 -0
  22. data/spec/javascripts/support/jasmine_helper.rb +15 -0
  23. data/spec/javascripts/support/jquery.min.js +4 -0
  24. data/spec/javascripts/support/sinon-1.7.1.js +4343 -0
  25. data/spec/javascripts/websocket_rails/channel_spec.js.coffee +99 -0
  26. data/spec/javascripts/websocket_rails/connection_spec.js.coffee +136 -0
  27. data/spec/javascripts/websocket_rails/event_spec.js.coffee +70 -0
  28. data/spec/javascripts/websocket_rails/helpers.js.coffee +7 -0
  29. data/spec/javascripts/websocket_rails/websocket_rails_spec.js.coffee +233 -0
  30. data/src/websocket_rails/abstract_connection.js +71 -0
  31. data/src/websocket_rails/channel.js +133 -0
  32. data/src/websocket_rails/connection.js +91 -0
  33. data/src/websocket_rails/event.js +66 -0
  34. data/src/websocket_rails/http_connection.js +97 -0
  35. data/src/websocket_rails/websocket_connection.js +59 -0
  36. data/src/websocket_rails/websocket_rails.js +218 -0
  37. data/websocket-rails-js.gemspec +25 -0
  38. data/websocket_rails.0.0.1.min.js +1 -0
  39. metadata +135 -0
@@ -0,0 +1,71 @@
1
+
2
+ /*
3
+ Abstract Interface for the WebSocketRails client.
4
+ */
5
+
6
+ (function() {
7
+ WebSocketRails.AbstractConnection = (function() {
8
+ function AbstractConnection(url, dispatcher) {
9
+ this.dispatcher = dispatcher;
10
+ this.message_queue = [];
11
+ }
12
+
13
+ AbstractConnection.prototype.close = function() {};
14
+
15
+ AbstractConnection.prototype.trigger = function(event) {
16
+ if (this.dispatcher.state !== 'connected') {
17
+ return this.message_queue.push(event);
18
+ } else {
19
+ return this.send_event(event);
20
+ }
21
+ };
22
+
23
+ AbstractConnection.prototype.send_event = function(event) {
24
+ if (this.connection_id != null) {
25
+ return event.connection_id = this.connection_id;
26
+ }
27
+ };
28
+
29
+ AbstractConnection.prototype.on_close = function(event) {
30
+ var close_event;
31
+ if (this.dispatcher && this.dispatcher._conn === this) {
32
+ close_event = new WebSocketRails.Event(['connection_closed', event]);
33
+ this.dispatcher.state = 'disconnected';
34
+ return this.dispatcher.dispatch(close_event);
35
+ }
36
+ };
37
+
38
+ AbstractConnection.prototype.on_error = function(event) {
39
+ var error_event;
40
+ if (this.dispatcher && this.dispatcher._conn === this) {
41
+ error_event = new WebSocketRails.Event(['connection_error', event]);
42
+ this.dispatcher.state = 'disconnected';
43
+ return this.dispatcher.dispatch(error_event);
44
+ }
45
+ };
46
+
47
+ AbstractConnection.prototype.on_message = function(event_data) {
48
+ if (this.dispatcher && this.dispatcher._conn === this) {
49
+ return this.dispatcher.new_message(event_data);
50
+ }
51
+ };
52
+
53
+ AbstractConnection.prototype.setConnectionId = function(connection_id) {
54
+ this.connection_id = connection_id;
55
+ };
56
+
57
+ AbstractConnection.prototype.flush_queue = function() {
58
+ var event, _i, _len, _ref;
59
+ _ref = this.message_queue;
60
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
61
+ event = _ref[_i];
62
+ this.trigger(event);
63
+ }
64
+ return this.message_queue = [];
65
+ };
66
+
67
+ return AbstractConnection;
68
+
69
+ })();
70
+
71
+ }).call(this);
@@ -0,0 +1,133 @@
1
+
2
+ /*
3
+ The channel object is returned when you subscribe to a channel.
4
+
5
+ For instance:
6
+ var dispatcher = new WebSocketRails('localhost:3000/websocket');
7
+ var awesome_channel = dispatcher.subscribe('awesome_channel');
8
+ awesome_channel.bind('event', function(data) { console.log('channel event!'); });
9
+ awesome_channel.trigger('awesome_event', awesome_object);
10
+ */
11
+
12
+ (function() {
13
+ var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
14
+
15
+ WebSocketRails.Channel = (function() {
16
+ function Channel(name, _dispatcher, is_private, on_success, on_failure) {
17
+ var event, event_name, _ref;
18
+ this.name = name;
19
+ this._dispatcher = _dispatcher;
20
+ this.is_private = is_private;
21
+ this.on_success = on_success;
22
+ this.on_failure = on_failure;
23
+ this._failure_launcher = __bind(this._failure_launcher, this);
24
+ this._success_launcher = __bind(this._success_launcher, this);
25
+ if (this.is_private) {
26
+ event_name = 'websocket_rails.subscribe_private';
27
+ } else {
28
+ event_name = 'websocket_rails.subscribe';
29
+ }
30
+ this.connection_id = (_ref = this._dispatcher._conn) != null ? _ref.connection_id : void 0;
31
+ event = new WebSocketRails.Event([
32
+ event_name, {
33
+ channel: this.name
34
+ }, {
35
+ connection_id: this.connection_id
36
+ }
37
+ ], this._success_launcher, this._failure_launcher);
38
+ this._dispatcher.trigger_event(event);
39
+ this._callbacks = {};
40
+ this._token = void 0;
41
+ this._queue = [];
42
+ }
43
+
44
+ Channel.prototype.is_public = function() {
45
+ return !this.is_private;
46
+ };
47
+
48
+ Channel.prototype.destroy = function() {
49
+ var event, event_name, _ref;
50
+ if (this.connection_id === ((_ref = this._dispatcher._conn) != null ? _ref.connection_id : void 0)) {
51
+ event_name = 'websocket_rails.unsubscribe';
52
+ event = new WebSocketRails.Event([
53
+ event_name, {
54
+ channel: this.name
55
+ }, {
56
+ connection_id: this.connection_id,
57
+ token: this._token
58
+ }
59
+ ]);
60
+ this._dispatcher.trigger_event(event);
61
+ }
62
+ return this._callbacks = {};
63
+ };
64
+
65
+ Channel.prototype.bind = function(event_name, callback) {
66
+ var _base;
67
+ if ((_base = this._callbacks)[event_name] == null) {
68
+ _base[event_name] = [];
69
+ }
70
+ return this._callbacks[event_name].push(callback);
71
+ };
72
+
73
+ Channel.prototype.unbind = function(event_name) {
74
+ return delete this._callbacks[event_name];
75
+ };
76
+
77
+ Channel.prototype.trigger = function(event_name, message) {
78
+ var event;
79
+ event = new WebSocketRails.Event([
80
+ event_name, message, {
81
+ connection_id: this.connection_id,
82
+ channel: this.name,
83
+ token: this._token
84
+ }
85
+ ]);
86
+ if (!this._token) {
87
+ return this._queue.push(event);
88
+ } else {
89
+ return this._dispatcher.trigger_event(event);
90
+ }
91
+ };
92
+
93
+ Channel.prototype.dispatch = function(event_name, message) {
94
+ var callback, event, _i, _j, _len, _len1, _ref, _ref1, _results;
95
+ if (event_name === 'websocket_rails.channel_token') {
96
+ this._token = message['token'];
97
+ _ref = this._queue;
98
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
99
+ event = _ref[_i];
100
+ this._dispatcher.trigger_event(event);
101
+ }
102
+ return this._queue = [];
103
+ } else {
104
+ if (this._callbacks[event_name] == null) {
105
+ return;
106
+ }
107
+ _ref1 = this._callbacks[event_name];
108
+ _results = [];
109
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
110
+ callback = _ref1[_j];
111
+ _results.push(callback(message));
112
+ }
113
+ return _results;
114
+ }
115
+ };
116
+
117
+ Channel.prototype._success_launcher = function(data) {
118
+ if (this.on_success != null) {
119
+ return this.on_success(data);
120
+ }
121
+ };
122
+
123
+ Channel.prototype._failure_launcher = function(data) {
124
+ if (this.on_failure != null) {
125
+ return this.on_failure(data);
126
+ }
127
+ };
128
+
129
+ return Channel;
130
+
131
+ })();
132
+
133
+ }).call(this);
@@ -0,0 +1,91 @@
1
+
2
+ /*
3
+ WebSocket Interface for the WebSocketRails client.
4
+ */
5
+
6
+ (function() {
7
+ WebSocketRails.Connection = (function() {
8
+ function Connection(url, dispatcher) {
9
+ this.url = url;
10
+ this.dispatcher = dispatcher;
11
+ this.message_queue = [];
12
+ this.state = 'connecting';
13
+ this.connection_id;
14
+ if (!(this.url.match(/^wss?:\/\//) || this.url.match(/^ws?:\/\//))) {
15
+ if (window.location.protocol === 'https:') {
16
+ this.url = "wss://" + this.url;
17
+ } else {
18
+ this.url = "ws://" + this.url;
19
+ }
20
+ }
21
+ this._conn = new WebSocket(this.url);
22
+ this._conn.onmessage = (function(_this) {
23
+ return function(event) {
24
+ var event_data;
25
+ event_data = JSON.parse(event.data);
26
+ return _this.on_message(event_data);
27
+ };
28
+ })(this);
29
+ this._conn.onclose = (function(_this) {
30
+ return function(event) {
31
+ return _this.on_close(event);
32
+ };
33
+ })(this);
34
+ this._conn.onerror = (function(_this) {
35
+ return function(event) {
36
+ return _this.on_error(event);
37
+ };
38
+ })(this);
39
+ }
40
+
41
+ Connection.prototype.on_message = function(event) {
42
+ return this.dispatcher.new_message(event);
43
+ };
44
+
45
+ Connection.prototype.on_close = function(event) {
46
+ var data;
47
+ this.dispatcher.state = 'disconnected';
48
+ data = (event != null ? event.data : void 0) ? event.data : event;
49
+ return this.dispatcher.dispatch(new WebSocketRails.Event(['connection_closed', data]));
50
+ };
51
+
52
+ Connection.prototype.on_error = function(event) {
53
+ this.dispatcher.state = 'disconnected';
54
+ return this.dispatcher.dispatch(new WebSocketRails.Event(['connection_error', event.data]));
55
+ };
56
+
57
+ Connection.prototype.trigger = function(event) {
58
+ if (this.dispatcher.state !== 'connected') {
59
+ return this.message_queue.push(event);
60
+ } else {
61
+ return this.send_event(event);
62
+ }
63
+ };
64
+
65
+ Connection.prototype.close = function() {
66
+ return this._conn.close();
67
+ };
68
+
69
+ Connection.prototype.setConnectionId = function(connection_id) {
70
+ return this.connection_id = connection_id;
71
+ };
72
+
73
+ Connection.prototype.send_event = function(event) {
74
+ return this._conn.send(event.serialize());
75
+ };
76
+
77
+ Connection.prototype.flush_queue = function() {
78
+ var event, _i, _len, _ref;
79
+ _ref = this.message_queue;
80
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
81
+ event = _ref[_i];
82
+ this.trigger(event);
83
+ }
84
+ return this.message_queue = [];
85
+ };
86
+
87
+ return Connection;
88
+
89
+ })();
90
+
91
+ }).call(this);
@@ -0,0 +1,66 @@
1
+
2
+ /*
3
+ The Event object stores all the relevant event information.
4
+ */
5
+
6
+ (function() {
7
+ WebSocketRails.Event = (function() {
8
+ function Event(message, success_callback, failure_callback) {
9
+ var options;
10
+ this.success_callback = success_callback;
11
+ this.failure_callback = failure_callback;
12
+ this.name = message[0];
13
+ this.data = message[1];
14
+ options = message[2];
15
+ if (options != null) {
16
+ this.id = options['id'] != null ? options['id'] : ((1 + Math.random()) * 0x10000) | 0;
17
+ this.channel = options.channel;
18
+ this.token = options.token;
19
+ this.connection_id = options.connection_id;
20
+ if (options.success != null) {
21
+ this.result = true;
22
+ this.success = options.success;
23
+ }
24
+ }
25
+ }
26
+
27
+ Event.prototype.is_channel = function() {
28
+ return this.channel != null;
29
+ };
30
+
31
+ Event.prototype.is_result = function() {
32
+ return typeof this.result !== 'undefined';
33
+ };
34
+
35
+ Event.prototype.is_ping = function() {
36
+ return this.name === 'websocket_rails.ping';
37
+ };
38
+
39
+ Event.prototype.serialize = function() {
40
+ return JSON.stringify([this.name, this.data, this.meta_data()]);
41
+ };
42
+
43
+ Event.prototype.meta_data = function() {
44
+ return {
45
+ id: this.id,
46
+ connection_id: this.connection_id,
47
+ channel: this.channel,
48
+ token: this.token
49
+ };
50
+ };
51
+
52
+ Event.prototype.run_callbacks = function(success, result) {
53
+ this.success = success;
54
+ this.result = result;
55
+ if (this.success === true) {
56
+ return typeof this.success_callback === "function" ? this.success_callback(this.result) : void 0;
57
+ } else {
58
+ return typeof this.failure_callback === "function" ? this.failure_callback(this.result) : void 0;
59
+ }
60
+ };
61
+
62
+ return Event;
63
+
64
+ })();
65
+
66
+ }).call(this);
@@ -0,0 +1,97 @@
1
+
2
+ /*
3
+ HTTP Interface for the WebSocketRails client.
4
+ */
5
+
6
+ (function() {
7
+ var __hasProp = {}.hasOwnProperty,
8
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
9
+
10
+ WebSocketRails.HttpConnection = (function(_super) {
11
+ __extends(HttpConnection, _super);
12
+
13
+ HttpConnection.prototype.connection_type = 'http';
14
+
15
+ HttpConnection.prototype._httpFactories = function() {
16
+ return [
17
+ function() {
18
+ return new XMLHttpRequest();
19
+ }, function() {
20
+ return new ActiveXObject("Msxml2.XMLHTTP");
21
+ }, function() {
22
+ return new ActiveXObject("Msxml3.XMLHTTP");
23
+ }, function() {
24
+ return new ActiveXObject("Microsoft.XMLHTTP");
25
+ }
26
+ ];
27
+ };
28
+
29
+ function HttpConnection(url, dispatcher) {
30
+ this.dispatcher = dispatcher;
31
+ HttpConnection.__super__.constructor.apply(this, arguments);
32
+ this._url = "http://" + url;
33
+ this._conn = this._createXMLHttpObject();
34
+ this.last_pos = 0;
35
+ this._conn.onreadystatechange = (function(_this) {
36
+ return function() {
37
+ return _this._parse_stream();
38
+ };
39
+ })(this);
40
+ this._conn.addEventListener("load", this.on_close, false);
41
+ this._conn.open("GET", this._url, true);
42
+ this._conn.send();
43
+ }
44
+
45
+ HttpConnection.prototype.close = function() {
46
+ return this._conn.abort();
47
+ };
48
+
49
+ HttpConnection.prototype.send_event = function(event) {
50
+ HttpConnection.__super__.send_event.apply(this, arguments);
51
+ return this._post_data(event.serialize());
52
+ };
53
+
54
+ HttpConnection.prototype._post_data = function(payload) {
55
+ return $.ajax(this._url, {
56
+ type: 'POST',
57
+ data: {
58
+ client_id: this.connection_id,
59
+ data: payload
60
+ },
61
+ success: function() {}
62
+ });
63
+ };
64
+
65
+ HttpConnection.prototype._createXMLHttpObject = function() {
66
+ var e, factories, factory, xmlhttp, _i, _len;
67
+ xmlhttp = false;
68
+ factories = this._httpFactories();
69
+ for (_i = 0, _len = factories.length; _i < _len; _i++) {
70
+ factory = factories[_i];
71
+ try {
72
+ xmlhttp = factory();
73
+ } catch (_error) {
74
+ e = _error;
75
+ continue;
76
+ }
77
+ break;
78
+ }
79
+ return xmlhttp;
80
+ };
81
+
82
+ HttpConnection.prototype._parse_stream = function() {
83
+ var data, event_data;
84
+ if (this._conn.readyState === 3) {
85
+ data = this._conn.responseText.substring(this.last_pos);
86
+ this.last_pos = this._conn.responseText.length;
87
+ data = data.replace(/\]\]\[\[/g, "],[");
88
+ event_data = JSON.parse(data);
89
+ return this.on_message(event_data);
90
+ }
91
+ };
92
+
93
+ return HttpConnection;
94
+
95
+ })(WebSocketRails.AbstractConnection);
96
+
97
+ }).call(this);