@@ -2,6 +2,7 @@ import { EventEmitter2 } from "eventemitter2";
22/* eslint-disable no-restricted-globals */
33import React , {
44 FunctionComponent ,
5+ ReactEventHandler ,
56 useCallback ,
67 useMemo ,
78 useState ,
@@ -79,6 +80,13 @@ const hideStyle: React.CSSProperties = {
7980 border : "0" ,
8081} ;
8182
83+ interface LoadedCssResult {
84+ id : string ;
85+ url : string ;
86+ succeed ?: boolean ;
87+ error ?: Error | string ;
88+ }
89+
8290/**
8391 * Insert link tag is called by css loaders like style-loader or mini-css-extract plugin.
8492 * See webpack config.
@@ -124,48 +132,70 @@ export async function attach(options: AttachOptions) {
124132 onAuthError : onContextAuthError ,
125133 } ) ;
126134
127- // Amount of initial css files to be loaded.
128- let initialCSSFileNumber = options . cssAssets . length ;
135+ const internalCssUrls = options . cssAssets ;
136+ const customCssUrls : string [ ] = [ ] ;
129137
130138 if ( options . customCSSURL ) {
131- initialCSSFileNumber ++ ;
132- }
133- if ( options . customFontsCSSURL ) {
134- initialCSSFileNumber ++ ;
139+ customCssUrls . push ( options . customCSSURL ) ;
135140 }
136141 if ( ! options . disableDefaultFonts && options . defaultFontsCSSURL ) {
137- initialCSSFileNumber ++ ;
142+ customCssUrls . push ( options . defaultFontsCSSURL ) ;
143+ }
144+ if ( options . customFontsCSSURL ) {
145+ customCssUrls . push ( options . customFontsCSSURL ) ;
138146 }
139147
140- // Current amount of loaded css files.
141- let cssLoaded = 0 ;
148+ const expectedCssFiles = internalCssUrls . length + customCssUrls . length ;
149+ const processCssResults : LoadedCssResult [ ] = [ ] ;
142150
143151 const Index : FunctionComponent = ( ) => {
144152 // Determine whether css has finished loading, before rendering the stream to prevent
145153 // flash of unstyled content.
146154 const [ isCSSLoaded , setIsCSSLoaded ] = useState ( false ) ;
147- const [ loadError , setLoadError ] = useState ( false ) ;
155+ const [ hasCssLoadErrors , setHasCssLoadErrors ] = useState ( false ) ;
148156
149157 const handleLoadError = useCallback ( ( href : string ) => {
158+ const message = `Failed to load CSS ${ encodeURIComponent ( href ) } ` ;
159+
150160 globalErrorReporter . report (
151161 // encode href, otherwise sentry will not send it.
152- `Failed to load CSS ${ encodeURIComponent ( href ) } `
162+ message
153163 ) ;
154- setLoadError ( true ) ;
155- cssLoaded ++ ;
156- // When amount of css loaded equals initial css file number, mark as ready.
157- if ( cssLoaded === initialCSSFileNumber ) {
158- setIsCSSLoaded ( true ) ;
159- }
160- } , [ ] ) ;
161- const handleCSSLoad = useCallback ( ( ) => {
162- cssLoaded ++ ;
163- // When amount of css loaded equals initial css file number, mark as ready.
164- if ( cssLoaded === initialCSSFileNumber ) {
164+
165+ // eslint-disable-next-line no-console
166+ console . warn ( message ) ;
167+
168+ processCssResults . push ( {
169+ id : href ,
170+ url : href ,
171+ succeed : false ,
172+ error : message ,
173+ } ) ;
174+
175+ setHasCssLoadErrors ( true ) ;
176+
177+ if ( processCssResults . length >= expectedCssFiles ) {
165178 setIsCSSLoaded ( true ) ;
166179 }
167180 } , [ ] ) ;
168181
182+ const handleCSSLoad : ReactEventHandler < HTMLLinkElement > = useCallback (
183+ ( event ) => {
184+ const el = event . target as HTMLLinkElement ;
185+
186+ processCssResults . push ( {
187+ id : el . href ,
188+ url : el . href ,
189+ succeed : true ,
190+ } ) ;
191+
192+ if ( processCssResults . length >= expectedCssFiles ) {
193+ setIsCSSLoaded ( true ) ;
194+ }
195+ } ,
196+ [ ]
197+ ) ;
198+
169199 // CSS assets to be loaded inside of the shadow dom.
170200 const [ shadowCSSAssets , setShadowCSSAssets ] = useState < CSSAsset [ ] > (
171201 options . cssAssets . map (
@@ -222,7 +252,7 @@ export async function attach(options: AttachOptions) {
222252 if ( linkTag . onload ) {
223253 linkTag . onload ( event . nativeEvent ) ;
224254 }
225- handleCSSLoad ( ) ;
255+ handleCSSLoad ( event ) ;
226256 } ,
227257 handleLoadError
228258 ) ,
@@ -243,7 +273,7 @@ export async function attach(options: AttachOptions) {
243273 < EncapsulationContext . Provider value = { encapsulationContext } >
244274 < ReactShadowRoot loadFonts >
245275 < ManagedCoralContextProvider >
246- { loadError && (
276+ { hasCssLoadErrors && (
247277 // TODO: (cvle) localization?
248278 < CSSLoadError >
249279 < div > Apologies, we weren't able to load some styles</ div >
0 commit comments