-
-
-
- [[_gettext('Close')]]
-
-
-
-
+ .toast-close {
+ margin: 0;
+ float: right;
+ cursor: pointer;
+ }
+
+ .toast-message-holder {
+ background: rgba(255, 255, 255, 0.25);
+ }
+
+ .toast-message-holder.fixed {
+ position: fixed;
+ padding: 10px 0;
+ margin-left: 10px;
+ margin-right: 10px;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 100;
+ }
+ `;
+
+ static properties = {
+ toasts: {type: Array},
+ isFixed: {type: Boolean}
+ };
+
+ constructor() {
+ super();
+ this.toasts = [];
+ this.isFixed = false;
+ this._headerNode = null;
+ this._debouncedCalcBound = this._debouncedCalc.bind(this);
+ this._handleKeyupBound = this._handleKeyup.bind(this);
+ this._debounceTimeout = null;
+ }
+
+ get hasToasts() {
+ return this.toasts && this.toasts.length > 0;
+ }
+
+ connectedCallback() {
+ super.connectedCallback();
+ this._headerNode = document.querySelector('.header');
+ window.addEventListener('scroll', this._debouncedCalcBound);
+ window.addEventListener('resize', this._debouncedCalcBound);
+ window.addEventListener('keyup', this._handleKeyupBound);
+ this._debouncedCalc();
+ }
+
+ disconnectedCallback() {
+ super.disconnectedCallback();
+ window.removeEventListener('scroll', this._debouncedCalcBound);
+ window.removeEventListener('resize', this._debouncedCalcBound);
+ window.removeEventListener('keyup', this._handleKeyupBound);
+ if (this._debounceTimeout) {
+ clearTimeout(this._debounceTimeout);
+ }
+ }
+
+ updated(changedProperties) {
+ if (changedProperties.has('toasts')) {
+ $.Topic('/favicon/update').publish({count: this.toasts.length});
+ }
+ }
+
+ render() {
+ if (!this.hasToasts) {
+ return html``;
+ }
+
+ return html`
+
+ ${this.toasts.map((item, index) => html`
+
+
this.dismissNotification(index)}>
+ ${this._gettext('Close')}
-
- `
+
+
+ `)}
+
+ `;
+ }
+
+ _handleKeyup(event) {
+ if (event.key === 'Escape') {
+ this.dismissNotifications();
}
+ }
- static get properties() {
- return {
- toasts: {
- type: Array,
- value() {
- return []
- }
- },
- isFixed: {
- type: Boolean,
- value: false
- },
- hasToasts: {
- type: Boolean,
- computed: '_computeHasToasts(toasts.*)'
- },
- keyEventTarget: {
- type: Object,
- value() {
- return document.body;
- }
- }
- }
+ _debouncedCalc() {
+ if (this._debounceTimeout) {
+ clearTimeout(this._debounceTimeout);
}
+ this._debounceTimeout = setTimeout(() => {
+ this.toastInWindow();
+ }, 25);
+ }
- get keyBindings() {
- return {
- 'esc:keyup': '_hideOnEsc'
- }
+ toastInWindow() {
+ if (!this._headerNode) {
+ return true;
}
+ const headerHeight = this._headerNode.offsetHeight;
+ const scrollPosition = window.scrollY;
- static get observers() {
- return [
- '_changedToasts(toasts.splices)'
- ]
+ if (this.isFixed) {
+ this.isFixed = 1 <= scrollPosition;
+ } else {
+ this.isFixed = headerHeight <= scrollPosition;
}
+ }
- _hideOnEsc(event) {
- return this.dismissNotifications();
- }
-
- _computeHasToasts() {
- return this.toasts.length > 0;
- }
-
- _debouncedCalc() {
- // calculate once in a while
- this.debounce('debouncedCalc', this.toastInWindow, 25);
- }
-
- conditionalClass() {
- return this.isFixed ? 'fixed' : '';
- }
-
- toastInWindow() {
- if (!this._headerNode) {
- return true
- }
- var headerHeight = this._headerNode.offsetHeight;
- var scrollPosition = window.scrollY;
-
- if (this.isFixed) {
- this.isFixed = 1 <= scrollPosition;
- }
- else {
- this.isFixed = headerHeight <= scrollPosition;
- }
- }
-
- connectedCallback() {
- super.connectedCallback();
- this._headerNode = document.querySelector('.header', document);
- this.listen(window, 'scroll', '_debouncedCalc');
- this.listen(window, 'resize', '_debouncedCalc');
- this._debouncedCalc();
- }
-
- _changedToasts(newValue, oldValue) {
- $.Topic('/favicon/update').publish({count: this.toasts.length});
- }
-
- dismissNotification(e) {
- $.Topic('/favicon/update').publish({count: this.toasts.length - 1});
- var idx = e.target.parentNode.indexPos
- this.splice('toasts', idx, 1);
-
- }
-
- dismissNotifications() {
- $.Topic('/favicon/update').publish({count: 0});
- this.splice('toasts', 0);
- }
-
- handleNotification(data) {
- if (!templateContext.rhodecode_user.notification_status && !data.message.force) {
- // do not act if notifications are disabled
- return
- }
- this.push('toasts', {
- level: data.message.level,
- message: data.message.message
- });
- }
-
- _gettext(x){
- return _gettext(x)
+ dismissNotification(index) {
+ $.Topic('/favicon/update').publish({count: this.toasts.length - 1});
+ this.toasts = [
+ ...this.toasts.slice(0, index),
+ ...this.toasts.slice(index + 1)
+ ];
+ }
+
+ dismissNotifications() {
+ $.Topic('/favicon/update').publish({count: 0});
+ this.toasts = [];
+ }
+
+ handleNotification(data) {
+ if (!templateContext.rhodecode_user.notification_status && !data.message.force) {
+ return;
}
+ this.toasts = [...this.toasts, {
+ level: data.message.level,
+ message: data.message.message
+ }];
+ }
+ _gettext(x) {
+ return _gettext(x);
+ }
}
-customElements.define(RhodecodeToast.is, RhodecodeToast);
+customElements.define('rhodecode-toast', RhodecodeToast);
diff --git a/rhodecode/public/js/src/components/rhodecode-unsafe-html/rhodecode-unsafe-html.js b/rhodecode/public/js/src/components/rhodecode-unsafe-html/rhodecode-unsafe-html.js
index 7290a207..72223043 100644
--- a/rhodecode/public/js/src/components/rhodecode-unsafe-html/rhodecode-unsafe-html.js
+++ b/rhodecode/public/js/src/components/rhodecode-unsafe-html/rhodecode-unsafe-html.js
@@ -1,30 +1,24 @@
-import {PolymerElement, html} from '@polymer/polymer/polymer-element.js';
+import {LitElement, html} from 'lit';
-export class RhodecodeUnsafeHtml extends PolymerElement {
+export class RhodecodeUnsafeHtml extends LitElement {
+ static properties = {
+ text: {type: String}
+ };
- static get is() {
- return 'rhodecode-unsafe-html';
- }
-
- static get template() {
- return html`
-
-
- `;
- }
-
- static get properties() {
- return {
- text: {
- type: String,
- observer: '_handleText'
- }
- }
- }
-
- _handleText(newVal, oldVal) {
- this.innerHTML = this.text;
+ constructor() {
+ super();
+ this.text = '';
+ }
+
+ render() {
+ return html`
`;
+ }
+
+ updated(changedProperties) {
+ if (changedProperties.has('text')) {
+ this.innerHTML = this.text;
}
+ }
}
-customElements.define(RhodecodeUnsafeHtml.is, RhodecodeUnsafeHtml);
+customElements.define('rhodecode-unsafe-html', RhodecodeUnsafeHtml);
diff --git a/rhodecode/templates/base/root.mako b/rhodecode/templates/base/root.mako
index 3a69305e..86cbd02b 100644
--- a/rhodecode/templates/base/root.mako
+++ b/rhodecode/templates/base/root.mako
@@ -58,7 +58,6 @@ c.template_context['attachment_store'] = {
%def>
${self.robots()}
-
## CSS definitions
diff --git a/rhodecode/templates/errors/error_document.mako b/rhodecode/templates/errors/error_document.mako
index 58978505..d58ff3ef 100644
--- a/rhodecode/templates/errors/error_document.mako
+++ b/rhodecode/templates/errors/error_document.mako
@@ -11,7 +11,6 @@
%endif
-
diff --git a/rhodecode/tests/rhodecode.ini b/rhodecode/tests/rhodecode.ini
index c628eba7..7a8726cb 100644
--- a/rhodecode/tests/rhodecode.ini
+++ b/rhodecode/tests/rhodecode.ini
@@ -588,7 +588,7 @@ search.location = %(here)s/.rc-test-data/data/index
channelstream.enabled = false
; server address for channelstream server on the backend
-channelstream.server = channelstream:9800
+channelstream.server = channelstream:8000
; location of the channelstream server from outside world
; use ws:// for http or wss:// for https. This address needs to be handled
diff --git a/webpack.config.js b/webpack.config.js
index bc868e78..83dd1fa7 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -15,11 +15,19 @@ let babelRCOptions = {
"presets": [
["env", {
"targets": {
- "browsers": ["last 2 versions"]
- }
+ "esmodules": true
+ },
+ "exclude": [
+ "transform-es2015-classes",
+ "transform-regenerator",
+ "transform-async-to-generator"
+ ]
}]
],
- "plugins": ["transform-object-rest-spread"]
+ "plugins": [
+ ["transform-class-properties", { "loose": true }],
+ "transform-object-rest-spread"
+ ]
};
module.exports = {
@@ -67,9 +75,10 @@ module.exports = {
{
// If you see a file that ends in .js, just send it to the babel-loader.
test: /\.js$/,
+ // Exclude node_modules, but process our Lit components
+ // Babel is configured to NOT transpile ES6 classes (see babelRCOptions exclude)
+ exclude: /node_modules/,
use: {loader: 'babel-loader', options: babelRCOptions}
- // Optionally exclude node_modules from transpilation except for polymer-webpack-loader:
- // exclude: /node_modules\/(?!polymer-webpack-loader\/).*/
},
// this is required because of bug:
// https://github.com/webpack-contrib/polymer-webpack-loader/issues/49