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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
80 | * Fired when `channels` array changes. | |
123 |
|
|
81 | * | |
124 |
|
|
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 |
|
|
86 | * Fired when `connect()` method succeeds. | |
135 |
|
|
87 | * | |
136 |
|
|
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 |
|
|
92 | * Fired when `connect` fails. | |
147 |
|
|
93 | * | |
148 |
|
|
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 |
|
|
98 | * Fired when `disconnect()` succeeds. | |
159 |
|
|
99 | * | |
160 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
re |
|
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 |
|
|
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 |
|
|
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(); |
|