8000 add onrelativetimeupdated field · github/relative-time-element@ed48ea7 · GitHub
[go: up one dir, main page]

Skip to content

Commit ed48ea7

Browse files
committed
add onrelativetimeupdated field
1 parent 9388664 commit ed48ea7

File tree

2 files changed

+115
-6
lines changed

2 files changed

+115
-6
lines changed

src/relative-time-element.ts

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Duration, unitNames, Unit, isDuration, elapsedTime, roundToSingleUnit, getRelativeTimeUnit} from './duration.js'
1+
import {Duration, elapsedTime, getRelativeTimeUnit, isDuration, roundToSingleUnit, Unit, unitNames} from './duration.js'
22
const root = (typeof globalThis !== 'undefined' ? globalThis : window) as typeof window
33
const HTMLElement = root.HTMLElement || (null as unknown as typeof window['HTMLElement'])
44

@@ -160,17 +160,24 @@ export default class RelativeTimeElement extends HTMLElement implements Intl.Dat
160160
duration = empty
161161
}
162162
const display = `${this.precision}sDisplay`
163-
if (duration.blank) return empty.toLocaleString(locale, {style, [display]: 'always'})
163+
if (duration.blank) {
164+
return empty.toLocaleString(locale, {style, [display]: 'always'})
165+
}
164166
return duration.abs().toLocaleString(locale, {style})
165167
}
166168

167169
#getRelativeFormat(duration: Duration): string {
168-
const relativeFormat = new Intl.RelativeTimeFormat(this.#lang, {numeric: 'auto', style: this.formatStyle})
170+
const relativeFormat = new Intl.RelativeTimeFormat(this.#lang, {
171+
numeric: 'auto',
172+
style: this.formatStyle,
173+
})
169174
const tense = this.tense
170175
if (tense === 'future' && duration.sign !== 1) duration = emptyDuration
171176
if (tense === 'past' && duration.sign !== -1) duration = emptyDuration
172177
const [int, unit] = getRelativeTimeUnit(duration)
173-
if (unit === 'second' && int < 10) return relativeFormat.format(0, 'second')
178+
if (unit === 'second' && int < 10) {
179+
return relativeFormat.format(0, 'second')
180+
}
174181
return relativeFormat.format(int, unit)
175182
}
176183

@@ -188,6 +195,24 @@ export default class RelativeTimeElement extends HTMLElement implements Intl.Dat
188195
return `${this.prefix} ${formatter.format(date)}`.trim()
189196
}
190197

198+
#onRelativeTimeUpdated: ((event: RelativeTimeUpdatedEvent) => void) | null = null
199+
get onRelativeTimeUpdated() {
200+
return this.#onRelativeTimeUpdated
201+
}
202+
203+
set onRelativeTimeUpdated(listener: ((event: RelativeTimeUpdatedEvent) => void) | null) {
204+
if (this.#onRelativeTimeUpdated) {
205+
this.removeEventListener(
206+
'relative-time-updated',
207+
this.#onRelativeTimeUpdated as unknown as EventListenerOrEventListenerObject,
208+
)
209+
}
210+
this.#onRelativeTimeUpdated = typeof listener === 'object' || typeof listener === 'function' ? listener : null
211+
if (typeof listener === 'function') {
212+
this.addEventListener('relative-time-updated', listener as unknown as EventListenerOrEventListenerObject)
213+
}
214+
}
215+
191216
get second() {
192217
const second = this.getAttribute('second')
193218
if (second === 'numeric' || second === '2-digit') return second
@@ -217,7 +242,9 @@ export default class RelativeTimeElement extends HTMLElement implements Intl.Dat
217242

218243
get weekday() {
219244
const weekday = this.getAttribute('weekday')
220-
if (weekday === 'long' || weekday === 'short' || weekday === 'narrow') return weekday
245+
if (weekday === 'long' || weekday === 'short' || weekday === 'narrow') {
246+
return weekday
247+
}
221248
if (this.format === 'datetime' && weekday !== '') return this.formatStyle
222249
}
223250

@@ -423,6 +450,8 @@ export default class RelativeTimeElement extends HTMLElement implements Intl.Dat
423450
this.#renderRoot.textContent = this.textContent
424451
}
425452

453+
this.setAttribute('aria-label', `${this.#renderRoot.textContent} (${this.getAttribute('title')})`)
454+
426455
if (newText !== oldText || newTitle !== oldTitle) {
427456
this.dispatchEvent(new RelativeTimeUpdatedEvent(oldText, newText, oldTitle, newTitle))
428457
}

