@@ -149,55 +149,87 @@ var tryExamplesGlobalMinHeight = 0;
149149 */
150150var tryExamplesConfigLoaded = false ;
151151
152- window . loadTryExamplesConfig = async ( configFilePath ) => {
153- if ( tryExamplesConfigLoaded ) {
154- return ;
155- }
156- try {
157- // Add a timestamp as query parameter to ensure a cached version of the
158- // file is not used.
159- const timestamp = new Date ( ) . getTime ( ) ;
160- const configFileUrl = `${ configFilePath } ?cb=${ timestamp } ` ;
161- const currentPageUrl = window . location . pathname ;
162-
163- const response = await fetch ( configFileUrl ) ;
164- if ( ! response . ok ) {
165- if ( response . status === 404 ) {
166- // Try examples ignore file is not present.
167- console . log ( "Optional try_examples config file not found." ) ;
168- return ;
169- }
170- throw new Error ( `Error fetching ${ configFilePath } ` ) ;
171- }
152+ // A config loader with request deduplication + permanent caching
153+ const ConfigLoader = ( ( ) => {
154+ let configLoadPromise = null ;
172155
173- const data = await response . json ( ) ;
174- if ( ! data ) {
156+ const loadConfig = async ( configFilePath ) => {
157+ if ( tryExamplesConfigLoaded ) {
175158 return ;
176159 }
177160
178- // Set minimum iframe height based on value in config file
179- if ( data . global_min_height ) {
180- tryExamplesGlobalMinHeight = parseInt ( data . global_min_height ) ;
161+ // Return the existing promise if the request is in progress, as we
162+ // don't want to make multiple requests for the same file. This
163+ // can happen if there are several try_examples directives on the
164+ // same page.
165+ if ( configLoadPromise ) {
166+ return configLoadPromise ;
181167 }
182168
183- // Disable interactive examples if file matches one of the ignore patterns
184- // by hiding try_examples_buttons.
185- Patterns = data . ignore_patterns ;
186- for ( let pattern of Patterns ) {
187- let regex = new RegExp ( pattern ) ;
188- if ( regex . test ( currentPageUrl ) ) {
189- var buttons = document . getElementsByClassName ( "try_examples_button" ) ;
190- for ( var i = 0 ; i < buttons . length ; i ++ ) {
191- buttons [ i ] . classList . add ( "hidden" ) ;
169+ // Create and cache the promise for the config request
170+ configLoadPromise = ( async ( ) => {
171+ try {
172+ // Add a timestamp as query parameter to ensure a cached version of the
173+ // file is not used.
174+ const timestamp = new Date ( ) . getTime ( ) ;
175+ const configFileUrl = `${ configFilePath } ?cb=${ timestamp } ` ;
176+ const currentPageUrl = window . location . pathname ;
177+
178+ const response = await fetch ( configFileUrl ) ;
179+ if ( ! response . ok ) {
180+ if ( response . status === 404 ) {
181+ console . log ( "Optional try_examples config file not found." ) ;
182+ return ;
183+ }
184+ throw new Error ( `Error fetching ${ configFilePath } ` ) ;
185+ }
186+
187+ const data = await response . json ( ) ;
188+ if ( ! data ) {
189+ return ;
190+ }
191+
192+ // Set minimum iframe height based on value in config file
193+ if ( data . global_min_height ) {
194+ tryExamplesGlobalMinHeight = parseInt ( data . global_min_height ) ;
195+ }
196+
197+ // Disable interactive examples if file matches one of the ignore patterns
198+ // by hiding try_examples_buttons.
199+ Patterns = data . ignore_patterns ;
200+ for ( let pattern of Patterns ) {
201+ let regex = new RegExp ( pattern ) ;
202+ if ( regex . test ( currentPageUrl ) ) {
203+ var buttons = document . getElementsByClassName (
204+ "try_examples_button" ,
205+ ) ;
206+ for ( var i = 0 ; i < buttons . length ; i ++ ) {
207+ buttons [ i ] . classList . add ( "hidden" ) ;
208+ }
209+ break ;
210+ }
192211 }
193- break ;
212+ } catch ( error ) {
213+ console . error ( error ) ;
214+ } finally {
215+ tryExamplesConfigLoaded = true ;
194216 }
195- }
196- } catch ( error ) {
197- console . error ( error ) ;
198- }
199- tryExamplesConfigLoaded = true ;
200- } ;
217+ } ) ( ) ;
218+
219+ return configLoadPromise ;
220+ } ;
221+
222+ return {
223+ loadConfig,
224+ // for testing/debugging only, could be removed
225+ resetState : ( ) => {
226+ tryExamplesConfigLoaded = false ;
227+ configLoadPromise = null ;
228+ } ,
229+ } ;
230+ } ) ( ) ;
231+
232+ window . loadTryExamplesConfig = ConfigLoader . loadConfig ;
201233
202234window . toggleTryExamplesButtons = ( ) => {
203235 /* Toggle visibility of TryExamples buttons. For use in console for debug
0 commit comments