Migrated 3 components, set Lit version 2 for babel 6 compatibility, added regenerator-runtime for reverse compatibility

This commit is contained in:
Andrii V 2025-11-14 12:56:54 +01:00
parent 0e136a5492
commit e17f3e7494
9 changed files with 436 additions and 267 deletions

View file

@ -1,3 +1,4 @@
import 'regenerator-runtime/runtime.js';
import '@polymer/iron-ajax/iron-ajax.js';
import './shared-styles.js';
import './channelstream-connection/channelstream-connection.js';

View file

@ -1,33 +1,30 @@
import {PolymerElement, html} from '@polymer/polymer/polymer-element.js';
import {LitElement} from 'lit';
export class RhodecodeFavicon extends PolymerElement {
export class RhodecodeFavicon extends LitElement {
static properties = {
favicon: {type: Object},
counter: {type: Number}
};
static get is() {
return 'rhodecode-favicon';
constructor() {
super();
this.favicon = null;
this.counter = 0;
}
connectedCallback() {
super.connectedCallback();
this.favicon = new Favico({
type: 'rectangle',
animation: 'none'
});
}
updated(changedProperties) {
if (changedProperties.has('counter') && this.favicon) {
this.favicon.badge(this.counter);
}
static get properties() {
return {
favicon: Object,
counter: {
type: Number,
observer: '_handleCounter'
}
}
}
connectedCallback() {
super.connectedCallback();
this.favicon = new Favico({
type: 'rectangle',
animation: 'none'
});
}
_handleCounter(newVal, oldVal) {
this.favicon.badge(this.counter);
}
}
}
customElements.define(RhodecodeFavicon.is, RhodecodeFavicon);
customElements.define('rhodecode-favicon', RhodecodeFavicon);

View file

@ -1,231 +1,241 @@
import {PolymerElement, html} from '@polymer/polymer/polymer-element.js';
import '@polymer/paper-toggle-button/paper-toggle-button.js';
import {mixinBehaviors} from '@polymer/polymer/lib/legacy/class.js';
import {IronA11yKeysBehavior} from '@polymer/iron-a11y-keys-behavior/iron-a11y-keys-behavior.js';
import {LitElement, html, css} from 'lit';
import {classMap} from 'lit/directives/class-map.js';
import '../rhodecode-unsafe-html/rhodecode-unsafe-html.js';
export class RhodecodeToast extends mixinBehaviors([IronA11yKeysBehavior], PolymerElement) {
static get is() {
return 'rhodecode-toast';
export class RhodecodeToast extends LitElement {
static styles = css`
.absolute-center {
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
static get template(){
return html`
<style include="shared-styles">
/* inset border for buttons - does not work in ie */
/* rounded borders */
/* rounded borders - bottom only */
/* rounded borders - top only */
/* text shadow */
/* centers text in a circle - input diameter of circle and color */
/* pill version of the circle */
.absolute-center {
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
.top-left-rounded-corner {
-webkit-border-top-left-radius: 2px;
-khtml-border-radius-topleft: 2px;
border-top-left-radius: 2px;
}
.top-left-rounded-corner {
-webkit-border-top-left-radius: 2px;
-khtml-border-radius-topleft: 2px;
border-top-left-radius: 2px;
}
.top-right-rounded-corner {
-webkit-border-top-right-radius: 2px;
-khtml-border-radius-topright: 2px;
border-top-right-radius: 2px;
}
.top-right-rounded-corner {
-webkit-border-top-right-radius: 2px;
-khtml-border-radius-topright: 2px;
border-top-right-radius: 2px;
}
.bottom-left-rounded-corner {
-webkit-border-bottom-left-radius: 2px;
-khtml-border-radius-bottomleft: 2px;
border-bottom-left-radius: 2px;
}
.bottom-left-rounded-corner {
-webkit-border-bottom-left-radius: 2px;
-khtml-border-radius-bottomleft: 2px;
border-bottom-left-radius: 2px;
}
.bottom-right-rounded-corner {
-webkit-border-bottom-right-radius: 2px;
-khtml-border-radius-bottomright: 2px;
border-bottom-right-radius: 2px;
}
.bottom-right-rounded-corner {
-webkit-border-bottom-right-radius: 2px;
-khtml-border-radius-bottomright: 2px;
border-bottom-right-radius: 2px;
}
.top-left-rounded-corner-mid {
-webkit-border-top-left-radius: 2px;
-khtml-border-radius-topleft: 2px;
border-top-left-radius: 2px;
}
.top-left-rounded-corner-mid {
-webkit-border-top-left-radius: 2px;
-khtml-border-radius-topleft: 2px;
border-top-left-radius: 2px;
}
.top-right-rounded-corner-mid {
-webkit-border-top-right-radius: 2px;
-khtml-border-radius-topright: 2px;
border-top-right-radius: 2px;
}
.top-right-rounded-corner-mid {
-webkit-border-top-right-radius: 2px;
-khtml-border-radius-topright: 2px;
border-top-right-radius: 2px;
}
.bottom-left-rounded-corner-mid {
-webkit-border-bottom-left-radius: 2px;
-khtml-border-radius-bottomleft: 2px;
border-bottom-left-radius: 2px;
}
.bottom-left-rounded-corner-mid {
-webkit-border-bottom-left-radius: 2px;
-khtml-border-radius-bottomleft: 2px;
border-bottom-left-radius: 2px;
}
.bottom-right-rounded-corner-mid {
-webkit-border-bottom-right-radius: 2px;
-khtml-border-radius-bottomright: 2px;
border-bottom-right-radius: 2px;
}
.bottom-right-rounded-corner-mid {
-webkit-border-bottom-right-radius: 2px;
-khtml-border-radius-bottomright: 2px;
border-bottom-right-radius: 2px;
}
.alert {
clear: both;
padding: 15px;
margin: 10px 0;
border: 1px solid;
border-radius: 2px;
color: #7E7F7F;
border-color: #84a5d2;
background-color: #e6edf6;
}
.alert {
margin: 10px 0;
}
.alert-success {
border-color: #0ac878;
background-color: #daf7eb;
}
.toast-close {
margin: 0;
float: right;
cursor: pointer;
}
.alert-error {
border-color: #e85e4d;
background-color: #fbdfdb;
}
.toast-message-holder {
background: rgba(255, 255, 255, 0.25);
}
.alert-warning {
border-color: #ffc854;
background-color: #fff4dd;
}
.toast-message-holder.fixed {
position: fixed;
padding: 10px 0;
margin-left: 10px;
margin-right: 10px;
top: 0;
left: 0;
right: 0;
z-index: 100;
}
</style>
.alert-info {
border-color: #84a5d2;
background-color: #e6edf6;
}
<template is="dom-if" if="[[hasToasts]]">
<div class$="container toast-message-holder [[conditionalClass(isFixed)]]">
<template is="dom-repeat" items="[[toasts]]">
<div class$="alert alert-[[item.level]]">
<div on-click="dismissNotification" class="toast-close" index-pos="[[index]]">
<span>[[_gettext('Close')]]</span>
</div>
<rhodecode-unsafe-html text="[[item.message]]"></rhodecode-unsafe-html>
</div>
</template>
.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`
<div class=${classMap({
'container': true,
'toast-message-holder': true,
'fixed': this.isFixed
})}>
${this.toasts.map((item, index) => html`
<div class="alert alert-${item.level}">
<div class="toast-close" @click=${() => this.dismissNotification(index)}>
<span>${this._gettext('Close')}</span>
</div>
</template>
`
<rhodecode-unsafe-html .text=${item.message}></rhodecode-unsafe-html>
</div>
`)}
</div>
`;
}
_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);

View file

@ -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`
<style include="shared-styles"></style>
<slot></slot>
`;
}
static get properties() {
return {
text: {
type: String,
observer: '_handleText'
}
}
}
_handleText(newVal, oldVal) {
this.innerHTML = this.text;
constructor() {
super();
this.text = '';
}
render() {
return html`<slot></slot>`;
}
updated(changedProperties) {
if (changedProperties.has('text')) {
this.innerHTML = this.text;
}
}
}
customElements.define(RhodecodeUnsafeHtml.is, RhodecodeUnsafeHtml);
customElements.define('rhodecode-unsafe-html', RhodecodeUnsafeHtml);