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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy