##// END OF EJS Templates
js: migrate to polymer 3.x
ergo -
r3173:b3d618e2 default
parent child
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,50 +1,60
1 {
1 {
2 "name": "rhodecode-enterprise",
2 "name": "rhodecode-enterprise",
3 "version": "1.0.0",
3 "version": "1.0.0",
4 "private": true,
4 "private": true,
5 "description" : "RhodeCode JS packaged",
5 "description" : "RhodeCode JS packaged",
6 "license": "SEE LICENSE IN LICENSE.txt",
6 "license": "SEE LICENSE IN LICENSE.txt",
7 "repository" : {
7 "repository" : {
8 "type" : "hg",
8 "type" : "hg",
9 "url" : "https://code.rhodecode.com/rhodecode-enterprise-ce"
9 "url" : "https://code.rhodecode.com/rhodecode-enterprise-ce"
10 },
10 },
11 "devDependencies": {
11 "devDependencies": {
12 "appenlight-client": "git+https://git@github.com/AppEnlight/appenlight-client-js.git#0.5.1",
12 "appenlight-client": "git+https://git@github.com/AppEnlight/appenlight-client-js.git#0.5.1",
13 "bower": "^1.8.4",
13 "bower": "^1.8.4",
14 "clipboard": "^2.0.1",
14 "clipboard": "^2.0.1",
15 "exports-loader": "^0.6.4",
15 "exports-loader": "^0.6.4",
16 "favico.js": "^0.3.10",
16 "favico.js": "^0.3.10",
17 "grunt": "^0.4.5",
17 "grunt": "^0.4.5",
18 "grunt-cli": "^1.3.1",
18 "grunt-cli": "^1.3.1",
19 "grunt-contrib-concat": "^0.5.1",
19 "grunt-contrib-concat": "^0.5.1",
20 "grunt-contrib-copy": "^1.0.0",
20 "grunt-contrib-copy": "^1.0.0",
21 "grunt-contrib-jshint": "^0.12.0",
21 "grunt-contrib-jshint": "^0.12.0",
22 "grunt-contrib-less": "^1.1.0",
22 "grunt-contrib-less": "^1.1.0",
23 "grunt-contrib-watch": "^0.6.1",
23 "grunt-contrib-watch": "^0.6.1",
24 "grunt-webpack": "^3.1.3",
24 "grunt-webpack": "^3.1.3",
25 "jquery": "1.11.3",
25 "jquery": "1.11.3",
26 "jshint": "^2.9.1-rc3",
26 "jshint": "^2.9.1-rc3",
27 "moment": "^2.18.1",
27 "moment": "^2.18.1",
28 "mousetrap": "^1.6.1",
28 "mousetrap": "^1.6.1",
29 "qrious": "^4.0.2",
29 "qrious": "^4.0.2",
30 "sticky-sidebar": "3.3.1",
30 "sticky-sidebar": "3.3.1",
31 "waypoints": "4.0.1",
31 "waypoints": "4.0.1",
32 "webpack": "4.23.1",
32 "webpack": "4.23.1",
33 "webpack-cli": "3.1.2",
33 "webpack-cli": "3.1.2",
34 "babel-core": "^6.26.3",
34 "babel-core": "^6.26.3",
35 "babel-loader": "^7.1.2",
35 "babel-loader": "^7.1.2",
36 "babel-plugin-transform-object-rest-spread": "^6.26.0",
36 "babel-plugin-transform-object-rest-spread": "^6.26.0",
37 "babel-preset-env": "^1.6.0",
37 "babel-preset-env": "^1.6.0",
38 "copy-webpack-plugin": "^4.4.2",
38 "copy-webpack-plugin": "^4.4.2",
39 "css-loader": "^0.28.11",
39 "css-loader": "^0.28.11",
40 "exports-loader": "^0.6.4",
40 "exports-loader": "^0.6.4",
41 "html-loader": "^0.4.4",
41 "html-loader": "^0.4.4",
42 "html-webpack-plugin": "^3.2.0",
42 "html-webpack-plugin": "^3.2.0",
43 "imports-loader": "^0.7.1",
43 "imports-loader": "^0.7.1",
44 "polymer-webpack-loader": "^2.0.1",
44 "polymer-webpack-loader": "^2.0.1",
45 "style-loader": "^0.21.0",
45 "style-loader": "^0.21.0",
46 "webpack-uglify-js-plugin": "^1.1.9",
46 "webpack-uglify-js-plugin": "^1.1.9",
47 "raw-loader": "1.0.0-beta.0",
47 "raw-loader": "1.0.0-beta.0",
48 "ts-loader": "^1.3.3"
48 "ts-loader": "^1.3.3",
49 "@webcomponents/webcomponentsjs": "^2.0.0",
50 "@polymer/polymer": "^3.0.0",
51 "@polymer/paper-button": "^3.0.0",
52 "@polymer/paper-spinner": "^3.0.0",
53 "@polymer/paper-tooltip": "^3.0.0",
54 "@polymer/paper-toast": "^3.0.0",
55 "@polymer/paper-toggle-button": "^3.0.0",
56 "@polymer/iron-ajax": "^3.0.0",
57 "@polymer/iron-autogrow-textarea": "^3.0.0",
58 "@polymer/iron-a11y-keys": "^3.0.0"
49 }
59 }
50 }
60 }
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
This diff has been collapsed as it changes many lines, (1003 lines changed) Show them Hide them
@@ -1,610 +1,577
1 <link rel="import" href="../../../../../../bower_components/polymer/polymer.html">
1 import {Polymer, html} from '@polymer/polymer/polymer-legacy';
2 <link rel="import" href="../../../../../../bower_components/iron-ajax/iron-ajax.html">
2 import '@polymer/iron-ajax/iron-ajax.js';
3
4 <!--
5
6 `<channelstream-connection>` allows you to connect and interact with channelstream server
7 abstracting websocket/long-polling connections from you.
8
9 In typical use, just slap some `<channelstream-connection>` at the top of your body:
10
3
11 <body>
4 const elemTemplate = html`
12 <channelstream-connection
5 <iron-ajax
13 username="{{user.username}}"
14 connect-url="http://127.0.0.1:8000/demo/connect"
15 disconnect-url="http://127.0.0.1:8000/disconnect"
16 subscribe-url="http://127.0.0.1:8000/demo/subscribe"
17 message-url="http://127.0.0.1:8000/demo/message"
18 long-poll-url="http://127.0.0.1:8000/listen"
19 websocket-url="http://127.0.0.1:8000/ws"
20 channels-url='["channel1", "channel2"]' />
21
22 Then you can do `channelstreamElem.connect()` to kick off your connection.
23 This element also handles automatic reconnections.
24
25 ## Default handlers
26
27 By default element has a listener attached that will fire `startListening()` handler on `channelstream-connected` event.
28
29 By default element has a listener attached that will fire `retryConnection()` handler on `channelstream-connect-error` event,
30 this handler will forever try to re-establish connection to the server incrementing intervals between retries up to 1 minute.
31
32 -->
33 <dom-module id="channelstream-connection">
34 <template>
35
36 <iron-ajax
37 id="ajaxConnect"
6 id="ajaxConnect"
38 url=""
7 url=""
39 handle-as="json"
8 handle-as="json"
40 method="post"
9 method="post"
41 content-type="application/json"
10 content-type="application/json"
42 loading="{{loadingConnect}}"
11 loading="{{loadingConnect}}"
43 last-response="{{connectLastResponse}}"
12 last-response="{{connectLastResponse}}"
44 on-response="_handleConnect"
13 on-response="_handleConnect"
45 on-error="_handleConnectError"
14 on-error="_handleConnectError"
46 debounce-duration="100"></iron-ajax>
15 debounce-duration="100"></iron-ajax>
47
16
48 <iron-ajax
17 <iron-ajax
49 id="ajaxDisconnect"
18 id="ajaxDisconnect"
50 url=""
19 url=""
51 handle-as="json"
20 handle-as="json"
52 method="post"
21 method="post"
53 content-type="application/json"
22 content-type="application/json"
54 loading="{{loadingDisconnect}}"
23 loading="{{loadingDisconnect}}"
55 last-response="{{_disconnectLastResponse}}"
24 last-response="{{_disconnectLastResponse}}"
56 on-response="_handleDisconnect"
25 on-response="_handleDisconnect"
57 debounce-duration="100"></iron-ajax>
26 debounce-duration="100"></iron-ajax>
58
27
59 <iron-ajax
28 <iron-ajax
60 id="ajaxSubscribe"
29 id="ajaxSubscribe"
61 url=""
30 url=""
62 handle-as="json"
31 handle-as="json"
63 method="post"
32 method="post"
64 content-type="application/json"
33 content-type="application/json"
65 loading="{{loadingSubscribe}}"
34 loading="{{loadingSubscribe}}"
66 last-response="{{subscribeLastResponse}}"
35 last-response="{{subscribeLastResponse}}"
67 on-response="_handleSubscribe"
36 on-response="_handleSubscribe"
68 debounce-duration="100"></iron-ajax>
37 debounce-duration="100"></iron-ajax>
69
38
70 <iron-ajax
39 <iron-ajax
71 id="ajaxUnsubscribe"
40 id="ajaxUnsubscribe"
72 url=""
41 url=""
73 handle-as="json"
42 handle-as="json"
74 method="post"
43 method="post"
75 content-type="application/json"
44 content-type="application/json"
76 loading="{{loadingUnsubscribe}}"
45 loading="{{loadingUnsubscribe}}"
77 last-response="{{unsubscribeLastResponse}}"
46 last-response="{{unsubscribeLastResponse}}"
78 on-response="_handleUnsubscribe"
47 on-response="_handleUnsubscribe"
79 debounce-duration="100"></iron-ajax>
48 debounce-duration="100"></iron-ajax>
80
49
81 <iron-ajax
50 <iron-ajax
82 id="ajaxMessage"
51 id="ajaxMessage"
83 url=""
52 url=""
84 handle-as="json"
53 handle-as="json"
85 method="post"
54 method="post"
86 content-type="application/json"
55 content-type="application/json"
87 loading="{{loadingMessage}}"
56 loading="{{loadingMessage}}"
88 last-response="{{messageLastResponse}}"
57 last-response="{{messageLastResponse}}"
89 on-response="_handleMessage"
58 on-response="_handleMessage"
90 on-error="_handleMessageError"
59 on-error="_handleMessageError"
91 debounce-duration="100"></iron-ajax>
60 debounce-duration="100"></iron-ajax>
92
61
93 <iron-ajax
62 <iron-ajax
94 id="ajaxListen"
63 id="ajaxListen"
95 url=""
64 url=""
96 handle-as="text"
65 handle-as="text"
97 loading="{{loadingListen}}"
66 loading="{{loadingListen}}"
98 last-response="{{listenLastResponse}}"
67 last-response="{{listenLastResponse}}"
99 on-request="_handleListenOpen"
68 on-request="_handleListenOpen"
100 on-error="_handleListenError"
69 on-error="_handleListenError"
101 on-response="_handleListenMessageEvent"
70 on-response="_handleListenMessageEvent"
102 debounce-duration="100"></iron-ajax>
71 debounce-duration="100"></iron-ajax>
103
72 `
104 </template>
105 <script>
106 Polymer({
107 is: 'channelstream-connection',
108
73
109 /**
74 Polymer({
110 * Fired when `channels` array changes.
75 is: 'channelstream-connection',
111 *
112 * @event channelstream-channels-changed
113 */
114
76
115 /**
77 _template: elemTemplate,
116 * Fired when `connect()` method succeeds.
117 *
118 * @event channelstream-connected
119 */
120
78
121 /**
79 /**
122 * Fired when `connect` fails.
80 * Fired when `channels` array changes.
123 *
81 *
124 * @event channelstream-connect-error
82 * @event channelstream-channels-changed
125 */
83 */
126
127 /**
128 * Fired when `disconnect()` succeeds.
129 *
130 * @event channelstream-disconnected
131 */
132
84
133 /**
85 /**
134 * Fired when `message()` succeeds.
86 * Fired when `connect()` method succeeds.
135 *
87 *
136 * @event channelstream-message-sent
88 * @event channelstream-connected
137 */
89 */
138
139 /**
140 * Fired when `message()` fails.
141 *
142 * @event channelstream-message-error
143 */
144
90
145 /**
91 /**
146 * Fired when `subscribe()` succeeds.
92 * Fired when `connect` fails.
147 *
93 *
148 * @event channelstream-subscribed
94 * @event channelstream-connect-error
149 */
95 */
150
151 /**
152 * Fired when `subscribe()` fails.
153 *
154 * @event channelstream-subscribe-error
155 */
156
96
157 /**
97 /**
158 * Fired when `unsubscribe()` succeeds.
98 * Fired when `disconnect()` succeeds.
159 *
99 *
160 * @event channelstream-unsubscribed
100 * @event channelstream-disconnected
161 */
101 */
162
163 /**
164 * Fired when `unsubscribe()` fails.
165 *
166 * @event channelstream-unsubscribe-error
167 */
168
102
169 /**
103 /**
170 * Fired when listening connection receives a message.
104 * Fired when `message()` succeeds.
171 *
105 *
172 * @event channelstream-listen-message
106 * @event channelstream-message-sent
173 */
107 */
174
175 /**
176 * Fired when listening connection is opened.
177 *
178 * @event channelstream-listen-opened
179 */
180
108
181 /**
109 /**
182 * Fired when listening connection is closed.
110 * Fired when `message()` fails.
183 *
111 *
184 * @event channelstream-listen-closed
112 * @event channelstream-message-error
185 */
113 */
186
114
187 /**
115 /**
188 * Fired when listening connection suffers an error.
116 * Fired when `subscribe()` succeeds.
189 *
117 *
190 * @event channelstream-listen-error
118 * @event channelstream-subscribed
191 */
119 */
192
120
193 properties: {
121 /**
194 isReady: Boolean,
122 * Fired when `subscribe()` fails.
195 /** List of channels user should be subscribed to. */
123 *
196 channels: {
124 * @event channelstream-subscribe-error
197 type: Array,
125 */
198 value: function () {
126
199 return []
127 /**
200 },
128 * Fired when `unsubscribe()` succeeds.
201 notify: true
129 *
202 },
130 * @event channelstream-unsubscribed
203 /** Username of connecting user. */
131 */
204 username: {
132
205 type: String,
133 /**
206 value: 'Anonymous',
134 * Fired when `unsubscribe()` fails.
207 reflectToAttribute: true
135 *
208 },
136 * @event channelstream-unsubscribe-error
209 /** Connection identifier. */
137 */
210 connectionId: {
138
211 type: String,
139 /**
212 reflectToAttribute: true
140 * Fired when listening connection receives a message.
213 },
141 *
214 /** Websocket instance. */
142 * @event channelstream-listen-message
215 websocket: {
143 */
216 type: Object,
217 value: null
218 },
219 /** Websocket connection url. */
220 websocketUrl: {
221 type: String,
222 value: ''
223 },
224 /** URL used in `connect()`. */
225 connectUrl: {
226 type: String,
227 value: ''
228 },
229 /** URL used in `disconnect()`. */
230 disconnectUrl: {
231 type: String,
232 value: ''
233 },
234 /** URL used in `subscribe()`. */
235 subscribeUrl: {
236 type: String,
237 value: ''
238 },
239 /** URL used in `unsubscribe()`. */
240 unsubscribeUrl: {
241 type: String,
242 value: ''
243 },
244 /** URL used in `message()`. */
245 messageUrl: {
246 type: String,
247 value: ''
248 },
249 /** Long-polling connection url. */
250 longPollUrl: {
251 type: String,
252 value: ''
253 },
254 /** Long-polling connection url. */
255 shouldReconnect: {
256 type: Boolean,
257 value: true
258 },
259 /** Should send heartbeats. */
260 heartbeats: {
261 type: Boolean,
262 value: true
263 },
264 /** How much should every retry interval increase (in milliseconds) */
265 increaseBounceIv: {
266 type: Number,
267 value: 2000
268 },
269 _currentBounceIv: {
270 type: Number,
271 reflectToAttribute: true,
272 value: 0
273 },
274 /** Should use websockets or long-polling by default */
275 useWebsocket: {
276 type: Boolean,
277 reflectToAttribute: true,
278 value: true
279 },
280 connected: {
281 type: Boolean,
282 reflectToAttribute: true,
283 value: false
284 }
285 },
286
144
287 observers: [
145 /**
288 '_handleChannelsChange(channels.splices)'
146 * Fired when listening connection is opened.
289 ],
147 *
148 * @event channelstream-listen-opened
149 */
290
150
291 listeners: {
151 /**
292 'channelstream-connected': 'startListening',
152 * Fired when listening connection is closed.
293 'channelstream-connect-error': 'retryConnection',
153 *
294 },
154 * @event channelstream-listen-closed
155 */
295
156
296 /**
157 /**
297 * Mutators hold functions that you can set locally to change the data
158 * Fired when listening connection suffers an error.
298 * that the client is sending to all endpoints
159 *
299 * you can call it like `elem.mutators('connect', yourFunc())`
160 * @event channelstream-listen-error
300 * mutators will be executed in order they were pushed onto arrays
161 */
301 *
302 */
303 mutators: {
304 connect: function () {
305 return []
306 }(),
307 message: function () {
308 return []
309 }(),
310 subscribe: function () {
311 return []
312 }(),
313 unsubscribe: function () {
314 return []
315 }(),
316 disconnect: function () {
317 return []
318 }()
319 },
320 ready: function () {
321 this.isReady = true;
322 },
323
162
324 /**
163 properties: {
325 * Connects user and fetches connection id from the server.
164 isReady: Boolean,
326 *
165 /** List of channels user should be subscribed to. */
327 */
166 channels: {
328 connect: function () {
167 type: Array,
329 var request = this.$['ajaxConnect'];
168 value: function () {
330 request.url = this.connectUrl;
169 return []
331 request.body = {
332 username: this.username,
333 channels: this.channels
334 };
335 for (var i = 0; i < this.mutators.connect.length; i++) {
336 this.mutators.connect[i](request);
337 }
338 request.generateRequest()
339 },
340 /**
341 * Overwrite with custom function that will
342 */
343 addMutator: function (type, func) {
344 this.mutators[type].push(func);
345 },
170 },
346 /**
171 notify: true
347 * Subscribes user to channels.
172 },
348 *
173 /** Username of connecting user. */
349 */
174 username: {
350 subscribe: function (channels) {
175 type: String,
351 var request = this.$['ajaxSubscribe'];
176 value: 'Anonymous',
352 request.url = this.subscribeUrl;
177 reflectToAttribute: true
353 request.body = {
178 },
354 channels: channels,
179 /** Connection identifier. */
355 conn_id: this.connectionId
180 connectionId: {
356 };
181 type: String,
357 for (var i = 0; i < this.mutators.subscribe.length; i++) {
182 reflectToAttribute: true
358 this.mutators.subscribe[i](request);
183 },
359 }
184 /** Websocket instance. */
360 if (request.body.channels.length) {
185 websocket: {
361 request.generateRequest();
186 type: Object,
362 }
187 value: null
363 },
188 },
364 /**
189 /** Websocket connection url. */
365 * Unsubscribes user from channels.
190 websocketUrl: {
366 *
191 type: String,
367 */
192 value: ''
368 unsubscribe: function (unsubscribe) {
193 },
369 var request = this.$['ajaxUnsubscribe'];
194 /** URL used in `connect()`. */
195 connectUrl: {
196 type: String,
197 value: ''
198 },
199 /** URL used in `disconnect()`. */
200 disconnectUrl: {
201 type: String,
202 value: ''
203 },
204 /** URL used in `subscribe()`. */
205 subscribeUrl: {
206 type: String,
207 value: ''
208 },
209 /** URL used in `unsubscribe()`. */
210 unsubscribeUrl: {
211 type: String,
212 value: ''
213 },
214 /** URL used in `message()`. */
215 messageUrl: {
216 type: String,
217 value: ''
218 },
219 /** Long-polling connection url. */
220 longPollUrl: {
221 type: String,
222 value: ''
223 },
224 /** Long-polling connection url. */
225 shouldReconnect: {
226 type: Boolean,
227 value: true
228 },
229 /** Should send heartbeats. */
230 heartbeats: {
231 type: Boolean,
232 value: true
233 },
234 /** How much should every retry interval increase (in milliseconds) */
235 increaseBounceIv: {
236 type: Number,
237 value: 2000
238 },
239 _currentBounceIv: {
240 type: Number,
241 reflectToAttribute: true,
242 value: 0
243 },
244 /** Should use websockets or long-polling by default */
245 useWebsocket: {
246 type: Boolean,
247 reflectToAttribute: true,
248 value: true
249 },
250 connected: {
251 type: Boolean,
252 reflectToAttribute: true,
253 value: false
254 }
255 },
370
256
371 request.url = this.unsubscribeUrl;
257 observers: [
372 request.body = {
258 '_handleChannelsChange(channels.splices)'
373 channels: unsubscribe,
259 ],
374 conn_id: this.connectionId
375 };
376 for (var i = 0; i < this.mutators.unsubscribe.length; i++) {
377 this.mutators.unsubscribe[i](request);
378 }
379 request.generateRequest()
380 },
381
260
382 /**
261 listeners: {
383 * calculates list of channels we should add user to based on difference
262 'channelstream-connected': 'startListening',
384 * between channels property and passed channel list
263 'channelstream-connect-error': 'retryConnection',
385 */
264 },
386 calculateSubscribe: function (channels) {
265
387 var currentlySubscribed = this.channels;
266 /**
388 var toSubscribe = [];
267 * Mutators hold functions that you can set locally to change the data
389 for (var i = 0; i < channels.length; i++) {
268 * that the client is sending to all endpoints
390 if (currentlySubscribed.indexOf(channels[i]) === -1) {
269 * you can call it like `elem.mutators('connect', yourFunc())`
391 toSubscribe.push(channels[i]);
270 * mutators will be executed in order they were pushed onto arrays
392 }
271 *
393 }
272 */
394 return toSubscribe
273 mutators: {
395 },
274 connect: function () {
396 /**
275 return []
397 * calculates list of channels we should remove user from based difference
276 }(),
398 * between channels property and passed channel list
277 message: function () {
399 */
278 return []
400 calculateUnsubscribe: function (channels) {
279 }(),
401 var currentlySubscribed = this.channels;
280 subscribe: function () {
402 var toUnsubscribe = [];
281 return []
403 for (var i = 0; i < channels.length; i++) {
282 }(),
404 if (currentlySubscribed.indexOf(channels[i]) !== -1) {
283 unsubscribe: function () {
405 toUnsubscribe.push(channels[i]);
284 return []
406 }
285 }(),
407 }
286 disconnect: function () {
408 return toUnsubscribe
287 return []
409 },
288 }()
410 /**
289 },
411 * Marks the connection as expired.
290 ready: function () {
412 *
291 this.isReady = true;
413 */
292 },
414 disconnect: function () {
293
415 var request = this.$['ajaxDisconnect'];
294 /**
416 request.url = this.disconnectUrl;
295 * Connects user and fetches connection id from the server.
417 request.params = {
296 *
418 conn_id: this.connectionId
297 */
419 };
298 connect: function () {
420 for (var i = 0; i < this.mutators.disconnect.length; i++) {
299 var request = this.$['ajaxConnect'];
421 this.mutators.disconnect[i](request);
300 request.url = this.connectUrl;
422 }
301 request.body = {
423 // mark connection as expired
302 username: this.username,
424 request.generateRequest();
303 channels: this.channels
425 // disconnect existing connection
304 };
426 this.closeConnection();
305 for (var i = 0; i < this.mutators.connect.length; i++) {
427 },
306 this.mutators.connect[i](request);
307 }
308 request.generateRequest()
309 },
310 /**
311 * Overwrite with custom function that will
312 */
313 addMutator: function (type, func) {
314 this.mutators[type].push(func);
315 },
316 /**
317 * Subscribes user to channels.
318 *
319 */
320 subscribe: function (channels) {
321 var request = this.$['ajaxSubscribe'];
322 request.url = this.subscribeUrl;
323 request.body = {
324 channels: channels,
325 conn_id: this.connectionId
326 };
327 for (var i = 0; i < this.mutators.subscribe.length; i++) {
328 this.mutators.subscribe[i](request);
329 }
330 if (request.body.channels.length) {
331 request.generateRequest();
332 }
333 },
334 /**
335 * Unsubscribes user from channels.
336 *
337 */
338 unsubscribe: function (unsubscribe) {
339 var request = this.$['ajaxUnsubscribe'];
340
341 request.url = this.unsubscribeUrl;
342 request.body = {
343 channels: unsubscribe,
344 conn_id: this.connectionId
345 };
346 for (var i = 0; i < this.mutators.unsubscribe.length; i++) {
347 this.mutators.unsubscribe[i](request);
348 }
349 request.generateRequest()
350 },
428
351
429 /**
352 /**
430 * Sends a message to the server.
353 * calculates list of channels we should add user to based on difference
431 *
354 * between channels property and passed channel list
432 */
355 */
433 message: function (message) {
356 calculateSubscribe: function (channels) {
434 var request = this.$['ajaxMessage'];
357 var currentlySubscribed = this.channels;
435 request.url = this.messageUrl;
358 var toSubscribe = [];
436 request.body = message;
359 for (var i = 0; i < channels.length; i++) {
437 for (var i = 0; i < this.mutators.message.length; i++) {
360 if (currentlySubscribed.indexOf(channels[i]) === -1) {
438 this.mutators.message[i](request)
361 toSubscribe.push(channels[i]);
439 }
362 }
440 request.generateRequest();
363 }
441 },
364 return toSubscribe
442 /**
365 },
443 * Opens "long lived" (websocket/longpoll) connection to the channelstream server.
366 /**
444 *
367 * calculates list of channels we should remove user from based difference
445 */
368 * between channels property and passed channel list
446 startListening: function (event) {
369 */
447 this.fire('start-listening', {});
370 calculateUnsubscribe: function (channels) {
448 if (this.useWebsocket) {
371 var currentlySubscribed = this.channels;
449 this.useWebsocket = window.WebSocket ? true : false;
372 var toUnsubscribe = [];
450 }
373 for (var i = 0; i < channels.length; i++) {
451 if (this.useWebsocket) {
374 if (currentlySubscribed.indexOf(channels[i]) !== -1) {
452 this.openWebsocket();
375 toUnsubscribe.push(channels[i]);
453 }
376 }
454 else {
377 }
455 this.openLongPoll();
378 return toUnsubscribe
456 }
379 },
457 },
380 /**
458 /**
381 * Marks the connection as expired.
459 * Opens websocket connection.
382 *
460 *
383 */
461 */
384 disconnect: function () {
462 openWebsocket: function () {
385 var request = this.$['ajaxDisconnect'];
463 var url = this.websocketUrl + '?conn_id=' + this.connectionId;
386 request.url = this.disconnectUrl;
464 this.websocket = new WebSocket(url);
387 request.params = {
465 this.websocket.onopen = this._handleListenOpen.bind(this);
388 conn_id: this.connectionId
466 this.websocket.onclose = this._handleListenCloseEvent.bind(this);
389 };
467 this.websocket.onerror = this._handleListenErrorEvent.bind(this);
390 for (var i = 0; i < this.mutators.disconnect.length; i++) {
468 this.websocket.onmessage = this._handleListenMessageEvent.bind(this);
391 this.mutators.disconnect[i](request);
469 },
392 }
470 /**
393 // mark connection as expired
471 * Opens long-poll connection.
394 request.generateRequest();
472 *
395 // disconnect existing connection
473 */
396 this.closeConnection();
474 openLongPoll: function () {
397 },
475 var request = this.$['ajaxListen'];
476 request.url = this.longPollUrl + '?conn_id=' + this.connectionId;
477 request.generateRequest()
478 },
479 /**
480 * Retries `connect()` call while incrementing interval between tries up to 1 minute.
481 *
482 */
483 retryConnection: function () {
484 if (!this.shouldReconnect) {
485 return;
486 }
487 if (this._currentBounceIv < 60000) {
488 this._currentBounceIv = this._currentBounceIv + this.increaseBounceIv;
489 }
490 else {
491 this._currentBounceIv = 60000;
492 }
493 setTimeout(this.connect.bind(this), this._currentBounceIv);
494 },
495 /**
496 * Closes listening connection.
497 *
498 */
499 closeConnection: function () {
500 var request = this.$['ajaxListen'];
501 if (this.websocket && this.websocket.readyState === WebSocket.OPEN) {
502 this.websocket.onclose = null;
503 this.websocket.onerror = null;
504 this.websocket.close();
505 }
506 if (request.loading) {
507 request.lastRequest.abort();
508 }
509 this.connected = false;
510 },
511
398
512 _handleChannelsChange: function (event) {
399 /**
513 // do not fire the event if set() didn't mutate anything
400 * Sends a message to the server.
514 // is this a reliable way to do it?
401 *
515 if (!this.isReady || event === undefined) {
402 */
516 return
403 message: function (message) {
517 }
404 var request = this.$['ajaxMessage'];
518 this.fire('channelstream-channels-changed', event)
405 request.url = this.messageUrl;
519 },
406 request.body = message;
520
407 for (var i = 0; i < this.mutators.message.length; i++) {
521 _handleListenOpen: function (event) {
408 this.mutators.message[i](request)
522 this.connected = true;
409 }
523 this.fire('channelstream-listen-opened', event);
410 request.generateRequest();
524 this.createHeartBeats();