1
- const privateData = new WeakMap ( )
1
+ interface CachedData {
2
+ src : string
3
+ data : Promise < string | CSPTrustedHTMLToStringable | Error >
4
+ }
5
+ const privateData = new WeakMap < IncludeFragmentElement , CachedData > ( )
2
6
3
7
function isWildcard ( accept : string | null ) {
4
8
return accept && ! ! accept . split ( ',' ) . find ( x => x . match ( / ^ \s * \* \/ \* / ) )
@@ -63,8 +67,8 @@ export default class IncludeFragmentElement extends HTMLElement {
63
67
}
64
68
65
69
// TODO: Should this return a TrustedHTML if available, or always a string?
66
- get data ( ) : Promise < string > {
67
- return this . #getStringData ( )
70
+ get data ( ) : Promise < string | Error > {
71
+ return this . #getStringOrErrorData ( )
68
72
}
69
73
70
74
#busy = false
@@ -115,9 +119,8 @@ export default class IncludeFragmentElement extends HTMLElement {
115
119
} )
116
120
}
117
121
118
- // TODO: Should this return `this.#getData()` directly?
119
- load ( ) : Promise < string > {
120
- return this . #getStringData( )
122
+ load ( ) : Promise < string | Error > {
123
+ return this . #getStringOrErrorData( )
121
124
}
122
125
123
126
fetch ( request : RequestInfo ) : Promise < Response > {
@@ -152,15 +155,18 @@ export default class IncludeFragmentElement extends HTMLElement {
152
155
this . #busy = true
153
156
this . #observer. unobserve ( this )
154
157
try {
155
- const html = await this . #getData( )
158
+ const data = await this . #getData( )
159
+ if ( data instanceof Error ) {
160
+ throw data
161
+ }
156
162
// Until TypeScript is natively compatible with CSP trusted types, we
157
163
// have to treat this as a string here.
158
164
// https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1246
159
- const htmlTreatedAsString = html as string
165
+ const dataTreatedAsString = data as string
160
166
161
167
const template = document . createElement ( 'template' )
162
168
// eslint-disable-next-line github/no-inner-html
163
- template . innerHTML = htmlTreatedAsString
169
+ template . innerHTML = dataTreatedAsString
164
170
const fragment = document . importNode ( template . content , true )
165
171
const canceled = ! this . dispatchEvent (
166
172
new CustomEvent ( 'include-fragment-replace' , { cancelable : true , detail : { fragment} } )
@@ -173,12 +179,13 @@ export default class IncludeFragmentElement extends HTMLElement {
173
179
}
174
180
}
175
181
176
- #getData( ) : Promise < string | CSPTrustedHTMLToStringable > {
182
+ async #getData( ) : Promise < string | CSPTrustedHTMLToStringable | Error > {
177
183
const src = this . src
178
- let data = privateData . get ( this )
179
- if ( data && data . src === src ) {
180
- return data . data
184
+ const cachedData = privateData . get ( this )
185
+ if ( cachedData && cachedData . src === src ) {
186
+ return cachedData . data
181
187
} else {
188
+ let data : Promise < string | CSPTrustedHTMLToStringable | Error >
182
189
if ( src ) {
183
190
data = this . #fetchDataWithEvents( )
184
191
} else {
@@ -189,8 +196,12 @@ export default class IncludeFragmentElement extends HTMLElement {
189
196
}
190
197
}
191
198
192
- async #getStringData( ) : Promise < string > {
193
- return ( await this . #getData( ) ) . toString ( )
199
+ async #getStringOrErrorData( ) : Promise < string | Error > {
200
+ const data = await this . #getData( )
201
+ if ( data instanceof Error ) {
202
+ return data
203
+ }
204
+ return data . toString ( )
194
205
}
195
206
196
207
// Functional stand in for the W3 spec "queue a task" paradigm
0 commit comments