diff --git a/web_src/css/base.css b/web_src/css/base.css index 0f1b122fa6..c7b5fe9f44 100644 --- a/web_src/css/base.css +++ b/web_src/css/base.css @@ -255,7 +255,8 @@ h1.error-code { } ::selection, -relative-time::part(relative-time)::selection { +relative-time::part(relative-time)::selection, +absolute-date::part(absolute-date)::selection { background: var(--color-selection-bg); color: var(--color-selection-fg); } diff --git a/web_src/js/webcomponents/absolute-date.js b/web_src/js/webcomponents/absolute-date.js index 32f0ad7d13..163d4d4f4f 100644 --- a/web_src/js/webcomponents/absolute-date.js +++ b/web_src/js/webcomponents/absolute-date.js @@ -13,6 +13,7 @@ window.customElements.define('absolute-date', class extends HTMLElement { static observedAttributes = ['date', 'year', 'month', 'weekday', 'day']; initialized = false; + contentSpan = null; update = () => { const opt = {}; @@ -22,8 +23,13 @@ window.customElements.define('absolute-date', class extends HTMLElement { const lang = this.closest('[lang]')?.getAttribute('lang') || this.ownerDocument.documentElement.getAttribute('lang') || ''; - if (!this.shadowRoot) this.attachShadow({mode: 'open'}); - this.shadowRoot.textContent = toAbsoluteLocaleDate(this.getAttribute('date'), lang, opt); + if (!this.shadowRoot) { + this.attachShadow({mode: 'open'}); + this.contentSpan = document.createElement('span'); + this.contentSpan.setAttribute('part', 'absolute-date'); + this.shadowRoot.append(this.contentSpan); + } + this.contentSpan.textContent = toAbsoluteLocaleDate(this.getAttribute('date'), lang, opt); }; attributeChangedCallback(_name, oldValue, newValue) { diff --git a/web_src/js/webcomponents/absolute-date.test.js b/web_src/js/webcomponents/absolute-date.test.js index 95fb1a9017..c94cce002e 100644 --- a/web_src/js/webcomponents/absolute-date.test.js +++ b/web_src/js/webcomponents/absolute-date.test.js @@ -22,3 +22,21 @@ test('toAbsoluteLocaleDate', () => { expect(new Date('2024-03-15').toLocaleString('en-US')).toEqual('3/14/2024, 8:00:00 PM'); expect(toAbsoluteLocaleDate('2024-03-15', 'en-US')).toEqual('3/15/2024, 12:00:00 AM'); }); + +test('absolute-date structure', () => { + const element = document.createElement('absolute-date'); + element.setAttribute('date', '2026-06-16T00:00:00Z'); + element.setAttribute('year', 'numeric'); + + document.body.append(element); + + const shadowRoot = element.shadowRoot; + const childSpan = shadowRoot.querySelector('span'); + + expect(shadowRoot).toBeTruthy(); // verifies if isolated open shadow root exists + expect(childSpan).toBeTruthy(); // verifies that a clean tag was spawned + expect(childSpan.getAttribute('part')).toBe('absolute-date'); // verifies the CSS styling hook bridge + expect(childSpan.textContent).toContain('2026'); // verifies that the date string outputs + + element.remove();// clean up DOM env +});