@@ -49,15 +49,17 @@ function isIgnored(node, filter) {
4949 * @return {Boolean|Object } Error Object if the constrainsts are met or boolean otherwise
5050 */
5151function checkConnection ( conn ) {
52- if ( conn ) {
53- // Don't pre* if using 2G or if Save-Data is enabled.
54- if ( conn . saveData ) {
55- return new Error ( 'Save-Data is enabled' ) ;
56- }
52+ // If no connection object, assume it's okay to prefetch
53+ if ( ! conn ) return true ;
5754
58- if ( / 2 g / . test ( conn . effectiveType ) ) {
59- return new Error ( 'network conditions are poor' ) ;
60- }
55+ // Don't prefetch if Save-Data is enabled.
56+ if ( conn . saveData ) {
57+ return new Error ( 'Save-Data is enabled' ) ;
58+ }
59+
60+ // Don't prefetch if using 2G connection.
61+ if ( / 2 g / . test ( conn . effectiveType ) ) {
62+ return new Error ( 'network conditions are poor' ) ;
6163 }
6264
6365 return true ;
@@ -120,7 +122,7 @@ export function listen(options = {}) {
120122 } ;
121123
122124 const observer = new IntersectionObserver ( entries => {
123- entries . forEach ( entry => {
125+ for ( let entry of entries ) {
124126 // On enter
125127 if ( entry . isIntersecting ) {
126128 entry = entry . target ;
@@ -140,7 +142,11 @@ export function listen(options = {}) {
140142 // either it's the prerender + prefetch mode or it's prerender *only* mode
141143 // Prerendering limit is following options.limit. UA may impose arbitraty numeric limit
142144 // The same URL is not already present as a speculation rule
143- if ( ( shouldPrerenderAndPrefetch || shouldOnlyPrerender ) && toPrerender . size < limit && ! specRulesInViewport . has ( entry . href ) ) {
145+ if (
146+ ( shouldPrerenderAndPrefetch || shouldOnlyPrerender ) &&
147+ toPrerender . size < limit &&
148+ ! specRulesInViewport . has ( entry . href )
149+ ) {
144150 prerender ( hrefFn ? hrefFn ( entry ) : entry . href , options . eagerness )
145151 . then ( specMap => {
146152 for ( const [ key , value ] of specMap ) {
@@ -161,8 +167,13 @@ export function listen(options = {}) {
161167 // Do not prefetch if will match/exceed limit and user has not switched to shouldOnlyPrerender mode
162168 if ( toPrefetch . size < limit && ! shouldOnlyPrerender ) {
163169 toAdd ( ( ) => {
164- prefetch ( hrefFn ? hrefFn ( entry ) : entry . href , options . priority ,
165- options . checkAccessControlAllowOrigin , options . checkAccessControlAllowCredentials , options . onlyOnMouseover )
170+ prefetch (
171+ hrefFn ? hrefFn ( entry ) : entry . href ,
172+ options . priority ,
173+ options . checkAccessControlAllowOrigin ,
174+ options . checkAccessControlAllowCredentials ,
175+ options . onlyOnMouseover ,
176+ )
166177 . then ( isDone )
167178 . catch ( error => {
168179 isDone ( ) ;
@@ -175,40 +186,37 @@ export function listen(options = {}) {
175186 } else {
176187 entry = entry . target ;
177188 const index = hrefsInViewport . indexOf ( entry . href ) ;
178- if ( index > - 1 ) {
189+ if ( index !== - 1 ) {
179190 hrefsInViewport . splice ( index ) ;
180191 }
192+
181193 if ( specRulesInViewport . has ( entry . href ) ) {
182194 specRulesInViewport = removeSpeculationRule ( specRulesInViewport , entry . href ) ;
183195 }
184196 }
185- } ) ;
197+ }
186198 } , {
187199 threshold,
188200 } ) ;
189201
190202 timeoutFn ( ( ) => {
191203 // Find all links & Connect them to IO if allowed
192- const elementsToListen = options . el &&
193- options . el . length &&
194- options . el . length > 0 &&
195- options . el [ 0 ] . nodeName === 'A' ?
196- options . el :
197- ( options . el || document ) . querySelectorAll ( 'a' ) ;
198-
199- elementsToListen . forEach ( link => {
204+ const isAnchorElement = options . el && options . el . length > 0 && options . el [ 0 ] . nodeName === 'A' ;
205+ const elementsToListen = isAnchorElement ? options . el : ( options . el || document ) . querySelectorAll ( 'a' ) ;
206+
207+ for ( const link of elementsToListen ) {
200208 // If the anchor matches a permitted origin
201209 // ~> A `[]` or `true` means everything is allowed
202210 if ( ! allowed . length || allowed . includes ( link . hostname ) ) {
203211 // If there are any filters, the link must not match any of them
204212 if ( ! isIgnored ( link , ignores ) ) observer . observe ( link ) ;
205213 }
206- } ) ;
214+ }
207215 } , {
208216 timeout : options . timeout || 2000 ,
209217 } ) ;
210218
211- return function ( ) {
219+ return ( ) => {
212220 // wipe url list
213221 toPrefetch . clear ( ) ;
214222 // detach IO entries
@@ -237,18 +245,22 @@ export function prefetch(urls, isPriority, checkAccessControlAllowOrigin, checkA
237245 }
238246
239247 // Dev must supply own catch()
240- return Promise . all (
241- [ ] . concat ( urls ) . map ( str => {
242- if ( toPrefetch . has ( str ) ) return [ ] ;
243-
244- // Add it now, regardless of its success
245- // ~> so that we don't repeat broken links
246- toPrefetch . add ( str ) ;
247-
248- return prefetchOnHover ( ( isPriority ? viaFetch : supported ) , new URL ( str , location . href ) . toString ( ) , onlyOnMouseover ,
249- checkAccessControlAllowOrigin , checkAccessControlAllowCredentials , isPriority ) ;
250- } ) ,
251- ) ;
248+ return Promise . all ( [ urls ] . flat ( ) . map ( str => {
249+ if ( toPrefetch . has ( str ) ) return [ ] ;
250+
251+ // Add it now, regardless of its success
252+ // ~> so that we don't repeat broken links
253+ toPrefetch . add ( str ) ;
254+
255+ return prefetchOnHover (
256+ isPriority ? viaFetch : supported ,
257+ new URL ( str , location . href ) . toString ( ) ,
258+ onlyOnMouseover ,
259+ checkAccessControlAllowOrigin ,
260+ checkAccessControlAllowCredentials ,
261+ isPriority ,
262+ ) ;
263+ } ) ) ;
252264}
253265
254266/**
@@ -258,7 +270,7 @@ export function prefetch(urls, isPriority, checkAccessControlAllowOrigin, checkA
258270* @return {Object } a Promise
259271*/
260272export function prerender ( urls , eagerness = 'immediate' ) {
261- urls = [ ] . concat ( urls ) ;
273+ urls = [ urls ] . flat ( ) ;
262274
263275 const chkConn = checkConnection ( navigator . connection ) ;
264276 if ( chkConn instanceof Error ) {
0 commit comments