Skip to content

Commit 4e64ca1

Browse files
committed
feat: add flexible filter option;
- accepts RegExp, Function, or Array of either - 776 gz / 648 br
1 parent ab6375a commit 4e64ca1

1 file changed

Lines changed: 20 additions & 2 deletions

File tree

src/index.mjs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,21 @@ function prefetcher(url) {
3838
prefetch(new URL(url, location.href).toString(), observer.priority);
3939
}
4040

41+
/**
42+
* Determine if the anchor tag can be prefetched.
43+
* A filter can be a RegExp, Function, or Array of both.
44+
* - Function receives `node.href, node` arguments
45+
* - RegExp receives `node.href` only (the full URL)
46+
* @param {Element} node The anchor (<a>) tag.
47+
* @param {Mixed} filter The custom filter(s)
48+
* @return {Boolean} If true, then it was allowed.
49+
*/
50+
function isAllowed(node, filter) {
51+
return Array.isArray(filter)
52+
? filter.every(x => isAllowed(node, x))
53+
: (filter.test || filter)(node.href, node);
54+
}
55+
4156
/**
4257
* Prefetch an array of URLs if the user's effective
4358
* connection type and data-saver preferences suggests
@@ -49,6 +64,7 @@ function prefetcher(url) {
4964
* @param {Object} options.el - DOM element to prefetch in-viewport links of
5065
* @param {Boolean} options.priority - Attempt higher priority fetch (low or high)
5166
* @param {Array} options.origins - Allowed origins to prefetch (empty allows all)
67+
* @param {Array|RegExp|Function} options.filter - Custom filter(s) that run after origin checks
5268
* @param {Number} options.timeout - Timeout after which prefetching will occur
5369
* @param {Function} options.timeoutFn - Custom timeout function
5470
*/
@@ -63,6 +79,7 @@ export default function (options) {
6379
observer.priority = options.priority;
6480

6581
const allowed = options.origins || [location.hostname];
82+
const filter = options.filter;
6683

6784
options.timeoutFn(() => {
6885
// If URLs are given, prefetch them.
@@ -73,9 +90,10 @@ export default function (options) {
7390
Array.from(options.el.querySelectorAll('a'), link => {
7491
observer.observe(link);
7592
// If the anchor matches a permitted origin
76-
// ~> An empty list means everything is allowed
93+
// ~> A `[]` or `true` means everything is allowed
7794
if (!allowed.length || allowed.includes(link.hostname)) {
78-
toPrefetch.add(link.href);
95+
// If there are any filters, they must also return true
96+
if (!filter || isAllowed(link, filter)) toPrefetch.add(link.href);
7997
}
8098
});
8199
}

0 commit comments

Comments
 (0)