Skip to content

Commit 965b7ca

Browse files
committed
Modernize code and improve readability
1 parent ac8f120 commit 965b7ca

File tree

7 files changed

+86
-73
lines changed

7 files changed

+86
-73
lines changed

.size-limit.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
},
1717
{
1818
"path": "dist/quicklink.umd.js",
19-
"limit": "2.51 kB",
19+
"limit": "2.55 kB",
2020
"gzip": true
2121
}
2222
]

src/chunks.mjs

Lines changed: 33 additions & 33 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
102-
if (!allowed.length || allowed.includes(link.hostname)) {
105+
if (allowed.length === 0 || 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: 42 additions & 28 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;
@@ -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
@@ -238,15 +246,21 @@ export function prefetch(urls, isPriority, checkAccessControlAllowOrigin, checkA
238246

239247
// Dev must supply own catch()
240248
return Promise.all(
241-
[].concat(urls).map(str => {
249+
[urls].flat().map(str => {
242250
if (toPrefetch.has(str)) return [];
243251

244252
// Add it now, regardless of its success
245253
// ~> so that we don't repeat broken links
246254
toPrefetch.add(str);
247255

248-
return prefetchOnHover((isPriority ? viaFetch : supported), new URL(str, location.href).toString(), onlyOnMouseover,
249-
checkAccessControlAllowOrigin, checkAccessControlAllowCredentials, isPriority);
256+
return prefetchOnHover(
257+
isPriority ? viaFetch : supported,
258+
new URL(str, location.href).toString(),
259+
onlyOnMouseover,
260+
checkAccessControlAllowOrigin,
261+
checkAccessControlAllowCredentials,
262+
isPriority,
263+
);
250264
}),
251265
);
252266
}
@@ -258,7 +272,7 @@ export function prefetch(urls, isPriority, checkAccessControlAllowOrigin, checkA
258272
* @return {Object} a Promise
259273
*/
260274
export function prerender(urls, eagerness = 'immediate') {
261-
urls = [].concat(urls);
275+
urls = [urls].flat();
262276

263277
const chkConn = checkConnection(navigator.connection);
264278
if (chkConn instanceof Error) {

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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export function addSpeculationRules(urlsToPrerender, eagerness) {
3838
}],
3939
});
4040

41-
document.head.appendChild(specScript);
41+
document.head.append(specScript);
4242
specMap.set(url, specScript);
4343
}
4444
} catch (error) {

src/react-chunks.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const useIntersect = ({root = null, rootMargin, threshold = 0} = {}) => {
2525

2626
useEffect(() => {
2727
if (observer.current) observer.current.disconnect();
28+
2829
observer.current = new window.IntersectionObserver(
2930
([entry]) => updateEntry(entry),
3031
{
@@ -50,7 +51,7 @@ const __defaultAccessor = mix => {
5051
const prefetchChunks = (entry, prefetchHandler, accessor = __defaultAccessor) => {
5152
const {files} = rmanifest(window.__rmanifest, entry.pathname);
5253
const chunkURLs = files.map(accessor).filter(Boolean);
53-
if (chunkURLs.length) {
54+
if (chunkURLs.length > 0) {
5455
prefetchHandler(chunkURLs);
5556
} else {
5657
// also prefetch regular links in-viewport

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)