1717import prefetch from './prefetch.mjs' ;
1818import requestIdleCallback from './request-idle-callback.mjs' ;
1919
20+ const loaderFunctions = new Map ( ) ;
21+ const observer = new IntersectionObserver ( entries => {
22+ entries
23+ . filter ( entry => entry . isIntersecting )
24+ . forEach ( entry => {
25+ const url = entry . target . href ;
26+ if ( ! loaderFunctions . has ( url ) ) {
27+ return ;
28+ }
29+ loaderFunctions . get ( url ) . call ( null ) ;
30+ } ) ;
31+ } ) ;
2032/**
2133 * Prefetch in-viewport links from a target DOM element. The
2234 * element will be observed using Intersection Observer.
@@ -26,36 +38,13 @@ import requestIdleCallback from './request-idle-callback.mjs';
2638 */
2739function fetchInViewportLinks ( el , options ) {
2840 const links = Array . from ( el . querySelectorAll ( 'a' ) ) ;
29- const observer = new IntersectionObserver ( entries => {
30- const urls = entries
31- . filter ( entry => entry . isIntersecting )
32- . map ( entry => {
33- observer . unobserve ( entry . target ) ;
34- return entry . target . href ;
35- } ) ;
36- // prefetch() maintains a list of in-memory URLs
37- // previously fetched so we don't attempt a refetch
38- prefetchURLs ( urls , options . priority ) ;
39- } ) ;
4041 links . forEach ( link => {
4142 observer . observe ( link ) ;
4243 } ) ;
4344 // Return a list of found URLs
4445 return links . map ( link => link . href ) ;
4546} ;
4647
47- /**
48- * Prefetch an array of URLs using rel=prefetch
49- * if supported. Falls back to XHR otherwise.
50- * @param {Array } urls - Array of URLs to prefetch
51- * @param {string } priority - "priority" of the request
52- */
53- function prefetchURLs ( urls , priority ) {
54- urls . forEach ( url => {
55- prefetch ( url , priority ) ;
56- } ) ;
57- } ;
58-
5948/**
6049 * Prefetch an array of URLs if the user's effective
6150 * connection type and data-saver preferences suggests
@@ -80,14 +69,18 @@ export default function (options) {
8069 ...options ,
8170 } ;
8271
72+ if ( ! options . urls ) {
73+ options . urls = fetchInViewportLinks ( options . el , options ) ;
74+ }
75+
76+ options . urls . forEach ( url => {
77+ loaderFunctions . set ( url , ( ) => {
78+ loaderFunctions . delete ( url ) ;
79+ prefetch ( url , options . priority ) ;
80+ } ) ;
81+ } ) ;
8382 options . timeoutFn ( ( ) => {
84- // Prefetch an array of URLs if supplied (as an override)
85- if ( options . urls !== undefined && options . urls . length > 0 ) {
86- prefetchURLs ( options . urls , options . priority ) ;
87- return options . urls ;
88- } else {
89- // Element to extract in-viewport links for
90- return fetchInViewportLinks ( options . el , options ) ;
91- }
83+ // This is a bit weird, but somehow map access gets transpiled the wrong way.
84+ Array . from ( loaderFunctions . values ( ) ) . forEach ( f => f ( ) ) ;
9285 } , { timeout : options . timeout } ) ;
9386}
0 commit comments