lanes 0.5.6 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +6 -2
  3. data/client/lanes/Config.coffee +6 -5
  4. data/client/lanes/access/LoginDialog.cjsx +4 -2
  5. data/client/lanes/access/Roles.coffee +3 -0
  6. data/client/lanes/access/screens/user-management/Editor.cjsx +1 -1
  7. data/client/lanes/components/grid/Body.cjsx +4 -3
  8. data/client/lanes/components/grid/Grid.cjsx +4 -3
  9. data/client/lanes/components/grid/Header.cjsx +1 -1
  10. data/client/lanes/components/grid/PopOverMixin.cjsx +6 -6
  11. data/client/lanes/components/grid/Selections.cjsx +16 -6
  12. data/client/lanes/components/grid/Toolbar.cjsx +1 -1
  13. data/client/lanes/components/grid/styles.scss +21 -5
  14. data/client/lanes/components/modal/Modal.cjsx +18 -9
  15. data/client/lanes/components/record-finder/Clause.cjsx +1 -2
  16. data/client/lanes/components/record-finder/Dialog.cjsx +11 -3
  17. data/client/lanes/components/record-finder/RecordFinder.cjsx +14 -7
  18. data/client/lanes/components/record-finder/styles.scss +1 -0
  19. data/client/lanes/components/select-field/SelectField.cjsx +36 -10
  20. data/client/lanes/components/select-field/styles.scss +7 -0
  21. data/client/lanes/components/shared/Checkbox.cjsx +34 -0
  22. data/client/lanes/components/shared/DateTime.cjsx +3 -2
  23. data/client/lanes/components/shared/ErrorDisplay.cjsx +1 -1
  24. data/client/lanes/components/shared/FieldMixin.cjsx +26 -15
  25. data/client/lanes/components/shared/FieldSet.cjsx +1 -1
  26. data/client/lanes/components/shared/FieldWrapper.cjsx +2 -2
  27. data/client/lanes/components/shared/FormGroup.cjsx +2 -2
  28. data/client/lanes/components/shared/Icon.cjsx +31 -4
  29. data/client/lanes/components/shared/IconButton.cjsx +8 -0
  30. data/client/lanes/components/shared/ImageAsset.cjsx +8 -5
  31. data/client/lanes/components/shared/IndeterminateCheckbox.cjsx +19 -0
  32. data/client/lanes/components/shared/InputFieldMixin.cjsx +6 -0
  33. data/client/lanes/components/shared/JobProgress.cjsx +4 -3
  34. data/client/lanes/components/shared/NetworkActivityOverlay.cjsx +1 -1
  35. data/client/lanes/components/shared/ScreenWrapper.cjsx +1 -1
  36. data/client/lanes/components/shared/ToggleField.cjsx +2 -1
  37. data/client/lanes/components/shared/Tooltip.cjsx +10 -2
  38. data/client/lanes/components/shared/fields.scss +7 -2
  39. data/client/lanes/components/toolbar/RemoteChangeSets.cjsx +10 -7
  40. data/client/lanes/components/toolbar/SaveButton.cjsx +5 -4
  41. data/client/lanes/components/toolbar/Toolbar.cjsx +18 -19
  42. data/client/lanes/components/toolbar/changes-notification.scss +3 -1
  43. data/client/lanes/components/toolbar/styles.scss +6 -3
  44. data/client/lanes/lib/HotReload.coffee +1 -1
  45. data/client/lanes/lib/all.js +1 -1
  46. data/client/lanes/lib/dom.coffee +14 -1
  47. data/client/lanes/lib/format.coffee +3 -0
  48. data/client/lanes/lib/loader.coffee +0 -2
  49. data/client/lanes/lib/{dom-polyfills.coffee → polyfills.coffee} +3 -0
  50. data/client/lanes/lib/utilFunctions.coffee +5 -7
  51. data/client/lanes/models/Asset.coffee +33 -20
  52. data/client/lanes/models/AssociationMap.coffee +5 -6
  53. data/client/lanes/models/Base.coffee +5 -2
  54. data/client/lanes/models/Collection.coffee +23 -2
  55. data/client/lanes/models/PubSub.coffee +51 -13
  56. data/client/lanes/models/Query.coffee +53 -42
  57. data/client/lanes/models/State.coffee +5 -4
  58. data/client/lanes/models/Sync.coffee +5 -3
  59. data/client/lanes/models/index.js +1 -1
  60. data/client/lanes/models/mixins/TrackCollectionRemovals.coffee +17 -0
  61. data/client/lanes/models/query/ArrayResult.coffee +16 -17
  62. data/client/lanes/models/query/CollectionResult.coffee +4 -4
  63. data/client/lanes/react/Component.coffee +14 -13
  64. data/client/lanes/react/Root.cjsx +1 -1
  65. data/client/lanes/react/Screen.coffee +1 -0
  66. data/client/lanes/react/Viewport.coffee +52 -16
  67. data/client/lanes/react/mixins/Access.coffee +5 -0
  68. data/client/lanes/react/mixins/Data.coffee +52 -144
  69. data/client/lanes/react/mixins/MonitorSize.coffee +1 -1
  70. data/client/lanes/react/mixins/ReadEditingState.coffee +3 -0
  71. data/client/lanes/screens/Commands.coffee +1 -1
  72. data/client/lanes/screens/CommonComponents.cjsx +2 -2
  73. data/client/lanes/screens/Definitions.coffee +3 -1
  74. data/client/lanes/screens/SystemSettings.cjsx +13 -18
  75. data/client/lanes/screens/UserPreferences.cjsx +1 -1
  76. data/client/lanes/styles/fonts.scss +2 -3
  77. data/client/lanes/styles/global/styles.scss +2 -1
  78. data/client/lanes/testing/TestObjects.coffee +6 -2
  79. data/client/lanes/vendor/action_cable.js +590 -0
  80. data/client/lanes/vendor/development/calendar.js +56 -56
  81. data/client/lanes/vendor/development/commons.js +7819 -6690
  82. data/client/lanes/vendor/development/data.js +1877 -1455
  83. data/client/lanes/vendor/development/helpers.js +39 -82
  84. data/client/lanes/vendor/development/toggle.js +20 -20
  85. data/client/lanes/vendor/development/ui.js +14629 -14261
  86. data/client/lanes/vendor/development/widgets.js +3146 -2173
  87. data/client/lanes/vendor/index.js +1 -2
  88. data/client/lanes/vendor/production/calendar.js +56 -56
  89. data/client/lanes/vendor/production/commons.js +6352 -6185
  90. data/client/lanes/vendor/production/data.js +1871 -1456
  91. data/client/lanes/vendor/production/toggle.js +20 -20
  92. data/client/lanes/vendor/production/ui.js +14694 -14286
  93. data/client/lanes/vendor/production/widgets.js +3139 -2166
  94. data/client/lanes/vendor/standalone/index.js +5666 -4586
  95. data/client/lanes/vendor/styles/widgets.scss +5 -5
  96. data/client/lanes/workspace/Layout.cjsx +1 -10
  97. data/client/lanes/workspace/Navbar.cjsx +8 -13
  98. data/client/lanes/workspace/ScreenView.cjsx +3 -4
  99. data/client/lanes/workspace/ScreensMenu.cjsx +8 -19
  100. data/client/lanes/workspace/Tabs.cjsx +6 -14
  101. data/db/migrate/02_create_assets.rb +1 -3
  102. data/lanes.gemspec +16 -11
  103. data/lib/lanes/access/test_fixture_extensions.rb +6 -10
  104. data/lib/lanes/access/track_modifications.rb +24 -0
  105. data/lib/lanes/api/cable.rb +49 -0
  106. data/lib/lanes/api/controller_base.rb +52 -9
  107. data/lib/lanes/api/default_routes.rb +9 -0
  108. data/lib/lanes/api/generic_controller.rb +2 -9
  109. data/lib/lanes/api/handlers/asset.rb +5 -6
  110. data/lib/lanes/api/helper_methods.rb +3 -2
  111. data/lib/lanes/api/javascript_processor.rb +6 -5
  112. data/lib/lanes/api/pub_sub.rb +14 -32
  113. data/lib/lanes/api/request_wrapper.rb +1 -1
  114. data/lib/lanes/api/root.rb +4 -7
  115. data/lib/lanes/api/routing.rb +3 -3
  116. data/lib/lanes/api/sprockets_extension.rb +1 -1
  117. data/lib/lanes/api.rb +4 -0
  118. data/lib/lanes/asset.rb +25 -25
  119. data/lib/lanes/concerns/asset_uploader.rb +25 -47
  120. data/lib/lanes/concerns/export_scope.rb +5 -7
  121. data/lib/lanes/concerns/queries.rb +7 -3
  122. data/lib/lanes/concerns/set_attribute_data.rb +12 -6
  123. data/lib/lanes/configuration.rb +4 -7
  124. data/lib/lanes/db.rb +3 -1
  125. data/lib/lanes/guard_tasks.rb +2 -1
  126. data/lib/lanes/hot_reload_plugin.rb +2 -1
  127. data/lib/lanes/job.rb +0 -1
  128. data/lib/lanes/logger.rb +3 -3
  129. data/lib/lanes/model.rb +0 -3
  130. data/lib/lanes/spec_helper.rb +1 -1
  131. data/lib/lanes/system_settings.rb +8 -14
  132. data/lib/lanes/version.rb +1 -1
  133. data/npm-build/data.js +1 -0
  134. data/npm-build/package.json +21 -19
  135. data/npm-build/ui.js +3 -0
  136. data/npm-build/update-dayz +2 -2
  137. data/npm-build/update-model-bindings.js +5 -0
  138. data/spec/command-reference-files/initial/Gemfile +1 -1
  139. data/spec/command-reference-files/initial/config/database.yml +1 -0
  140. data/spec/command-reference-files/initial/config/lanes.rb +3 -3
  141. data/spec/command-reference-files/screen/spec/appy-app/screens/ready-set-go/ReadySetGoSpec.coffee +1 -1
  142. data/spec/lanes/components/grid/GridSpec.coffee +2 -2
  143. data/spec/lanes/components/grid/PopoverEditorSpec.coffee +11 -12
  144. data/spec/lanes/components/select-field/SelectFieldSpec.coffee +6 -4
  145. data/spec/lanes/components/shared/NetworkActivityOverlaySpec.coffee +1 -1
  146. data/spec/lanes/models/PubSubSpec.coffee +6 -8
  147. data/spec/lanes/models/QuerySpec.coffee +19 -0
  148. data/spec/lanes/react/mixins/DataSpec.coffee +18 -16
  149. data/spec/server/api/coffeescript_processor_spec.rb +1 -1
  150. data/spec/server/api/controller_base_spec.rb +77 -0
  151. data/spec/server/api/pub_sub_spec.rb +9 -0
  152. data/spec/server/asset_spec.rb +23 -18
  153. data/spec/server/concerns/export_scope_spec.rb +2 -1
  154. data/spec/server/concerns/exported_limits_spec.rb +14 -9
  155. data/spec/server/concerns/set_attribute_data_spec.rb +17 -0
  156. data/spec/server/spec_helper.rb +29 -11
  157. data/templates/config/database.yml +1 -0
  158. data/templates/spec/client/Screen.coffee +1 -1
  159. data/views/specs.erb +4 -1
  160. metadata +138 -89
  161. data/client/lanes/vendor/message-bus-ajax.js +0 -44
  162. data/client/lanes/vendor/message-bus.js +0 -414
