Skip to content

Commit aadb279

Browse files
committed
Modernize code and improve readability
1 parent 5f23ff2 commit aadb279

File tree

5 files changed

+77
-70
lines changed

5 files changed

+77
-70
lines changed

src/chunks.mjs

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@ const toPrefetch = new Set();
3232
* @return {Boolean} If true, then it should be ignored
3333
*/
3434
function isIgnored(node, filter) {
35-
return Array.isArray(filter) ?
36-
filter.some(x => isIgnored(node, x)) :
37-
(filter.test || filter).call(filter, node.href, node);
35+
if (Array.isArray(filter)) {
36+
return filter.some(x => isIgnored(node, x));
37+
}
38+
39+
return (filter.test || filter).call(filter, node.href, node);
3840
}
3941

4042
/**
@@ -59,8 +61,8 @@ function isIgnored(node, filter) {
5961
export function listen(options = {}) {
6062
if (!window.IntersectionObserver) return;
6163

62-
const [toAdd, isDone] = throttle(options.throttle || 1 / 0);
63-
const limit = options.limit || 1 / 0;
64+
const [toAdd, isDone] = throttle(options.throttle || Number.Infinity);
65+
const limit = options.limit || Number.Infinity;
6466

6567
const allowed = options.origins || [location.hostname];
6668
const ignores = options.ignores || [];
@@ -79,36 +81,37 @@ export function listen(options = {}) {
7981
};
8082

8183
const observer = new IntersectionObserver(entries => {
82-
entries.forEach(entry => {
83-
if (entry.isIntersecting) {
84-
observer.unobserve(entry = entry.target);
85-
// Do not prefetch if will match/exceed limit
86-
if (toPrefetch.size < limit) {
87-
toAdd(() => {
88-
prefetchChunks ?
89-
prefetchChunks(entry, prefetchHandler) :
90-
prefetchHandler(entry.href);
91-
});
92-
}
84+
for (const {isIntersecting, target} of entries) {
85+
if (!isIntersecting) continue;
86+
87+
observer.unobserve(target);
88+
// Do not prefetch if will match/exceed limit
89+
if (toPrefetch.size < limit) {
90+
toAdd(() => {
91+
prefetchChunks ?
92+
prefetchChunks(target, prefetchHandler) :
93+
prefetchHandler(target.href);
94+
});
9395
}
94-
});
96+
}
9597
});
9698

9799
timeoutFn(() => {
98100
// Find all links & Connect them to IO if allowed
99-
(options.el || document).querySelectorAll('a').forEach(link => {
101+
const links = (options.el || document).querySelectorAll('a[href]');
102+
for (const link of links) {
100103
// If the anchor matches a permitted origin
101104
// ~> A `[]` or `true` means everything is allowed
102105
if (!allowed.length || allowed.includes(link.hostname)) {
103106
// If there are any filters, the link must not match any of them
104107
if (!isIgnored(link, ignores)) observer.observe(link);
105108
}
106-
});
109+
}
107110
}, {
108111
timeout: options.timeout || 2000,
109112
});
110113

111-
return function () {
114+
return () => {
112115
// wipe url list
113116
toPrefetch.clear();
114117
// detach IO entries
@@ -124,30 +127,27 @@ export function listen(options = {}) {
124127
*/
125128
export function prefetch(url, isPriority) {
126129
const {connection} = navigator;
130+
if (!connection) return Promise.resolve();
127131

128-
if (connection) {
129-
// Don't prefetch if using 2G or if Save-Data is enabled.
130-
if (connection.saveData) {
131-
return Promise.reject(new Error('Cannot prefetch, Save-Data is enabled'));
132-
}
132+
// Don't prefetch if using 2G or if Save-Data is enabled.
133+
if (connection.saveData) {
134+
return Promise.reject(new Error('Cannot prefetch, Save-Data is enabled'));
135+
}
133136

134-
if (/2g/.test(connection.effectiveType)) {
135-
return Promise.reject(new Error('Cannot prefetch, network conditions are poor'));
136-
}
137+
if (/2g/.test(connection.effectiveType)) {
138+
return Promise.reject(new Error('Cannot prefetch, network conditions are poor'));
137139
}
138140

139141
// Dev must supply own catch()
140142
return Promise.all(
141-
[].concat(url).map(str => {
143+
[url].flat().map(str => {
142144
if (toPrefetch.has(str)) return [];
143145

144146
// Add it now, regardless of its success
145147
// ~> so that we don't repeat broken links
146148
toPrefetch.add(str);
147149

148-
return (isPriority ? viaFetch : supported)(
149-
new URL(str, location.href).toString(),
150-
);
150+
return (isPriority ? viaFetch : supported)(new URL(str, location.href).toString());
151151
}),
152152
);
153153
}

src/index.mjs

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,17 @@ function isIgnored(node, filter) {
4949
* @return {Boolean|Object} Error Object if the constrainsts are met or boolean otherwise
5050
*/
5151
function 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 (/2g/.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 (/2g/.test(conn.effectiveType)) {
62+
return new Error('network conditions are poor');
6163
}
6264

6365
return true;
@@ -119,7 +121,7 @@ export function listen(options = {}) {
119121
};
120122

121123
const observer = new IntersectionObserver(entries => {
122-
entries.forEach(entry => {
124+
for (let entry of entries) {
123125
// On enter
124126
if (entry.isIntersecting) {
125127
entry = entry.target;
@@ -165,37 +167,33 @@ export function listen(options = {}) {
165167
} else {
166168
entry = entry.target;
167169
const index = hrefsInViewport.indexOf(entry.href);
168-
if (index > -1) {
170+
if (index !== -1) {
169171
hrefsInViewport.splice(index);
170172
}
171173
}
172-
});
174+
}
173175
}, {
174176
threshold,
175177
});
176178

177179
timeoutFn(() => {
178180
// Find all links & Connect them to IO if allowed
179-
const elementsToListen = options.el &&
180-
options.el.length &&
181-
options.el.length > 0 &&
182-
options.el[0].nodeName === 'A' ?
183-
options.el :
184-
(options.el || document).querySelectorAll('a');
185-
186-
elementsToListen.forEach(link => {
181+
const isAnchorElement = options.el && options.el.length > 0 && options.el[0].nodeName === 'A';
182+
const elementsToListen = isAnchorElement ? options.el : (options.el || document).querySelectorAll('a');
183+
184+
for (const link of elementsToListen) {
187185
// If the anchor matches a permitted origin
188186
// ~> A `[]` or `true` means everything is allowed
189187
if (!allowed.length || allowed.includes(link.hostname)) {
190188
// If there are any filters, the link must not match any of them
191189
if (!isIgnored(link, ignores)) observer.observe(link);
192190
}
193-
});
191+
}
194192
}, {
195193
timeout: options.timeout || 2000,
196194
});
197195

198-
return function () {
196+
return () => {
199197
// wipe url list
200198
toPrefetch.clear();
201199
// detach IO entries
@@ -225,15 +223,21 @@ export function prefetch(urls, isPriority, checkAccessControlAllowOrigin, checkA
225223

226224
// Dev must supply own catch()
227225
return Promise.all(
228-
[].concat(urls).map(str => {
226+
[urls].flat().map(str => {
229227
if (toPrefetch.has(str)) return [];
230228

231229
// Add it now, regardless of its success
232230
// ~> so that we don't repeat broken links
233231
toPrefetch.add(str);
234232

235-
return prefetchOnHover((isPriority ? viaFetch : supported), new URL(str, location.href).toString(), onlyOnMouseover,
236-
checkAccessControlAllowOrigin, checkAccessControlAllowCredentials, isPriority);
233+
return prefetchOnHover(
234+
isPriority ? viaFetch : supported,
235+
new URL(str, location.href).toString(),
236+
onlyOnMouseover,
237+
checkAccessControlAllowOrigin,
238+
checkAccessControlAllowCredentials,
239+
isPriority,
240+
);
237241
}),
238242
);
239243
}
@@ -258,7 +262,7 @@ export function prerender(urls, eagerness = 'immediate') {
258262
return Promise.reject(new Error('This browser does not support the speculation rules API. Falling back to prefetch.'));
259263
}
260264

261-
for (const url of [].concat(urls)) {
265+
for (const url of [urls].flat()) {
262266
toPrerender.add(url);
263267
}
264268

src/prefetch.mjs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ function viaDOM(url, hasCrossorigin) {
4646
link.onload = resolve;
4747
link.onerror = reject;
4848

49-
document.head.appendChild(link);
49+
document.head.append(link);
5050
});
5151
}
5252

@@ -97,7 +97,7 @@ export function viaFetch(url, hasModeCors, hasCredentials, isPriority) {
9797
const options = {headers: {accept: '*/*'}};
9898
if (!hasModeCors) options.mode = 'no-cors';
9999
if (hasCredentials) options.credentials = 'include';
100-
isPriority ? options.priority = 'high' : options.priority = 'low';
100+
options.priority = isPriority ? 'high' : 'low';
101101
return window.fetch ? fetch(url, options) : viaXHR(url, hasCredentials);
102102
}
103103

@@ -116,7 +116,7 @@ export function prefetchOnHover(callback, url, onlyOnMouseover, ...args) {
116116
const timerMap = new Map();
117117

118118
for (const el of elements) {
119-
const mouseenterListener = _ => {
119+
const mouseenterListener = () => {
120120
const timer = setTimeout(() => {
121121
el.removeEventListener('mouseenter', mouseenterListener);
122122
el.removeEventListener('mouseleave', mouseleaveListener);
@@ -125,7 +125,7 @@ export function prefetchOnHover(callback, url, onlyOnMouseover, ...args) {
125125
timerMap.set(el, timer);
126126
};
127127

128-
const mouseleaveListener = _ => {
128+
const mouseleaveListener = () => {
129129
const timer = timerMap.get(el);
130130
if (timer) {
131131
clearTimeout(timer);

src/prerender.mjs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,16 @@
2626
export function addSpeculationRules(urlsToPrerender, eagerness) {
2727
const specScript = document.createElement('script');
2828
specScript.type = 'speculationrules';
29-
specScript.text = `{"prerender":[{"source": "list",
30-
"urls": ["${Array.from(urlsToPrerender).join('","')}"],
31-
"eagerness": "${eagerness}"}]}`;
29+
specScript.text =
30+
'{' +
31+
'"prerender":[{' +
32+
'"source":"list",' +
33+
`"urls":["${[...urlsToPrerender].join('","')}"],` +
34+
`"eagerness":"${eagerness}"` +
35+
'}]}';
36+
3237
try {
33-
document.head.appendChild(specScript);
38+
document.head.append(specScript);
3439
} catch (error) {
3540
return error;
3641
}

src/request-idle-callback.mjs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,14 @@
1616

1717
// RIC and shim for browsers setTimeout() without it
1818
const requestIdleCallback = window.requestIdleCallback ||
19-
function (cb) {
19+
(cb => {
2020
const start = Date.now();
2121
return setTimeout(() => {
2222
cb({
2323
didTimeout: false,
24-
timeRemaining() {
25-
return Math.max(0, 50 - (Date.now() - start));
26-
},
24+
timeRemaining: () => Math.max(0, 50 - (Date.now() - start)),
2725
});
2826
}, 1);
29-
};
27+
});
3028

3129
export default requestIdleCallback;

0 commit comments

Comments
 (0)