1(function () { 2 const link = document.createElement("link"); 3 const modulePreloadSupported = 4 link.relList && 5 link.relList.supports && 6 link.relList.supports("modulepreload"); 7 8 const isJsPath = (path) => { 9 const cleanPath = path.split("?")[0].split("#")[0]; 10 return /\.(c?m?[jt]s|jsx?|tsx?)$/.test(cleanPath); 11 }; 12 13 const isCssPath = (path) => { 14 const cleanPath = path.split("?")[0].split("#")[0]; 15 return /\.(css|s[ac]ss|less|styl|pcss)$/.test(cleanPath); 16 }; 17 18 const fetchRetry = (url, options = {}, retries) => 19 fetch(url, options) 20 .then((res) => { 21 if (res.ok) return res; 22 if (retries > 0) return fetchRetry(url, options, retries - 1); 23 throw new Error(res.status); 24 }) 25 .catch((error) => { 26 console.error(error.message); 27 }); 28 29 const generatePreloadLink = (path, typeOverride) => { 30 return new Promise((resolve, reject) => { 31 const element = document.createElement("link"); 32 element.crossOrigin = "anonymous"; 33 element.href = path; 34 element.rel = "preload"; 35 36 if ( 37 modulePreloadSupported && 38 typeOverride && 39 typeOverride === "module" && 40 isJsPath(path) 41 ) { 42 element.rel = "modulepreload"; 43 } 44 45 if (element.rel !== "modulepreload") { 46 if (isJsPath(path)) { 47 element.as = "script"; 48 } 49 if (isCssPath(path)) { 50 element.as = "style"; 51 } 52 } 53 54 resolve(element); 55 }); 56 }; 57 58 const generateScriptLink = (path, typeOverride) => { 59 return new Promise((resolve, reject) => { 60 const element = document.createElement("script"); 61 element.crossOrigin = "anonymous"; 62 element.src = path; 63 element.type = !typeOverride ? "text/javascript" : typeOverride; 64 if ( 65 path.indexOf(".ts") > -1 || 66 path.indexOf(".tsx") > -1 || 67 path.indexOf(".mjs") > -1 || 68 path.indexOf(".mts") > -1 69 ) { 70 element.type = "module"; 71 } 72 73 resolve(element); 74 }); 75 }; 76 77 const generateStyleLink = (path) => { 78 return new Promise((resolve) => { 79 const element = document.createElement("link"); 80 element.type = "text/css"; 81 element.rel = "stylesheet"; 82 element.crossOrigin = "anonymous"; 83 element.href = path; 84 85 resolve(element); 86 }); 87 }; 88 89 const sanitizeUrl = (url) => { 90 let { pathname, origin } = new URL(url, location.origin); // defaults to own origin 91 pathname = pathname.replace(/\/{2,}/g, "/"); 92 return `${origin}${pathname}`; 93 }; 94 95 const getDomain = (domainComponent) => { 96 let domain = ""; 97 if (!domainComponent.classList.contains("react-component-root")) { 98 domain = localStorage.getItem("spaUrl"); 99 } else { 100 domain = localStorage.getItem("spaUrl_" + domainComponent.id); 101 } 102 if (domainComponent && !domain) { 103 domain = domainComponent.dataset.remoteUrl; 104 } 105 return domain; 106 }; 107 108 const handleFile = (pathname, domain, typeOverride, isPreload) => { 109 return new Promise((resolve) => { 110 const filePath = sanitizeUrl(`${domain}/${pathname}`); 111 if (isPreload) { 112 generatePreloadLink(filePath, typeOverride).then((preloadTag) => { 113 resolve({ type: "preload", tag: preloadTag }); 114 }); 115 } else if (pathname.indexOf(".css") > 0) { 116 generateStyleLink(filePath).then((styleTag) => { 117 resolve({ type: "css", tag: styleTag }); 118 }); 119 } else { 120 generateScriptLink(filePath, typeOverride).then((scriptTag) => { 121 resolve({ type: "js", tag: scriptTag }); 122 }); 123 } 124 }); 125 }; 126 127 const handleFiles = (files, domain, typeOverride) => { 128 if (files && Array.isArray(files)) { 129 const bodyFragment = document.createDocumentFragment(); 130 const headFragment = document.createDocumentFragment(); 131 132 Promise.all( 133 files.map((file) => handleFile(file, domain, typeOverride)) 134 ).then((tags) => {
135 tags.forEach((tag) => { 136 if (tag.type === "css") { 137 headFragment.appendChild(tag.tag); 138 } else if (tag.type === "js") { 139 bodyFragment.appendChild(tag.tag); 140 } 141 }); 142 143 headFragment.hasChildNodes() && document.head.appendChild(headFragment); 144 bodyFragment.hasChildNodes() && document.body.appendChild(bodyFragment); 145 }); 146 } 147 }; 148 149 const handlePreloads = (preloads, domain, typeOverride) => { 150 if (preloads && Array.isArray(preloads)) { 151 const headFragment = document.createDocumentFragment(); 152 153 Promise.all( 154 preloads.map((preload) => 155 handleFile(preload, domain, typeOverride, true) 156 ) 157 ).then((tags) => { 158 tags.forEach((tag) => { 159 if (tag.type === "preload") { 160 headFragment.appendChild(tag.tag); 161 } 162 }); 163 164 headFragment.hasChildNodes() && document.head.appendChild(headFragment); 165 }); 166 } 167 }; 168 169 const domainComponents = Array.from( 170 document.querySelectorAll(".react-component-root") 171 ); 172 173 const legacyComponentRoot = document.getElementById("react-component-root"); 174 if (legacyComponentRoot) { 175 domainComponents.push(legacyComponentRoot); 176 } 177 const domainComponentList = Array.from(new Set(domainComponents)); 178 179 domainComponentList.forEach((domainComponent) => { 180 const loadOnWindowLoad = domainComponent.dataset?.["load-on-window-load"]; 181 const domain = getDomain(domainComponent); 182 183 if (domain) { 184 window.externalPublicPath = domain + "/"; 185 const manifestUrl = sanitizeUrl(`${domain}/asset-manifest.json`); 186 187 const fetchOptions = { 188 method: "GET", 189 credentials: "omit", 190 referrerPolicy: "strict-origin-when-cross-origin", 191 mode: "cors", 192 cache: "no-cache", 193 }; 194 195 const fetchSpa = () => { 196 fetchRetry(manifestUrl, fetchOptions, 2) 197 .then((response) => response.json()) 198 .then((asset) => { 199 const {entrypoints, typeOverride, preloads} = asset; 200 const files = entrypoints?.client?.js || entrypoints; 201 202 handleFiles(files, domain, typeOverride); 203 handlePreloads(preloads, domain, typeOverride); 204 }) 205 .catch((error) => { 206 console.error(error.message); 207 }); 208 } 209 210 if (loadOnWindowLoad === 'true') { 211 window.addEventListener("load", fetchSpa); 212 } else { 213 fetchSpa() 214 } 215 } 216 }); 217})();
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.