Skip to content

Commit 73421ea

Browse files
committed
Move getData and fetchDataWithEvents into the component
1 parent 6108723 commit 73421ea

File tree

1 file changed

+62
-63
lines changed

1 file changed

+62
-63
lines changed

src/index.ts

Lines changed: 62 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -9,65 +9,6 @@ function isWildcard(accept: string | null) {
99
return accept && !!accept.split(',').find(x => x.match(/^\s*\*\/\*/))
1010
}
1111

12-
function getData(el: IncludeFragmentElement) {
13-
const src = el.src
14-
let data = privateData.get(el)
15-
if (data && data.src === src) {
16-
return data.data
17-
} else {
18-
if (src) {
19-
data = fetchDataWithEvents(el)
20-
} else {
21-
data = Promise.reject(new Error('missing src'))
22-
}
23-
privateData.set(el, {src, data})
24-
return data
25-
}
26-
}
27-
28-
function fetchDataWithEvents(el: IncludeFragmentElement) {
29-
// We mimic the same event order as <img>, including the spec
30-
// which states events must be dispatched after "queue a task".
31-
// https://www.w3.org/TR/html52/semantics-embedded-content.html#the-img-element
32-
return task()
33-
.then(() => {
34-
el.dispatchEvent(new Event('loadstart'))
35-
return el.fetch(el.request())
36-
})
37-
.then(response => {
38-
if (response.status !== 200) {
39-
throw new Error(`Failed to load resource: the server responded with a status of ${response.status}`)
40-
}
41-
const ct = response.headers.get('Content-Type')
42-
if (!isWildcard(el.accept) && (!ct || !ct.includes(el.accept ? el.accept : 'text/html'))) {
43-
throw new Error(`Failed to load resource: expected ${el.accept || 'text/html'} but was ${ct}`)
44-
}
45-
return response.text()
46-
})
47-
.then(
48-
data => {
49-
// Dispatch `load` and `loadend` async to allow
50-
// the `load()` promise to resolve _before_ these
51-
// events are fired.
52-
task().then(() => {
53-
el.dispatchEvent(new Event('load'))
54-
el.dispatchEvent(new Event('loadend'))
55-
})
56-
return data
57-
},
58-
error => {
59-
// Dispatch `error` and `loadend` async to allow
60-
// the `load()` promise to resolve _before_ these
61-
// events are fired.
62-
task().then(() => {
63-
el.dispatchEvent(new Event('error'))
64-
el.dispatchEvent(new Event('loadend'))
65-
})
66-
throw error
67-
}
68-
)
69-
}
70-
7112
export default class IncludeFragmentElement extends HTMLElement {
7213
static get observedAttributes(): string[] {
7314
return ['src', 'loading']
@@ -106,7 +47,7 @@ export default class IncludeFragmentElement extends HTMLElement {
10647
}
10748

10849
get data(): Promise<string> {
109-
return getData(this)
50+
return this.#getData()
11051
}
11152

11253
attributeChangedCallback(attribute: string, oldVal: string | null): void {
@@ -160,7 +101,7 @@ export default class IncludeFragmentElement extends HTMLElement {
160101
}
161102

162103
load(): Promise<string> {
163-
return getData(this)
104+
return this.#getData()
164105
}
165106

166107
fetch(request: RequestInfo): Promise<Response> {
@@ -192,8 +133,7 @@ export default class IncludeFragmentElement extends HTMLElement {
192133

193134
#handleData(): Promise<void> {
194135
this.#observer.unobserve(this)
195-
196-
return getData(this).then(
136+
return this.#getData().then(
197137
(html: string) => {
198138
const template = document.createElement('template')
199139
// eslint-disable-next-line github/no-inner-html
@@ -211,6 +151,65 @@ export default class IncludeFragmentElement extends HTMLElement {
211151
}
212152
)
213153
}
154+
155+
#getData(): Promise<string> {
156+
const src = this.src
157+
let data = privateData.get(this)
158+
if (data && data.src === src) {
159+
return data.data
160+
} else {
161+
if (src) {
162+
data = this.#fetchDataWithEvents()
163+
} else {
164+
data = Promise.reject(new Error('missing src'))
165+
}
166+
privateData.set(this, {src, data})
167+
return data
168+
}
169+
}
170+
171+
#fetchDataWithEvents(): Promise<string> {
172+
// We mimic the same event order as <img>, including the spec
173+
// which states events must be dispatched after "queue a task".
174+
// https://www.w3.org/TR/html52/semantics-embedded-content.html#the-img-element
175+
return task()
176+
.then(() => {
177+
this.dispatchEvent(new Event('loadstart'))
178+
return this.fetch(this.request())
179+
})
180+
.then(response => {
181+
if (response.status !== 200) {
182+
throw new Error(`Failed to load resource: the server responded with a status of ${response.status}`)
183+
}
184+
const ct = response.headers.get('Content-Type')
185+
if (!isWildcard(this.accept) && (!ct || !ct.includes(this.accept ? this.accept : 'text/html'))) {
186+
throw new Error(`Failed to load resource: expected ${this.accept || 'text/html'} but was ${ct}`)
187+
}
188+
return response.text()
189+
})
190+
.then(
191+
data => {
192+
// Dispatch `load` and `loadend` async to allow
193+
// the `load()` promise to resolve _before_ these
194+
// events are fired.
195+
task().then(() => {
196+
this.dispatchEvent(new Event('load'))
197+
this.dispatchEvent(new Event('loadend'))
198+
})
199+
return data
200+
},
201+
error => {
202+
// Dispatch `error` and `loadend` async to allow
203+
// the `load()` promise to resolve _before_ these
204+
// events are fired.
205+
task().then(() => {
206+
this.dispatchEvent(new Event('error'))
207+
this.dispatchEvent(new Event('loadend'))
208+
})
209+
throw error
210+
}
211+
)
212+
}
214213
}
215214

216215
declare global {

0 commit comments

Comments
 (0)