##// END OF EJS Templates
js: migrate to polymer 3.x
ergo -
r3173:b3d618e2 default
parent child Browse files
Show More
@@ -45,6 +45,16 b''
45 45 "style-loader": "^0.21.0",
46 46 "webpack-uglify-js-plugin": "^1.1.9",
47 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 }
@@ -4,6 +4,222 b''
4 4
5 5 let
6 6 sources = {
7 "@polymer/font-roboto-3.0.2" = {
8 name = "_at_polymer_slash_font-roboto";
9 packageName = "@polymer/font-roboto";
10 version = "3.0.2";
11 src = fetchurl {
12 url = "https://registry.npmjs.org/@polymer/font-roboto/-/font-roboto-3.0.2.tgz";
13 sha512 = "tx5TauYSmzsIvmSqepUPDYbs4/Ejz2XbZ1IkD7JEGqkdNUJlh+9KU85G56Tfdk/xjEZ8zorFfN09OSwiMrIQWA==";
14 };
15 };
16 "@polymer/iron-a11y-announcer-3.0.1" = {
17 name = "_at_polymer_slash_iron-a11y-announcer";
18 packageName = "@polymer/iron-a11y-announcer";
19 version = "3.0.1";
20 src = fetchurl {
21 url = "https://registry.npmjs.org/@polymer/iron-a11y-announcer/-/iron-a11y-announcer-3.0.1.tgz";
22 sha512 = "Xiqmpz0AEEbMNGYPpbrXBIrcI/xaR4tn77pmSLfxVKGGwjEUR/YrRgyIwXp4EN7lvst1dFC8kyl2hLga0uDIVQ==";
23 };
24 };
25 "@polymer/iron-a11y-keys-3.0.1" = {
26 name = "_at_polymer_slash_iron-a11y-keys";
27 packageName = "@polymer/iron-a11y-keys";
28 version = "3.0.1";
29 src = fetchurl {
30 url = "https://registry.npmjs.org/@polymer/iron-a11y-keys/-/iron-a11y-keys-3.0.1.tgz";
31 sha512 = "zmTi8xHeY4ZMJLAitW2hAmW5zXZ35hVy/eHQUFadAlOccuBK3oRRmoPRQRaZgpyJrCVFDAQRXXzzJtUDil/0CA==";
32 };
33 };
34 "@polymer/iron-a11y-keys-behavior-3.0.1" = {
35 name = "_at_polymer_slash_iron-a11y-keys-behavior";
36 packageName = "@polymer/iron-a11y-keys-behavior";
37 version = "3.0.1";
38 src = fetchurl {
39 url = "https://registry.npmjs.org/@polymer/iron-a11y-keys-behavior/-/iron-a11y-keys-behavior-3.0.1.tgz";
40 sha512 = "lnrjKq3ysbBPT/74l0Fj0U9H9C35Tpw2C/tpJ8a+5g8Y3YJs1WSZYnEl1yOkw6sEyaxOq/1DkzH0+60gGu5/PQ==";
41 };
42 };
43 "@polymer/iron-ajax-3.0.1" = {
44 name = "_at_polymer_slash_iron-ajax";
45 packageName = "@polymer/iron-ajax";
46 version = "3.0.1";
47 src = fetchurl {
48 url = "https://registry.npmjs.org/@polymer/iron-ajax/-/iron-ajax-3.0.1.tgz";
49 sha512 = "7+TPEAfWsRdhj1Y8UeF1759ktpVu+c3sG16rJiUC3wF9+woQ9xI1zUm2d59i7Yc3aDEJrR/Q8Y262KlOvyGVNg==";
50 };
51 };
52 "@polymer/iron-autogrow-textarea-3.0.1" = {
53 name = "_at_polymer_slash_iron-autogrow-textarea";
54 packageName = "@polymer/iron-autogrow-textarea";
55 version = "3.0.1";
56 src = fetchurl {
57 url = "https://registry.npmjs.org/@polymer/iron-autogrow-textarea/-/iron-autogrow-textarea-3.0.1.tgz";
58 sha512 = "FgSL7APrOSL9Vu812sBCFlQ17hvnJsBAV2C2e1UAiaHhB+dyfLq8gGdGUpqVWuGJ50q4Y/49QwCNnLf85AdVYA==";
59 };
60 };
61 "@polymer/iron-behaviors-3.0.1" = {
62 name = "_at_polymer_slash_iron-behaviors";
63 packageName = "@polymer/iron-behaviors";
64 version = "3.0.1";
65 src = fetchurl {
66 url = "https://registry.npmjs.org/@polymer/iron-behaviors/-/iron-behaviors-3.0.1.tgz";
67 sha512 = "IMEwcv1lhf1HSQxuyWOUIL0lOBwmeaoSTpgCJeP9IBYnuB1SPQngmfRuHKgK6/m9LQ9F9miC7p3HeQQUdKAE0w==";
68 };
69 };
70 "@polymer/iron-checked-element-behavior-3.0.1" = {
71 name = "_at_polymer_slash_iron-checked-element-behavior";
72 packageName = "@polymer/iron-checked-element-behavior";
73 version = "3.0.1";
74 src = fetchurl {
75 url = "https://registry.npmjs.org/@polymer/iron-checked-element-behavior/-/iron-checked-element-behavior-3.0.1.tgz";
76 sha512 = "aDr0cbCNVq49q+pOqa6CZutFh+wWpwPMLpEth9swx+GkAj+gCURhuQkaUYhIo5f2egDbEioR1aeHMnPlU9dQZA==";
77 };
78 };
79 "@polymer/iron-fit-behavior-3.0.1" = {
80 name = "_at_polymer_slash_iron-fit-behavior";
81 packageName = "@polymer/iron-fit-behavior";
82 version = "3.0.1";
83 src = fetchurl {
84 url = "https://registry.npmjs.org/@polymer/iron-fit-behavior/-/iron-fit-behavior-3.0.1.tgz";
85 sha512 = "/M0B1L30k31vmwNBaGuZcxzUAhJSHoGccb/DF0CDKI/hT8UlkTvcyemaWdOpmHHLgY52ceKIkRwA3AeXrKyvaQ==";
86 };
87 };
88 "@polymer/iron-flex-layout-3.0.1" = {
89 name = "_at_polymer_slash_iron-flex-layout";
90 packageName = "@polymer/iron-flex-layout";
91 version = "3.0.1";
92 src = fetchurl {
93 url = "https://registry.npmjs.org/@polymer/iron-flex-layout/-/iron-flex-layout-3.0.1.tgz";
94 sha512 = "7gB869czArF+HZcPTVSgvA7tXYFze9EKckvM95NB7SqYF+NnsQyhoXgKnpFwGyo95lUjUW9TFDLUwDXnCYFtkw==";
95 };
96 };
97 "@polymer/iron-form-element-behavior-3.0.1" = {
98 name = "_at_polymer_slash_iron-form-element-behavior";
99 packageName = "@polymer/iron-form-element-behavior";
100 version = "3.0.1";
101 src = fetchurl {
102 url = "https://registry.npmjs.org/@polymer/iron-form-element-behavior/-/iron-form-element-behavior-3.0.1.tgz";
103 sha512 = "G/e2KXyL5AY7mMjmomHkGpgS0uAf4ovNpKhkuUTRnMuMJuf589bKqE85KN4ovE1Tzhv2hJoh/igyD6ekHiYU1A==";
104 };
105 };
106 "@polymer/iron-meta-3.0.1" = {
107 name = "_at_polymer_slash_iron-meta";
108 packageName = "@polymer/iron-meta";
109 version = "3.0.1";
110 src = fetchurl {
111 url = "https://registry.npmjs.org/@polymer/iron-meta/-/iron-meta-3.0.1.tgz";
112 sha512 = "pWguPugiLYmWFV9UWxLWzZ6gm4wBwQdDy4VULKwdHCqR7OP7u98h+XDdGZsSlDPv6qoryV/e3tGHlTIT0mbzJA==";
113 };
114 };
115 "@polymer/iron-overlay-behavior-3.0.2" = {
116 name = "_at_polymer_slash_iron-overlay-behavior";
117 packageName = "@polymer/iron-overlay-behavior";
118 version = "3.0.2";
119 src = fetchurl {
120 url = "https://registry.npmjs.org/@polymer/iron-overlay-behavior/-/iron-overlay-behavior-3.0.2.tgz";
121 sha512 = "j1qmt6mJHCwpe1mKOvqK5kcCUPQr5LSrlqpgRDbUuLgUfNJ/vGTipjrkBlfbEUagm5FEQdc1VLPLSQP6WVuP9g==";
122 };
123 };
124 "@polymer/iron-resizable-behavior-3.0.1" = {
125 name = "_at_polymer_slash_iron-resizable-behavior";
126 packageName = "@polymer/iron-resizable-behavior";
127 version = "3.0.1";
128 src = fetchurl {
129 url = "https://registry.npmjs.org/@polymer/iron-resizable-behavior/-/iron-resizable-behavior-3.0.1.tgz";
130 sha512 = "FyHxRxFspVoRaeZSWpT3y0C9awomb4tXXolIJcZ7RvXhMP632V5lez+ch5G5SwK0LpnAPkg35eB0LPMFv+YMMQ==";
131 };
132 };
133 "@polymer/iron-validatable-behavior-3.0.1" = {
134 name = "_at_polymer_slash_iron-validatable-behavior";
135 packageName = "@polymer/iron-validatable-behavior";
136 version = "3.0.1";
137 src = fetchurl {
138 url = "https://registry.npmjs.org/@polymer/iron-validatable-behavior/-/iron-validatable-behavior-3.0.1.tgz";
139 sha512 = "wwpYh6wOa4fNI+jH5EYKC7TVPYQ2OfgQqocWat7GsNWcsblKYhLYbwsvEY5nO0n2xKqNfZzDLrUom5INJN7msQ==";
140 };
141 };
142 "@polymer/paper-behaviors-3.0.1" = {
143 name = "_at_polymer_slash_paper-behaviors";
144 packageName = "@polymer/paper-behaviors";
145 version = "3.0.1";
146 src = fetchurl {
147 url = "https://registry.npmjs.org/@polymer/paper-behaviors/-/paper-behaviors-3.0.1.tgz";
148 sha512 = "6knhj69fPJejv8qR0kCSUY+Q0XjaUf0OSnkjRjmTJPAwSrRYtgqE+l6P1FfA+py1X/cUjgne9EF5rMZAKJIg1g==";
149 };
150 };
151 "@polymer/paper-button-3.0.1" = {
152 name = "_at_polymer_slash_paper-button";
153 packageName = "@polymer/paper-button";
154 version = "3.0.1";
155 src = fetchurl {
156 url = "https://registry.npmjs.org/@polymer/paper-button/-/paper-button-3.0.1.tgz";
157 sha512 = "JRNBc+Oj9EWnmyLr7FcCr8T1KAnEHPh6mosln9BUdkM+qYaYsudSICh3cjTIbnj6AuF5OJidoLkM1dlyj0j6Zg==";
158 };
159 };
160 "@polymer/paper-ripple-3.0.1" = {
161 name = "_at_polymer_slash_paper-ripple";
162 packageName = "@polymer/paper-ripple";
163 version = "3.0.1";
164 src = fetchurl {
165 url = "https://registry.npmjs.org/@polymer/paper-ripple/-/paper-ripple-3.0.1.tgz";
166 sha512 = "dgOe12GyCF1VZBLUQqnzGWlf3xb255FajNCVB1VFj/AtskYtoamnafa7m3a+1vs+C8qbg4Benn5KwgxVDSW4cg==";
167 };
168 };
169 "@polymer/paper-spinner-3.0.1" = {
170 name = "_at_polymer_slash_paper-spinner";
171 packageName = "@polymer/paper-spinner";
172 version = "3.0.1";
173 src = fetchurl {
174 url = "https://registry.npmjs.org/@polymer/paper-spinner/-/paper-spinner-3.0.1.tgz";
175 sha512 = "MYIU6qWZnhZ5yNFOBzROPgBteGfxKEnDZ6bCgjrvUtJkBuQEz0MQZzSE/zmZc0oaJ9u5QK5xAFuYdudsGv7+sQ==";
176 };
177 };
178 "@polymer/paper-styles-3.0.1" = {
179 name = "_at_polymer_slash_paper-styles";
180 packageName = "@polymer/paper-styles";
181 version = "3.0.1";
182 src = fetchurl {
183 url = "https://registry.npmjs.org/@polymer/paper-styles/-/paper-styles-3.0.1.tgz";
184 sha512 = "y6hmObLqlCx602TQiSBKHqjwkE7xmDiFkoxdYGaNjtv4xcysOTdVJsDR/R9UHwIaxJ7gHlthMSykir1nv78++g==";
185 };
186 };
187 "@polymer/paper-toast-3.0.1" = {
188 name = "_at_polymer_slash_paper-toast";
189 packageName = "@polymer/paper-toast";
190 version = "3.0.1";
191 src = fetchurl {
192 url = "https://registry.npmjs.org/@polymer/paper-toast/-/paper-toast-3.0.1.tgz";
193 sha512 = "pizuogzObniDdICUc6dSLrnDt2VzzoRne1gCmbD6sfOATVv5tc8UfrqhA2iHngbNBEbniBiciS3iogdp5KTVUQ==";
194 };
195 };
196 "@polymer/paper-toggle-button-3.0.1" = {
197 name = "_at_polymer_slash_paper-toggle-button";
198 packageName = "@polymer/paper-toggle-button";
199 version = "3.0.1";
200 src = fetchurl {
201 url = "https://registry.npmjs.org/@polymer/paper-toggle-button/-/paper-toggle-button-3.0.1.tgz";
202 sha512 = "jadZB60fycT7YnSAH0H23LYo6/2HYmMZTtNr9LpdSIRFPLX6mqqxewex92cFz019bMKaRJgORn308hRlJo2u6A==";
203 };
204 };
205 "@polymer/paper-tooltip-3.0.1" = {
206 name = "_at_polymer_slash_paper-tooltip";
207 packageName = "@polymer/paper-tooltip";
208 version = "3.0.1";
209 src = fetchurl {
210 url = "https://registry.npmjs.org/@polymer/paper-tooltip/-/paper-tooltip-3.0.1.tgz";
211 sha512 = "yiUk09opTEnE1lK+tb501ENb+yQBi4p++Ep0eGJAHesVYKVMPNgPphVKkIizkDaU+n0SE+zXfTsRbYyOMDYXSg==";
212 };
213 };
214 "@polymer/polymer-3.1.0" = {
215 name = "_at_polymer_slash_polymer";
216 packageName = "@polymer/polymer";
217 version = "3.1.0";
218 src = fetchurl {
219 url = "https://registry.npmjs.org/@polymer/polymer/-/polymer-3.1.0.tgz";
220 sha512 = "hwN8IMERsFATz/9dSMxYHL+84J9uBkPuuarxJWlTsppZ4CAYTZKnepBfNrKoyNsafBmA3yXBiiKPPf+fJtza7A==";
221 };
222 };
7 223 "@types/clone-0.1.30" = {
8 224 name = "_at_types_slash_clone";
9 225 packageName = "@types/clone";
@@ -193,6 +409,24 b' let'
193 409 sha512 = "mJ3QKWtCchL1vhU/kZlJnLPuQZnlDOdZsyP0bbLWPGdYsQDnSBvyTLhzwBA3QAMlzEL9V4JHygEmK6/OTEyytA==";
194 410 };
195 411 };
412 "@webcomponents/shadycss-1.5.2" = {
413 name = "_at_webcomponents_slash_shadycss";
414 packageName = "@webcomponents/shadycss";
415 version = "1.5.2";
416 src = fetchurl {
417 url = "https://registry.npmjs.org/@webcomponents/shadycss/-/shadycss-1.5.2.tgz";
418 sha512 = "0OyrmVc7S+INtzoqP2ofAo+OdVn2Nj0Qvq4wD9FEGN7nMmLRxaD2mzy6hD6EslzxUSuGH302CDU4KXiY66SEqg==";
419 };
420 };
421 "@webcomponents/webcomponentsjs-2.1.3" = {
422 name = "_at_webcomponents_slash_webcomponentsjs";
423 packageName = "@webcomponents/webcomponentsjs";
424 version = "2.1.3";
425 src = fetchurl {
426 url = "https://registry.npmjs.org/@webcomponents/webcomponentsjs/-/webcomponentsjs-2.1.3.tgz";
427 sha512 = "0UHJNY88lR3pnEYtBVT7F8cuuxOiITQGWJa0LxoELqkBSB7IabzJFOj5K99PajD3CGAsWpjB0CAeijfe376Y1w==";
428 };
429 };
196 430 "@xtuc/ieee754-1.2.0" = {
197 431 name = "_at_xtuc_slash_ieee754";
198 432 packageName = "@xtuc/ieee754";
@@ -1454,13 +1688,13 b' let'
1454 1688 sha1 = "b534e7c734c4f81ec5fbe8aca2ad24354b962c6c";
1455 1689 };
1456 1690 };
1457 "caniuse-db-1.0.30000899" = {
1691 "caniuse-db-1.0.30000900" = {
1458 1692 name = "caniuse-db";
1459 1693 packageName = "caniuse-db";
1460 version = "1.0.30000899";
1461 src = fetchurl {
1462 url = "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000899.tgz";
1463 sha512 = "MSCUohyoLU4/PGapapw/PLQkmQ+sFgzX6e3tM6ue8HX9HW9rBD5gRiAYKhC8r0QkvUE0pWTA8Ze6f3jrzBizVg==";
1694 version = "1.0.30000900";
1695 src = fetchurl {
1696 url = "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000900.tgz";
1697 sha512 = "fvicVRDlhHIQpt/bmbLl3hDHKUZb5ZP8O2OuZLz2fSEPlUBbvwwbhhqhGS617ldN6bDoo9A3+MQKQyFq0p7UXA==";
1464 1698 };
1465 1699 };
1466 1700 "caniuse-lite-1.0.30000899" = {
@@ -7482,6 +7716,30 b' let'
7482 7716 version = "1.0.0";
7483 7717 src = ./..;
7484 7718 dependencies = [
7719 sources."@polymer/font-roboto-3.0.2"
7720 sources."@polymer/iron-a11y-announcer-3.0.1"
7721 sources."@polymer/iron-a11y-keys-3.0.1"
7722 sources."@polymer/iron-a11y-keys-behavior-3.0.1"
7723 sources."@polymer/iron-ajax-3.0.1"
7724 sources."@polymer/iron-autogrow-textarea-3.0.1"
7725 sources."@polymer/iron-behaviors-3.0.1"
7726 sources."@polymer/iron-checked-element-behavior-3.0.1"
7727 sources."@polymer/iron-fit-behavior-3.0.1"
7728 sources."@polymer/iron-flex-layout-3.0.1"
7729 sources."@polymer/iron-form-element-behavior-3.0.1"
7730 sources."@polymer/iron-meta-3.0.1"
7731 sources."@polymer/iron-overlay-behavior-3.0.2"
7732 sources."@polymer/iron-resizable-behavior-3.0.1"
7733 sources."@polymer/iron-validatable-behavior-3.0.1"
7734 sources."@polymer/paper-behaviors-3.0.1"
7735 sources."@polymer/paper-button-3.0.1"
7736 sources."@polymer/paper-ripple-3.0.1"
7737 sources."@polymer/paper-spinner-3.0.1"
7738 sources."@polymer/paper-styles-3.0.1"
7739 sources."@polymer/paper-toast-3.0.1"
7740 sources."@polymer/paper-toggle-button-3.0.1"
7741 sources."@polymer/paper-tooltip-3.0.1"
7742 sources."@polymer/polymer-3.1.0"
7485 7743 sources."@types/clone-0.1.30"
7486 7744 sources."@types/node-6.14.0"
7487 7745 sources."@types/parse5-2.2.34"
@@ -7503,6 +7761,8 b' let'
7503 7761 sources."@webassemblyjs/wasm-parser-1.7.10"
7504 7762 sources."@webassemblyjs/wast-parser-1.7.10"
7505 7763 sources."@webassemblyjs/wast-printer-1.7.10"
7764 sources."@webcomponents/shadycss-1.5.2"
7765 sources."@webcomponents/webcomponentsjs-2.1.3"
7506 7766 sources."@xtuc/ieee754-1.2.0"
7507 7767 sources."@xtuc/long-4.2.1"
7508 7768 sources."abbrev-1.1.1"
@@ -7716,7 +7976,7 b' let'
7716 7976 sources."browserslist-1.7.7"
7717 7977 ];
7718 7978 })
7719 sources."caniuse-db-1.0.30000899"
7979 sources."caniuse-db-1.0.30000900"
7720 7980 sources."caniuse-lite-1.0.30000899"
7721 7981 sources."caseless-0.12.0"
7722 7982 sources."center-align-0.1.3"
This diff has been collapsed as it changes many lines, (1003 lines changed) Show them Hide them
@@ -1,39 +1,8 b''
1 <link rel="import" href="../../../../../../bower_components/polymer/polymer.html">
2 <link rel="import" href="../../../../../../bower_components/iron-ajax/iron-ajax.html">
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:
1 import {Polymer, html} from '@polymer/polymer/polymer-legacy';
2 import '@polymer/iron-ajax/iron-ajax.js';
10 3
11 <body>
12 <channelstream-connection
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
4 const elemTemplate = html`
5 <iron-ajax
37 6 id="ajaxConnect"
38 7 url=""
39 8 handle-as="json"
@@ -45,7 +14,7 b' this handler will forever try to re-esta'
45 14 on-error="_handleConnectError"
46 15 debounce-duration="100"></iron-ajax>
47 16
48 <iron-ajax
17 <iron-ajax
49 18 id="ajaxDisconnect"
50 19 url=""
51 20 handle-as="json"
@@ -56,7 +25,7 b' this handler will forever try to re-esta'
56 25 on-response="_handleDisconnect"
57 26 debounce-duration="100"></iron-ajax>
58 27
59 <iron-ajax
28 <iron-ajax
60 29 id="ajaxSubscribe"
61 30 url=""
62 31 handle-as="json"
@@ -67,7 +36,7 b' this handler will forever try to re-esta'
67 36 on-response="_handleSubscribe"
68 37 debounce-duration="100"></iron-ajax>
69 38
70 <iron-ajax
39 <iron-ajax
71 40 id="ajaxUnsubscribe"
72 41 url=""
73 42 handle-as="json"
@@ -78,7 +47,7 b' this handler will forever try to re-esta'
78 47 on-response="_handleUnsubscribe"
79 48 debounce-duration="100"></iron-ajax>
80 49
81 <iron-ajax
50 <iron-ajax
82 51 id="ajaxMessage"
83 52 url=""
84 53 handle-as="json"
@@ -90,7 +59,7 b' this handler will forever try to re-esta'
90 59 on-error="_handleMessageError"
91 60 debounce-duration="100"></iron-ajax>
92 61
93 <iron-ajax
62 <iron-ajax
94 63 id="ajaxListen"
95 64 url=""
96 65 handle-as="text"
@@ -100,511 +69,509 b' this handler will forever try to re-esta'
100 69 on-error="_handleListenError"
101 70 on-response="_handleListenMessageEvent"
102 71 debounce-duration="100"></iron-ajax>
103
104 </template>
105 <script>
106 Polymer({
107 is: 'channelstream-connection',
72 `
108 73
109 /**
110 * Fired when `channels` array changes.
111 *
112 * @event channelstream-channels-changed
113 */
74 Polymer({
75 is: 'channelstream-connection',
114 76
115 /**
116 * Fired when `connect()` method succeeds.
117 *
118 * @event channelstream-connected
119 */
77 _template: elemTemplate,
120 78
121 /**
122 * Fired when `connect` fails.
123 *
124 * @event channelstream-connect-error
125 */
126
127 /**
128 * Fired when `disconnect()` succeeds.
129 *
130 * @event channelstream-disconnected
131 */
79 /**
80 * Fired when `channels` array changes.
81 *
82 * @event channelstream-channels-changed
83 */
132 84
133 /**
134 * Fired when `message()` succeeds.
135 *
136 * @event channelstream-message-sent
137 */
138
139 /**
140 * Fired when `message()` fails.
141 *
142 * @event channelstream-message-error
143 */
85 /**
86 * Fired when `connect()` method succeeds.
87 *
88 * @event channelstream-connected
89 */
144 90
145 /**
146 * Fired when `subscribe()` succeeds.
147 *
148 * @event channelstream-subscribed
149 */
150
151 /**
152 * Fired when `subscribe()` fails.
153 *
154 * @event channelstream-subscribe-error
155 */
91 /**
92 * Fired when `connect` fails.
93 *
94 * @event channelstream-connect-error
95 */
156 96
157 /**
158 * Fired when `unsubscribe()` succeeds.
159 *
160 * @event channelstream-unsubscribed
161 */
162
163 /**
164 * Fired when `unsubscribe()` fails.
165 *
166 * @event channelstream-unsubscribe-error
167 */
97 /**
98 * Fired when `disconnect()` succeeds.
99 *
100 * @event channelstream-disconnected
101 */
168 102
169 /**
170 * Fired when listening connection receives a message.
171 *
172 * @event channelstream-listen-message
173 */
174
175 /**
176 * Fired when listening connection is opened.
177 *
178 * @event channelstream-listen-opened
179 */
103 /**
104 * Fired when `message()` succeeds.
105 *
106 * @event channelstream-message-sent
107 */
180 108
181 /**
182 * Fired when listening connection is closed.
183 *
184 * @event channelstream-listen-closed
185 */
109 /**
110 * Fired when `message()` fails.
111 *
112 * @event channelstream-message-error
113 */
186 114
187 /**
188 * Fired when listening connection suffers an error.
189 *
190 * @event channelstream-listen-error
191 */
115 /**
116 * Fired when `subscribe()` succeeds.
117 *
118 * @event channelstream-subscribed
119 */
192 120
193 properties: {
194 isReady: Boolean,
195 /** List of channels user should be subscribed to. */
196 channels: {
197 type: Array,
198 value: function () {
199 return []
200 },
201 notify: true
202 },
203 /** Username of connecting user. */
204 username: {
205 type: String,
206 value: 'Anonymous',
207 reflectToAttribute: true
208 },
209 /** Connection identifier. */
210 connectionId: {
211 type: String,
212 reflectToAttribute: true
213 },
214 /** Websocket instance. */
215 websocket: {
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 },
121 /**
122 * Fired when `subscribe()` fails.
123 *
124 * @event channelstream-subscribe-error
125 */
126
127 /**
128 * Fired when `unsubscribe()` succeeds.
129 *
130 * @event channelstream-unsubscribed
131 */
132
133 /**
134 * Fired when `unsubscribe()` fails.
135 *
136 * @event channelstream-unsubscribe-error
137 */
138
139 /**
140 * Fired when listening connection receives a message.
141 *
142 * @event channelstream-listen-message
143 */
286 144
287 observers: [
288 '_handleChannelsChange(channels.splices)'
289 ],
145 /**
146 * Fired when listening connection is opened.
147 *
148 * @event channelstream-listen-opened
149 */
290 150
291 listeners: {
292 'channelstream-connected': 'startListening',
293 'channelstream-connect-error': 'retryConnection',
294 },
151 /**
152 * Fired when listening connection is closed.
153 *
154 * @event channelstream-listen-closed
155 */
295 156
296 /**
297 * Mutators hold functions that you can set locally to change the data
298 * that the client is sending to all endpoints
299 * you can call it like `elem.mutators('connect', yourFunc())`
300 * mutators will be executed in order they were pushed onto arrays
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 },
157 /**
158 * Fired when listening connection suffers an error.
159 *
160 * @event channelstream-listen-error
161 */
323 162
324 /**
325 * Connects user and fetches connection id from the server.
326 *
327 */
328 connect: function () {
329 var request = this.$['ajaxConnect'];
330 request.url = this.connectUrl;
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);
163 properties: {
164 isReady: Boolean,
165 /** List of channels user should be subscribed to. */
166 channels: {
167 type: Array,
168 value: function () {
169 return []
345 170 },
346 /**
347 * Subscribes user to channels.
348 *
349 */
350 subscribe: function (channels) {
351 var request = this.$['ajaxSubscribe'];
352 request.url = this.subscribeUrl;
353 request.body = {
354 channels: channels,
355 conn_id: this.connectionId
356 };
357 for (var i = 0; i < this.mutators.subscribe.length; i++) {
358 this.mutators.subscribe[i](request);
359 }
360 if (request.body.channels.length) {
361 request.generateRequest();
362 }
363 },
364 /**
365 * Unsubscribes user from channels.
366 *
367 */
368 unsubscribe: function (unsubscribe) {
369 var request = this.$['ajaxUnsubscribe'];
171 notify: true
172 },
173 /** Username of connecting user. */
174 username: {
175 type: String,
176 value: 'Anonymous',
177 reflectToAttribute: true
178 },
179 /** Connection identifier. */
180 connectionId: {
181 type: String,
182 reflectToAttribute: true
183 },
184 /** Websocket instance. */
185 websocket: {
186 type: Object,
187 value: null
188 },
189 /** Websocket connection url. */
190 websocketUrl: {
191 type: String,
192 value: ''
193 },
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;
372 request.body = {
373 channels: unsubscribe,
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 },
257 observers: [
258 '_handleChannelsChange(channels.splices)'
259 ],
381 260
382 /**
383 * calculates list of channels we should add user to based on difference
384 * between channels property and passed channel list
385 */
386 calculateSubscribe: function (channels) {
387 var currentlySubscribed = this.channels;
388 var toSubscribe = [];
389 for (var i = 0; i < channels.length; i++) {
390 if (currentlySubscribed.indexOf(channels[i]) === -1) {
391 toSubscribe.push(channels[i]);
392 }
393 }
394 return toSubscribe
395 },
396 /**
397 * calculates list of channels we should remove user from based difference
398 * between channels property and passed channel list
399 */
400 calculateUnsubscribe: function (channels) {
401 var currentlySubscribed = this.channels;
402 var toUnsubscribe = [];
403 for (var i = 0; i < channels.length; i++) {
404 if (currentlySubscribed.indexOf(channels[i]) !== -1) {
405 toUnsubscribe.push(channels[i]);
406 }
407 }
408 return toUnsubscribe
409 },
410 /**
411 * Marks the connection as expired.
412 *
413 */
414 disconnect: function () {
415 var request = this.$['ajaxDisconnect'];
416 request.url = this.disconnectUrl;
417 request.params = {
418 conn_id: this.connectionId
419 };
420 for (var i = 0; i < this.mutators.disconnect.length; i++) {
421 this.mutators.disconnect[i](request);
422 }
423 // mark connection as expired
424 request.generateRequest();
425 // disconnect existing connection
426 this.closeConnection();
427 },
261 listeners: {
262 'channelstream-connected': 'startListening',
263 'channelstream-connect-error': 'retryConnection',
264 },
265
266 /**
267 * Mutators hold functions that you can set locally to change the data
268 * that the client is sending to all endpoints
269 * you can call it like `elem.mutators('connect', yourFunc())`
270 * mutators will be executed in order they were pushed onto arrays
271 *
272 */
273 mutators: {
274 connect: function () {
275 return []
276 }(),
277 message: function () {
278 return []
279 }(),
280 subscribe: function () {
281 return []
282 }(),
283 unsubscribe: function () {
284 return []
285 }(),
286 disconnect: function () {
287 return []
288 }()
289 },
290 ready: function () {
291 this.isReady = true;
292 },
293
294 /**
295 * Connects user and fetches connection id from the server.
296 *
297 */
298 connect: function () {
299 var request = this.$['ajaxConnect'];
300 request.url = this.connectUrl;
301 request.body = {
302 username: this.username,
303 channels: this.channels
304 };
305 for (var i = 0; i < this.mutators.connect.length; i++) {
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 /**
430 * Sends a message to the server.
431 *
432 */
433 message: function (message) {
434 var request = this.$['ajaxMessage'];
435 request.url = this.messageUrl;
436 request.body = message;
437 for (var i = 0; i < this.mutators.message.length; i++) {
438 this.mutators.message[i](request)
439 }
440 request.generateRequest();
441 },
442 /**
443 * Opens "long lived" (websocket/longpoll) connection to the channelstream server.
444 *
445 */
446 startListening: function (event) {
447 this.fire('start-listening', {});
448 if (this.useWebsocket) {
449 this.useWebsocket = window.WebSocket ? true : false;
450 }
451 if (this.useWebsocket) {
452 this.openWebsocket();
453 }
454 else {
455 this.openLongPoll();
456 }
457 },
458 /**
459 * Opens websocket connection.
460 *
461 */
462 openWebsocket: function () {
463 var url = this.websocketUrl + '?conn_id=' + this.connectionId;
464 this.websocket = new WebSocket(url);
465 this.websocket.onopen = this._handleListenOpen.bind(this);
466 this.websocket.onclose = this._handleListenCloseEvent.bind(this);
467 this.websocket.onerror = this._handleListenErrorEvent.bind(this);
468 this.websocket.onmessage = this._handleListenMessageEvent.bind(this);
469 },
470 /**
471 * Opens long-poll connection.
472 *
473 */
474 openLongPoll: function () {
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 },
352 /**
353 * calculates list of channels we should add user to based on difference
354 * between channels property and passed channel list
355 */
356 calculateSubscribe: function (channels) {
357 var currentlySubscribed = this.channels;
358 var toSubscribe = [];
359 for (var i = 0; i < channels.length; i++) {
360 if (currentlySubscribed.indexOf(channels[i]) === -1) {
361 toSubscribe.push(channels[i]);
362 }
363 }
364 return toSubscribe
365 },
366 /**
367 * calculates list of channels we should remove user from based difference
368 * between channels property and passed channel list
369 */
370 calculateUnsubscribe: function (channels) {
371 var currentlySubscribed = this.channels;
372 var toUnsubscribe = [];
373 for (var i = 0; i < channels.length; i++) {
374 if (currentlySubscribed.indexOf(channels[i]) !== -1) {
375 toUnsubscribe.push(channels[i]);
376 }
377 }
378 return toUnsubscribe
379 },
380 /**
381 * Marks the connection as expired.
382 *
383 */
384 disconnect: function () {
385 var request = this.$['ajaxDisconnect'];
386 request.url = this.disconnectUrl;
387 request.params = {
388 conn_id: this.connectionId
389 };
390 for (var i = 0; i < this.mutators.disconnect.length; i++) {
391 this.mutators.disconnect[i](request);
392 }
393 // mark connection as expired
394 request.generateRequest();
395 // disconnect existing connection
396 this.closeConnection();
397 },
511 398
512 _handleChannelsChange: function (event) {
513 // do not fire the event if set() didn't mutate anything
514 // is this a reliable way to do it?
515 if (!this.isReady || event === undefined) {
516 return
517 }
518 this.fire('channelstream-channels-changed', event)
519 },
520
521 _handleListenOpen: function (event) {
522 this.connected = true;
523 this.fire('channelstream-listen-opened', event);
524 this.createHeartBeats();
525 },
526
527 createHeartBeats: function () {
528 if (typeof self._heartbeat === 'undefined' && this.websocket !== null
529 && this.heartbeats) {
530 self._heartbeat = setInterval(this._sendHeartBeat.bind(this), 10000);
531 }
532 },
533
534 _sendHeartBeat: function () {
535 if (this.websocket.readyState === WebSocket.OPEN && this.heartbeats) {
536 this.websocket.send(JSON.stringify({type: 'heartbeat'}));
537 }
538 },
539
540 _handleListenError: function (event) {
541 this.connected = false;
542 this.retryConnection();
543 },
544 _handleConnectError: function (event) {
545 this.connected = false;
546 this.fire('channelstream-connect-error', event.detail);
547 },
548
549 _handleListenMessageEvent: function (event) {
550 var data = null;
551 // comes from iron-ajax
552 if (event.detail) {
553 data = JSON.parse(event.detail.response)
554 // comes from websocket
555 setTimeout(this.openLongPoll.bind(this), 0);
556 } else {
557 data = JSON.parse(event.data)
558 }
559 this.fire('channelstream-listen-message', data);
399 /**
400 * Sends a message to the server.
401 *
402 */
403 message: function (message) {
404 var request = this.$['ajaxMessage'];
405 request.url = this.messageUrl;
406 request.body = message;
407 for (var i = 0; i < this.mutators.message.length; i++) {
408 this.mutators.message[i](request)
409 }
410 request.generateRequest();
411 },
412 /**
413 * Opens "long lived" (websocket/longpoll) connection to the channelstream server.
414 *
415 */
416 startListening: function (event) {
417 this.fire('start-listening', {});
418 if (this.useWebsocket) {
419 this.useWebsocket = window.WebSocket ? true : false;
420 }
421 if (this.useWebsocket) {
422 this.openWebsocket();
423 }
424 else {
425 this.openLongPoll();
426 }
427 },
428 /**
429 * Opens websocket connection.
430 *
431 */
432 openWebsocket: function () {
433 var url = this.websocketUrl + '?conn_id=' + this.connectionId;
434 this.websocket = new WebSocket(url);
435 this.websocket.onopen = this._handleListenOpen.bind(this);
436 this.websocket.onclose = this._handleListenCloseEvent.bind(this);
437 this.websocket.onerror = this._handleListenErrorEvent.bind(this);
438 this.websocket.onmessage = this._handleListenMessageEvent.bind(this);
439 },
440 /**
441 * Opens long-poll connection.
442 *
443 */
444 openLongPoll: function () {
445 var request = this.$['ajaxListen'];
446 request.url = this.longPollUrl + '?conn_id=' + this.connectionId;
447 request.generateRequest()
448 },
449 /**
450 * Retries `connect()` call while incrementing interval between tries up to 1 minute.
451 *
452 */
453 retryConnection: function () {
454 if (!this.shouldReconnect) {
455 return;
456 }
457 if (this._currentBounceIv < 60000) {
458 this._currentBounceIv = this._currentBounceIv + this.increaseBounceIv;
459 }
460 else {
461 this._currentBounceIv = 60000;
462 }
463 setTimeout(this.connect.bind(this), this._currentBounceIv);
464 },
465 /**
466 * Closes listening connection.
467 *
468 */
469 closeConnection: function () {
470 var request = this.$['ajaxListen'];
471 if (this.websocket && this.websocket.readyState === WebSocket.OPEN) {
472 this.websocket.onclose = null;
473 this.websocket.onerror = null;
474 this.websocket.close();
475 }
476 if (request.loading) {
477 request.lastRequest.abort();
478 }
479 this.connected = false;
480 },
560 481
561 },
482 _handleChannelsChange: function (event) {
483 // do not fire the event if set() didn't mutate anything
484 // is this a reliable way to do it?
485 if (!this.isReady || event === undefined) {
486 return
487 }
488 this.fire('channelstream-channels-changed', event)
489 },
562 490
563 _handleListenCloseEvent: function (event) {
564 this.connected = false;
565 this.fire('channelstream-listen-closed', event.detail);
566 this.retryConnection();
567 },
491 _handleListenOpen: function (event) {
492 this.connected = true;
493 this.fire('channelstream-listen-opened', event);
494 this.createHeartBeats();
495 },
568 496
569 _handleListenErrorEvent: function (event) {
570 this.connected = false;
571 this.fire('channelstream-listen-error', {})
572 },
497 createHeartBeats: function () {
498 if (typeof self._heartbeat === 'undefined' && this.websocket !== null
499 && this.heartbeats) {
500 self._heartbeat = setInterval(this._sendHeartBeat.bind(this), 10000);
501 }
502 },
573 503
574 _handleConnect: function (event) {
575 this.currentBounceIv = 0;
576 this.connectionId = event.detail.response.conn_id;
577 this.fire('channelstream-connected', event.detail.response);
578 },
504 _sendHeartBeat: function () {
505 if (this.websocket.readyState === WebSocket.OPEN && this.heartbeats) {
506 this.websocket.send(JSON.stringify({type: 'heartbeat'}));
507 }
508 },
579 509
580 _handleDisconnect: function (event) {
581 this.connected = false;
582 this.fire('channelstream-disconnected', {});
583 },
510 _handleListenError: function (event) {
511 this.connected = false;
512 this.retryConnection();
513 },
514 _handleConnectError: function (event) {
515 this.connected = false;
516 this.fire('channelstream-connect-error', event.detail);
517 },
584 518
585 _handleMessage: function (event) {
586 this.fire('channelstream-message-sent', event.detail.response);
587 },
588 _handleMessageError: function (event) {
589 this.fire('channelstream-message-error', event.detail);
590 },
519 _handleListenMessageEvent: function (event) {
520 var data = null;
521 // comes from iron-ajax
522 if (event.detail) {
523 data = JSON.parse(event.detail.response)
524 // comes from websocket
525 setTimeout(this.openLongPoll.bind(this), 0);
526 } else {
527 data = JSON.parse(event.data)
528 }
529 this.fire('channelstream-listen-message', data);
591 530
592 _handleSubscribe: function (event) {
593 this.fire('channelstream-subscribed', event.detail.response);
594 },
531 },
532
533 _handleListenCloseEvent: function (event) {
534 this.connected = false;
535 this.fire('channelstream-listen-closed', event.detail);
536 this.retryConnection();
537 },
538
539 _handleListenErrorEvent: function (event) {
540 this.connected = false;
541 this.fire('channelstream-listen-error', {})
542 },
595 543
596 _handleSubscribeError: function (event) {
597 this.fire('channelstream-subscribe-error', event.detail);
598 },
544 _handleConnect: function (event) {
545 this.currentBounceIv = 0;
546 this.connectionId = event.detail.response.conn_id;
547 this.fire('channelstream-connected', event.detail.response);
548 },
599 549
600 _handleUnsubscribe: function (event) {
601 this.fire('channelstream-unsubscribed', event.detail.response);
602 },
550 _handleDisconnect: function (event) {
551 this.connected = false;
552 this.fire('channelstream-disconnected', {});
553 },
603 554
604 _handleUnsubscribeError: function (event) {
605 this.fire('channelstream-unsubscribe-error', event.detail);
606 }
607 });
555 _handleMessage: function (event) {
556 this.fire('channelstream-message-sent', event.detail.response);
557 },
558 _handleMessageError: function (event) {
559 this.fire('channelstream-message-error', event.detail);
560 },
561
562 _handleSubscribe: function (event) {
563 this.fire('channelstream-subscribed', event.detail.response);
564 },
608 565
609 </script>
610 </dom-module>
566 _handleSubscribeError: function (event) {
567 this.fire('channelstream-subscribe-error', event.detail);
568 },
569
570 _handleUnsubscribe: function (event) {
571 this.fire('channelstream-unsubscribed', event.detail.response);
572 },
573
574 _handleUnsubscribeError: function (event) {
575 this.fire('channelstream-unsubscribe-error', event.detail);
576 }
577 });
@@ -1,7 +1,7 b''
1 import '../../../../../bower_components/iron-ajax/iron-ajax.html';
1 import '@polymer/iron-ajax/iron-ajax.js';
2 2 import './root-styles.gen.html';
3 import './channelstream-connection/channelstream-connection.html';
4 import './rhodecode-toast/rhodecode-toast.html';
5 import './rhodecode-toggle/rhodecode-toggle.html';
6 import './rhodecode-unsafe-html/rhodecode-unsafe-html.html';
7 import './rhodecode-app/rhodecode-app.html';
3 import './channelstream-connection/channelstream-connection.js';
4 import './rhodecode-toast/rhodecode-toast.js';
5 import './rhodecode-toggle/rhodecode-toggle.js';
6 import './rhodecode-unsafe-html/rhodecode-unsafe-html.js';
7 import './rhodecode-app/rhodecode-app.js';
@@ -1,10 +1,19 b''
1 <link rel="import" href="../../../../../../bower_components/polymer/polymer.html">
2 <link rel="import" href="../channelstream-connection/channelstream-connection.html">
3 <link rel="import" href="../rhodecode-toast/rhodecode-toast.html">
4 <link rel="import" href="../rhodecode-favicon/rhodecode-favicon.html">
1 import {PolymerElement, html} from '@polymer/polymer/polymer-element.js';
2 import '../channelstream-connection/channelstream-connection.js';
3 import '../rhodecode-toast/rhodecode-toast.js';
4 import '../rhodecode-favicon/rhodecode-favicon.js';
5
6 var ccLog = Logger.get('RhodeCodeApp');
7 ccLog.setLevel(Logger.OFF);
5 8
6 <dom-module id="rhodecode-app">
7 <template>
9 export class RhodecodeApp extends PolymerElement {
10
11 static get is() {
12 return 'rhodecode-app';
13 }
14
15 static get template(){
16 return html`
8 17 <channelstream-connection
9 18 id="channelstream-connection"
10 19 on-channelstream-listen-message="receivedMessage"
@@ -12,184 +21,174 b''
12 21 on-channelstream-subscribed="handleSubscribed">
13 22 </channelstream-connection>
14 23 <rhodecode-favicon></rhodecode-favicon>
15 </template>
16 <script>
17 var ccLog = Logger.get('RhodeCodeApp');
18 ccLog.setLevel(Logger.OFF);
19
20 class RhodecodeApp extends Polymer.Element {
21
22 static get is() {
23 return 'rhodecode-app';
24 }
24 `
25 }
25 26
26 connectedCallback() {
27 super.connectedCallback();
28 ccLog.debug('rhodeCodeApp created');
29 $.Topic('/notifications').subscribe(this.handleNotifications.bind(this));
30 $.Topic('/favicon/update').subscribe(this.faviconUpdate.bind(this));
31 $.Topic('/connection_controller/subscribe').subscribe(
32 this.subscribeToChannelTopic.bind(this));
33 // this event can be used to coordinate plugins to do their
34 // initialization before channelstream is kicked off
35 $.Topic('/__MAIN_APP__').publish({});
36
37 for (var i = 0; i < alertMessagePayloads.length; i++) {
38 $.Topic('/notifications').publish(alertMessagePayloads[i]);
39 }
40 this.initPlugins();
41 // after rest of application loads and topics get fired, launch connection
42 $(document).ready(function () {
43 this.kickoffChannelstreamPlugin();
44 }.bind(this));
45 }
27 connectedCallback() {
28 super.connectedCallback();
29 ccLog.debug('rhodeCodeApp created');
30 $.Topic('/notifications').subscribe(this.handleNotifications.bind(this));
31 $.Topic('/favicon/update').subscribe(this.faviconUpdate.bind(this));
32 $.Topic('/connection_controller/subscribe').subscribe(
33 this.subscribeToChannelTopic.bind(this));
34 // this event can be used to coordinate plugins to do their
35 // initialization before channelstream is kicked off
36 $.Topic('/__MAIN_APP__').publish({});
46 37
47 initPlugins() {
48 for (var i = 0; i < window.APPLICATION_PLUGINS.length; i++) {
49 var pluginDef = window.APPLICATION_PLUGINS[i];
50 if (pluginDef.component) {
51 var pluginElem = document.createElement(pluginDef.component);
52 this.shadowRoot.appendChild(pluginElem);
53 if (typeof pluginElem.init !== 'undefined') {
54 pluginElem.init();
55 }
56 }
57 }
58 }
59
60 /** proxy to channelstream connection */
61 getChannelStreamConnection() {
62 return this.$['channelstream-connection'];
63 }
64
65 handleNotifications(data) {
66 var elem = document.getElementById('notifications');
67 if (elem) {
68 elem.handleNotification(data);
69 }
70
71 }
38 for (var i = 0; i < alertMessagePayloads.length; i++) {
39 $.Topic('/notifications').publish(alertMessagePayloads[i]);
40 }
41 this.initPlugins();
42 // after rest of application loads and topics get fired, launch connection
43 $(document).ready(function () {
44 this.kickoffChannelstreamPlugin();
45 }.bind(this));
46 }
72 47
73 faviconUpdate(data) {
74 this.shadowRoot.querySelector('rhodecode-favicon').counter = data.count;
75 }
76
77 /** opens connection to ws server */
78 kickoffChannelstreamPlugin(data) {
79 ccLog.debug('kickoffChannelstreamPlugin');
80 var channels = ['broadcast'];
81 var addChannels = this.checkViewChannels();
82 for (var i = 0; i < addChannels.length; i++) {
83 channels.push(addChannels[i]);
84 }
85 if (window.CHANNELSTREAM_SETTINGS && CHANNELSTREAM_SETTINGS.enabled) {
86 var channelstreamConnection = this.getChannelStreamConnection();
87 channelstreamConnection.connectUrl = CHANNELSTREAM_URLS.connect;
88 channelstreamConnection.subscribeUrl = CHANNELSTREAM_URLS.subscribe;
89 channelstreamConnection.websocketUrl = CHANNELSTREAM_URLS.ws + '/ws';
90 channelstreamConnection.longPollUrl = CHANNELSTREAM_URLS.longpoll + '/listen';
91 // some channels might already be registered by topic
92 for (var i = 0; i < channels.length; i++) {
93 channelstreamConnection.push('channels', channels[i]);
94 }
95 // append any additional channels registered in other plugins
96 $.Topic('/connection_controller/subscribe').processPrepared();
97 channelstreamConnection.connect();
48 initPlugins() {
49 for (var i = 0; i < window.APPLICATION_PLUGINS.length; i++) {
50 var pluginDef = window.APPLICATION_PLUGINS[i];
51 if (pluginDef.component) {
52 var pluginElem = document.createElement(pluginDef.component);
53 this.shadowRoot.appendChild(pluginElem);
54 if (typeof pluginElem.init !== 'undefined') {
55 pluginElem.init();
98 56 }
99 57 }
58 }
59 }
100 60
101 checkViewChannels() {
102 // subscribe to different channels data is sent.
61 /** proxy to channelstream connection */
62 getChannelStreamConnection() {
63 return this.$['channelstream-connection'];
64 }
103 65
104 var channels = [];
105 // subscribe to PR repo channel for PR's'
106 if (templateContext.pull_request_data.pull_request_id) {
107 var channelName = '/repo$' + templateContext.repo_name + '$/pr/' +
108 String(templateContext.pull_request_data.pull_request_id);
109 channels.push(channelName);
110 }
66 handleNotifications(data) {
67 var elem = document.getElementById('notifications');
68 if (elem) {
69 elem.handleNotification(data);
70 }
111 71
112 if (templateContext.commit_data.commit_id) {
113 var channelName = '/repo$' + templateContext.repo_name + '$/commit/' +
114 String(templateContext.commit_data.commit_id);
115 channels.push(channelName);
116 }
72 }
73
74 faviconUpdate(data) {
75 this.shadowRoot.querySelector('rhodecode-favicon').counter = data.count;
76 }
117 77
118 return channels;
78 /** opens connection to ws server */
79 kickoffChannelstreamPlugin(data) {
80 ccLog.debug('kickoffChannelstreamPlugin');
81 var channels = ['broadcast'];
82 var addChannels = this.checkViewChannels();
83 for (var i = 0; i < addChannels.length; i++) {
84 channels.push(addChannels[i]);
85 }
86 if (window.CHANNELSTREAM_SETTINGS && CHANNELSTREAM_SETTINGS.enabled) {
87 var channelstreamConnection = this.getChannelStreamConnection();
88 channelstreamConnection.connectUrl = CHANNELSTREAM_URLS.connect;
89 channelstreamConnection.subscribeUrl = CHANNELSTREAM_URLS.subscribe;
90 channelstreamConnection.websocketUrl = CHANNELSTREAM_URLS.ws + '/ws';
91 channelstreamConnection.longPollUrl = CHANNELSTREAM_URLS.longpoll + '/listen';
92 // some channels might already be registered by topic
93 for (var i = 0; i < channels.length; i++) {
94 channelstreamConnection.push('channels', channels[i]);
119 95 }
96 // append any additional channels registered in other plugins
97 $.Topic('/connection_controller/subscribe').processPrepared();
98 channelstreamConnection.connect();
99 }
100 }
101
102 checkViewChannels() {
103 // subscribe to different channels data is sent.
120 104
121 /** subscribes users from channels in channelstream */
122 subscribeToChannelTopic(channels) {
123 var channelstreamConnection = this.getChannelStreamConnection();
124 var toSubscribe = channelstreamConnection.calculateSubscribe(channels);
125 ccLog.debug('subscribeToChannelTopic', toSubscribe);
126 if (toSubscribe.length > 0) {
127 // if we are connected then subscribe
128 if (channelstreamConnection.connected) {
129 channelstreamConnection.subscribe(toSubscribe);
130 }
131 // not connected? just push channels onto the stack
132 else {
133 for (var i = 0; i < toSubscribe.length; i++) {
134 channelstreamConnection.push('channels', toSubscribe[i]);
135 }
136 }
105 var channels = [];
106 // subscribe to PR repo channel for PR's'
107 if (templateContext.pull_request_data.pull_request_id) {
108 var channelName = '/repo$' + templateContext.repo_name + '$/pr/' +
109 String(templateContext.pull_request_data.pull_request_id);
110 channels.push(channelName);
111 }
112
113 if (templateContext.commit_data.commit_id) {
114 var channelName = '/repo$' + templateContext.repo_name + '$/commit/' +
115 String(templateContext.commit_data.commit_id);
116 channels.push(channelName);
117 }
118
119 return channels;
120 }
121
122 /** subscribes users from channels in channelstream */
123 subscribeToChannelTopic(channels) {
124 var channelstreamConnection = this.getChannelStreamConnection();
125 var toSubscribe = channelstreamConnection.calculateSubscribe(channels);
126 ccLog.debug('subscribeToChannelTopic', toSubscribe);
127 if (toSubscribe.length > 0) {
128 // if we are connected then subscribe
129 if (channelstreamConnection.connected) {
130 channelstreamConnection.subscribe(toSubscribe);
131 }
132 // not connected? just push channels onto the stack
133 else {
134 for (var i = 0; i < toSubscribe.length; i++) {
135 channelstreamConnection.push('channels', toSubscribe[i]);
137 136 }
138 137 }
138 }
139 }
139 140
140 /** publish received messages into correct topic */
141 receivedMessage(event) {
142 for (var i = 0; i < event.detail.length; i++) {
143 var message = event.detail[i];
144 if (message.message.topic) {
145 ccLog.debug('publishing', message.message.topic);
146 $.Topic(message.message.topic).publish(message);
147 }
148 else if (message.type === 'presence') {
149 $.Topic('/connection_controller/presence').publish(message);
150 }
151 else {
152 ccLog.warn('unhandled message', message);
153 }
154 }
141 /** publish received messages into correct topic */
142 receivedMessage(event) {
143 for (var i = 0; i < event.detail.length; i++) {
144 var message = event.detail[i];
145 if (message.message.topic) {
146 ccLog.debug('publishing', message.message.topic);
147 $.Topic(message.message.topic).publish(message);
148 }
149 else if (message.type === 'presence') {
150 $.Topic('/connection_controller/presence').publish(message);
155 151 }
152 else {
153 ccLog.warn('unhandled message', message);
154 }
155 }
156 }
156 157
157 handleConnected(event) {
158 var channelstreamConnection = this.getChannelStreamConnection();
159 channelstreamConnection.set('channelsState',
160 event.detail.channels_info);
161 channelstreamConnection.set('userState', event.detail.state);
162 channelstreamConnection.set('channels', event.detail.channels);
163 this.propagageChannelsState();
164 }
158 handleConnected(event) {
159 var channelstreamConnection = this.getChannelStreamConnection();
160 channelstreamConnection.set('channelsState',
161 event.detail.channels_info);
162 channelstreamConnection.set('userState', event.detail.state);
163 channelstreamConnection.set('channels', event.detail.channels);
164 this.propagageChannelsState();
165 }
165 166
166 handleSubscribed(event) {
167 var channelstreamConnection = this.getChannelStreamConnection();
168 var channelInfo = event.detail.channels_info;
169 var channelKeys = Object.keys(event.detail.channels_info);
170 for (var i = 0; i < channelKeys.length; i++) {
171 var key = channelKeys[i];
172 channelstreamConnection.set(['channelsState', key], channelInfo[key]);
173 }
174 channelstreamConnection.set('channels', event.detail.channels);
175 this.propagageChannelsState();
176 }
167 handleSubscribed(event) {
168 var channelstreamConnection = this.getChannelStreamConnection();
169 var channelInfo = event.detail.channels_info;
170 var channelKeys = Object.keys(event.detail.channels_info);
171 for (var i = 0; i < channelKeys.length; i++) {
172 var key = channelKeys[i];
173 channelstreamConnection.set(['channelsState', key], channelInfo[key]);
174 }
175 channelstreamConnection.set('channels', event.detail.channels);
176 this.propagageChannelsState();
177 }
177 178
178 /** propagates channel states on topics */
179 propagageChannelsState(event) {
180 var channelstreamConnection = this.getChannelStreamConnection();
181 var channel_data = channelstreamConnection.channelsState;
182 var channels = channelstreamConnection.channels;
183 for (var i = 0; i < channels.length; i++) {
184 var key = channels[i];
185 $.Topic('/connection_controller/channel_update').publish(
186 {channel: key, state: channel_data[key]}
187 );
188 }
189 }
179 /** propagates channel states on topics */
180 propagageChannelsState(event) {
181 var channelstreamConnection = this.getChannelStreamConnection();
182 var channel_data = channelstreamConnection.channelsState;
183 var channels = channelstreamConnection.channels;
184 for (var i = 0; i < channels.length; i++) {
185 var key = channels[i];
186 $.Topic('/connection_controller/channel_update').publish(
187 {channel: key, state: channel_data[key]}
188 );
189 }
190 }
190 191
191 }
192 }
192 193
193 customElements.define(RhodecodeApp.is, RhodecodeApp);
194 </script>
195 </dom-module>
194 customElements.define(RhodecodeApp.is, RhodecodeApp);
@@ -1,38 +1,33 b''
1 <link rel="import" href="../../../../../../bower_components/polymer/polymer.html">
1 import {PolymerElement, html} from '@polymer/polymer/polymer-element.js';
2 2
3 <dom-module id="rhodecode-favicon">
4 <template>
5 </template>
6 <script>
7 class RhodecodeFavicon extends Polymer.Element {
3 export class RhodecodeFavicon extends PolymerElement {
8 4
9 static get is() { return 'rhodecode-favicon'; }
5 static get is() {
6 return 'rhodecode-favicon';
7 }
10 8
11 static get properties() {
12 return {
13 favicon: Object,
14 counter: {
15 type: Number,
16 observer: '_handleCounter'
17 }
18 }
9 static get properties() {
10 return {
11 favicon: Object,
12 counter: {
13 type: Number,
14 observer: '_handleCounter'
19 15 }
20
21 connectedCallback() {
22 super.connectedCallback();
23 this.favicon = new Favico({
24 type: 'rectangle',
25 animation: 'none'
26 });
27 }
16 }
17 }
28 18
29 _handleCounter(newVal, oldVal) {
30 this.favicon.badge(this.counter);
31 }
19 connectedCallback() {
20 super.connectedCallback();
21 this.favicon = new Favico({
22 type: 'rectangle',
23 animation: 'none'
24 });
25 }
32 26
33 }
34 customElements.define(RhodecodeFavicon.is, RhodecodeFavicon);
27 _handleCounter(newVal, oldVal) {
28 this.favicon.badge(this.counter);
29 }
35 30
31 }
36 32
37 </script>
38 </dom-module>
33 customElements.define(RhodecodeFavicon.is, RhodecodeFavicon);
@@ -1,9 +1,17 b''
1 <link rel="import" href="../../../../../../bower_components/paper-button/paper-button.html">
2 <link rel="import"
3 href="../../../../../../bower_components/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
4 <link rel="import" href="../rhodecode-unsafe-html/rhodecode-unsafe-html.html">
5 <dom-module id="rhodecode-toast">
6 <template>
1 import {PolymerElement, html} from '@polymer/polymer/polymer-element.js';
2 import '@polymer/paper-toggle-button/paper-toggle-button.js';
3 import {mixinBehaviors} from '@polymer/polymer/lib/legacy/class.js';
4 import {IronA11yKeysBehavior} from '@polymer/iron-a11y-keys-behavior/iron-a11y-keys-behavior.js';
5 import '../rhodecode-unsafe-html/rhodecode-unsafe-html.js';
6
7 export class RhodecodeToast extends mixinBehaviors([IronA11yKeysBehavior], PolymerElement) {
8
9 static get is() {
10 return 'rhodecode-toast';
11 }
12
13 static get template(){
14 return html`
7 15 <style include="shared-styles">
8 16 /* inset border for buttons - does not work in ie */
9 17 /* rounded borders */
@@ -107,127 +115,117 b''
107 115 </template>
108 116 </div>
109 117 </template>
110 </template>
111
112 <script>
113
114 class RhodecodeToast extends Polymer.mixinBehaviors([Polymer.IronA11yKeysBehavior], Polymer.Element) {
115
116 static get is() {
117 return 'rhodecode-toast';
118 }
118 `
119 }
119 120
120 static get properties() {
121 return {
122 toasts: {
123 type: Array,
124 value() {
125 return []
126 }
127 },
128 isFixed: {
129 type: Boolean,
130 value: false
131 },
132 hasToasts: {
133 type: Boolean,
134 computed: '_computeHasToasts(toasts.*)'
135 },
136 keyEventTarget: {
137 type: Object,
138 value() {
139 return document.body;
140 }
141 }
121 static get properties() {
122 return {
123 toasts: {
124 type: Array,
125 value() {
126 return []
142 127 }
143 }
144
145 get keyBindings() {
146 return {
147 'esc:keyup': '_hideOnEsc'
128 },
129 isFixed: {
130 type: Boolean,
131 value: false
132 },
133 hasToasts: {
134 type: Boolean,
135 computed: '_computeHasToasts(toasts.*)'
136 },
137 keyEventTarget: {
138 type: Object,
139 value() {
140 return document.body;
148 141 }
149 142 }
143 }
144 }
150 145
151 static get observers() {
152 return [
153 '_changedToasts(toasts.splices)'
154 ]
155 }
146 get keyBindings() {
147 return {
148 'esc:keyup': '_hideOnEsc'
149 }
150 }
156 151
157 _hideOnEsc(event) {
158 return this.dismissNotifications();
159 }
152 static get observers() {
153 return [
154 '_changedToasts(toasts.splices)'
155 ]
156 }
160 157
161 _computeHasToasts() {
162 return this.toasts.length > 0;
163 }
158 _hideOnEsc(event) {
159 return this.dismissNotifications();
160 }
164 161
165 _debouncedCalc() {
166 // calculate once in a while
167 this.debounce('debouncedCalc', this.toastInWindow, 25);
168 }
162 _computeHasToasts() {
163 return this.toasts.length > 0;
164 }
169 165
170 conditionalClass() {
171 return this.isFixed ? 'fixed' : '';
172 }
166 _debouncedCalc() {
167 // calculate once in a while
168 this.debounce('debouncedCalc', this.toastInWindow, 25);
169 }
173 170
174 toastInWindow() {
175 if (!this._headerNode) {
176 return true
177 }
178 var headerHeight = this._headerNode.offsetHeight;
179 var scrollPosition = window.scrollY;
171 conditionalClass() {
172 return this.isFixed ? 'fixed' : '';
173 }
180 174
181 if (this.isFixed) {
182 this.isFixed = 1 <= scrollPosition;
183 }
184 else {
185 this.isFixed = headerHeight <= scrollPosition;
186 }
187 }
175 toastInWindow() {
176 if (!this._headerNode) {
177 return true
178 }
179 var headerHeight = this._headerNode.offsetHeight;
180 var scrollPosition = window.scrollY;
188 181
189 connectedCallback() {
190 super.connectedCallback();
191 this._headerNode = document.querySelector('.header', document);
192 this.listen(window, 'scroll', '_debouncedCalc');
193 this.listen(window, 'resize', '_debouncedCalc');
194 this._debouncedCalc();
195 }
182 if (this.isFixed) {
183 this.isFixed = 1 <= scrollPosition;
184 }
185 else {
186 this.isFixed = headerHeight <= scrollPosition;
187 }
188 }
196 189
197 _changedToasts(newValue, oldValue) {
198 $.Topic('/favicon/update').publish({count: this.toasts.length});
199 }
190 connectedCallback() {
191 super.connectedCallback();
192 this._headerNode = document.querySelector('.header', document);
193 this.listen(window, 'scroll', '_debouncedCalc');
194 this.listen(window, 'resize', '_debouncedCalc');
195 this._debouncedCalc();
196 }
200 197
201 dismissNotification(e) {
202 $.Topic('/favicon/update').publish({count: this.toasts.length - 1});
203 var idx = e.target.parentNode.indexPos
204 this.splice('toasts', idx, 1);
198 _changedToasts(newValue, oldValue) {
199 $.Topic('/favicon/update').publish({count: this.toasts.length});
200 }
205 201
206 }
202 dismissNotification(e) {
203 $.Topic('/favicon/update').publish({count: this.toasts.length - 1});
204 var idx = e.target.parentNode.indexPos
205 this.splice('toasts', idx, 1);
207 206
208 dismissNotifications() {
209 $.Topic('/favicon/update').publish({count: 0});
210 this.splice('toasts', 0);
211 }
207 }
208
209 dismissNotifications() {
210 $.Topic('/favicon/update').publish({count: 0});
211 this.splice('toasts', 0);
212 }
212 213
213 handleNotification(data) {
214 if (!templateContext.rhodecode_user.notification_status && !data.message.force) {
215 // do not act if notifications are disabled
216 return
217 }
218 this.push('toasts', {
219 level: data.message.level,
220 message: data.message.message
221 });
222 }
214 handleNotification(data) {
215 if (!templateContext.rhodecode_user.notification_status && !data.message.force) {
216 // do not act if notifications are disabled
217 return
218 }
219 this.push('toasts', {
220 level: data.message.level,
221 message: data.message.message
222 });
223 }
223 224
224 _gettext(x){
225 return _gettext(x)
226 }
225 _gettext(x){
226 return _gettext(x)
227 }
227 228
228 }
229 }
229 230
230 customElements.define(RhodecodeToast.is, RhodecodeToast);
231
232 </script>
233 </dom-module>
231 customElements.define(RhodecodeToast.is, RhodecodeToast);
@@ -1,61 +1,57 b''
1 <link rel="import"
2 href="../../../../../../bower_components/paper-toggle-button/paper-toggle-button.html">
3 <link rel="import" href="../../../../../../bower_components/paper-spinner/paper-spinner.html">
4 <link rel="import" href="../../../../../../bower_components/paper-tooltip/paper-tooltip.html">
1 import {PolymerElement, html} from '@polymer/polymer/polymer-element.js';
2 import '@polymer/paper-toggle-button/paper-toggle-button.js';
3 import '@polymer/paper-spinner/paper-spinner.js';
4 import '@polymer/paper-tooltip/paper-tooltip.js';
5 5
6 <dom-module id="rhodecode-toggle">
6 export class RhodecodeToggle extends PolymerElement {
7 7
8 <style include="shared-styles">
9 .rc-toggle {
10 float: left;
11 position: relative;
12 }
8 static get is() {
9 return 'rhodecode-toggle';
10 }
13 11
14 .rc-toggle paper-spinner {
15 position: absolute;
16 top: 0;
17 left: -30px;
18 width: 20px;
19 height: 20px;
20 }
21 </style>
22
23 <template>
12 static get template() {
13 return html`
14 <style include="shared-styles">
15 .rc-toggle {
16 float: left;
17 position: relative;
18 }
19
20 .rc-toggle paper-spinner {
21 position: absolute;
22 top: 0;
23 left: -30px;
24 width: 20px;
25 height: 20px;
26 }
27 </style>
24 28 <div class="rc-toggle">
25 <paper-toggle-button checked={{checked}}>[[labelStatus(checked)]]</paper-toggle-button>
29 <paper-toggle-button checked={{checked}}>[[labelStatus(checked)]]
30 </paper-toggle-button>
26 31 <paper-tooltip>[[tooltipText]]</paper-tooltip>
27 32 <template is="dom-if" if="[[shouldShow(noSpinner)]]">
28 33 <paper-spinner active=[[active]]></paper-spinner>
29 34 </template>
30 35 </div>
31 </template>
32
33 <script>
34
35 class RhodecodeToggle extends Polymer.Element {
36
37 static get is() {
38 return 'rhodecode-toggle';
39 }
36 `;
37 }
40 38
41 static get properties() {
42 return {
43 noSpinner: {type: Boolean, value: false, reflectToAttribute: true},
44 tooltipText: {type: String, value: "Click to toggle", reflectToAttribute: true},
45 checked: {type: Boolean, value: false, reflectToAttribute: true},
46 active: {type: Boolean, value: false, reflectToAttribute: true, notify: true}
47 }
48 }
39 static get properties() {
40 return {
41 noSpinner: {type: Boolean, value: false, reflectToAttribute: true},
42 tooltipText: {type: String, value: "Click to toggle", reflectToAttribute: true},
43 checked: {type: Boolean, value: false, reflectToAttribute: true},
44 active: {type: Boolean, value: false, reflectToAttribute: true, notify: true}
45 }
46 }
49 47
50 shouldShow() {
51 return !this.noSpinner
52 }
48 shouldShow() {
49 return !this.noSpinner
50 }
53 51
54 labelStatus(isActive) {
55 return this.checked ? 'Enabled' : "Disabled"
56 }
57 }
52 labelStatus(isActive) {
53 return this.checked ? 'Enabled' : "Disabled"
54 }
55 }
58 56
59 customElements.define(RhodecodeToggle.is, RhodecodeToggle);
60 </script>
61 </dom-module>
57 customElements.define(RhodecodeToggle.is, RhodecodeToggle);
@@ -1,31 +1,30 b''
1 <link rel="import" href="../../../../../../bower_components/polymer/polymer-element.html">
1 import {PolymerElement, html} from '@polymer/polymer/polymer-element.js';
2
3 export class RhodecodeUnsafeHtml extends PolymerElement {
2 4
3 <dom-module id="rhodecode-unsafe-html">
4 <template>
5 static get is() {
6 return 'rhodecode-unsafe-html';
7 }
8
9 static get template() {
10 return html`
5 11 <style include="shared-styles"></style>
6 12 <slot></slot>
7 </template>
8 <script>
9 class RhodecodeUnsafeHtml extends Polymer.Element {
10
11 static get is() {
12 return 'rhodecode-unsafe-html';
13 }
13 `;
14 }
14 15
15 static get properties() {
16 return {
17 text: {
18 type: String,
19 observer: '_handleText'
20 }
21 }
22 }
23
24 _handleText(newVal, oldVal) {
25 this.innerHTML = this.text;
16 static get properties() {
17 return {
18 text: {
19 type: String,
20 observer: '_handleText'
26 21 }
27 22 }
23 }
28 24
29 customElements.define(RhodecodeUnsafeHtml.is, RhodecodeUnsafeHtml);
30 </script>
31 </dom-module>
25 _handleText(newVal, oldVal) {
26 this.innerHTML = this.text;
27 }
28 }
29
30 customElements.define(RhodecodeUnsafeHtml.is, RhodecodeUnsafeHtml);
General Comments 0
You need to be logged in to leave comments. Login now