##// END OF EJS Templates
js: use ES6 classes for polymer 2.x
ergo -
r3172:d37fc984 default
parent child Browse files
Show More
@@ -1,10 +1,10 b''
1 1 {
2 2 "presets": [
3 3 ["env", {
4 4 "targets": {
5 5 "browsers": ["last 2 versions"]
6 6 }
7 7 }]
8 8 ],
9 "plugins": ["transform-object-rest-spread"]
9 "plugins": ["transform-object-rest-spread"]
10 10 }
@@ -1,176 +1,176 b''
1 1 {
2 2 "dirs": {
3 3 "css": {
4 4 "src":"rhodecode/public/css",
5 5 "dest":"rhodecode/public/css"
6 6 },
7 7 "js": {
8 8 "src": "rhodecode/public/js/src",
9 9 "src_rc": "rhodecode/public/js/rhodecode",
10 10 "dest": "rhodecode/public/js",
11 11 "bower": "bower_components",
12 12 "node_modules": "node_modules"
13 13 }
14 14 },
15 15 "copy": {
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 },
23 23 "concat": {
24 24 "polymercss": {
25 25 "src": [
26 26 "<%= dirs.js.src %>/components/root-styles-prefix.html",
27 27 "<%= dirs.css.src %>/style-polymer.css",
28 28 "<%= dirs.js.src %>/components/root-styles-suffix.html"
29 29 ],
30 30 "dest": "<%= dirs.js.dest %>/src/components/root-styles.gen.html",
31 31 "nonull": true
32 32 },
33 33 "dist": {
34 34 "src": [
35 35 "<%= dirs.js.node_modules %>/jquery/dist/jquery.min.js",
36 36 "<%= dirs.js.node_modules %>/mousetrap/mousetrap.min.js",
37 37 "<%= dirs.js.node_modules %>/moment/min/moment.min.js",
38 38 "<%= dirs.js.node_modules %>/clipboard/dist/clipboard.min.js",
39 39 "<%= dirs.js.node_modules %>/favico.js/favico-0.3.10.min.js",
40 40 "<%= dirs.js.node_modules %>/sticky-sidebar/dist/sticky-sidebar.min.js",
41 41 "<%= dirs.js.node_modules %>/sticky-sidebar/dist/jquery.sticky-sidebar.min.js",
42 42 "<%= dirs.js.node_modules %>/waypoints/lib/noframework.waypoints.min.js",
43 43 "<%= dirs.js.node_modules %>/waypoints/lib/jquery.waypoints.min.js",
44 44 "<%= dirs.js.node_modules %>/appenlight-client/appenlight-client.min.js",
45 45 "<%= dirs.js.src %>/logging.js",
46 46 "<%= dirs.js.src %>/bootstrap.js",
47 47 "<%= dirs.js.src %>/i18n_utils.js",
48 48 "<%= dirs.js.src %>/deform.js",
49 49 "<%= dirs.js.src %>/ejs.js",
50 50 "<%= dirs.js.src %>/ejs_templates/utils.js",
51 51 "<%= dirs.js.src %>/plugins/jquery.pjax.js",
52 52 "<%= dirs.js.src %>/plugins/jquery.dataTables.js",
53 53 "<%= dirs.js.src %>/plugins/flavoured_checkbox.js",
54 54 "<%= dirs.js.src %>/plugins/jquery.auto-grow-input.js",
55 55 "<%= dirs.js.src %>/plugins/jquery.autocomplete.js",
56 56 "<%= dirs.js.src %>/plugins/jquery.debounce.js",
57 57 "<%= dirs.js.src %>/plugins/jquery.mark.js",
58 58 "<%= dirs.js.src %>/plugins/jquery.timeago.js",
59 59 "<%= dirs.js.src %>/plugins/jquery.timeago-extension.js",
60 60 "<%= dirs.js.src %>/select2/select2.js",
61 61 "<%= dirs.js.src %>/codemirror/codemirror.js",
62 62 "<%= dirs.js.src %>/codemirror/codemirror_loadmode.js",
63 63 "<%= dirs.js.src %>/codemirror/codemirror_hint.js",
64 64 "<%= dirs.js.src %>/codemirror/codemirror_overlay.js",
65 65 "<%= dirs.js.src %>/codemirror/codemirror_placeholder.js",
66 66 "<%= dirs.js.src %>/codemirror/codemirror_simplemode.js",
67 67 "<%= dirs.js.dest %>/mode/meta.js",
68 68 "<%= dirs.js.dest %>/mode/meta_ext.js",
69 69 "<%= dirs.js.src_rc %>/i18n/select2/translations.js",
70 70 "<%= dirs.js.src %>/rhodecode/utils/array.js",
71 71 "<%= dirs.js.src %>/rhodecode/utils/string.js",
72 72 "<%= dirs.js.src %>/rhodecode/utils/pyroutes.js",
73 73 "<%= dirs.js.src %>/rhodecode/utils/ajax.js",
74 74 "<%= dirs.js.src %>/rhodecode/utils/autocomplete.js",
75 75 "<%= dirs.js.src %>/rhodecode/utils/colorgenerator.js",
76 76 "<%= dirs.js.src %>/rhodecode/utils/ie.js",
77 77 "<%= dirs.js.src %>/rhodecode/utils/os.js",
78 78 "<%= dirs.js.src %>/rhodecode/utils/topics.js",
79 79 "<%= dirs.js.src %>/rhodecode/init.js",
80 80 "<%= dirs.js.src %>/rhodecode/changelog.js",
81 81 "<%= dirs.js.src %>/rhodecode/codemirror.js",
82 82 "<%= dirs.js.src %>/rhodecode/comments.js",
83 83 "<%= dirs.js.src %>/rhodecode/constants.js",
84 84 "<%= dirs.js.src %>/rhodecode/files.js",
85 85 "<%= dirs.js.src %>/rhodecode/followers.js",
86 86 "<%= dirs.js.src %>/rhodecode/menus.js",
87 87 "<%= dirs.js.src %>/rhodecode/notifications.js",
88 88 "<%= dirs.js.src %>/rhodecode/permissions.js",
89 89 "<%= dirs.js.src %>/rhodecode/pjax.js",
90 90 "<%= dirs.js.src %>/rhodecode/pullrequests.js",
91 91 "<%= dirs.js.src %>/rhodecode/settings.js",
92 92 "<%= dirs.js.src %>/rhodecode/select2_widgets.js",
93 93 "<%= dirs.js.src %>/rhodecode/tooltips.js",
94 94 "<%= dirs.js.src %>/rhodecode/users.js",
95 95 "<%= dirs.js.src %>/rhodecode/appenlight.js",
96 96 "<%= dirs.js.src %>/rhodecode.js",
97 97 "<%= dirs.js.dest %>/rhodecode-components.js"
98 98 ],
99 99 "dest": "<%= dirs.js.dest %>/scripts.js",
100 100 "nonull": true
101 101 }
102 102 },
103 103 "less": {
104 104 "development": {
105 105 "options": {
106 106 "compress": false,
107 107 "yuicompress": false,
108 108 "optimization": 0
109 109 },
110 110 "files": {
111 111 "<%= dirs.css.dest %>/style.css": "<%= dirs.css.src %>/main.less",
112 112 "<%= dirs.css.dest %>/style-polymer.css": "<%= dirs.css.src %>/polymer.less"
113 113 }
114 114 },
115 115 "production": {
116 116 "options": {
117 117 "compress": true,
118 118 "yuicompress": true,
119 119 "optimization": 2
120 120 },
121 121 "files": {
122 122 "<%= dirs.css.dest %>/style.css": "<%= dirs.css.src %>/main.less",
123 123 "<%= dirs.css.dest %>/style-polymer.css": "<%= dirs.css.src %>/polymer.less"
124 124 }
125 125 },
126 126 "components": {
127 127 "files": [
128 128 {
129 129 "cwd": "<%= dirs.js.src %>/components/",
130 130 "dest": "<%= dirs.js.src %>/components/",
131 131 "src": [
132 132 "**/*.less"
133 133 ],
134 134 "expand": true,
135 135 "ext": ".css"
136 136 }
137 137 ]
138 138 }
139 139 },
140 140 "watch": {
141 141 "less": {
142 142 "files": [
143 143 "<%= dirs.css.src %>/**/*.less",
144 144 "<%= dirs.js.src %>/components/**/*.less"
145 145 ],
146 146 "tasks": [
147 147 "less:development",
148 148 "less:components",
149 149 "concat:polymercss",
150 150 "webpack",
151 151 "concat:dist"
152 152 ]
153 153 },
154 154 "js": {
155 155 "files": [
156 156 "!<%= dirs.js.src %>/components/root-styles.gen.html",
157 157 "<%= dirs.js.src %>/**/*.js",
158 158 "<%= dirs.js.src %>/components/**/*.html"
159 159 ],
160 160 "tasks": [
161 161 "less:components",
162 162 "concat:polymercss",
163 163 "webpack",
164 164 "concat:dist"
165 165 ]
166 166 }
167 167 },
168 168 "jshint": {
169 169 "rhodecode": {
170 170 "src": "<%= dirs.js.src %>/rhodecode/**/*.js",
171 171 "options": {
172 172 "jshintrc": ".jshintrc"
173 173 }
174 174 }
175 175 }
176 176 }
@@ -1,185 +1,195 b''
1 1 <link rel="import" href="../../../../../../bower_components/polymer/polymer.html">
2 2 <link rel="import" href="../channelstream-connection/channelstream-connection.html">
3 3 <link rel="import" href="../rhodecode-toast/rhodecode-toast.html">
4 4 <link rel="import" href="../rhodecode-favicon/rhodecode-favicon.html">
5 5
6 6 <dom-module id="rhodecode-app">
7 7 <template>
8 8 <channelstream-connection
9 9 id="channelstream-connection"
10 10 on-channelstream-listen-message="receivedMessage"
11 11 on-channelstream-connected="handleConnected"
12 12 on-channelstream-subscribed="handleSubscribed">
13 13 </channelstream-connection>
14 14 <rhodecode-favicon></rhodecode-favicon>
15 15 </template>
16 16 <script>
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));
26 31 $.Topic('/connection_controller/subscribe').subscribe(
27 32 this.subscribeToChannelTopic.bind(this));
28 33 // this event can be used to coordinate plugins to do their
29 34 // initialization before channelstream is kicked off
30 35 $.Topic('/__MAIN_APP__').publish({});
31 36
32 37 for (var i = 0; i < alertMessagePayloads.length; i++) {
33 38 $.Topic('/notifications').publish(alertMessagePayloads[i]);
34 39 }
35 40 this.initPlugins();
36 41 // after rest of application loads and topics get fired, launch connection
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;
83 89 channelstreamConnection.websocketUrl = CHANNELSTREAM_URLS.ws + '/ws';
84 90 channelstreamConnection.longPollUrl = CHANNELSTREAM_URLS.longpoll + '/listen';
85 91 // some channels might already be registered by topic
86 92 for (var i = 0; i < channels.length; i++) {
87 93 channelstreamConnection.push('channels', channels[i]);
88 94 }
89 95 // append any additional channels registered in other plugins
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 = [];
99 105 // subscribe to PR repo channel for PR's'
100 106 if (templateContext.pull_request_data.pull_request_id) {
101 107 var channelName = '/repo$' + templateContext.repo_name + '$/pr/' +
102 108 String(templateContext.pull_request_data.pull_request_id);
103 109 channels.push(channelName);
104 110 }
105 111
106 112 if (templateContext.commit_data.commit_id) {
107 113 var channelName = '/repo$' + templateContext.repo_name + '$/commit/' +
108 114 String(templateContext.commit_data.commit_id);
109 115 channels.push(channelName);
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);
120 126 if (toSubscribe.length > 0) {
121 127 // if we are connected then subscribe
122 128 if (channelstreamConnection.connected) {
123 129 channelstreamConnection.subscribe(toSubscribe);
124 130 }
125 131 // not connected? just push channels onto the stack
126 132 else {
127 133 for (var i = 0; i < toSubscribe.length; i++) {
128 134 channelstreamConnection.push('channels', toSubscribe[i]);
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);
163 170 for (var i = 0; i < channelKeys.length; i++) {
164 171 var key = channelKeys[i];
165 172 channelstreamConnection.set(['channelsState', key], channelInfo[key]);
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;
175 183 for (var i = 0; i < channels.length; i++) {
176 184 var key = channels[i];
177 185 $.Topic('/connection_controller/channel_update').publish(
178 186 {channel: key, state: channel_data[key]}
179 187 );
180 188 }
181 189 }
182 });
183 190
191 }
192
193 customElements.define(RhodecodeApp.is, RhodecodeApp);
184 194 </script>
185 195 </dom-module>
@@ -1,29 +1,38 b''
1 1 <link rel="import" href="../../../../../../bower_components/polymer/polymer.html">
2 2
3 3 <dom-module id="rhodecode-favicon">
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,200 +1,233 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>
6 7 <style include="shared-styles">
7 8 /* inset border for buttons - does not work in ie */
8 9 /* rounded borders */
9 10 /* rounded borders - bottom only */
10 11 /* rounded borders - top only */
11 12 /* text shadow */
12 13 /* centers text in a circle - input diameter of circle and color */
13 14 /* pill version of the circle */
14 15 .absolute-center {
15 16 margin: auto;
16 17 position: absolute;
17 18 top: 0;
18 19 left: 0;
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;
76 89 margin-left: 10px;
77 90 margin-right: 10px;
78 91 top: 0;
79 92 left: 0;
80 93 right: 0;
81 94 z-index: 100;
82 95 }
83 96 </style>
84 97
85 98 <template is="dom-if" if="[[hasToasts]]">
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>
93 106 </div>
94 107 </template>
95 108 </div>
96 109 </template>
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,48 +1,61 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
5 6 <dom-module id="rhodecode-toggle">
6 7
7 8 <style include="shared-styles">
8 9 .rc-toggle {
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;
15 17 left: -30px;
16 18 width: 20px;
17 19 height: 20px;
18 20 }
19 21 </style>
20 22
21 23 <template>
22 24 <div class="rc-toggle">
23 25 <paper-toggle-button checked={{checked}}>[[labelStatus(checked)]]</paper-toggle-button>
24 26 <paper-tooltip>[[tooltipText]]</paper-tooltip>
25 27 <template is="dom-if" if="[[shouldShow(noSpinner)]]">
26 28 <paper-spinner active=[[active]]></paper-spinner>
27 29 </template>
28 30 </div>
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,23 +1,31 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>
5 5 <style include="shared-styles"></style>
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>
@@ -1,161 +1,163 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <!DOCTYPE html>
3 3
4 4 <%
5 5 c.template_context['repo_name'] = getattr(c, 'repo_name', '')
6 6 go_import_header = ''
7 7 if hasattr(c, 'rhodecode_db_repo'):
8 8 c.template_context['repo_type'] = c.rhodecode_db_repo.repo_type
9 9 c.template_context['repo_landing_commit'] = c.rhodecode_db_repo.landing_rev[1]
10 10
11 11 if getattr(c, 'repo_group', None):
12 12 c.template_context['repo_group_id'] = c.repo_group.group_id
13 13
14 14 if getattr(c, 'rhodecode_user', None) and c.rhodecode_user.user_id:
15 15 c.template_context['rhodecode_user']['username'] = c.rhodecode_user.username
16 16 c.template_context['rhodecode_user']['email'] = c.rhodecode_user.email
17 17 c.template_context['rhodecode_user']['notification_status'] = c.rhodecode_user.get_instance().user_data.get('notification_status', True)
18 18 c.template_context['rhodecode_user']['first_name'] = c.rhodecode_user.first_name
19 19 c.template_context['rhodecode_user']['last_name'] = c.rhodecode_user.last_name
20 20
21 21 c.template_context['visual']['default_renderer'] = h.get_visual_attr(c, 'default_renderer')
22 22 c.template_context['default_user'] = {
23 23 'username': h.DEFAULT_USER,
24 24 'user_id': 1
25 25 }
26 26
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" />
33 35
34 36 ${h.go_import_header(request, getattr(c, 'rhodecode_db_repo', None))}
35 37
36 38 % if 'safari' in (request.user_agent or '').lower():
37 39 <meta name="referrer" content="origin">
38 40 % else:
39 41 <meta name="referrer" content="origin-when-cross-origin">
40 42 % endif
41 43
42 44 <%def name="robots()">
43 45 <meta name="robots" content="index, nofollow"/>
44 46 </%def>
45 47 ${self.robots()}
46 48 <link rel="icon" href="${h.asset('images/favicon.ico', ver=c.rhodecode_version_hash)}" sizes="16x16 32x32" type="image/png" />
47 49
48 50 ## CSS definitions
49 51 <%def name="css()">
50 52 <link rel="stylesheet" type="text/css" href="${h.asset('css/style.css', ver=c.rhodecode_version_hash)}" media="screen"/>
51 53 <!--[if lt IE 9]>
52 54 <link rel="stylesheet" type="text/css" href="${h.asset('css/ie.css', ver=c.rhodecode_version_hash)}" media="screen"/>
53 55 <![endif]-->
54 56 ## EXTRA FOR CSS
55 57 ${self.css_extra()}
56 58 </%def>
57 59 ## CSS EXTRA - optionally inject some extra CSS stuff needed for specific websites
58 60 <%def name="css_extra()">
59 61 </%def>
60 62
61 63 ${self.css()}
62 64
63 65 ## JAVASCRIPT
64 66 <%def name="js()">
65 67
66 68 <script src="${h.asset('js/rhodecode/i18n/%s.js' % c.language, ver=c.rhodecode_version_hash)}"></script>
67 69 <script type="text/javascript">
68 70 // register templateContext to pass template variables to JS
69 71 var templateContext = ${h.json.dumps(c.template_context)|n};
70 72
71 73 var APPLICATION_URL = "${h.route_path('home').rstrip('/')}";
72 74 var APPLICATION_PLUGINS = [];
73 75 var ASSET_URL = "${h.asset('')}";
74 76 var DEFAULT_RENDERER = "${h.get_visual_attr(c, 'default_renderer')}";
75 77 var CSRF_TOKEN = "${getattr(c, 'csrf_token', '')}";
76 78
77 79 var APPENLIGHT = {
78 80 enabled: ${'true' if getattr(c, 'appenlight_enabled', False) else 'false'},
79 81 key: '${getattr(c, "appenlight_api_public_key", "")}',
80 82 % if getattr(c, 'appenlight_server_url', None):
81 83 serverUrl: '${getattr(c, "appenlight_server_url", "")}',
82 84 % endif
83 85 requestInfo: {
84 86 % if getattr(c, 'rhodecode_user', None):
85 87 ip: '${c.rhodecode_user.ip_addr}',
86 88 username: '${c.rhodecode_user.username}'
87 89 % endif
88 90 },
89 91 tags: {
90 92 rhodecode_version: '${c.rhodecode_version}',
91 93 rhodecode_edition: '${c.rhodecode_edition}'
92 94 }
93 95 };
94 96
95 97 </script>
96 98 <%include file="/base/plugins_base.mako"/>
97 99 <!--[if lt IE 9]>
98 100 <script language="javascript" type="text/javascript" src="${h.asset('js/src/excanvas.min.js')}"></script>
99 101 <![endif]-->
100 102 <script language="javascript" type="text/javascript" src="${h.asset('js/rhodecode/routes.js', ver=c.rhodecode_version_hash)}"></script>
101 103 <script> var alertMessagePayloads = ${h.flash.json_alerts(request=request)|n}; </script>
102 104 ## avoide escaping the %N
103 105 <script language="javascript" type="text/javascript" src="${h.asset('js/scripts.js', ver=c.rhodecode_version_hash)}"></script>
104 106 <script>CodeMirror.modeURL = "${h.asset('') + 'js/mode/%N/%N.js?ver='+c.rhodecode_version_hash}";</script>
105 107
106 108
107 109 ## JAVASCRIPT EXTRA - optionally inject some extra JS for specificed templates
108 110 ${self.js_extra()}
109 111
110 112 <script type="text/javascript">
111 113 Rhodecode = (function() {
112 114 function _Rhodecode() {
113 115 this.comments = new CommentsController();
114 116 }
115 117 return new _Rhodecode();
116 118 })();
117 119
118 120 $(document).ready(function(){
119 121 show_more_event();
120 122 timeagoActivate();
121 123 clipboardActivate();
122 124 })
123 125 </script>
124 126
125 127 </%def>
126 128
127 129 ## JAVASCRIPT EXTRA - optionally inject some extra JS for specificed templates
128 130 <%def name="js_extra()"></%def>
129 131 ${self.js()}
130 132
131 133 <%def name="head_extra()"></%def>
132 134 ${self.head_extra()}
133 135 ## extra stuff
134 136 %if c.pre_code:
135 137 ${c.pre_code|n}
136 138 %endif
137 139 </head>
138 140 <body id="body">
139 141 <noscript>
140 142 <div class="noscript-error">
141 143 ${_('Please enable JavaScript to use RhodeCode Enterprise')}
142 144 </div>
143 145 </noscript>
144 146 ## IE hacks
145 147 <!--[if IE 7]>
146 148 <script>$(document.body).addClass('ie7')</script>
147 149 <![endif]-->
148 150 <!--[if IE 8]>
149 151 <script>$(document.body).addClass('ie8')</script>
150 152 <![endif]-->
151 153 <!--[if IE 9]>
152 154 <script>$(document.body).addClass('ie9')</script>
153 155 <![endif]-->
154 156
155 157 ${next.body()}
156 158 %if c.post_code:
157 159 ${c.post_code|n}
158 160 %endif
159 161 <rhodecode-app></rhodecode-app>
160 162 </body>
161 163 </html>
@@ -1,69 +1,82 b''
1 1 /* webpack.config.js */
2 2 require('style-loader');
3 3 require('css-loader');
4 4 var path = require('path');
5 5
6 6 const projectName = 'rhodecode-components';
7 7 let destinationDirectory = path.join(process.cwd(), 'rhodecode', 'public', 'js')
8 8
9 9 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: {
16 28 main: path.resolve(__dirname, 'rhodecode/public/js/src/components/index.js'),
17 29 },
18 30 output: {
19 31 filename: 'rhodecode-components.js',
20 32 path: path.resolve(destinationDirectory)
21 33 },
22 34 // Tell Webpack which directories to look in to resolve import statements.
23 35 // Normally Webpack will look in node_modules by default but since we’re overriding
24 36 // the property we’ll need to tell it to look there in addition to the
25 37 // bower_components folder.
26 38 resolve: {
27 39 modules: [
28 40 path.resolve(__dirname, 'node_modules'),
29 41 path.resolve(__dirname, 'bower_components')
30 42 ]
31 43 },
32 44 // These rules tell Webpack how to process different module types.
33 45 // Remember, *everything* is a module in Webpack. That includes
34 46 // CSS, and (thanks to our loader) HTML.
35 47 module: {
36 48 rules: [
37 49 {
38 50 // If you see a file that ends in .html, send it to these loaders.
39 51 test: /\.html$/,
40 52 // This is an example of chained loaders in Webpack.
41 53 // Chained loaders run last to first. So it will run
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,
49 62 }
50 63 }
51 64 ],
52 65 },
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 },
60 73 // this is required because of bug:
61 74 // https://github.com/webpack-contrib/polymer-webpack-loader/issues/49
62 75 {
63 76 test: /intl-messageformat.min.js/,
64 77 use: 'imports-loader?this=>window'
65 78 }
66 79 ]
67 80 },
68 81 plugins: []
69 82 };
General Comments 0
You need to be logged in to leave comments. Login now