const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); const notForced = () => !('colorSchemeOs' in document.documentElement.dataset); const lightColor = 'rgba(255, 255, 255, 0.8)'; const darkColor = 'rgba(0, 0, 0, 0.8)'; const getColorScheme = () => { if (notForced()) { return darkModeMediaQuery.matches ? darkColor : lightColor; } if ('colorScheme' in document.documentElement.dataset) { return document.documentElement.dataset.colorScheme === 'dark' ? darkColor : lightColor; } return darkModeMediaQuery.matches ? darkColor : lightColor; }; /** * Creates a custom element with the default spinner of the Joomla logo */ class JoomlaCoreLoader extends HTMLElement { get inline() { return this.hasAttribute('inline'); } set inline(value) { if (value !== null) { this.setAttribute('inline', ''); } else { this.removeAttribute('inline'); } } get size() { return this.getAttribute('size') || '345'; } set size(value) { this.setAttribute('size', value); } get color() { return this.getAttribute('color'); } set color(value) { this.setAttribute('color', value); } static get observedAttributes() { return ['color', 'size', 'inline']; } constructor() { super(); this.attachShadow({ mode: 'open' }); const template = document.createElement('template'); template.innerHTML = ` `; this.shadowRoot.appendChild(template.content.cloneNode(true)); } connectedCallback() { this.style.backgroundColor = this.color ? this.color : getColorScheme(); darkModeMediaQuery.addEventListener('change', this.systemQuery); if (!this.inline) { this.classList.add('fullscreen'); } } disconnectedCallback() { darkModeMediaQuery.removeEventListener('change', this.systemQuery); } attributeChangedCallback(attr, oldValue, newValue) { switch (attr) { case 'color': if (newValue && newValue !== oldValue) { this.style.backgroundColor = newValue; } break; case 'size': if (newValue && newValue !== oldValue) { const svg = this.shadowRoot.querySelector('svg'); svg.setAttribute('width', newValue); svg.setAttribute('height', newValue); } break; case 'inline': if (this.hasAttribute('inline')) { this.classList.remove('fullscreen'); } else { this.classList.add('fullscreen'); } break; } } systemQuery(event) { if (!notForced() || this.color) return; const color = event.matches === true ? darkColor : lightColor; if (this.style.backgroundColor !== color) { this.style.backgroundColor = color; } } } window.customElements.define('joomla-core-loader', JoomlaCoreLoader);