UNPKG

posthog-js

Version:

Posthog-js allows you to automatically capture usage and send events to PostHog.

163 lines • 7.57 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var globals_1 = require("@posthog/browser-common/utils/globals"); var globals_2 = require("../utils/globals"); var logger_1 = require("@posthog/browser-common/utils/logger"); var logger = (0, logger_1.createLogger)('[ExternalScriptsLoader]'); var findScript = function (url) { var scripts = globals_1.document === null || globals_1.document === void 0 ? void 0 : globals_1.document.querySelectorAll('script'); if (scripts) { for (var i = 0; i < scripts.length; i++) { // `.src` reads back as a resolved absolute URL, but `url` is relative // whenever `api_host` is a path such as `/ingest`, so that comparison // alone never matches for reverse-proxied setups. The `src` attribute // holds exactly what `loadScript` wrote, so compare against both. if (scripts[i].src === url || scripts[i].getAttribute('src') === url) { return scripts[i]; } } } return undefined; }; var loadScript = function (posthog, url, callback) { if (posthog.config.disable_external_dependency_loading) { logger.warn("".concat(url, " was requested but loading of external scripts is disabled.")); return callback('Loading of external scripts is disabled'); } // Share the result when the same script is requested more than once so the browser // only downloads and executes it once. var existingScript = findScript(url); if (existingScript) { if (existingScript.__posthog_loading_callback_fired) { return callback(); } var existingError = existingScript.__posthog_loading_error; if (existingError) { return callback(existingError); } // oxlint-disable-next-line posthog-js/no-add-event-listener existingScript.addEventListener('load', function (event) { ; existingScript.__posthog_loading_callback_fired = true; callback(undefined, event); }); // oxlint-disable-next-line posthog-js/no-add-event-listener existingScript.addEventListener('error', function (error) { ; existingScript.__posthog_loading_error = error; callback(error); }); return; } var addScript = function () { var _a; if (!globals_1.document) { return callback('document not found'); } if (findScript(url)) { return loadScript(posthog, url, callback); } var scriptTag = globals_1.document.createElement('script'); scriptTag.type = 'text/javascript'; scriptTag.crossOrigin = 'anonymous'; scriptTag.src = url; scriptTag.onload = function (event) { ; scriptTag.__posthog_loading_callback_fired = true; callback(undefined, event); }; scriptTag.onerror = function (error) { ; scriptTag.__posthog_loading_error = error; callback(error); }; if (posthog.config.prepare_external_dependency_script) { scriptTag = posthog.config.prepare_external_dependency_script(scriptTag); } if (!scriptTag) { return callback('prepare_external_dependency_script returned null'); } if (posthog.config.external_scripts_inject_target === 'head') { globals_1.document.head.appendChild(scriptTag); } else { var scripts = globals_1.document.querySelectorAll('body > script'); if (scripts.length > 0) { (_a = scripts[0].parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(scriptTag, scripts[0]); } else { globals_1.document.body.appendChild(scriptTag); } } }; if (globals_1.document === null || globals_1.document === void 0 ? void 0 : globals_1.document.body) { addScript(); } else { // Inlining this because we don't care about `passive: true` here // and this saves us ~3% of the bundle size // oxlint-disable-next-line posthog-js/no-add-event-listener globals_1.document === null || globals_1.document === void 0 ? void 0 : globals_1.document.addEventListener('DOMContentLoaded', addScript); } }; var fallbackScripts = {}; var legacyScriptUrl = function (posthog, kind) { var scriptPath = "/static/".concat(kind, ".js?v=").concat(posthog.version); if (kind === 'toolbar') { // toolbar.js has a 24-hour CDN TTL but contains a rotating token valid for // only 5 minutes. Bust the cache on a 5-minute boundary so the browser always // fetches a fresh copy with a valid token. var fiveMinutesInMillis = 5 * 60 * 1000; var timestampToNearestFiveMinutes = Math.floor(Date.now() / fiveMinutesInMillis) * fiveMinutesInMillis; scriptPath = "".concat(scriptPath, "&t=").concat(timestampToNearestFiveMinutes); } return posthog.requestRouter.endpointFor('assets', scriptPath); }; globals_2.assignableWindow.__PosthogExtensions__ = globals_2.assignableWindow.__PosthogExtensions__ || {}; globals_2.assignableWindow.__PosthogExtensions__.loadExternalDependency = function (posthog, kind, callback) { // remote-config always loads from the token-specific path if (kind === 'remote-config') { var url = posthog.requestRouter.endpointFor('assets', "/array/".concat(posthog.config.token, "/config.js")); loadScript(posthog, url, callback); return; } var scriptVersioning = posthog.config.strict_script_versioning; if (scriptVersioning) { // posthog.version is baked into the executing array.js bundle, so this points at // the exact semver-qualified sibling asset without relying on alias redirects. var url_1 = posthog.requestRouter.endpointFor('assets', "/static/".concat(posthog.version, "/").concat(kind, ".js")); var existingFallback = fallbackScripts[url_1]; if (scriptVersioning === 'fallback' && existingFallback) { if (findScript(existingFallback)) { loadScript(posthog, existingFallback, callback); return; } delete fallbackScripts[url_1]; } loadScript(posthog, url_1, scriptVersioning === 'fallback' ? function (error, event) { var _a; if (!error) { callback(undefined, event); } else if (typeof error === 'string') { callback(error); } else { var fallbackUrl = legacyScriptUrl(posthog, kind); fallbackScripts[url_1] = fallbackUrl; var failedScript = findScript(url_1); (_a = failedScript === null || failedScript === void 0 ? void 0 : failedScript.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(failedScript); loadScript(posthog, fallbackUrl, callback); } } : callback); return; } loadScript(posthog, legacyScriptUrl(posthog, kind), callback); }; globals_2.assignableWindow.__PosthogExtensions__.loadSiteApp = function (posthog, url, callback) { var scriptUrl = posthog.requestRouter.endpointFor('api', url); loadScript(posthog, scriptUrl, callback); }; //# sourceMappingURL=external-scripts-loader.js.map