UNPKG

posthog-js

Version:

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

236 lines • 13.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WebExperiments = exports.webExperimentUrlValidationMap = void 0; var globals_1 = require("@posthog/browser-common/utils/globals"); var constants_1 = require("./constants"); var core_1 = require("@posthog/core"); var request_utils_1 = require("@posthog/browser-common/utils/request-utils"); var regex_utils_1 = require("@posthog/browser-common/utils/regex-utils"); var url_targeting_utils_1 = require("@posthog/browser-common/utils/url-targeting-utils"); var logger_1 = require("@posthog/browser-common/utils/logger"); var blocked_uas_1 = require("@posthog/browser-common/utils/blocked-uas"); var event_utils_1 = require("@posthog/browser-common/utils/event-utils"); var BOT_REFUSE_MSG = 'Refusing to render web experiment since the viewer is a likely bot'; exports.webExperimentUrlValidationMap = { icontains: function (conditionsUrl, href) { return href.toLowerCase().indexOf(conditionsUrl.toLowerCase()) > -1; }, not_icontains: function (conditionsUrl, href) { return href.toLowerCase().indexOf(conditionsUrl.toLowerCase()) === -1; }, regex: function (conditionsUrl, href) { return (0, regex_utils_1.isMatchingRegex)(href, conditionsUrl); }, not_regex: function (conditionsUrl, href) { return !(0, regex_utils_1.isMatchingRegex)(href, conditionsUrl); }, exact: function (conditionsUrl, href) { return href === conditionsUrl; }, is_not: function (conditionsUrl, href) { return href !== conditionsUrl; }, }; var WebExperiments = /** @class */ (function () { function WebExperiments(_instance) { var _this = this; this._instance = _instance; this.getWebExperimentsAndEvaluateDisplayLogic = function (forceReload) { if (forceReload === void 0) { forceReload = false; } _this.getWebExperiments(function (webExperiments) { WebExperiments._logInfo("retrieved web experiments from the server"); _this._flagToExperiments = new Map(); webExperiments.forEach(function (webExperiment) { var _a; if (webExperiment.feature_flag_key) { if (_this._flagToExperiments) { WebExperiments._logInfo("setting flag key ", webExperiment.feature_flag_key, " to web experiment ", webExperiment); (_a = _this._flagToExperiments) === null || _a === void 0 ? void 0 : _a.set(webExperiment.feature_flag_key, webExperiment); } var selectedVariant = _this._instance.getFeatureFlag(webExperiment.feature_flag_key); if ((0, core_1.isString)(selectedVariant) && webExperiment.variants[selectedVariant]) { _this._applyTransforms(webExperiment.name, selectedVariant, webExperiment.variants[selectedVariant].transforms); } } else if (webExperiment.variants) { for (var variant in webExperiment.variants) { var testVariant = webExperiment.variants[variant]; var matchTest = WebExperiments._matchesTestVariant(testVariant, _this._instance); if (matchTest) { _this._applyTransforms(webExperiment.name, variant, testVariant.transforms); } } } }); }, forceReload); }; this._instance.onFeatureFlags(function (flags) { _this.onFeatureFlags(flags); }); } Object.defineProperty(WebExperiments.prototype, "_config", { get: function () { return this._instance.config; }, enumerable: false, configurable: true }); // No-op: activation is driven by the onFeatureFlags callback registered in the constructor WebExperiments.prototype.initialize = function () { }; WebExperiments.prototype.onFeatureFlags = function (flags) { var _this = this; if (this._is_bot()) { WebExperiments._logInfo(BOT_REFUSE_MSG); return; } if (this._config.disable_web_experiments) { return; } if ((0, core_1.isNullish)(this._flagToExperiments)) { // Indicates first load so we trigger the loaders this._flagToExperiments = new Map(); this.loadIfEnabled(); this.previewWebExperiment(); return; } WebExperiments._logInfo('applying feature flags', flags); flags.forEach(function (flag) { var _a, _b; if (_this._flagToExperiments && ((_a = _this._flagToExperiments) === null || _a === void 0 ? void 0 : _a.has(flag))) { var selectedVariant = _this._instance.getFeatureFlag(flag); var webExperiment = (_b = _this._flagToExperiments) === null || _b === void 0 ? void 0 : _b.get(flag); if (selectedVariant && (webExperiment === null || webExperiment === void 0 ? void 0 : webExperiment.variants[selectedVariant])) { _this._applyTransforms(webExperiment.name, selectedVariant, webExperiment.variants[selectedVariant].transforms); } } }); }; WebExperiments.prototype.previewWebExperiment = function () { var _this = this; var location = WebExperiments.getWindowLocation(); if (location === null || location === void 0 ? void 0 : location.search) { var experimentID_1 = (0, request_utils_1.getQueryParam)(location === null || location === void 0 ? void 0 : location.search, '__experiment_id'); var variant_1 = (0, request_utils_1.getQueryParam)(location === null || location === void 0 ? void 0 : location.search, '__experiment_variant'); if (experimentID_1 && variant_1) { WebExperiments._logInfo("previewing web experiments ".concat(experimentID_1, " && ").concat(variant_1)); this.getWebExperiments(function (webExperiments) { _this._showPreviewWebExperiment(parseInt(experimentID_1), variant_1, webExperiments); }, false, true); } } }; WebExperiments.prototype.loadIfEnabled = function () { if (this._config.disable_web_experiments) { return; } this.getWebExperimentsAndEvaluateDisplayLogic(); }; WebExperiments.prototype.getWebExperiments = function (callback, forceReload, previewing) { if (this._config.disable_web_experiments && !previewing) { return callback([]); } var existingWebExperiments = this._instance.get_property(constants_1.WEB_EXPERIMENTS); if (existingWebExperiments && !forceReload) { return callback(existingWebExperiments); } this._instance._send_request({ url: this._instance.requestRouter.endpointFor('api', "/api/web_experiments/?token=".concat(this._config.token)), method: 'GET', timestampMode: 'query', callback: function (response) { if (response.statusCode !== 200 || !response.json) { return callback([]); } var webExperiments = response.json.experiments || []; return callback(webExperiments); }, }); }; WebExperiments.prototype._showPreviewWebExperiment = function (experimentID, variant, webExperiments) { var previewExperiments = webExperiments.filter(function (exp) { return exp.id === experimentID; }); if (previewExperiments && previewExperiments.length > 0) { WebExperiments._logInfo("Previewing web experiment [".concat(previewExperiments[0].name, "] with variant [").concat(variant, "]")); this._applyTransforms(previewExperiments[0].name, variant, previewExperiments[0].variants[variant].transforms); } }; WebExperiments._matchesTestVariant = function (testVariant, instance) { if ((0, core_1.isNullish)(testVariant.conditions)) { return false; } return (WebExperiments._matchUrlConditions(testVariant, instance) && WebExperiments._matchUTMConditions(testVariant)); }; WebExperiments._matchUrlConditions = function (testVariant, instance) { var _a, _b, _c, _d; if ((0, core_1.isNullish)(testVariant.conditions) || (0, core_1.isNullish)((_a = testVariant.conditions) === null || _a === void 0 ? void 0 : _a.url)) { return true; } var location = WebExperiments.getWindowLocation(); if (location) { // honors the `get_current_url` config hook so apps that rewrite their URL can target experiments correctly var href = (0, url_targeting_utils_1.applyUrlTargetingOverride)(instance, location.href); var urlCheck = ((_b = testVariant.conditions) === null || _b === void 0 ? void 0 : _b.url) ? exports.webExperimentUrlValidationMap[(_d = (_c = testVariant.conditions) === null || _c === void 0 ? void 0 : _c.urlMatchType) !== null && _d !== void 0 ? _d : 'icontains'](testVariant.conditions.url, href) : true; return urlCheck; } return false; }; WebExperiments.getWindowLocation = function () { return globals_1.window === null || globals_1.window === void 0 ? void 0 : globals_1.window.location; }; WebExperiments._matchUTMConditions = function (testVariant) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s; if ((0, core_1.isNullish)(testVariant.conditions) || (0, core_1.isNullish)((_a = testVariant.conditions) === null || _a === void 0 ? void 0 : _a.utm)) { return true; } var campaignParams = (0, event_utils_1.getCampaignParams)(); if (campaignParams['utm_source']) { var utmCampaignMatched = ((_c = (_b = testVariant.conditions) === null || _b === void 0 ? void 0 : _b.utm) === null || _c === void 0 ? void 0 : _c.utm_campaign) ? ((_e = (_d = testVariant.conditions) === null || _d === void 0 ? void 0 : _d.utm) === null || _e === void 0 ? void 0 : _e.utm_campaign) == campaignParams['utm_campaign'] : true; var utmSourceMatched = ((_g = (_f = testVariant.conditions) === null || _f === void 0 ? void 0 : _f.utm) === null || _g === void 0 ? void 0 : _g.utm_source) ? ((_j = (_h = testVariant.conditions) === null || _h === void 0 ? void 0 : _h.utm) === null || _j === void 0 ? void 0 : _j.utm_source) == campaignParams['utm_source'] : true; var utmMediumMatched = ((_l = (_k = testVariant.conditions) === null || _k === void 0 ? void 0 : _k.utm) === null || _l === void 0 ? void 0 : _l.utm_medium) ? ((_o = (_m = testVariant.conditions) === null || _m === void 0 ? void 0 : _m.utm) === null || _o === void 0 ? void 0 : _o.utm_medium) == campaignParams['utm_medium'] : true; var utmTermMatched = ((_q = (_p = testVariant.conditions) === null || _p === void 0 ? void 0 : _p.utm) === null || _q === void 0 ? void 0 : _q.utm_term) ? ((_s = (_r = testVariant.conditions) === null || _r === void 0 ? void 0 : _r.utm) === null || _s === void 0 ? void 0 : _s.utm_term) == campaignParams['utm_term'] : true; return utmCampaignMatched && utmMediumMatched && utmTermMatched && utmSourceMatched; } return false; }; WebExperiments._logInfo = function (msg) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } logger_1.logger.info("[WebExperiments] ".concat(msg), args); }; WebExperiments.prototype._applyTransforms = function (experiment, variant, transforms) { if (this._is_bot()) { WebExperiments._logInfo(BOT_REFUSE_MSG); return; } if (variant === 'control') { WebExperiments._logInfo('Control variants leave the page unmodified.'); return; } transforms.forEach(function (transform) { if (transform.selector) { WebExperiments._logInfo("applying transform of variant ".concat(variant, " for experiment ").concat(experiment, " "), transform); // oxlint-disable-next-line no-restricted-globals var elements = document === null || document === void 0 ? void 0 : document.querySelectorAll(transform.selector); elements === null || elements === void 0 ? void 0 : elements.forEach(function (element) { var htmlElement = element; if (transform.html) { htmlElement.innerHTML = transform.html; } if (transform.css) { htmlElement.setAttribute('style', transform.css); } }); } }); }; WebExperiments.prototype._is_bot = function () { if (globals_1.navigator && this._instance) { return (0, blocked_uas_1.isLikelyBot)(globals_1.navigator, this._config.custom_blocked_useragents); } else { return undefined; } }; return WebExperiments; }()); exports.WebExperiments = WebExperiments; //# sourceMappingURL=web-experiments.js.map