test/relative-time.js

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {assert} from '@open-wc/testing'
2-
import {RelativeTimeElement} from '../src/index.ts'
2+
import {RelativeTimeElement, RelativeTimeUpdatedEvent} from '../src/index.ts'
33

44
suite('relative-time', function () {
55
let dateNow
@@ -753,6 +753,86 @@ suite('relative-time', function () {
753753
})
754754
})
755755

756+
suite('relative-time-updated event', () => {
757+
test('dispatches a bubbling+composed relative-time-updated event on each update', async () => {
758+
const el = document.createElement('relative-time')
759+
el.setAttribute('datetime', '1970-01-01T00:00:00.000-08:00')
760+
let event
761+
el.addEventListener('relative-time-updated', e => (event = e))
762+
await Promise.resolve()
763+
assert.instanceOf(event, RelativeTimeUpdatedEvent)
764+
assert.propertyVal(event, 'composed', true)
765+
assert.propertyVal(event, 'bubbles', true)
766+
})
767+
768+
test('event contains oldText, newText, oldTitle, newTitle properties', async () => {
769+
const el = document.createElement('relative-time')
770+
el.setAttribute('datetime', '1970-01-01T00:00:00.000-08:00')
771+
let event
772+
el.addEventListener('relative-time-updated', e => (event = e))
773+
await Promise.resolve()
774+
assert.propertyVal(event, 'oldText', '')
775+
assert.propertyVal(event, 'newText', 'on Jan 1, 1970')
776+
assert.propertyVal(event, 'oldTitle', '')
777+
assert.propertyVal(event, 'newTitle', 'Jan 1, 1970, 12:00 PM GMT+4')
778+
el.setAttribute('datetime', '1970-01-01T01:00:00.000-08:00')
779+
await Promise.resolve()
780+
assert.propertyVal(event, 'oldText', 'on Jan 1, 1970')
781+
assert.propertyVal(event, 'newText', 'on Jan 1, 1970')
782+
assert.propertyVal(event, 'oldTitle', 'Jan 1, 1970, 12:00 PM GMT+4')
783+
assert.propertyVal(event, 'newTitle', 'Jan 1, 1970, 1:00 PM GMT+4')
784+
})
785+
786+
test('allows binding of `onrelativetimeupdated` property', async () => {
787+
const el = document.createElement('relative-time')
788+
el.setAttribute('datetime', '1970-01-01T00:00:00.000-08:00')
789+
let event
790+
el.onRelativeTimeUpdated = e => (event = e)
791+
await Promise.resolve()
792+
assert.instanceOf(event, RelativeTimeUpdatedEvent)
793+
})
794+
795+
test('unbinds old `onRelativeTimeUpdated` property values', async () => {
796+
const el = document.createElement('relative-time')
797+
el.setAttribute('datetime', '1970-01-01T00:00:00.000-08:00')
798+
let called = false
799+
const fn = () => (called = true)
800+
el.onRelativeTimeUpdated = fn
801+
assert.equal(el.onRelativeTimeUpdated, fn)
802+
el.onRelativeTimeUpdated = null
803+
assert.equal(el.onRelativeTimeUpdated, null)
804+
await Promise.resolve()
805+
assert.equal(called, false, 'onRelativeTimeUpdated was called but should not have been')
806+
})
807+
808+
test('only binds function event listeners on `onRelativeTimeUpdated`', async () => {
809+
const el = document.createElement('relative-time')
810+
el.setAttribute('datetime', '1970-01-01T00:00:00.000-08:00')
811+
let called = false
812+
const listenerObject = {
813+
handleEvent() {
814+
called = true
815+
},
816+
}
817+
el.onRelativeTimeUpdated = listenerObject
818+
assert.equal(el.onRelativeTimeUpdated, listenerObject)
819+
await Promise.resolve()
820+
assert.equal(called, false, 'onRelativeTimeUpdated was called but should not have been')
821+
})
822+
823+
test('calling stopImmediatePropagation() effects onRelativeTimeUpdated property', async () => {
824+
const el = document.createElement('relative-time')
825+
el.setAttribute('datetime', '1970-01-01T00:00:00.000-08:00')
826+
let called = false
827+
el.addEventListener('relative-time-updated', e => {
828+
e.stopImmediatePropagation()
829+
})
830+
el.onRelativeTimeUpdated = () => (called = true)
831+
await Promise.resolve()
832+
assert.equal(called, false, 'onRelativeTimeUpdated was called but should not have been')
833+
})
834+
})
835+
756836
suite('table tests', function () {
757837
const referenceDate = '2022-10-24T14:46:00.000Z'
758838
const tests = new Set([

0 commit comments

Comments
 (0)
0