PageSourceSearch

https://www.landrover.it/etc.clientlibs/jlr-spa/clientlibs/clientl….ACSHASHedf22aaeb55c8ef949e78d020780552f.js

js landrover.it collected 2026-09-29 14:30:46 UTC 6,466 bytes, 217 lines download raw bytes

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.