This repository has been archived by the owner on Apr 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathindex.js
80 lines (70 loc) · 2.49 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
'use strict';
function getClosestLink(node, root) {
if (!node || node === root) return;
if ('a' !== node.nodeName.toLowerCase() || !node.href) {
return getClosestLink(node.parentNode, root);
}
return node;
}
function setDefault(x, d) {
return x === undefined ? d : x;
}
function hijack(options, callback) {
if (typeof window === 'undefined') return;
if (typeof options === 'function') {
callback = options;
}
if (callback === undefined) {
throw new Error('hijack requires a callback');
}
var root = setDefault(options.root, document.documentElement);
var skipModifierKeys = setDefault(options.skipModifierKeys, true);
var skipDownload = setDefault(options.skipDownload, true);
var skipTargetBlank = setDefault(options.skipTargetBlank, true);
var skipExternal = setDefault(options.skipExternal, true);
var skipMailTo = setDefault(options.skipMailTo, true);
var skipOtherOrigin = setDefault(options.skipOtherOrigin, true);
var skipFragment = setDefault(options.skipFragment, true);
var preventDefault = setDefault(options.preventDefault, true);
function onClick(e) {
if (e.defaultPrevented) return;
if (e.button && e.button !== 0) return;
if (
skipModifierKeys &&
(e.ctrlKey || e.metaKey || e.altKey || e.shiftKey)
) {
return;
}
var link = getClosestLink(e.target, root);
if (!link) return;
if (options.skipFilter && options.skipFilter(link)) return;
if (skipFragment && /^#/.test(link.getAttribute('href'))) return;
if (skipDownload && link.hasAttribute('download')) return;
if (skipExternal && link.getAttribute('rel') === 'external') return;
if (skipTargetBlank && link.getAttribute('target') === '_blank') return;
if (skipMailTo && /mailto:/.test(link.getAttribute('href'))) return;
// IE doesn't populate all link properties when setting href with a
// relative URL. However, href will return an absolute URL which then can
// be used on itself to populate these additional fields.
// https://stackoverflow.com/a/13405933/2284669
if (!link.host) link.href = link.href;
if (
skipOtherOrigin &&
/:\/\//.test(link.href) &&
(location.protocol !== link.protocol || location.host !== link.host)
) {
return;
}
if (preventDefault) {
e.preventDefault();
}
callback(link, e);
}
root.addEventListener('click', onClick);
return function unhijackLinks() {
root.removeEventListener('click', onClick);
};
}
module.exports = {
hijack: hijack
};