1 2;(function () { 3 4 5 var urlToPreload 6 var mouseoverTimer 7 var lastTouchTimestamp 8 9 var prefetcher = document.createElement('link') 10 var isSupported = prefetcher.relList && prefetcher.relList.supports && prefetcher.relList.supports('prefetch') 11 var isDataSaverEnabled = navigator.connection && navigator.connection.saveData 12 var allowQueryString = 'instantAllowQueryString' in document.body.dataset 13 var allowExternalLinks = 'instantAllowExternalLinks' in document.body.dataset 14 15 if (isSupported && !isDataSaverEnabled) { 16 prefetcher.rel = 'prefetch' 17 document.head.appendChild(prefetcher) 18 19 var eventListenersOptions = { 20 capture: true, 21 passive: true 22 } 23 document.addEventListener('touchstart', touchstartListener, eventListenersOptions) 24 document.addEventListener('mouseover', mouseoverListener, eventListenersOptions) 25 } 26 27 function touchstartListener (event) { 28 29 lastTouchTimestamp = performance.now() 30 31 var linkElement = event.target.closest('a') 32 33 if (!isPreloadable(linkElement)) { 34 return 35 } 36 37 linkElement.addEventListener('touchcancel', touchendAndTouchcancelListener, { passive: true }) 38 linkElement.addEventListener('touchend', touchendAndTouchcancelListener, { passive: true }) 39 40 urlToPreload = linkElement.href 41 preload(linkElement.href) 42 } 43 44 function touchendAndTouchcancelListener () { 45 urlToPreload = undefined 46 stopPreloading() 47 } 48 49 function mouseoverListener (event) { 50 if (performance.now() - lastTouchTimestamp < 1100) { 51 return 52 } 53 54 var linkElement = event.target.closest('a') 55 56 if (!isPreloadable(linkElement)) { 57 return 58 } 59 60 linkElement.addEventListener('mouseout', mouseoutListener, { passive: true }) 61 62 urlToPreload = linkElement.href 63 64 mouseoverTimer = setTimeout(function () { 65 preload(linkElement.href) 66 mouseoverTimer = undefined 67 }, 65) 68 } 69 70 function mouseoutListener (event) { 71 if (event.relatedTarget && event.target.closest('a') === event.relatedTarget.closest('a')) { 72 return 73 } 74 75 if (mouseoverTimer) { 76 clearTimeout(mouseoverTimer) 77 mouseoverTimer = undefined 78 } else { 79 urlToPreload = undefined 80 stopPreloading() 81 } 82 } 83 84 function isPreloadable (linkElement) { 85 if (!linkElement || !linkElement.href) { 86 return 87 } 88 89 if (urlToPreload === linkElement.href) { 90 return 91 } 92 93 var preloadLocation = new URL(linkElement.href) 94 95 if (!allowExternalLinks && preloadLocation.origin !== location.origin && !('instant' in linkElement.dataset)) { 96 return 97 } 98 99 if (!['http:', 'https:'].includes(preloadLocation.protocol)) { 100 return 101 } 102 103 if (preloadLocation.protocol === 'http:' && location.protocol === 'https:') { 104 return 105 } 106 107 if (!allowQueryString && preloadLocation.search && !('instant' in linkElement.dataset)) { 108 return 109 } 110 111 if (preloadLocation.hash && preloadLocation.pathname + preloadLocation.search === location.pathname + location.search) { 112 return 113 } 114 115 if ('noInstant' in linkElement.dataset) { 116 return 117 } 118 119 return true 120 } 121 122 function preload (url) { 123 prefetcher.href = url 124 } 125 126 function stopPreloading () { 127 prefetcher.removeAttribute('href') 128 } 129})()
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.