Skip to content

Commit 223bc5d

Browse files
authored
Merge pull request #216 from github/switch-to-promise-batching-on-attributechangedcallback
Switch to promise batching on attributechangedcallback
2 parents dcf479f + a1bd31e commit 223bc5d

File tree

6 files changed

+228
-109
lines changed

6 files changed

+228
-109
lines changed

src/relative-time-element.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ const dateObserver = new (class {
7979

8080
export default class RelativeTimeElement extends HTMLElement implements Intl.DateTimeFormatOptions {
8181
#customTitle = false
82-
#updating = false
82+
#updating: false | Promise<void> = false
8383

8484
get #lang() {
8585
return this.closest('[lang]')?.getAttribute('lang') ?? 'default'
@@ -341,12 +341,14 @@ export default class RelativeTimeElement extends HTMLElement implements Intl.Dat
341341
this.#customTitle = newValue !== null && this.getFormattedTitle() !== newValue
342342
}
343343
if (!this.#updating && !(attrName === 'title' && this.#customTitle)) {
344-
this.update()
344+
this.#updating = (async () => {
345+
await Promise.resolve()
346+
this.update()
347+
})()
345348
}
346349
}
347350

348351
update() {
349-
this.#updating = true
350352
const oldText: string = this.#renderRoot.textContent || ''
351353
const oldTitle: string = this.getAttribute('title') || ''
352354
let newTitle: string = oldTitle

test/local-time.js

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,107 +12,120 @@ suite('local-time', function () {
1212
fixture.innerHTML = ''
1313
})
1414

15-
test('null getFormattedDate when datetime missing', function () {
15+
test('null getFormattedDate when datetime missing', async () => {
1616
const time = document.createElement('local-time')
1717
time.setAttribute('format', '%Y-%m-%dT%H:%M:%SZ')
18+
await Promise.resolve()
1819
assert.isUndefined(time.getFormattedDate())
1920
})
2021

21-
test('getFormattedDate returns empty string when format missing', function () {
22+
test('getFormattedDate returns empty string when format missing', async () => {
2223
const time = document.createElement('local-time')
2324
time.setAttribute('datetime', '1970-01-01T00:00:00.000Z')
25+
await Promise.resolve()
2426
assert.equal(time.getFormattedDate(), '')
2527
})
2628

27-
test('getFormattedDate with only date attributes', function () {
29+
test('getFormattedDate with only date attributes', async () => {
2830
const time = document.createElement('local-time')
2931
time.setAttribute('datetime', '1970-01-01T00:00:00.000Z')
3032
time.setAttribute('day', 'numeric')
3133
time.setAttribute('month', 'short')
3234
time.setAttribute('year', 'numeric')
3335

3436
const value = time.getFormattedDate()
37+
await Promise.resolve()
3538
assert.include(['Dec 31, 1969', '31 Dec 1969', 'Jan 1, 1970', '1 Jan 1970'], value)
3639
})
3740

38-
test('getFormattedDate without year attribute', function () {
41+
test('getFormattedDate without year attribute', async () => {
3942
const time = document.createElement('local-time')
4043
time.setAttribute('datetime', '1970-01-01T00:00:00.000Z')
4144
time.setAttribute('day', 'numeric')
4245
time.setAttribute('month', 'short')
4346

4447
const value = time.getFormattedDate()
48+
await Promise.resolve()
4549
assert.include(['Dec 31', '31 Dec', 'Jan 1', '1 Jan'], value)
4650
})
4751

48-
test('getFormattedDate with only time attributes', function () {
52+
test('getFormattedDate with only time attributes', async () => {
4953
const time = document.createElement('local-time')
5054
time.setAttribute('lang', 'en-US')
5155
time.setAttribute('datetime', '1970-01-01T00:00:00.000Z')
5256
time.setAttribute('hour', 'numeric')
5357
time.setAttribute('minute', '2-digit')
5458

59+
await Promise.resolve()
5560
if ('Intl' in window) {
5661
assert.match(time.getFormattedDate(), /^\d{1,2}:\d\d (AM|PM)$/)
5762
} else {
5863
assert.match(time.getFormattedDate(), /^\d{2}:\d{2}$/)
5964
}
6065
})
6166

62-
test('ignores contents if datetime attribute is missing', function () {
67+
test('ignores contents if datetime attribute is missing', async () => {
6368
const time = document.createElement('local-time')
6469
time.setAttribute('year', 'numeric')
70+
await Promise.resolve()
6571
assert.equal(time.shadowRoot.textContent, '')
6672
})
6773

68-
test('sets formatted contents to format attribute', function () {
74+
test('sets formatted contents to format attribute', async () => {
6975
const time = document.createElement('local-time')
7076
time.setAttribute('datetime', '1970-01-01T00:00:00.000Z')
7177
time.setAttribute('year', 'numeric')
78+
await Promise.resolve()
7279
assert.include(['1969', '1970'], time.shadowRoot.textContent)
7380
})
7481

75-
test('updates format when attributes change', function () {
82+
test('updates format when attributes change', async () => {
7683
const time = document.createElement('local-time')
7784
time.setAttribute('datetime', '1970-01-01T00:00:00.000Z')
7885

7986
time.setAttribute('year', 'numeric')
87+
await Promise.resolve()
8088
assert.include(['1969', '1970'], time.shadowRoot.textContent)
8189

8290
time.setAttribute('year', '2-digit')
91+
await Promise.resolve()
8392
assert.include(['69', '70'], time.shadowRoot.textContent)
8493
})
8594

86-
test('sets formatted contents when parsed element is upgraded', function () {
95+
test('sets formatted contents when parsed element is upgraded', async () => {
8796
const root = document.createElement('div')
8897
root.innerHTML = '<local-time datetime="1970-01-01T00:00:00.000Z" year="numeric"></local-time>'
8998
if ('CustomElements' in window) {
9099
window.CustomElements.upgradeSubtree(root)
91100
}
101+
await Promise.resolve()
92102
assert.include(['1969', '1970'], root.children[0].shadowRoot.textContent)
93103
})
94-
;('Intl' in window ? test : test.skip)('displays time zone name', function () {
104+
;('Intl' in window ? test : test.skip)('displays time zone name', async () => {
95105
const root = document.createElement('div')
96106
root.innerHTML =
97107
'<local-time datetime="1970-01-01T00:00:00.000Z" minute="2-digit" time-zone-name="short"></local-time>'
98108
if ('CustomElements' in window) {
99109
window.CustomElements.upgradeSubtree(root)
100110
}
111+
await Promise.resolve()
101112
assert.match(root.children[0].shadowRoot.textContent, /^\d{1,2} (\w+([+-]\d+)?)$/)
102113
assert.equal(root.children[0].shadowRoot.textContent, '0 GMT+4')
103114
})
104115

105-
test('updates time zone when the `time-zone-name` attribute changes', function () {
116+
test('updates time zone when the `time-zone-name` attribute changes', async () => {
106117
const el = document.createElement('local-time')
107118
el.setAttribute('lang', 'en-US')
108119
el.setAttribute('datetime', '1970-01-01T00:00:00.000-08:00')
109120
el.setAttribute('time-zone-name', 'short')
110121

111122
fixture.appendChild(el)
123+
await Promise.resolve()
112124
assert.equal(el.shadowRoot.textContent, '1/1/1970, GMT+4')
113125

114126
el.setAttribute('time-zone-name', 'long')
115127

128+
await Promise.resolve()
116129
assert.equal(el.shadowRoot.textContent, '1/1/1970, Gulf Standard Time')
117130
})
118131
})

0 commit comments

Comments
 (0)