summaryrefslogtreecommitdiffstats
path: root/browser/extensions/webcompat/shims
diff options
context:
space:
mode:
Diffstat (limited to 'browser/extensions/webcompat/shims')
-rw-r--r--browser/extensions/webcompat/shims/adsafeprotected-ima.js69
-rw-r--r--browser/extensions/webcompat/shims/bmauth.js21
-rw-r--r--browser/extensions/webcompat/shims/eluminate.js68
-rw-r--r--browser/extensions/webcompat/shims/empty-script.js5
-rw-r--r--browser/extensions/webcompat/shims/facebook-sdk.js198
-rw-r--r--browser/extensions/webcompat/shims/google-analytics-ecommerce-plugin.js13
-rw-r--r--browser/extensions/webcompat/shims/google-analytics-legacy.js133
-rw-r--r--browser/extensions/webcompat/shims/google-analytics-tag-manager.js24
-rw-r--r--browser/extensions/webcompat/shims/google-analytics.js45
-rw-r--r--browser/extensions/webcompat/shims/google-publisher-tags.js163
-rw-r--r--browser/extensions/webcompat/shims/live-test-shim.js84
-rw-r--r--browser/extensions/webcompat/shims/mochitest-shim-1.js89
-rw-r--r--browser/extensions/webcompat/shims/mochitest-shim-2.js87
-rw-r--r--browser/extensions/webcompat/shims/mochitest-shim-3.js7
-rw-r--r--browser/extensions/webcompat/shims/rambler-authenticator.js86
-rw-r--r--browser/extensions/webcompat/shims/rich-relevance.js30
16 files changed, 1122 insertions, 0 deletions
diff --git a/browser/extensions/webcompat/shims/adsafeprotected-ima.js b/browser/extensions/webcompat/shims/adsafeprotected-ima.js
new file mode 100644
index 0000000000..de273de7d8
--- /dev/null
+++ b/browser/extensions/webcompat/shims/adsafeprotected-ima.js
@@ -0,0 +1,69 @@
+/* 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/. */
+
+"use strict";
+
+/**
+ * Bug 1508639 - Shim Ad Safe Protected's Google IMA adapter
+ */
+
+if (!window.googleImaVansAdapter) {
+ const shimId = "AdSafeProtectedGoogleIMAAdapter";
+
+ const sendMessageToAddon = (function() {
+ const pendingMessages = new Map();
+ const channel = new MessageChannel();
+ channel.port1.onerror = console.error;
+ channel.port1.onmessage = event => {
+ const { messageId, response } = event.data;
+ const resolve = pendingMessages.get(messageId);
+ if (resolve) {
+ pendingMessages.delete(messageId);
+ resolve(response);
+ }
+ };
+ function reconnect() {
+ const detail = {
+ pendingMessages: [...pendingMessages.values()],
+ port: channel.port2,
+ shimId,
+ };
+ window.dispatchEvent(new CustomEvent("ShimConnects", { detail }));
+ }
+ window.addEventListener("ShimHelperReady", reconnect);
+ reconnect();
+ return function(message) {
+ const messageId =
+ Math.random()
+ .toString(36)
+ .substring(2) + Date.now().toString(36);
+ return new Promise(resolve => {
+ const payload = {
+ message,
+ messageId,
+ shimId,
+ };
+ pendingMessages.set(messageId, resolve);
+ channel.port1.postMessage(payload);
+ });
+ };
+ })();
+
+ window.googleImaVansAdapter = {
+ init: () => {},
+ dispose: () => {},
+ };
+
+ // Treat it as an opt-in when the user clicks on a video
+ // TODO: Improve this! It races to tell the bg script to unblock the ad from
+ // https://pubads.g.doubleclick.net/gampad/ads before the page loads them.
+ async function click(e) {
+ if (e.isTrusted && e.target.closest("#video-player")) {
+ document.documentElement.removeEventListener("click", click, true);
+ await sendMessageToAddon("optIn");
+ // TODO: reload ima3.js?
+ }
+ }
+ document.documentElement.addEventListener("click", click, true);
+}
diff --git a/browser/extensions/webcompat/shims/bmauth.js b/browser/extensions/webcompat/shims/bmauth.js
new file mode 100644
index 0000000000..944f2100d6
--- /dev/null
+++ b/browser/extensions/webcompat/shims/bmauth.js
@@ -0,0 +1,21 @@
+/* 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/. */
+
+"use strict";
+
+if (!window.BmAuth) {
+ window.BmAuth = {
+ init: () => new Promise(() => {}),
+ handleSignIn: () => {
+ // TODO: handle this properly!
+ },
+ isAuthenticated: () => Promise.resolve(false),
+ addListener: () => {},
+ api: {
+ event: {
+ addListener: () => {},
+ },
+ },
+ };
+}
diff --git a/browser/extensions/webcompat/shims/eluminate.js b/browser/extensions/webcompat/shims/eluminate.js
new file mode 100644
index 0000000000..863d4ef2da
--- /dev/null
+++ b/browser/extensions/webcompat/shims/eluminate.js
@@ -0,0 +1,68 @@
+/* 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/. */
+
+"use strict";
+
+if (!window.CM_DDX) {
+ window.CM_DDX = {
+ domReadyFired: false,
+ headScripts: true,
+ dispatcherLoadRequested: false,
+ firstPassFunctionBinding: false,
+ BAD_PAGE_ID_ELAPSED_TIMEOUT: 5000,
+ version: -1,
+ standalone: false,
+ test: {
+ syndicate: true,
+ testCounter: "",
+ doTest: false,
+ newWin: false,
+ process: () => {},
+ },
+ partner: {},
+ invokeFunctionWhenAvailable: a => {
+ a();
+ },
+ gup: d => "",
+ privacy: {
+ isDoNotTrackEnabled: () => false,
+ setDoNotTrack: () => {},
+ getDoNotTrack: () => false,
+ },
+ setSubCookie: () => {},
+ };
+
+ const noopfn = () => {};
+ const w = window;
+ w.cmAddShared = noopfn;
+ w.cmCalcSKUString = noopfn;
+ w.cmCreateManualImpressionTag = noopfn;
+ w.cmCreateManualLinkClickTag = noopfn;
+ w.cmCreateManualPageviewTag = noopfn;
+ w.cmCreateOrderTag = noopfn;
+ w.cmCreatePageviewTag = noopfn;
+ w.cmRetrieveUserID = noopfn;
+ w.cmSetClientID = noopfn;
+ w.cmSetCurrencyCode = noopfn;
+ w.cmSetFirstPartyIDs = noopfn;
+ w.cmSetSubCookie = noopfn;
+ w.cmSetupCookieMigration = noopfn;
+ w.cmSetupNormalization = noopfn;
+ w.cmSetupOther = noopfn;
+ w.cmStartTagSet = noopfn;
+
+ function cmExecuteTagQueue() {
+ var b = window.cmTagQueue;
+ if (b) {
+ if (!Array.isArray(b)) {
+ return undefined;
+ }
+ for (var a = 0; a < b.length; ++a) {
+ window[b[a][0]].apply(window, b[a].slice(1));
+ }
+ }
+ return true;
+ }
+ cmExecuteTagQueue();
+}
diff --git a/browser/extensions/webcompat/shims/empty-script.js b/browser/extensions/webcompat/shims/empty-script.js
new file mode 100644
index 0000000000..d01f2ab537
--- /dev/null
+++ b/browser/extensions/webcompat/shims/empty-script.js
@@ -0,0 +1,5 @@
+/* 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/. */
+
+/* This script is intentionally empty */
diff --git a/browser/extensions/webcompat/shims/facebook-sdk.js b/browser/extensions/webcompat/shims/facebook-sdk.js
new file mode 100644
index 0000000000..95928be857
--- /dev/null
+++ b/browser/extensions/webcompat/shims/facebook-sdk.js
@@ -0,0 +1,198 @@
+/* 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/. */
+
+"use strict";
+
+/**
+ * Bug 1226498 - Shim Facebook SDK
+ *
+ * The Facebook SDK is commonly used by sites to allow users to authenticate
+ * for logins, but it is blocked by strict tracking protection. It is possible
+ * to shim the SDK and allow users to still opt into logging in via Facebook.
+ * It is also possible to replace any Facebook widgets or comments with
+ * placeholders that the user may click to opt into loading the content.
+ */
+
+if (!window.FB) {
+ const originalUrl = document.currentScript.src;
+ const pendingParses = [];
+
+ function getGUID() {
+ return (
+ Math.random()
+ .toString(36)
+ .substring(2) + Date.now().toString(36)
+ );
+ }
+
+ const shimId = "FacebookSDK";
+
+ const sendMessageToAddon = (function() {
+ const pendingMessages = new Map();
+ const channel = new MessageChannel();
+ channel.port1.onerror = console.error;
+ channel.port1.onmessage = event => {
+ const { messageId, response } = event.data;
+ const resolve = pendingMessages.get(messageId);
+ if (resolve) {
+ pendingMessages.delete(messageId);
+ resolve(response);
+ }
+ };
+ function reconnect() {
+ const detail = {
+ pendingMessages: [...pendingMessages.values()],
+ port: channel.port2,
+ shimId,
+ };
+ window.dispatchEvent(new CustomEvent("ShimConnects", { detail }));
+ }
+ window.addEventListener("ShimHelperReady", reconnect);
+ reconnect();
+ return function(message) {
+ const messageId = getGUID();
+ return new Promise(resolve => {
+ const payload = {
+ message,
+ messageId,
+ shimId,
+ };
+ pendingMessages.set(messageId, resolve);
+ channel.port1.postMessage(payload);
+ });
+ };
+ })();
+
+ let ready = false;
+ let initInfo;
+ const needPopup =
+ !/app_runner/.test(window.name) && !/iframe_canvas/.test(window.name);
+ const popupName = getGUID();
+
+ if (needPopup) {
+ const oldWindowOpen = window.open;
+ window.open = function(href, name, params) {
+ try {
+ const url = new URL(href);
+ if (
+ url.protocol === "https:" &&
+ (url.hostname === "m.facebook.com" ||
+ url.hostname === "www.facebook.com") &&
+ url.pathname.endsWith("/oauth")
+ ) {
+ name = popupName;
+ }
+ } catch (_) {}
+ return oldWindowOpen.call(window, href, name, params);
+ };
+ }
+
+ async function allowFacebookSDK(callback) {
+ await sendMessageToAddon("optIn");
+
+ window.FB = undefined;
+ const oldInit = window.fbAsyncInit;
+ window.fbAsyncInit = () => {
+ ready = true;
+ if (typeof initInfo !== "undefined") {
+ window.FB.init(initInfo);
+ } else if (oldInit) {
+ oldInit();
+ }
+ if (callback) {
+ callback();
+ }
+ };
+
+ const s = document.createElement("script");
+ s.src = originalUrl;
+ await new Promise((resolve, reject) => {
+ s.onerror = reject;
+ s.onload = function() {
+ for (const args of pendingParses) {
+ window.FB.XFBML.parse.apply(window.FB.XFBML, args);
+ }
+ resolve();
+ };
+ document.head.appendChild(s);
+ });
+ }
+
+ function buildPopupParams() {
+ const { outerWidth, outerHeight, screenX, screenY } = window;
+ const { width, height } = window.screen;
+ const w = Math.min(width, 400);
+ const h = Math.min(height, 400);
+ const ua = navigator.userAgent;
+ const isMobile = ua.includes("Mobile") || ua.includes("Tablet");
+ const left = screenX + (screenX < 0 ? width : 0) + (outerWidth - w) / 2;
+ const top = screenY + (screenY < 0 ? height : 0) + (outerHeight - h) / 2.5;
+ let params = `left=${left},top=${top},width=${w},height=${h},scrollbars=1,toolbar=0,location=1`;
+ if (!isMobile) {
+ params = `${params},width=${w},height=${h}`;
+ }
+ return params;
+ }
+
+ async function doLogin(a, b) {
+ window.FB.login(a, b);
+ }
+
+ function proxy(name, fn) {
+ return function() {
+ if (ready) {
+ return window.FB[name].apply(this, arguments);
+ }
+ return fn.apply(this, arguments);
+ };
+ }
+
+ window.FB = {
+ api: proxy("api", () => {}),
+ AppEvents: {
+ EventNames: {},
+ logPageView: () => {},
+ },
+ Event: {
+ subscribe: () => {},
+ },
+ getAccessToken: proxy("getAccessToken", () => null),
+ getAuthResponse: proxy("getAuthResponse", () => {
+ return { status: "" };
+ }),
+ getLoginStatus: proxy("getLoginStatus", cb => {
+ cb({ status: "" });
+ }),
+ getUserID: proxy("getUserID", () => {}),
+ init: _initInfo => {
+ if (ready) {
+ doLogin(_initInfo);
+ } else {
+ initInfo = _initInfo; // in case the site is not using fbAsyncInit
+ }
+ },
+ login: (a, b) => {
+ // We have to load Facebook's script, and then wait for it to call
+ // window.open. By that time, the popup blocker will likely trigger.
+ // So we open a popup now with about:blank, and then make sure FB
+ // will re-use that same popup later.
+ if (needPopup) {
+ window.open("about:blank", popupName, buildPopupParams());
+ }
+ allowFacebookSDK(() => {
+ doLogin(a, b);
+ });
+ },
+ logout: proxy("logout", cb => cb()),
+ XFBML: {
+ parse: e => {
+ pendingParses.push([e]);
+ },
+ },
+ };
+
+ if (window.fbAsyncInit) {
+ window.fbAsyncInit();
+ }
+}
diff --git a/browser/extensions/webcompat/shims/google-analytics-ecommerce-plugin.js b/browser/extensions/webcompat/shims/google-analytics-ecommerce-plugin.js
new file mode 100644
index 0000000000..60b49df120
--- /dev/null
+++ b/browser/extensions/webcompat/shims/google-analytics-ecommerce-plugin.js
@@ -0,0 +1,13 @@
+/* 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/. */
+
+"use strict";
+
+if (!window.gaplugins) {
+ window.gaplugins = {};
+}
+
+if (!window.gaplugins.EC) {
+ window.gaplugins.EC = () => {};
+}
diff --git a/browser/extensions/webcompat/shims/google-analytics-legacy.js b/browser/extensions/webcompat/shims/google-analytics-legacy.js
new file mode 100644
index 0000000000..056186f75c
--- /dev/null
+++ b/browser/extensions/webcompat/shims/google-analytics-legacy.js
@@ -0,0 +1,133 @@
+/* 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/. */
+
+// based on https://github.com/gorhill/uBlock/blob/caa8e7d35ba61214a9d13e7d324b2bd2aa73237f/src/web_accessible_resources/google-analytics_ga.js
+
+"use strict";
+
+if (!window._gaq) {
+ function noopfn() {}
+
+ const gaq = {
+ Na: noopfn,
+ O: noopfn,
+ Sa: noopfn,
+ Ta: noopfn,
+ Va: noopfn,
+ _createAsyncTracker: noopfn,
+ _getAsyncTracker: noopfn,
+ _getPlugin: noopfn,
+ push: a => {
+ if (typeof a === "function") {
+ a();
+ return;
+ }
+ if (!Array.isArray(a)) {
+ return;
+ }
+ if (a[0] === "_link" && typeof a[1] === "string") {
+ window.location.assign(a[1]);
+ }
+ if (
+ a[0] === "_set" &&
+ a[1] === "hitCallback" &&
+ typeof a[2] === "function"
+ ) {
+ a[2]();
+ }
+ },
+ };
+
+ const tracker = {
+ _addIgnoredOrganic: noopfn,
+ _addIgnoredRef: noopfn,
+ _addItem: noopfn,
+ _addOrganic: noopfn,
+ _addTrans: noopfn,
+ _clearIgnoredOrganic: noopfn,
+ _clearIgnoredRef: noopfn,
+ _clearOrganic: noopfn,
+ _cookiePathCopy: noopfn,
+ _deleteCustomVar: noopfn,
+ _getName: noopfn,
+ _setAccount: noopfn,
+ _getAccount: noopfn,
+ _getClientInfo: noopfn,
+ _getDetectFlash: noopfn,
+ _getDetectTitle: noopfn,
+ _getLinkerUrl: a => a,
+ _getLocalGifPath: noopfn,
+ _getServiceMode: noopfn,
+ _getVersion: noopfn,
+ _getVisitorCustomVar: noopfn,
+ _initData: noopfn,
+ _link: noopfn,
+ _linkByPost: noopfn,
+ _setAllowAnchor: noopfn,
+ _setAllowHash: noopfn,
+ _setAllowLinker: noopfn,
+ _setCampContentKey: noopfn,
+ _setCampMediumKey: noopfn,
+ _setCampNameKey: noopfn,
+ _setCampNOKey: noopfn,
+ _setCampSourceKey: noopfn,
+ _setCampTermKey: noopfn,
+ _setCampaignCookieTimeout: noopfn,
+ _setCampaignTrack: noopfn,
+ _setClientInfo: noopfn,
+ _setCookiePath: noopfn,
+ _setCookiePersistence: noopfn,
+ _setCookieTimeout: noopfn,
+ _setCustomVar: noopfn,
+ _setDetectFlash: noopfn,
+ _setDetectTitle: noopfn,
+ _setDomainName: noopfn,
+ _setLocalGifPath: noopfn,
+ _setLocalRemoteServerMode: noopfn,
+ _setLocalServerMode: noopfn,
+ _setReferrerOverride: noopfn,
+ _setRemoteServerMode: noopfn,
+ _setSampleRate: noopfn,
+ _setSessionTimeout: noopfn,
+ _setSiteSpeedSampleRate: noopfn,
+ _setSessionCookieTimeout: noopfn,
+ _setVar: noopfn,
+ _setVisitorCookieTimeout: noopfn,
+ _trackEvent: noopfn,
+ _trackPageLoadTime: noopfn,
+ _trackPageview: noopfn,
+ _trackSocial: noopfn,
+ _trackTiming: noopfn,
+ _trackTrans: noopfn,
+ _visitCode: noopfn,
+ };
+
+ const gat = {
+ _anonymizeIP: noopfn,
+ _createTracker: noopfn,
+ _forceSSL: noopfn,
+ _getPlugin: noopfn,
+ _getTracker: () => tracker,
+ _getTrackerByName: () => tracker,
+ _getTrackers: noopfn,
+ aa: noopfn,
+ ab: noopfn,
+ hb: noopfn,
+ la: noopfn,
+ oa: noopfn,
+ pa: noopfn,
+ u: noopfn,
+ };
+
+ window._gat = gat;
+
+ const aa = window._gaq || [];
+ if (Array.isArray(aa)) {
+ while (aa[0]) {
+ gaq.push(aa.shift());
+ }
+ }
+
+ window._gaq = gaq.qf = gaq;
+}
diff --git a/browser/extensions/webcompat/shims/google-analytics-tag-manager.js b/browser/extensions/webcompat/shims/google-analytics-tag-manager.js
new file mode 100644
index 0000000000..b8398f91b6
--- /dev/null
+++ b/browser/extensions/webcompat/shims/google-analytics-tag-manager.js
@@ -0,0 +1,24 @@
+/* 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/. */
+
+// based on https://github.com/gorhill/uBlock/blob/caa8e7d35ba61214a9d13e7d324b2bd2aa73237f/src/web_accessible_resources/googletagmanager_gtm.js
+
+"use strict";
+
+if (!window.ga) {
+ window.ga = () => {};
+
+ try {
+ window.dataLayer.hide.end();
+ } catch (_) {}
+
+ const dl = window.dataLayer;
+ if (typeof dl.push === "function") {
+ dl.push = o => {
+ if (o instanceof Object && typeof o.eventCallback === "function") {
+ setTimeout(o.eventCallback, 1);
+ }
+ };
+ }
+}
diff --git a/browser/extensions/webcompat/shims/google-analytics.js b/browser/extensions/webcompat/shims/google-analytics.js
new file mode 100644
index 0000000000..f0162b1f63
--- /dev/null
+++ b/browser/extensions/webcompat/shims/google-analytics.js
@@ -0,0 +1,45 @@
+/* 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/. */
+
+// based on https://github.com/gorhill/uBlock/blob/8a1a8b103f56e4fcef1264e02dfd718a29bda006/src/web_accessible_resources/google-analytics_analytics.js
+
+"use strict";
+
+if (!window[window.GoogleAnalyticsObject || "ga"]) {
+ function ga() {
+ const len = arguments.length;
+ if (!len) {
+ return;
+ }
+ const args = Array.from(arguments);
+ let fn;
+ let a = args[len - 1];
+ if (a instanceof Object && a.hitCallback instanceof Function) {
+ fn = a.hitCallback;
+ } else {
+ const pos = args.indexOf("hitCallback");
+ if (pos !== -1 && args[pos + 1] instanceof Function) {
+ fn = args[pos + 1];
+ }
+ }
+ if (!(fn instanceof Function)) {
+ return;
+ }
+ try {
+ fn();
+ } catch (_) {}
+ }
+ ga.create = () => {};
+ ga.getByName = () => null;
+ ga.getAll = () => [];
+ ga.remove = () => {};
+ ga.loaded = true;
+
+ const gaName = window.GoogleAnalyticsObject || "ga";
+ window[gaName] = ga;
+}
+
+try {
+ window.dataLayer.hide.end();
+} catch (_) {}
diff --git a/browser/extensions/webcompat/shims/google-publisher-tags.js b/browser/extensions/webcompat/shims/google-publisher-tags.js
new file mode 100644
index 0000000000..756e29bac5
--- /dev/null
+++ b/browser/extensions/webcompat/shims/google-publisher-tags.js
@@ -0,0 +1,163 @@
+/* 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/. */
+
+"use strict";
+
+/**
+ * Bug 1600538 - Shim Google Publisher Tags
+ */
+
+"use strict";
+
+if (!window.googletag?.apiReady) {
+ const noopfn = function() {};
+ const noopthisfn = function() {
+ return this;
+ };
+ const noopnullfn = function() {
+ return null;
+ };
+ const nooparrayfn = function() {
+ return [];
+ };
+ const noopstrfn = function() {
+ return "";
+ };
+
+ function newPassbackSlot() {
+ return {
+ display: noopfn,
+ get: noopnullfn,
+ set: noopthisfn,
+ setClickUrl: noopthisfn,
+ setTagForChildDirectedTreatment: noopthisfn,
+ setTargeting: noopthisfn,
+ updateTargetingFromMap: noopthisfn,
+ };
+ }
+
+ function display(id) {
+ const parent = document.getElementById(id);
+ if (parent) {
+ parent.appendChild(document.createElement("div"));
+ }
+ }
+
+ const companionAdsService = {
+ addEventListener: noopthisfn,
+ enableSyncLoading: noopfn,
+ setRefreshUnfilledSlots: noopfn,
+ };
+
+ const contentService = {
+ addEventListener: noopthisfn,
+ setContent: noopfn,
+ };
+
+ const pubadsService = {
+ addEventListener: noopthisfn,
+ clear: noopfn,
+ clearCategoryExclusions: noopthisfn,
+ clearTagForChildDirectedTreatment: noopthisfn,
+ clearTargeting: noopthisfn,
+ collapseEmptyDivs: noopfn,
+ defineOutOfPagePassback: () => newPassbackSlot(),
+ definePassback: () => newPassbackSlot(),
+ disableInitialLoad: noopfn,
+ display,
+ enableAsyncRendering: noopfn,
+ enableSingleRequest: noopfn,
+ enableSyncRendering: noopfn,
+ enableVideoAds: noopfn,
+ get: noopnullfn,
+ getAttributeKeys: nooparrayfn,
+ getTargeting: noopfn,
+ getTargetingKeys: nooparrayfn,
+ getSlots: nooparrayfn,
+ refresh: noopfn,
+ set: noopthisfn,
+ setCategoryExclusion: noopthisfn,
+ setCentering: noopfn,
+ setCookieOptions: noopthisfn,
+ setForceSafeFrame: noopthisfn,
+ setLocation: noopthisfn,
+ setPublisherProvidedId: noopthisfn,
+ setRequestNonPersonalizedAds: noopthisfn,
+ setSafeFrameConfig: noopthisfn,
+ setTagForChildDirectedTreatment: noopthisfn,
+ setTargeting: noopthisfn,
+ setVideoContent: noopthisfn,
+ updateCorrelator: noopfn,
+ };
+
+ function newSizeMappingBuilder() {
+ return {
+ addSize: noopthisfn,
+ build: noopnullfn,
+ };
+ }
+
+ function newSlot() {
+ return {
+ addService: noopthisfn,
+ clearCategoryExclusions: noopthisfn,
+ clearTargeting: noopthisfn,
+ defineSizeMapping: noopthisfn,
+ get: noopnullfn,
+ getAdUnitPath: nooparrayfn,
+ getAttributeKeys: nooparrayfn,
+ getCategoryExclusions: nooparrayfn,
+ getDomId: noopstrfn,
+ getSlotElementId: noopstrfn,
+ getSlotId: noopthisfn,
+ getTargeting: nooparrayfn,
+ getTargetingKeys: nooparrayfn,
+ set: noopthisfn,
+ setCategoryExclusion: noopthisfn,
+ setClickUrl: noopthisfn,
+ setCollapseEmptyDiv: noopthisfn,
+ setTargeting: noopthisfn,
+ };
+ }
+
+ let gt = window.googletag;
+ if (!gt) {
+ gt = window.googletag = {};
+ }
+
+ for (const [key, value] of Object.entries({
+ apiReady: true,
+ companionAds: () => companionAdsService,
+ content: () => contentService,
+ defineOutOfPageSlot: () => newSlot(),
+ defineSlot: () => newSlot(),
+ destroySlots: noopfn,
+ disablePublisherConsole: noopfn,
+ display,
+ enableServices: noopfn,
+ getVersion: noopstrfn,
+ pubads: () => pubadsService,
+ pubabsReady: true,
+ setAdIframeTitle: noopfn,
+ sizeMapping: () => newSizeMappingBuilder(),
+ })) {
+ gt[key] = value;
+ }
+
+ function runCmd(fn) {
+ try {
+ fn();
+ } catch (_) {}
+ return 1;
+ }
+
+ const cmds = gt.cmd;
+ const newCmd = [];
+ newCmd.push = runCmd;
+ gt.cmd = newCmd;
+
+ for (const cmd of cmds) {
+ runCmd(cmd);
+ }
+}
diff --git a/browser/extensions/webcompat/shims/live-test-shim.js b/browser/extensions/webcompat/shims/live-test-shim.js
new file mode 100644
index 0000000000..552020820f
--- /dev/null
+++ b/browser/extensions/webcompat/shims/live-test-shim.js
@@ -0,0 +1,84 @@
+/* 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/. */
+
+"use strict";
+
+/* globals browser */
+
+if (!window.LiveTestShimPromise) {
+ const originalUrl = document.currentScript.src;
+
+ const shimId = "LiveTestShim";
+
+ const sendMessageToAddon = (function() {
+ const pendingMessages = new Map();
+ const channel = new MessageChannel();
+ channel.port1.onerror = console.error;
+ channel.port1.onmessage = event => {
+ const { messageId, response } = event.data;
+ const resolve = pendingMessages.get(messageId);
+ if (resolve) {
+ pendingMessages.delete(messageId);
+ resolve(response);
+ }
+ };
+ function reconnect() {
+ const detail = {
+ pendingMessages: [...pendingMessages.values()],
+ port: channel.port2,
+ shimId,
+ };
+ window.dispatchEvent(new CustomEvent("ShimConnects", { detail }));
+ }
+ window.addEventListener("ShimHelperReady", reconnect);
+ reconnect();
+ return function(message) {
+ const messageId =
+ Math.random()
+ .toString(36)
+ .substring(2) + Date.now().toString(36);
+ return new Promise(resolve => {
+ const payload = {
+ message,
+ messageId,
+ shimId,
+ };
+ pendingMessages.set(messageId, resolve);
+ channel.port1.postMessage(payload);
+ });
+ };
+ })();
+
+ async function go(options) {
+ try {
+ const o = document.getElementById("shims");
+ const cl = o.classList;
+ cl.remove("red");
+ cl.add("green");
+ o.innerText = JSON.stringify(options || "");
+ } catch (_) {}
+
+ if (window !== top) {
+ return;
+ }
+
+ await sendMessageToAddon("optIn");
+
+ const s = document.createElement("script");
+ s.src = originalUrl;
+ document.head.appendChild(s);
+ }
+
+ window[`${shimId}Promise`] = sendMessageToAddon("getOptions").then(
+ options => {
+ if (document.readyState !== "loading") {
+ go(options);
+ } else {
+ window.addEventListener("DOMContentLoaded", () => {
+ go(options);
+ });
+ }
+ }
+ );
+}
diff --git a/browser/extensions/webcompat/shims/mochitest-shim-1.js b/browser/extensions/webcompat/shims/mochitest-shim-1.js
new file mode 100644
index 0000000000..d18e965f3c
--- /dev/null
+++ b/browser/extensions/webcompat/shims/mochitest-shim-1.js
@@ -0,0 +1,89 @@
+/* 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/. */
+
+"use strict";
+
+/* globals browser */
+
+if (!window.MochitestShimPromise) {
+ const originalUrl = document.currentScript.src;
+
+ const shimId = "MochitestShim";
+
+ const sendMessageToAddon = (function() {
+ const pendingMessages = new Map();
+ const channel = new MessageChannel();
+ channel.port1.onerror = console.error;
+ channel.port1.onmessage = event => {
+ const { messageId, response } = event.data;
+ const resolve = pendingMessages.get(messageId);
+ if (resolve) {
+ pendingMessages.delete(messageId);
+ resolve(response);
+ }
+ };
+ function reconnect() {
+ const detail = {
+ pendingMessages: [...pendingMessages.values()],
+ port: channel.port2,
+ shimId,
+ };
+ window.dispatchEvent(new CustomEvent("ShimConnects", { detail }));
+ }
+ window.addEventListener("ShimHelperReady", reconnect);
+ reconnect();
+ return function(message) {
+ const messageId =
+ Math.random()
+ .toString(36)
+ .substring(2) + Date.now().toString(36);
+ return new Promise(resolve => {
+ const payload = {
+ message,
+ messageId,
+ shimId,
+ };
+ pendingMessages.set(messageId, resolve);
+ channel.port1.postMessage(payload);
+ });
+ };
+ })();
+
+ async function go(options) {
+ try {
+ const o = document.getElementById("shims");
+ const cl = o.classList;
+ cl.remove("red");
+ cl.add("green");
+ o.innerText = JSON.stringify(options || "");
+ } catch (_) {}
+
+ window.shimPromiseResolve("shimmed");
+
+ if (window !== top) {
+ window.optInPromiseResolve(false);
+ return;
+ }
+
+ await sendMessageToAddon("optIn");
+
+ window.doingOptIn = true;
+ const s = document.createElement("script");
+ s.src = originalUrl;
+ s.onerror = () => window.optInPromiseResolve("error");
+ document.head.appendChild(s);
+ }
+
+ window[`${shimId}Promise`] = new Promise(resolve => {
+ sendMessageToAddon("getOptions").then(options => {
+ if (document.readyState !== "loading") {
+ resolve(go(options));
+ } else {
+ window.addEventListener("DOMContentLoaded", () => {
+ resolve(go(options));
+ });
+ }
+ });
+ });
+}
diff --git a/browser/extensions/webcompat/shims/mochitest-shim-2.js b/browser/extensions/webcompat/shims/mochitest-shim-2.js
new file mode 100644
index 0000000000..3b60038599
--- /dev/null
+++ b/browser/extensions/webcompat/shims/mochitest-shim-2.js
@@ -0,0 +1,87 @@
+/* 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/. */
+
+"use strict";
+
+/* globals browser */
+
+if (!window.testPromise) {
+ const originalUrl = document.currentScript.src;
+
+ const shimId = "MochitestShim2";
+
+ const sendMessageToAddon = (function() {
+ const pendingMessages = new Map();
+ const channel = new MessageChannel();
+ channel.port1.onerror = console.error;
+ channel.port1.onmessage = event => {
+ const { messageId, response } = event.data;
+ const resolve = pendingMessages.get(messageId);
+ if (resolve) {
+ pendingMessages.delete(messageId);
+ resolve(response);
+ }
+ };
+ function reconnect() {
+ const detail = {
+ pendingMessages: [...pendingMessages.values()],
+ port: channel.port2,
+ shimId,
+ };
+ window.dispatchEvent(new CustomEvent("ShimConnects", { detail }));
+ }
+ window.addEventListener("ShimHelperReady", reconnect);
+ reconnect();
+ return function(message) {
+ const messageId =
+ Math.random()
+ .toString(36)
+ .substring(2) + Date.now().toString(36);
+ return new Promise(resolve => {
+ const payload = {
+ message,
+ messageId,
+ shimId,
+ };
+ pendingMessages.set(messageId, resolve);
+ channel.port1.postMessage(payload);
+ });
+ };
+ })();
+
+ async function go(options) {
+ try {
+ const o = document.getElementById("shims");
+ const cl = o.classList;
+ cl.remove("red");
+ cl.add("green");
+ o.innerText = JSON.stringify(options || "");
+ } catch (_) {}
+
+ window.shimPromiseResolve("shimmed");
+
+ if (window !== top) {
+ window.optInPromiseResolve(false);
+ return;
+ }
+
+ await sendMessageToAddon("optIn");
+
+ window.doingOptIn = true;
+ const s = document.createElement("script");
+ s.src = originalUrl;
+ s.onerror = () => window.optInPromiseResolve("error");
+ document.head.appendChild(s);
+ }
+
+ sendMessageToAddon("getOptions").then(options => {
+ if (document.readyState !== "loading") {
+ go(options);
+ } else {
+ window.addEventListener("DOMContentLoaded", () => {
+ go(options);
+ });
+ }
+ });
+}
diff --git a/browser/extensions/webcompat/shims/mochitest-shim-3.js b/browser/extensions/webcompat/shims/mochitest-shim-3.js
new file mode 100644
index 0000000000..dc0a8005f5
--- /dev/null
+++ b/browser/extensions/webcompat/shims/mochitest-shim-3.js
@@ -0,0 +1,7 @@
+/* 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/. */
+
+"use strict";
+
+window.shimPromiseResolve("shimmed");
diff --git a/browser/extensions/webcompat/shims/rambler-authenticator.js b/browser/extensions/webcompat/shims/rambler-authenticator.js
new file mode 100644
index 0000000000..0554eabc2c
--- /dev/null
+++ b/browser/extensions/webcompat/shims/rambler-authenticator.js
@@ -0,0 +1,86 @@
+/* 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/. */
+
+"use strict";
+
+if (!window.ramblerIdHelper) {
+ const originalScript = document.currentScript.src;
+
+ const sendMessageToAddon = (function() {
+ const shimId = "Rambler";
+ const pendingMessages = new Map();
+ const channel = new MessageChannel();
+ channel.port1.onerror = console.error;
+ channel.port1.onmessage = event => {
+ const { messageId, response } = event.data;
+ const resolve = pendingMessages.get(messageId);
+ if (resolve) {
+ pendingMessages.delete(messageId);
+ resolve(response);
+ }
+ };
+ function reconnect() {
+ const detail = {
+ pendingMessages: [...pendingMessages.values()],
+ port: channel.port2,
+ shimId,
+ };
+ window.dispatchEvent(new CustomEvent("ShimConnects", { detail }));
+ }
+ window.addEventListener("ShimHelperReady", reconnect);
+ reconnect();
+ return function(message) {
+ const messageId =
+ Math.random()
+ .toString(36)
+ .substring(2) + Date.now().toString(36);
+ return new Promise(resolve => {
+ const payload = {
+ message,
+ messageId,
+ shimId,
+ };
+ pendingMessages.set(messageId, resolve);
+ channel.port1.postMessage(payload);
+ });
+ };
+ })();
+
+ const ramblerIdHelper = {
+ getProfileInfo: (successCallback, errorCallback) => {
+ successCallback({});
+ },
+ openAuth: () => {
+ sendMessageToAddon("optIn").then(function() {
+ const openAuthArgs = arguments;
+ window.ramblerIdHelper = undefined;
+ const s = document.createElement("script");
+ s.src = originalScript;
+ document.head.appendChild(s);
+ s.addEventListener("load", () => {
+ const helper = window.ramblerIdHelper;
+ for (const { fn, args } of callLog) {
+ helper[fn].apply(helper, args);
+ }
+ helper.openAuth.apply(helper, openAuthArgs);
+ });
+ });
+ },
+ };
+
+ const callLog = [];
+ function addLoggedCall(fn) {
+ ramblerIdHelper[fn] = () => {
+ callLog.push({ fn, args: arguments });
+ };
+ }
+
+ addLoggedCall("registerOnFrameCloseCallback");
+ addLoggedCall("registerOnFrameRedirect");
+ addLoggedCall("registerOnPossibleLoginCallback");
+ addLoggedCall("registerOnPossibleLogoutCallback");
+ addLoggedCall("registerOnPossibleOauthLoginCallback");
+
+ window.ramblerIdHelper = ramblerIdHelper;
+}
diff --git a/browser/extensions/webcompat/shims/rich-relevance.js b/browser/extensions/webcompat/shims/rich-relevance.js
new file mode 100644
index 0000000000..d7f2802ac9
--- /dev/null
+++ b/browser/extensions/webcompat/shims/rich-relevance.js
@@ -0,0 +1,30 @@
+/* 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/. */
+
+"use strict";
+
+/**
+ * Bug 1449347 - Rich Relevance
+ */
+
+"use strict";
+
+if (!window.r3_common) {
+ const noopfn = () => {};
+
+ window.rr_flush_onload = noopfn;
+ window.r3 = noopfn;
+ window.r3_home = noopfn;
+ window.RR = noopfn;
+ window.r3_common = function() {};
+ window.r3_common.prototype = {
+ addContext: noopfn,
+ addPlacementType: noopfn,
+ setUserId: noopfn,
+ setSessionId: noopfn,
+ setClickthruServer: noopfn,
+ setBaseUrl: noopfn,
+ setApiKey: noopfn,
+ };
+}