@@ -1,6 +1,7 @@
1
1
  Lanes.Test.makeScreen = (props = {}, args = {}) ->
2
2
  class TestScreen
3
- render: -> React.createElement('div', 'hello screen')
3
+ FILE: { path: ['test'] }
4
+ render: -> React.createElement('div')
4
5
  _.extend(TestScreen.prototype, props)
5
6
  Screen = Lanes.React.Screen.extend(TestScreen)
6
7
  Lanes.Test.renderComponent(Screen, props: args)
@@ -8,13 +9,15 @@ Lanes.Test.makeScreen = (props = {}, args = {}) ->
8
9
 
9
10
  Lanes.Test.makeComponent = (props = {}, args = {}) ->
10
11
  class TestComponent
11
- render: -> React.createElement('div', 'hello component')
12
+ FILE: { path: ['test'] }
13
+ render: -> React.createElement('div')
12
14
  _.extend(TestComponent.prototype, props)
13
15
  Component = Lanes.React.Component.extend(TestComponent)
14
16
  Lanes.Test.renderComponent(Component, props: args)
15
17
 
16
18
  Lanes.Test.defineModel = (props = {}) ->
17
19
  class TestModel
20
+ FILE: { path: ['test'] }
18
21
  constructor: -> super
19
22
  _.extend(TestModel.prototype, props)
