@@ -21,10 +21,9 @@ 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+ // Functional stand in for the W3 spec "queue a task" paradigm
25+ function task ( ) : Promise < void > {
26+ return new Promise ( resolve => setTimeout ( resolve , 0 ) )
2827}
2928
3029async function handleData ( el : IncludeFragmentElement ) {
@@ -148,9 +147,12 @@ export default class IncludeFragmentElement extends HTMLElement {
148147
149148 load ( ) : Promise < string > {
150149 observer . unobserve ( this )
151- return Promise . resolve ( )
150+ // We mimic the same event order as <img>, including the spec
151+ // which states events must be dispatched after "queue a task".
152+ // https://www.w3.org/TR/html52/semantics-embedded-content.html#the-img-element
153+ return task ( )
152154 . then ( ( ) => {
153- fire ( 'loadstart' , this )
155+ this . dispatchEvent ( new Event ( 'loadstart' ) )
154156 return this . fetch ( this . request ( ) )
155157 } )
156158 . then ( response => {
@@ -161,21 +163,27 @@ export default class IncludeFragmentElement extends HTMLElement {
161163 if ( ! isWildcard ( this . accept ) && ( ! ct || ! ct . includes ( this . accept ? this . accept : 'text/html' ) ) ) {
162164 throw new Error ( `Failed to load resource: expected ${ this . accept || 'text/html' } but was ${ ct } ` )
163165 }
164- return response
166+ return response . text ( )
167+ } )
168+ . then ( data => {
169+ // Dispatch `load` and `loadend` async to allow
170+ // the `load()` promise to resolve _before_ these
171+ // events are fired.
172+ task ( ) . then ( ( ) => {
173+ this . dispatchEvent ( new Event ( 'load' ) )
174+ this . dispatchEvent ( new Event ( 'loadend' ) )
175+ } )
176+ return data
177+ } , error => {
178+ // Dispatch `error` and `loadend` async to allow
179+ // the `load()` promise to resolve _before_ these
180+ // events are fired.
181+ task ( ) . then ( ( ) => {
182+ this . dispatchEvent ( new Event ( 'error' ) )
183+ this . dispatchEvent ( new Event ( 'loadend' ) )
184+ } )
185+ throw error
165186 } )
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- )
179187 }
180188
181189 fetch ( request : RequestInfo ) : Promise < Response > {
0 commit comments