UNPKG

1.76 kBJavaScriptView Raw
1const support = function(feature) {
2 if (typeof document === `undefined`) {
3 return false
4 }
5 const fakeLink = document.createElement(`link`)
6 try {
7 if (fakeLink.relList && typeof fakeLink.relList.supports === `function`) {
8 return fakeLink.relList.supports(feature)
9 }
10 } catch (err) {
11 return false
12 }
13 return false
14}
15
16const linkPrefetchStrategy = function(url, options) {
17 return new Promise((resolve, reject) => {
18 if (typeof document === `undefined`) {
19 reject()
20 return
21 }
22
23 const link = document.createElement(`link`)
24 link.setAttribute(`rel`, `prefetch`)
25 link.setAttribute(`href`, url)
26
27 Object.keys(options).forEach(key => {
28 link.setAttribute(key, options[key])
29 })
30
31 link.onload = resolve
32 link.onerror = reject
33
34 const parentElement =
35 document.getElementsByTagName(`head`)[0] ||
36 document.getElementsByName(`script`)[0].parentNode
37 parentElement.appendChild(link)
38 })
39}
40
41const xhrPrefetchStrategy = function(url) {
42 return new Promise((resolve, reject) => {
43 const req = new XMLHttpRequest()
44 req.open(`GET`, url, true)
45
46 req.onload = () => {
47 if (req.status === 200) {
48 resolve()
49 } else {
50 reject()
51 }
52 }
53
54 req.send(null)
55 })
56}
57
58const supportedPrefetchStrategy = support(`prefetch`)
59 ? linkPrefetchStrategy
60 : xhrPrefetchStrategy
61
62const preFetched = {}
63
64const prefetch = function(url, options) {
65 return new Promise(resolve => {
66 if (preFetched[url]) {
67 resolve()
68 return
69 }
70
71 supportedPrefetchStrategy(url, options)
72 .then(() => {
73 resolve()
74 preFetched[url] = true
75 })
76 .catch(() => {}) // 404s are logged to the console anyway
77 })
78}
79
80export default prefetch