20
23
  Lanes.Models.Base.extend(TestModel)
@@ -29,6 +32,7 @@ Lanes.Test.makeCollection = (props = {}, args = {}) ->
29
32
  _.extend(TestCollection.prototype, props)
30
33
  unless TestCollection::model
31
34
  class TestModel
35
+ FILE: { path: ['test'] }
32
36
  constructor: -> super
33
37
  TestCollection::model = Lanes.Models.Base.extend(TestModel)
34
38
  Lanes.Models.Collection.extend(TestCollection)
@@ -0,0 +1,590 @@
1
+ (function() {
2
+ var slice = [].slice;
3
+
4
+ this.ActionCable = {
5
+ INTERNAL: {
6
+ "message_types": {
7
+ "welcome": "welcome",
8
+ "ping": "ping",
9
+ "confirmation": "confirm_subscription",
10
+ "rejection": "reject_subscription"
11
+ },
12
+ "default_mount_path": "/cable",
13
+ "protocols": ["actioncable-v1-json", "actioncable-unsupported"]
14
+ },
15
+ createConsumer: function(url) {
16
+ var ref;
17
+ if (url == null) {
18
+ url = (ref = this.getConfig("url")) != null ? ref : this.INTERNAL.default_mount_path;
19
+ }
20
+ return new ActionCable.Consumer(this.createWebSocketURL(url));
21
+ },
22
+ getConfig: function(name) {
23
+ var element;
24
+ element = document.head.querySelector("meta[name='action-cable-" + name + "']");
25
+ return element != null ? element.getAttribute("content") : void 0;
26
+ },
27
+ createWebSocketURL: function(url) {
28
+ var a;
29
+ if (url && !/^wss?:/i.test(url)) {
30
+ a = document.createElement("a");
31
+ a.href = url;
32
+ a.href = a.href;
33
+ a.protocol = a.protocol.replace("http", "ws");
34
+ return a.href;
35
+ } else {
36
+ return url;
37
+ }
38
+ },
39
+ startDebugging: function() {
40
+ return this.debugging = true;
41
+ },
42
+ stopDebugging: function() {
43
+ return this.debugging = null;
44
+ },
45
+ log: function() {
46
+ var messages;
47
+ messages = 1 <= arguments.length ? slice.call(arguments, 0) : [];
48
+ if (this.debugging) {
49
+ messages.push(Date.now());
50
+ return console.log.apply(console, ["[ActionCable]"].concat(slice.call(messages)));
51
+ }
52
+ }
53
+ };
54
+
55
+ if (typeof window !== "undefined" && window !== null) {
56
+ window.ActionCable = this.ActionCable;
57
+ }
58
+
59
+ if (typeof module !== "undefined" && module !== null) {
60
+ module.exports = this.ActionCable;
61
+ }
62
+
63
+ }).call(this);
64
+ (function() {
65
+ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
66
+
67
+ ActionCable.ConnectionMonitor = (function() {
68
+ var clamp, now, secondsSince;
69
+
70
+ ConnectionMonitor.pollInterval = {
71
+ min: 3,
72
+ max: 30
73
+ };
74
+
75
+ ConnectionMonitor.staleThreshold = 6;
76
+
77
+ function ConnectionMonitor(connection) {
78
+ this.connection = connection;
79
+ this.visibilityDidChange = bind(this.visibilityDidChange, this);
80
+ this.reconnectAttempts = 0;
81
+ }
82
+
83
+ ConnectionMonitor.prototype.start = function() {
84
+ if (!this.isRunning()) {
85
+ this.startedAt = now();
86
+ delete this.stoppedAt;
87
+ this.startPolling();
88
+ document.addEventListener("visibilitychange", this.visibilityDidChange);
89
+ return ActionCable.log("ConnectionMonitor started. pollInterval = " + (this.getPollInterval()) + " ms");
90
+ }
91
+ };
92
+
93
+ ConnectionMonitor.prototype.stop = function() {
94
+ if (this.isRunning()) {
95
+ this.stoppedAt = now();
96
+ this.stopPolling();
97
+ document.removeEventListener("visibilitychange", this.visibilityDidChange);
98
+ return ActionCable.log("ConnectionMonitor stopped");
99
+ }
100
+ };
101
+
102
+ ConnectionMonitor.prototype.isRunning = function() {
103
+ return (this.startedAt != null) && (this.stoppedAt == null);
104
+ };
105
+
106
+ ConnectionMonitor.prototype.recordPing = function() {
107
+ return this.pingedAt = now();
108
+ };
109
+
110
+ ConnectionMonitor.prototype.recordConnect = function() {
111
+ this.reconnectAttempts = 0;
112
+ this.recordPing();
113
+ delete this.disconnectedAt;
114
+ return ActionCable.log("ConnectionMonitor recorded connect");
115
+ };
116
+
117
+ ConnectionMonitor.prototype.recordDisconnect = function() {
118
+ this.disconnectedAt = now();
119
+ return ActionCable.log("ConnectionMonitor recorded disconnect");
120
+ };
121
+
122
+ ConnectionMonitor.prototype.startPolling = function() {
123
+ this.stopPolling();
124
+ return this.poll();
125
+ };
126
+
127
+ ConnectionMonitor.prototype.stopPolling = function() {
128
+ return clearTimeout(this.pollTimeout);
129
+ };
130
+
131
+ ConnectionMonitor.prototype.poll = function() {
132
+ return this.pollTimeout = setTimeout((function(_this) {
133
+ return function() {
134
+ _this.reconnectIfStale();
135
+ return _this.poll();
136
+ };
137
+ })(this), this.getPollInterval());
138
+ };
139
+
140
+ ConnectionMonitor.prototype.getPollInterval = function() {
141
+ var interval, max, min, ref;
142
+ ref = this.constructor.pollInterval, min = ref.min, max = ref.max;
143
+ interval = 5 * Math.log(this.reconnectAttempts + 1);
144
+ return Math.round(clamp(interval, min, max) * 1000);
145
+ };
146
+
147
+ ConnectionMonitor.prototype.reconnectIfStale = function() {
148
+ if (this.connectionIsStale()) {
149
+ ActionCable.log("ConnectionMonitor detected stale connection. reconnectAttempts = " + this.reconnectAttempts + ", pollInterval = " + (this.getPollInterval()) + " ms, time disconnected = " + (secondsSince(this.disconnectedAt)) + " s, stale threshold = " + this.constructor.staleThreshold + " s");
150
+ this.reconnectAttempts++;
151
+ if (this.disconnectedRecently()) {
152
+ return ActionCable.log("ConnectionMonitor skipping reopening recent disconnect");
153
+ } else {
154
+ ActionCable.log("ConnectionMonitor reopening");
155
+ return this.connection.reopen();
156
+ }
157
+ }
158
+ };
159
+
160
+ ConnectionMonitor.prototype.connectionIsStale = function() {
161
+ var ref;
162
+ return secondsSince((ref = this.pingedAt) != null ? ref : this.startedAt) > this.constructor.staleThreshold;
163
+ };
164
+
165
+ ConnectionMonitor.prototype.disconnectedRecently = function() {
166
+ return this.disconnectedAt && secondsSince(this.disconnectedAt) < this.constructor.staleThreshold;
167
+ };
168
+
169
+ ConnectionMonitor.prototype.visibilityDidChange = function() {
170
+ if (document.visibilityState === "visible") {
171
+ return setTimeout((function(_this) {
172
+ return function() {
173
+ if (_this.connectionIsStale() || !_this.connection.isOpen()) {
174
+ ActionCable.log("ConnectionMonitor reopening stale connection on visibilitychange. visbilityState = " + document.visibilityState);
175
+ return _this.connection.reopen();
176
+ }
177
+ };
178
+ })(this), 200);
179
+ }
180
+ };
181
+
182
+ now = function() {
183
+ return new Date().getTime();
184
+ };
185
+
186
+ secondsSince = function(time) {
187
+ return (now() - time) / 1000;
188
+ };
189
+
190
+ clamp = function(number, min, max) {
191
+ return Math.max(min, Math.min(max, number));
192
+ };
193
+
194
+ return ConnectionMonitor;
195
+
196
+ })();
197
+
198
+ }).call(this);
199
+ (function() {
200
+ var i, message_types, protocols, ref, supportedProtocols, unsupportedProtocol,
201
+ slice = [].slice,
202
+ bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
203
+ indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
204
+
205
+ ref = ActionCable.INTERNAL, message_types = ref.message_types, protocols = ref.protocols;
206
+
207
+ supportedProtocols = 2 <= protocols.length ? slice.call(protocols, 0, i = protocols.length - 1) : (i = 0, []), unsupportedProtocol = protocols[i++];
208
+
209
+ ActionCable.Connection = (function() {
210
+ Connection.reopenDelay = 500;
211
+
212
+ function Connection(consumer) {
213
+ this.consumer = consumer;
214
+ this.open = bind(this.open, this);
215
+ this.subscriptions = this.consumer.subscriptions;
216
+ this.monitor = new ActionCable.ConnectionMonitor(this);
217
+ this.disconnected = true;
218
+ }
219
+
220
+ Connection.prototype.send = function(data) {
221
+ if (this.isOpen()) {
222
+ this.webSocket.send(JSON.stringify(data));
223
+ return true;
224
+ } else {
225
+ return false;
226
+ }
227
+ };
228
+
229
+ Connection.prototype.open = function() {
230
+ if (this.isActive()) {
231
+ ActionCable.log("Attempted to open WebSocket, but existing socket is " + (this.getState()));
232
+ throw new Error("Existing connection must be closed before opening");
233
+ } else {
234
+ ActionCable.log("Opening WebSocket, current state is " + (this.getState()) + ", subprotocols: " + protocols);
235
+ if (this.webSocket != null) {
236
+ this.uninstallEventHandlers();
237
+ }
238
+ this.webSocket = new WebSocket(this.consumer.url, protocols);
239
+ this.installEventHandlers();
240
+ this.monitor.start();
241
+ return true;
242
+ }
243
+ };
244
+
245
+ Connection.prototype.close = function(arg) {
246
+ var allowReconnect, ref1;
247
+ allowReconnect = (arg != null ? arg : {
248
+ allowReconnect: true
249
+ }).allowReconnect;
250
+ if (!allowReconnect) {
251
+ this.monitor.stop();
252
+ }
253
+ if (this.isActive()) {
254
+ return (ref1 = this.webSocket) != null ? ref1.close() : void 0;
255
+ }
256
+ };
257
+
258
+ Connection.prototype.reopen = function() {
259
+ var error, error1;
260
+ ActionCable.log("Reopening WebSocket, current state is " + (this.getState()));
261
+ if (this.isActive()) {
262
+ try {
263
+ return this.close();
264
+ } catch (error1) {
265
+ error = error1;
266
+ return ActionCable.log("Failed to reopen WebSocket", error);
267
+ } finally {
268
+ ActionCable.log("Reopening WebSocket in " + this.constructor.reopenDelay + "ms");
269
+ setTimeout(this.open, this.constructor.reopenDelay);
270
+ }
271
+ } else {
272
+ return this.open();
273
+ }
274
+ };
275
+
276
+ Connection.prototype.getProtocol = function() {
277
+ var ref1;
278
+ return (ref1 = this.webSocket) != null ? ref1.protocol : void 0;
279
+ };
280
+
281
+ Connection.prototype.isOpen = function() {
282
+ return this.isState("open");
283
+ };
284
+
285
+ Connection.prototype.isActive = function() {
286
+ return this.isState("open", "connecting");
287
+ };
288
+
289
+ Connection.prototype.isProtocolSupported = function() {
290
+ var ref1;
291
+ return ref1 = this.getProtocol(), indexOf.call(supportedProtocols, ref1) >= 0;
292
+ };
293
+
294
+ Connection.prototype.isState = function() {
295
+ var ref1, states;
296
+ states = 1 <= arguments.length ? slice.call(arguments, 0) : [];
297
+ return ref1 = this.getState(), indexOf.call(states, ref1) >= 0;
298
+ };
299
+
300
+ Connection.prototype.getState = function() {
301
+ var ref1, state, value;
302
+ for (state in WebSocket) {
303
+ value = WebSocket[state];
304
+ if (value === ((ref1 = this.webSocket) != null ? ref1.readyState : void 0)) {
305
+ return state.toLowerCase();
306
+ }
307
+ }
308
+ return null;
309
+ };
310
+
311
+ Connection.prototype.installEventHandlers = function() {
312
+ var eventName, handler;
313
+ for (eventName in this.events) {
314
+ handler = this.events[eventName].bind(this);
315
+ this.webSocket["on" + eventName] = handler;
316
+ }
317
+ };
318
+
319
+ Connection.prototype.uninstallEventHandlers = function() {
320
+ var eventName;
321
+ for (eventName in this.events) {
322
+ this.webSocket["on" + eventName] = function() {};
323
+ }
324
+ };
325
+
326
+ Connection.prototype.events = {
327
+ message: function(event) {
328
+ var identifier, message, ref1, type;
329
+ if (!this.isProtocolSupported()) {
330
+ return;
331
+ }
332
+ ref1 = JSON.parse(event.data), identifier = ref1.identifier, message = ref1.message, type = ref1.type;
333
+ switch (type) {
334
+ case message_types.welcome:
335
+ this.monitor.recordConnect();
336
+ return this.subscriptions.reload();
337
+ case message_types.ping:
338
+ return this.monitor.recordPing();
339
+ case message_types.confirmation:
340
+ return this.subscriptions.notify(identifier, "connected");
341
+ case message_types.rejection:
342
+ return this.subscriptions.reject(identifier);
343
+ default:
344
+ return this.subscriptions.notify(identifier, "received", message);
345
+ }
346
+ },
347
+ open: function() {
348
+ ActionCable.log("WebSocket onopen event, using '" + (this.getProtocol()) + "' subprotocol");
349
+ this.disconnected = false;
350
+ if (!this.isProtocolSupported()) {
351
+ ActionCable.log("Protocol is unsupported. Stopping monitor and disconnecting.");
352
+ return this.close({
353
+ allowReconnect: false
354
+ });
355
+ }
356
+ },
357
+ close: function(event) {
358
+ ActionCable.log("WebSocket onclose event");
359
+ if (this.disconnected) {
360
+ return;
361
+ }
362
+ this.disconnected = true;
363
+ this.monitor.recordDisconnect();
364
+ return this.subscriptions.notifyAll("disconnected", {
365
+ willAttemptReconnect: this.monitor.isRunning()
366
+ });
367
+ },
368
+ error: function() {
369
+ return ActionCable.log("WebSocket onerror event");
370
+ }
371
+ };
372
+
373
+ return Connection;
374
+
375
+ })();
376
+
377
+ }).call(this);
378
+ (function() {
379
+ var slice = [].slice;
380
+
381
+ ActionCable.Subscriptions = (function() {
382
+ function Subscriptions(consumer) {
383
+ this.consumer = consumer;
384
+ this.subscriptions = [];
385
+ }
386
+
387
+ Subscriptions.prototype.create = function(channelName, mixin) {
388
+ var channel, params, subscription;
389
+ channel = channelName;
390
+ params = typeof channel === "object" ? channel : {
391
+ channel: channel
392
+ };
393
+ subscription = new ActionCable.Subscription(this.consumer, params, mixin);
394
+ return this.add(subscription);
395
+ };
396
+
397
+ Subscriptions.prototype.add = function(subscription) {
398
+ this.subscriptions.push(subscription);
399
+ this.consumer.ensureActiveConnection();
400
+ this.notify(subscription, "initialized");
401
+ this.sendCommand(subscription, "subscribe");
402
+ return subscription;
403
+ };
404
+
405
+ Subscriptions.prototype.remove = function(subscription) {
406
+ this.forget(subscription);
407
+ if (!this.findAll(subscription.identifier).length) {
408
+ this.sendCommand(subscription, "unsubscribe");
409
+ }
410
+ return subscription;
411
+ };
412
+
413
+ Subscriptions.prototype.reject = function(identifier) {
414
+ var i, len, ref, results, subscription;
415
+ ref = this.findAll(identifier);
416
+ results = [];
417
+ for (i = 0, len = ref.length; i < len; i++) {
418
+ subscription = ref[i];
419
+ this.forget(subscription);
420
+ this.notify(subscription, "rejected");
421
+ results.push(subscription);
422
+ }
423
+ return results;
424
+ };
425
+
426
+ Subscriptions.prototype.forget = function(subscription) {
427
+ var s;
428
+ this.subscriptions = (function() {
429
+ var i, len, ref, results;
430
+ ref = this.subscriptions;
431
+ results = [];
432
+ for (i = 0, len = ref.length; i < len; i++) {
433
+ s = ref[i];
434
+ if (s !== subscription) {
435
+ results.push(s);
436
+ }
437
+ }
438
+ return results;
439
+ }).call(this);
440
+ return subscription;
441
+ };
442
+
443
+ Subscriptions.prototype.findAll = function(identifier) {
444
+ var i, len, ref, results, s;
445
+ ref = this.subscriptions;
446
+ results = [];
447
+ for (i = 0, len = ref.length; i < len; i++) {
448
+ s = ref[i];
449
+ if (s.identifier === identifier) {
450
+ results.push(s);
451
+ }
452
+ }
453
+ return results;
454
+ };
455
+
456
+ Subscriptions.prototype.reload = function() {
457
+ var i, len, ref, results, subscription;
458
+ ref = this.subscriptions;
459
+ results = [];
460
+ for (i = 0, len = ref.length; i < len; i++) {
461
+ subscription = ref[i];
462
+ results.push(this.sendCommand(subscription, "subscribe"));
463
+ }
464
+ return results;
465
+ };
466
+
467
+ Subscriptions.prototype.notifyAll = function() {
468
+ var args, callbackName, i, len, ref, results, subscription;
469
+ callbackName = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
470
+ ref = this.subscriptions;
471
+ results = [];
472
+ for (i = 0, len = ref.length; i < len; i++) {
473
+ subscription = ref[i];
474
+ results.push(this.notify.apply(this, [subscription, callbackName].concat(slice.call(args))));
475
+ }
476
+ return results;
477
+ };
478
+
479
+ Subscriptions.prototype.notify = function() {
480
+ var args, callbackName, i, len, results, subscription, subscriptions;
481
+ subscription = arguments[0], callbackName = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : [];
482
+ if (typeof subscription === "string") {
483
+ subscriptions = this.findAll(subscription);
484
+ } else {
485
+ subscriptions = [subscription];
486
+ }
487
+ results = [];
488
+ for (i = 0, len = subscriptions.length; i < len; i++) {
489
+ subscription = subscriptions[i];
490
+ results.push(typeof subscription[callbackName] === "function" ? subscription[callbackName].apply(subscription, args) : void 0);
491
+ }
492
+ return results;
493
+ };
494
+
495
+ Subscriptions.prototype.sendCommand = function(subscription, command) {
496
+ var identifier;
497
+ identifier = subscription.identifier;
498
+ return this.consumer.send({
499
+ command: command,
500
+ identifier: identifier
501
+ });
502
+ };
503
+
504
+ return Subscriptions;
505
+
506
+ })();
507
+
508
+ }).call(this);
509
+ (function() {
510
+ ActionCable.Subscription = (function() {
511
+ var extend;
512
+
513
+ function Subscription(consumer, params, mixin) {
514
+ this.consumer = consumer;
515
+ if (params == null) {
516
+ params = {};
517
+ }
518
+ this.identifier = JSON.stringify(params);
519
+ extend(this, mixin);
520
+ }
521
+
522
+ Subscription.prototype.perform = function(action, data) {
523
+ if (data == null) {
524
+ data = {};
525
+ }
526
+ data.action = action;
527
+ return this.send(data);
528
+ };
529
+
530
+ Subscription.prototype.send = function(data) {
531
+ return this.consumer.send({
532
+ command: "message",
533
+ identifier: this.identifier,
534
+ data: JSON.stringify(data)
535
+ });
536
+ };
537
+
538
+ Subscription.prototype.unsubscribe = function() {
539
+ return this.consumer.subscriptions.remove(this);
540
+ };
541
+
542
+ extend = function(object, properties) {
543
+ var key, value;
544
+ if (properties != null) {
545
+ for (key in properties) {
546
+ value = properties[key];
547
+ object[key] = value;
548
+ }
549
+ }
550
+ return object;
551
+ };
552
+
553
+ return Subscription;
554
+
555
+ })();
556
+
557
+ }).call(this);
558
+ (function() {
559
+ ActionCable.Consumer = (function() {
560
+ function Consumer(url) {
561
+ this.url = url;
562
+ this.subscriptions = new ActionCable.Subscriptions(this);
563
+ this.connection = new ActionCable.Connection(this);
564
+ }
565
+
566
+ Consumer.prototype.send = function(data) {
567
+ return this.connection.send(data);
568
+ };
569
+
570
+ Consumer.prototype.connect = function() {
571
+ return this.connection.open();
572
+ };
573
+
574
+ Consumer.prototype.disconnect = function() {
575
+ return this.connection.close({
576
+ allowReconnect: false
577
+ });
578
+ };
579
+
580
+ Consumer.prototype.ensureActiveConnection = function() {
581
+ if (!this.connection.isActive()) {
582
+ return this.connection.open();
583
+ }
584
+ };
585
+
586
+ return Consumer;
587
+
588
+ })();
589
+
590
+ }).call(this);