##// END OF EJS Templates
js: use ES6 classes for polymer 2.x
ergo -
r3172:d37fc984 default
parent child Browse files
Show More
@@ -6,5 +6,5 b''
6 6 }
7 7 }]
8 8 ],
9 "plugins": ["transform-object-rest-spread"]
9 "plugins": ["transform-object-rest-spread"]
10 10 }
@@ -16,7 +16,7 b''
16 16 "main": {
17 17 "expand": true,
18 18 "cwd": "bower_components",
19 "src": "webcomponentsjs/webcomponents*.*",
19 "src": "webcomponentsjs/*.*",
20 20 "dest": "<%= dirs.js.dest %>/vendors"
21 21 }
22 22 },
@@ -17,9 +17,14 b''
17 17 var ccLog = Logger.get('RhodeCodeApp');
18 18 ccLog.setLevel(Logger.OFF);
19 19
20 var rhodeCodeApp = Polymer({
21 is: 'rhodecode-app',
22 attached: function () {
20 class RhodecodeApp extends Polymer.Element {
21
22 static get is() {
23 return 'rhodecode-app';
24 }
25
26 connectedCallback() {
27 super.connectedCallback();
23 28 ccLog.debug('rhodeCodeApp created');
24 29 $.Topic('/notifications').subscribe(this.handleNotifications.bind(this));
25 30 $.Topic('/favicon/update').subscribe(this.faviconUpdate.bind(this));
@@ -37,46 +42,47 b''
37 42 $(document).ready(function () {
38 43 this.kickoffChannelstreamPlugin();
39 44 }.bind(this));
40 },
45 }
41 46
42 initPlugins: function(){
47 initPlugins() {
43 48 for (var i = 0; i < window.APPLICATION_PLUGINS.length; i++) {
44 49 var pluginDef = window.APPLICATION_PLUGINS[i];
45 if (pluginDef.component){
50 if (pluginDef.component) {
46 51 var pluginElem = document.createElement(pluginDef.component);
47 52 this.shadowRoot.appendChild(pluginElem);
48 if (typeof pluginElem.init !== 'undefined'){
53 if (typeof pluginElem.init !== 'undefined') {
49 54 pluginElem.init();
50 55 }
51 56 }
52 57 }
53 },
58 }
59
54 60 /** proxy to channelstream connection */
55 getChannelStreamConnection: function () {
61 getChannelStreamConnection() {
56 62 return this.$['channelstream-connection'];
57 },
63 }
58 64
59 handleNotifications: function (data) {
65 handleNotifications(data) {
60 66 var elem = document.getElementById('notifications');
61 if(elem){
67 if (elem) {
62 68 elem.handleNotification(data);
63 69 }
64 70
65 },
71 }
66 72
67 faviconUpdate: function (data) {
73 faviconUpdate(data) {
68 74 this.shadowRoot.querySelector('rhodecode-favicon').counter = data.count;
69 },
75 }
70 76
71 77 /** opens connection to ws server */
72 kickoffChannelstreamPlugin: function (data) {
78 kickoffChannelstreamPlugin(data) {
73 79 ccLog.debug('kickoffChannelstreamPlugin');
74 80 var channels = ['broadcast'];
75 81 var addChannels = this.checkViewChannels();
76 82 for (var i = 0; i < addChannels.length; i++) {
77 83 channels.push(addChannels[i]);
78 84 }
79 if (window.CHANNELSTREAM_SETTINGS && CHANNELSTREAM_SETTINGS.enabled){
85 if (window.CHANNELSTREAM_SETTINGS && CHANNELSTREAM_SETTINGS.enabled) {
80 86 var channelstreamConnection = this.getChannelStreamConnection();
81 87 channelstreamConnection.connectUrl = CHANNELSTREAM_URLS.connect;
82 88 channelstreamConnection.subscribeUrl = CHANNELSTREAM_URLS.subscribe;
@@ -90,9 +96,9 b''
90 96 $.Topic('/connection_controller/subscribe').processPrepared();
91 97 channelstreamConnection.connect();
92 98 }
93 },
99 }
94 100
95 checkViewChannels: function () {
101 checkViewChannels() {
96 102 // subscribe to different channels data is sent.
97 103
98 104 var channels = [];
@@ -110,10 +116,10 b''
110 116 }
111 117
112 118 return channels;
113 },
119 }
114 120
115 121 /** subscribes users from channels in channelstream */
116 subscribeToChannelTopic: function (channels) {
122 subscribeToChannelTopic(channels) {
117 123 var channelstreamConnection = this.getChannelStreamConnection();
118 124 var toSubscribe = channelstreamConnection.calculateSubscribe(channels);
119 125 ccLog.debug('subscribeToChannelTopic', toSubscribe);
@@ -129,34 +135,35 b''
129 135 }
130 136 }
131 137 }
132 },
138 }
133 139
134 140 /** publish received messages into correct topic */
135 receivedMessage: function (event) {
141 receivedMessage(event) {
136 142 for (var i = 0; i < event.detail.length; i++) {
137 143 var message = event.detail[i];
138 144 if (message.message.topic) {
139 145 ccLog.debug('publishing', message.message.topic);
140 146 $.Topic(message.message.topic).publish(message);
141 147 }
142 else if (message.type === 'presence'){
148 else if (message.type === 'presence') {
143 149 $.Topic('/connection_controller/presence').publish(message);
144 150 }
145 151 else {
146 152 ccLog.warn('unhandled message', message);
147 153 }
148 154 }
149 },
155 }
150 156
151 handleConnected: function (event) {
157 handleConnected(event) {
152 158 var channelstreamConnection = this.getChannelStreamConnection();
153 159 channelstreamConnection.set('channelsState',
154 160 event.detail.channels_info);
155 161 channelstreamConnection.set('userState', event.detail.state);
156 162 channelstreamConnection.set('channels', event.detail.channels);
157 163 this.propagageChannelsState();
158 },
159 handleSubscribed: function (event) {
164 }
165
166 handleSubscribed(event) {
160 167 var channelstreamConnection = this.getChannelStreamConnection();
161 168 var channelInfo = event.detail.channels_info;
162 169 var channelKeys = Object.keys(event.detail.channels_info);
@@ -166,9 +173,10 b''
166 173 }
167 174 channelstreamConnection.set('channels', event.detail.channels);
168 175 this.propagageChannelsState();
169 },
176 }
177
170 178 /** propagates channel states on topics */
171 propagageChannelsState: function (event) {
179 propagageChannelsState(event) {
172 180 var channelstreamConnection = this.getChannelStreamConnection();
173 181 var channel_data = channelstreamConnection.channelsState;
174 182 var channels = channelstreamConnection.channels;
@@ -179,7 +187,9 b''
179 187 );
180 188 }
181 189 }
182 });
183 190
191 }
192
193 customElements.define(RhodecodeApp.is, RhodecodeApp);
184 194 </script>
185 195 </dom-module>
@@ -4,26 +4,35 b''
4 4 <template>
5 5 </template>
6 6 <script>
7 Polymer({
8 is: 'rhodecode-favicon',
9 properties: {
10 favicon: Object,
11 counter: {
12 type: Number,
13 observer: '_handleCounter'
7 class RhodecodeFavicon extends Polymer.Element {
8
9 static get is() { return 'rhodecode-favicon'; }
10
11 static get properties() {
12 return {
13 favicon: Object,
14 counter: {
15 type: Number,
16 observer: '_handleCounter'
17 }
14 18 }
15 },
19 }
16 20
17 ready: function () {
21 connectedCallback() {
22 super.connectedCallback();
18 23 this.favicon = new Favico({
19 24 type: 'rectangle',
20 25 animation: 'none'
21 26 });
22 },
23 _handleCounter: function (newVal, oldVal) {
27 }
28
29 _handleCounter(newVal, oldVal) {
24 30 this.favicon.badge(this.counter);
25 31 }
26 });
32
33 }
34 customElements.define(RhodecodeFavicon.is, RhodecodeFavicon);
35
27 36
28 37 </script>
29 38 </dom-module>
@@ -1,5 +1,6 b''
1 1 <link rel="import" href="../../../../../../bower_components/paper-button/paper-button.html">
2 <link rel="import" href="../../../../../../bower_components/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
2 <link rel="import"
3 href="../../../../../../bower_components/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
3 4 <link rel="import" href="../rhodecode-unsafe-html/rhodecode-unsafe-html.html">
4 5 <dom-module id="rhodecode-toast">
5 6 <template>
@@ -19,57 +20,69 b''
19 20 bottom: 0;
20 21 right: 0;
21 22 }
23
22 24 .top-left-rounded-corner {
23 25 -webkit-border-top-left-radius: 2px;
24 26 -khtml-border-radius-topleft: 2px;
25 27 border-top-left-radius: 2px;
26 28 }
29
27 30 .top-right-rounded-corner {
28 31 -webkit-border-top-right-radius: 2px;
29 32 -khtml-border-radius-topright: 2px;
30 33 border-top-right-radius: 2px;
31 34 }
35
32 36 .bottom-left-rounded-corner {
33 37 -webkit-border-bottom-left-radius: 2px;
34 38 -khtml-border-radius-bottomleft: 2px;
35 39 border-bottom-left-radius: 2px;
36 40 }
41
37 42 .bottom-right-rounded-corner {
38 43 -webkit-border-bottom-right-radius: 2px;
39 44 -khtml-border-radius-bottomright: 2px;
40 45 border-bottom-right-radius: 2px;
41 46 }
47
42 48 .top-left-rounded-corner-mid {
43 49 -webkit-border-top-left-radius: 2px;
44 50 -khtml-border-radius-topleft: 2px;
45 51 border-top-left-radius: 2px;
46 52 }
53
47 54 .top-right-rounded-corner-mid {
48 55 -webkit-border-top-right-radius: 2px;
49 56 -khtml-border-radius-topright: 2px;
50 57 border-top-right-radius: 2px;
51 58 }
59
52 60 .bottom-left-rounded-corner-mid {
53 61 -webkit-border-bottom-left-radius: 2px;
54 62 -khtml-border-radius-bottomleft: 2px;
55 63 border-bottom-left-radius: 2px;
56 64 }
65
57 66 .bottom-right-rounded-corner-mid {
58 67 -webkit-border-bottom-right-radius: 2px;
59 68 -khtml-border-radius-bottomright: 2px;
60 69 border-bottom-right-radius: 2px;
61 70 }
71
62 72 .alert {
63 73 margin: 10px 0;
64 74 }
75
65 76 .toast-close {
66 77 margin: 0;
67 78 float: right;
68 79 cursor: pointer;
69 80 }
81
70 82 .toast-message-holder {
71 83 background: rgba(255, 255, 255, 0.25);
72 84 }
85
73 86 .toast-message-holder.fixed {
74 87 position: fixed;
75 88 padding: 10px 0;
@@ -86,7 +99,7 b''
86 99 <div class$="container toast-message-holder [[conditionalClass(isFixed)]]">
87 100 <template is="dom-repeat" items="[[toasts]]">
88 101 <div class$="alert alert-[[item.level]]">
89 <div on-tap="dismissNotification" class="toast-close" index-pos="[[index]]">
102 <div on-click="dismissNotification" class="toast-close" index-pos="[[index]]">
90 103 <span>[[_gettext('Close')]]</span>
91 104 </div>
92 105 <rhodecode-unsafe-html text="[[item.message]]"></rhodecode-unsafe-html>
@@ -97,104 +110,124 b''
97 110 </template>
98 111
99 112 <script>
100 Polymer({
101 is: 'rhodecode-toast',
102 properties: {
103 toasts: {
104 type: Array,
105 value: function(){
106 return []
107 }
108 },
109 isFixed: {
110 type: Boolean,
111 value: false
112 },
113 hasToasts: {
114 type: Boolean,
115 computed: '_computeHasToasts(toasts.*)'
116 },
117 keyEventTarget: {
118 type: Object,
119 value: function() {
120 return document.body;
113
114 class RhodecodeToast extends Polymer.mixinBehaviors([Polymer.IronA11yKeysBehavior], Polymer.Element) {
115
116 static get is() {
117 return 'rhodecode-toast';
118 }
119
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 }
121 141 }
122 142 }
123 },
124 behaviors: [
125 Polymer.IronA11yKeysBehavior
126 ],
127 observers: [
128 '_changedToasts(toasts.splices)'
129 ],
143 }
144
145 get keyBindings() {
146 return {
147 'esc:keyup': '_hideOnEsc'
148 }
149 }
130 150
131 keyBindings: {
132 'esc:keyup': '_hideOnEsc'
133 },
151 static get observers() {
152 return [
153 '_changedToasts(toasts.splices)'
154 ]
155 }
134 156
135 _hideOnEsc: function (event) {
157 _hideOnEsc(event) {
136 158 return this.dismissNotifications();
137 },
159 }
138 160
139 _computeHasToasts: function(){
161 _computeHasToasts() {
140 162 return this.toasts.length > 0;
141 },
163 }
142 164
143 _debouncedCalc: function(){
165 _debouncedCalc() {
144 166 // calculate once in a while
145 167 this.debounce('debouncedCalc', this.toastInWindow, 25);
146 },
168 }
147 169
148 conditionalClass: function(){
149 return this.isFixed ? 'fixed': '';
150 },
170 conditionalClass() {
171 return this.isFixed ? 'fixed' : '';
172 }
151 173
152 toastInWindow: function() {
153 if (!this._headerNode){
174 toastInWindow() {
175 if (!this._headerNode) {
154 176 return true
155 177 }
156 178 var headerHeight = this._headerNode.offsetHeight;
157 179 var scrollPosition = window.scrollY;
158 180
159 if (this.isFixed){
181 if (this.isFixed) {
160 182 this.isFixed = 1 <= scrollPosition;
161 183 }
162 else{
184 else {
163 185 this.isFixed = headerHeight <= scrollPosition;
164 186 }
165 },
187 }
166 188
167 attached: function(){
189 connectedCallback() {
190 super.connectedCallback();
168 191 this._headerNode = document.querySelector('.header', document);
169 this.listen(window,'scroll', '_debouncedCalc');
170 this.listen(window,'resize', '_debouncedCalc');
192 this.listen(window, 'scroll', '_debouncedCalc');
193 this.listen(window, 'resize', '_debouncedCalc');
171 194 this._debouncedCalc();
172 },
173 _changedToasts: function(newValue, oldValue){
195 }
196
197 _changedToasts(newValue, oldValue) {
174 198 $.Topic('/favicon/update').publish({count: this.toasts.length});
175 },
176 dismissNotification: function(e) {
177 $.Topic('/favicon/update').publish({count: this.toasts.length-1});
199 }
200
201 dismissNotification(e) {
202 $.Topic('/favicon/update').publish({count: this.toasts.length - 1});
178 203 var idx = e.target.parentNode.indexPos
179 204 this.splice('toasts', idx, 1);
180 205
181 },
182 dismissNotifications: function(){
206 }
207
208 dismissNotifications() {
183 209 $.Topic('/favicon/update').publish({count: 0});
184 210 this.splice('toasts', 0);
185 },
186 handleNotification: function(data){
211 }
212
213 handleNotification(data) {
187 214 if (!templateContext.rhodecode_user.notification_status && !data.message.force) {
188 215 // do not act if notifications are disabled
189 216 return
190 217 }
191 this.push('toasts',{
218 this.push('toasts', {
192 219 level: data.message.level,
193 220 message: data.message.message
194 221 });
195 },
196 _gettext: _gettext
197 });
222 }
223
224 _gettext(x){
225 return _gettext(x)
226 }
227
228 }
229
230 customElements.define(RhodecodeToast.is, RhodecodeToast);
198 231
199 232 </script>
200 233 </dom-module>
@@ -1,4 +1,5 b''
1 <link rel="import" href="../../../../../../bower_components/paper-toggle-button/paper-toggle-button.html">
1 <link rel="import"
2 href="../../../../../../bower_components/paper-toggle-button/paper-toggle-button.html">
2 3 <link rel="import" href="../../../../../../bower_components/paper-spinner/paper-spinner.html">
3 4 <link rel="import" href="../../../../../../bower_components/paper-tooltip/paper-tooltip.html">
4 5
@@ -9,6 +10,7 b''
9 10 float: left;
10 11 position: relative;
11 12 }
13
12 14 .rc-toggle paper-spinner {
13 15 position: absolute;
14 16 top: 0;
@@ -29,20 +31,31 b''
29 31 </template>
30 32
31 33 <script>
32 Polymer({
33 is: 'rhodecode-toggle',
34 properties: {
35 noSpinner: { type: Boolean, value: false, reflectToAttribute:true},
36 tooltipText: { type: String, value: "Click to toggle", reflectToAttribute:true},
37 checked: { type: Boolean, value: false, reflectToAttribute:true},
38 active: { type: Boolean, value: false, reflectToAttribute:true, notify:true}
39 },
40 shouldShow: function(){
34
35 class RhodecodeToggle extends Polymer.Element {
36
37 static get is() {
38 return 'rhodecode-toggle';
39 }
40
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 }
49
50 shouldShow() {
41 51 return !this.noSpinner
42 },
43 labelStatus: function(isActive){
44 return this.checked? 'Enabled' : "Disabled"
45 52 }
46 });
53
54 labelStatus(isActive) {
55 return this.checked ? 'Enabled' : "Disabled"
56 }
57 }
58
59 customElements.define(RhodecodeToggle.is, RhodecodeToggle);
47 60 </script>
48 61 </dom-module>
@@ -1,4 +1,4 b''
1 <link rel="import" href="../../../../../../bower_components/polymer/polymer.html">
1 <link rel="import" href="../../../../../../bower_components/polymer/polymer-element.html">
2 2
3 3 <dom-module id="rhodecode-unsafe-html">
4 4 <template>
@@ -6,18 +6,26 b''
6 6 <slot></slot>
7 7 </template>
8 8 <script>
9 Polymer({
10 is: 'rhodecode-unsafe-html',
11 properties: {
12 text: {
13 type: String,
14 observer: '_handleText'
9 class RhodecodeUnsafeHtml extends Polymer.Element {
10
11 static get is() {
12 return 'rhodecode-unsafe-html';
13 }
14
15 static get properties() {
16 return {
17 text: {
18 type: String,
19 observer: '_handleText'
20 }
15 21 }
16 },
17 _handleText: function(newVal, oldVal){
22 }
23
24 _handleText(newVal, oldVal) {
18 25 this.innerHTML = this.text;
19 26 }
20 })
27 }
21 28
29 customElements.define(RhodecodeUnsafeHtml.is, RhodecodeUnsafeHtml);
22 30 </script>
23 31 </dom-module>
@@ -27,6 +27,8 b" c.template_context['default_user'] = {"
27 27 %>
28 28 <html xmlns="http://www.w3.org/1999/xhtml">
29 29 <head>
30
31 <script src="${h.asset('js/vendors/webcomponentsjs/custom-elements-es5-adapter.js', ver=c.rhodecode_version_hash)}"></script>
30 32 <script src="${h.asset('js/vendors/webcomponentsjs/webcomponents-lite.js', ver=c.rhodecode_version_hash)}"></script>
31 33 <title>${self.title()}</title>
32 34 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
@@ -10,6 +10,18 b' if (process.env.RC_STATIC_DIR) {'
10 10 destinationDirectory = process.env.RC_STATIC_DIR;
11 11 }
12 12
13 // doing it this way because it seems that plugin via grunt does not pick up .babelrc
14 let babelRCOptions = {
15 "presets": [
16 ["env", {
17 "targets": {
18 "browsers": ["last 2 versions"]
19 }
20 }]
21 ],
22 "plugins": ["transform-object-rest-spread"]
23 }
24
13 25 module.exports = {
14 26 // Tell Webpack which file kicks off our app.
15 27 entry: {
@@ -42,7 +54,8 b' module.exports = {'
42 54 // polymer-webpack-loader, and hand the output to
43 55 // babel-loader. This let's us transpile JS in our `<script>` elements.
44 56 use: [
45 {loader: 'babel-loader'},
57 {loader: 'babel-loader',
58 options: babelRCOptions},
46 59 {loader: 'polymer-webpack-loader',
47 60 options: {
48 61 processStyleLinks: true,
@@ -53,7 +66,7 b' module.exports = {'
53 66 {
54 67 // If you see a file that ends in .js, just send it to the babel-loader.
55 68 test: /\.js$/,
56 use: 'babel-loader'
69 use: {loader: 'babel-loader', options: babelRCOptions}
57 70 // Optionally exclude node_modules from transpilation except for polymer-webpack-loader:
58 71 // exclude: /node_modules\/(?!polymer-webpack-loader\/).*/
59 72 },
General Comments 0
You need to be logged in to leave comments. Login now