8000 Merge pull request #246 from github/add-onrelativetimeupdated-getter · github/relative-time-element@cce3194 · GitHub
[go: up one dir, main page]

Skip to content

Commit cce3194

Browse files
authored
Merge pull request #246 from github/add-onrelativetimeupdated-getter
Add onrelativetimeupdated getter
2 parents 9302a83 + 2d82523 commit cce3194

File tree

2 files changed

+113
-6
lines changed

2 files changed

+113
-6
lines changed

src/relative-time-element.ts

Lines changed: 32 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

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
@@ -733,6 +733,86 @@ suite('relative-time', function () {
733733
})
734734
})
735735

736+
suite('relative-time-updated event', () => {
737+
test('dispatches a bubbling+composed relative-time-updated event on each update', async () => {
738+
const el = document.createElement('relative-time')
739+
el.setAttribute('datetime', '1970-01-01T00:00:00.000-08:00')
740+
let event
741+
el.addEventListener('relative-time-updated', e => (event = e))
742+
await Promise.resolve()
743+
assert.instanceOf(event, RelativeTimeUpdatedEvent)
744+
assert.propertyVal(event, 'composed', true)
745+
assert.propertyVal(event, 'bubbles', true)
746+
})
747+
748+
test('event contains oldText, newText, oldTitle, newTitle properties', async () => {
749+
const el = document.createElement('relative-time')
750+
el.setAttribute('datetime', '1970-01-01T00:00:00.000-08:00')
751+
let event
752+
el.addEventListener('relative-time-updated', e => (event = e))
753+
await Promise.resolve()
754+
assert.propertyVal(event, 'oldText', '')
755+
assert.propertyVal(event, 'newText', 'on Jan 1, 1970')
756+
assert.propertyVal(event, 'oldTitle', '')
757+
assert.propertyVal(event, 'newTitle', 'Jan 1, 1970, 12:00 PM GMT+4')
758+
el.setAttribute('datetime', '1970-01-01T01:00:00.000-08:00')
759+
await Promise.resolve()
760+
assert.propertyVal(event, 'oldText', 'on Jan 1, 1970')
761+
assert.propertyVal(event, 'newText', 'on Jan 1, 1970')
762+
assert.propertyVal(event, 'oldTitle', 'Jan 1, 1970, 12:00 PM GMT+4')
763+
assert.propertyVal(event, 'newTitle', 'Jan 1, 1970, 1:00 PM GMT+4')
764+
})
765+
766+
test('allows binding of `onrelativetimeupdated` property', async () => {
767+
const el = document.createElement('relative-time')
768+
el.setAttribute('datetime', '1970-01-01T00:00:00.000-08:00')
769+
let event
770+
el.onRelativeTimeUpdated = e => (event = e)
771+
await Promise.resolve()
772+
assert.instanceOf(event, RelativeTimeUpdatedEvent)
773+
})
774+
775+
test('unbinds old `onRelativeTimeUpdated` property values', async () => {
776+
const el = document.createElement('relative-time')
777+
el.setAttribute('datetime', '1970-01-01T00:00:00.000-08:00')
778+
let called = false
779+
const fn = () => (called = true)
780+
el.onRelativeTimeUpdated = fn
781+
assert.equal(el.onRelativeTimeUpdated, fn)
782+
el.onRelativeTimeUpdated = null
783+
assert.equal(el.onRelativeTimeUpdated, null)
784+
await Promise.resolve()
785+
assert.equal(called, false, 'onRelativeTimeUpdated was called but should not have been')
786+
})
787+
788+
test('only binds function event listeners on `onRelativeTimeUpdated`', async () => {
789+
const el = document.createElement('relative-time')
790+
el.setAttribute('datetime', '1970-01-01T00:00:00.000-08:00')
791+
let called = false
792+
const listenerObject = {
793+
handleEvent() {
794+
called = true
795+
},
796+
}
797+
el.onRelativeTimeUpdated = listenerObject
798+
assert.equal(el.onRelativeTimeUpdated, listenerObject)
799+
await Promise.resolve()
800+
assert.equal(called, false, 'onRelativeTimeUpdated was called but should not have been')
801+
})
802+
803+
test('calling stopImmediatePropagation() effects onRelativeTimeUpdated property', async () => {
804+
const el = document.createElement('relative-time')
805+
el.setAttribute('datetime', '1970-01-01T00:00:00.000-08:00')
806+
let called = false
807+
el.addEventListener('relative-time-updated', e => {
808+
e.stopImmediatePropagation()
809+
})
810+
el.onRelativeTimeUpdated = () => (called = true)
811+
await Promise.resolve()
812+
assert.equal(called, false, 'onRelativeTimeUpdated was called but should not have been')
813+
})
814+
})
815+
736816
suite('table tests', function () {
737817
const referenceDate = '2022-10-24T14:46:00.000Z'
738818
const tests = new Set([

0 commit comments

Comments
 (0)
0