Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 936abae

Browse files
committed
fix: guarantee order of load events
Fixes #21
1 parent 1565634 commit 936abae

File tree

2 files changed

+36
-22
lines changed

2 files changed

+36
-22
lines changed

src/index.ts

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,13 @@ const observer = new IntersectionObserver(entries => {
2121
})
2222

2323

24-
function fire(name: string, target: Element) {
25-
setTimeout(function () {
26-
target.dispatchEvent(new Event(name))
27-
}, 0)
24+
function fire(name: string, target: Element): Promise<void> {
25+
return new Promise(resolve => {
26+
setTimeout(function () {
27+
target.dispatchEvent(new Event(name))
28+
resolve()
29+
}, 0)
30+
})
2831
}
2932

3033
async function handleData(el: IncludeFragmentElement) {
@@ -149,10 +152,8 @@ export default class IncludeFragmentElement extends HTMLElement {
149152
load(): Promise<string> {
150153
observer.unobserve(this)
151154
return Promise.resolve()
152-
.then(() => {
153-
fire('loadstart', this)
154-
return this.fetch(this.request())
155-
})
155+
.then(() => fire('loadstart', this))
156+
.then(() => this.fetch(this.request()))
156157
.then(response => {
157158
if (response.status !== 200) {
158159
throw new Error(`Failed to load resource: the server responded with a status of ${response.status}`)
@@ -161,21 +162,15 @@ export default class IncludeFragmentElement extends HTMLElement {
161162
if (!isWildcard(this.accept) && (!ct || !ct.includes(this.accept ? this.accept : 'text/html'))) {
162163
throw new Error(`Failed to load resource: expected ${this.accept || 'text/html'} but was ${ct}`)
163164
}
164-
return response
165+
return response.text()
166+
})
167+
.then(data => {
168+
fire('load', this).then(() => fire('loadend', this))
169+
return Promise.resolve(data)
170+
}, error => {
171+
fire('error', this).then(() => fire('loadend', this))
172+
throw error
165173
})
166-
.then(response => response.text())
167-
.then(
168-
data => {
169-
fire('load', this)
170-
fire('loadend', this)
171-
return data
172-
},
173-
error => {
174-
fire('error', this)
175-
fire('loadend', this)
176-
throw error
177-
}
178-
)
179174
}
180175

181176
fetch(request: RequestInfo): Promise<Response> {

test/test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,25 @@ suite('include-fragment-element', function() {
426426
})
427427
})
428428

429+
test('loading events fire in guaranteed order', function() {
430+
const elem = document.createElement('include-fragment')
431+
const order = []
432+
const events = [
433+
when(elem, 'loadend').then(() => order.push('loadend')),
434+
when(elem, 'load').then(() => order.push('load')),
435+
when(elem, 'loadstart').then(() => order.push('loadstart'))
436+
]
437+
elem.src = '/hello'
438+
const originalSetTimeout = window.setTimeout
439+
let i = 60
440+
window.setTimeout = (fn, ms, ...rest) => originalSetTimeout.call(window, fn, ms + (i -= 20), ...rest)
441+
elem.load()
442+
return Promise.all(events).then(() => {
443+
window.setTimeout = originalSetTimeout
444+
assert.deepStrictEqual(order, ['loadstart', 'load', 'loadend'])
445+
})
446+
})
447+
429448
test('sets loading to "eager" by default', function() {
430449
const div = document.createElement('div')
431450
div.innerHTML = '<include-fragment loading="lazy" src="/hello">loading</include-fragment>'

0 commit comments

Comments
 (0)