summaryrefslogtreecommitdiffstats
path: root/browser/extensions/webcompat/shims/optimizely.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/extensions/webcompat/shims/optimizely.js')
-rw-r--r--browser/extensions/webcompat/shims/optimizely.js205
1 files changed, 205 insertions, 0 deletions
diff --git a/browser/extensions/webcompat/shims/optimizely.js b/browser/extensions/webcompat/shims/optimizely.js
new file mode 100644
index 0000000000..dcda87421d
--- /dev/null
+++ b/browser/extensions/webcompat/shims/optimizely.js
@@ -0,0 +1,205 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Bug 1714431 - Shim Optimizely
+ *
+ * This shim stubs out window.optimizely for those sites which
+ * break when it is not successfully loaded.
+ */
+
+if (!window.optimizely?.state) {
+ const behavior = {
+ query: () => [],
+ };
+
+ const dcp = {
+ getAttributeValue() {},
+ waitForAttributeValue: () => Promise.resolve(),
+ };
+
+ const data = {
+ accountId: "",
+ audiences: {},
+ campaigns: {},
+ clientName: "js",
+ clientVersion: "0.166.0",
+ dcpServiceId: null,
+ events: {},
+ experiments: {},
+ groups: {},
+ pages: {},
+ projectId: "",
+ revision: "",
+ snippetId: null,
+ variations: {},
+ };
+
+ const activationId = String(Date.now());
+
+ const state = {
+ getActivationId() {
+ return activationId;
+ },
+ getActiveExperimentIds() {
+ return [];
+ },
+ getCampaignStateLists() {
+ return {};
+ },
+ getCampaignStates() {
+ return {};
+ },
+ getDecisionObject() {
+ return null;
+ },
+ getDecisionString() {
+ return null;
+ },
+ getExperimentStates() {
+ return {};
+ },
+ getPageStates() {
+ return {};
+ },
+ getRedirectInfo() {
+ return null;
+ },
+ getVariationMap() {
+ return {};
+ },
+ isGlobalHoldback() {
+ return false;
+ },
+ };
+
+ const poll = (fn, to) => {
+ setInterval(() => {
+ try {
+ fn();
+ } catch (_) {}
+ }, to);
+ };
+
+ const waitUntil = test => {
+ let interval, resolve;
+ function check() {
+ try {
+ if (test()) {
+ clearInterval(interval);
+ resolve?.();
+ return true;
+ }
+ } catch (_) {}
+ return false;
+ }
+ return new Promise(r => {
+ resolve = r;
+ if (check()) {
+ resolve();
+ return;
+ }
+ interval = setInterval(check, 250);
+ });
+ };
+
+ const waitForElement = sel => {
+ return waitUntil(() => {
+ document.querySelector(sel);
+ });
+ };
+
+ const observeSelector = (sel, fn, opts) => {
+ let interval;
+ const observed = new Set();
+ function check() {
+ try {
+ for (const e of document.querySelectorAll(sel)) {
+ if (observed.has(e)) {
+ continue;
+ }
+ observed.add(e);
+ try {
+ fn(e);
+ } catch (_) {}
+ if (opts.once) {
+ clearInterval(interval);
+ }
+ }
+ } catch (_) {}
+ }
+ interval = setInterval(check, 250);
+ const timeout = { opts };
+ if (timeout) {
+ setTimeout(() => {
+ clearInterval(interval);
+ }, timeout);
+ }
+ };
+
+ const utils = {
+ Promise: window.Promise,
+ observeSelector,
+ poll,
+ waitForElement,
+ waitUntil,
+ };
+
+ const visitorId = {
+ randomId: "",
+ };
+
+ let browserVersion = "";
+ try {
+ browserVersion = navigator.userAgent.match(/rv:(.*)\)/)[1];
+ } catch (_) {}
+
+ const visitor = {
+ browserId: "ff",
+ browserVersion,
+ currentTimestamp: Date.now(),
+ custom: {},
+ customBehavior: {},
+ device: "desktop",
+ device_type: "desktop_laptop",
+ events: [],
+ first_session: true,
+ offset: 240,
+ referrer: null,
+ source_type: "direct",
+ visitorId,
+ };
+
+ window.optimizely = {
+ data: {
+ note: "Obsolete, use optimizely.get('data') instead",
+ },
+ get(e) {
+ switch (e) {
+ case "behavior":
+ return behavior;
+ case "data":
+ return data;
+ case "dcp":
+ return dcp;
+ case "jquery":
+ throw new Error("jQuery not implemented");
+ case "session":
+ return undefined;
+ case "state":
+ return state;
+ case "utils":
+ return utils;
+ case "visitor":
+ return visitor;
+ case "visitor_id":
+ return visitorId;
+ }
+ return undefined;
+ },
+ initialized: true,
+ push() {},
+ state: {},
+ };
+}