diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/about-compat/aboutPage.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/about-compat/aboutPage.js index e7195513321..97d6302543a 100644 --- a/components/feature/webcompat/src/main/assets/extensions/webcompat/about-compat/aboutPage.js +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/about-compat/aboutPage.js @@ -4,13 +4,9 @@ "use strict"; -/* global ExtensionAPI, Services, XPCOMUtils */ +/* global ExtensionAPI, XPCOMUtils */ -ChromeUtils.defineModuleGetter( - this, - "Services", - "resource://gre/modules/Services.jsm" -); +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); XPCOMUtils.defineLazyServiceGetter( this, diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/data/injections.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/data/injections.js index 52049ac9fac..ac1f19b3627 100644 --- a/components/feature/webcompat/src/main/assets/extensions/webcompat/data/injections.js +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/data/injections.js @@ -359,20 +359,6 @@ const AVAILABLE_INJECTIONS = [ allFrames: true, }, }, - { - id: "bug1711082", - platform: "all", - domain: "m.aliexpress.com", - bug: "1711082", - contentScripts: { - matches: ["*://m.aliexpress.com/*"], - js: [ - { - file: "injections/js/bug1711082-m.aliexpress.com-undisable-search.js", - }, - ], - }, - }, { id: "bug1712833", platform: "all", @@ -507,27 +493,18 @@ const AVAILABLE_INJECTIONS = [ ], }, }, - { - id: "bug1756692", - platform: "android", - domain: "zee5.com", - bug: "1756692", - contentScripts: { - matches: ["*://www.zee5.com/*"], - js: [ - { - file: "injections/js/bug1756692-effectiveType-shim.js", - }, - ], - }, - }, { id: "bug1739489", platform: "desktop", - domain: "draft.js", + domain: "Sites using draft.js", bug: "1739489", contentScripts: { - matches: ["*://draftjs.org/*", "*://www.facebook.com/*"], + matches: [ + "*://draftjs.org/*", // Bug 1739489 + "*://www.facebook.com/*", // Bug 1739489 + "*://twitter.com/*", // Bug 1776229 + "*://mobile.twitter.com/*", // Bug 1776229 + ], js: [ { file: "injections/js/bug1739489-draftjs-beforeinput.js", @@ -578,6 +555,36 @@ const AVAILABLE_INJECTIONS = [ ], }, }, + { + id: "bug1774490", + platform: "all", + domain: "rainews.it", + bug: "1774490", + contentScripts: { + matches: ["*://www.rainews.it/*"], + css: [ + { + file: "injections/css/bug1774490-rainews.it-gallery-fix.css", + }, + ], + }, + }, + { + id: "bug1774005", + platform: "all", + domain: "Sites relying on window.InstallTrigger", + bug: "1774005", + contentScripts: { + matches: [ + "*://*.pixiv.net/*", // Bug 1774006 + ], + js: [ + { + file: "injections/js/bug1774005-installtrigger-shim.js", + }, + ], + }, + }, ]; module.exports = AVAILABLE_INJECTIONS; diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/data/shims.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/data/shims.js index 321bbfade22..c0f071fd541 100644 --- a/components/feature/webcompat/src/main/assets/extensions/webcompat/data/shims.js +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/data/shims.js @@ -148,6 +148,25 @@ const AVAILABLE_SHIMS = [ ], onlyIfBlockedByETP: true, }, + { + id: "AdSafeProtectedFavIcon", + platform: "all", + name: "Ad Safe Protected favicon", + bug: "1717806", + matches: [ + { + patterns: ["*://static.adsafeprotected.com/favicon.ico"], + target: "https://redirect.firefox.etp/adsafeprotected_favicon", + types: ["image", "imageset", "xmlhttprequest"], + }, + { + patterns: ["https://redirect.firefox.etp/adsafeprotected_favicon"], + target: "tracking-pixel.png", + types: ["image", "imageset", "xmlhttprequest"], + }, + ], + onlyIfBlockedByETP: true, + }, { id: "AdSafeProtectedGoogleIMAAdapter", platform: "all", @@ -164,7 +183,35 @@ const AVAILABLE_SHIMS = [ name: "Ads by Google", bug: "1713726", file: "google-ads.js", - matches: ["*://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"], + matches: [ + "*://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js", + { + patterns: [ + "*://pagead2.googlesyndication.com/pagead/*.js*fcd=true", + "*://pagead2.googlesyndication.com/pagead/js/*.js*fcd=true", + ], + target: "empty-script.js", + types: ["xmlhttprequest"], + }, + ], + onlyIfBlockedByETP: true, + }, + { + id: "Branch", + platform: "all", + name: "Branch Web SDK", + bug: "1716220", + file: "branch.js", + matches: ["*://cdn.branch.io/branch-latest.min.js*"], + onlyIfBlockedByETP: true, + }, + { + id: "DoubleVerify", + platform: "all", + name: "DoubleVerify", + bug: "1771557", + file: "doubleverify.js", + matches: ["*://pub.doubleverify.com/signals/pub.js*"], onlyIfBlockedByETP: true, }, { @@ -247,6 +294,19 @@ const AVAILABLE_SHIMS = [ ], onlyIfBlockedByETP: true, }, + { + id: "PBMWebAPIFixes", + platform: "all", + name: "Private Browsing Web APIs", + bug: "1773110", + runFirst: "private-browsing-web-api-fixes.js", + matches: [ + "*://*.imgur.com/js/vendor.*.bundle.js", + "*://*.imgur.io/js/vendor.*.bundle.js", + "*://www.rva311.com/static/js/main.*.chunk.js", + ], + onlyIfPrivateBrowsing: true, + }, { id: "Eluminate", platform: "all", @@ -391,6 +451,15 @@ const AVAILABLE_SHIMS = [ }, ], }, + { + id: "IAM", + platform: "all", + name: "INFOnline IAM", + bug: "1761774", + file: "iam.js", + matches: ["*://script.ioam.de/iam.js"], + onlyIfBlockedByETP: true, + }, { id: "IASPET", platform: "all", @@ -426,13 +495,25 @@ const AVAILABLE_SHIMS = [ ], onlyIfBlockedByETP: true, }, + { + id: "Nielsen", + platform: "all", + name: "Nielsen", + bug: "1760754", + file: "nielsen.js", + matches: ["*://*.imrworldwide.com/v60.js"], + onlyIfBlockedByETP: true, + }, { id: "Optimizely", platform: "all", name: "Optimizely", bug: "1714431", file: "optimizely.js", - matches: ["*://cdn.optimizely.com/js/*.js"], + matches: [ + "*://cdn.optimizely.com/js/*.js", + "*://cdn.optimizely.com/public/*.js", + ], onlyIfBlockedByETP: true, }, { @@ -454,6 +535,19 @@ const AVAILABLE_SHIMS = [ matches: ["*://media.richrelevance.com/rrserver/js/1.2/p13n.js"], onlyIfBlockedByETP: true, }, + { + id: "Firebase", + platform: "all", + name: "Firebase", + bug: "1668408", + onlyIfPrivateBrowsing: true, + runFirst: "firebase.js", + matches: [ + "*://www.gstatic.com/firebasejs/*/firebase-messaging.js*", + "*://orangerie.eu/js/vendor*.js*", + "*://web.whatsapp.com/vendor*bootstrap_qr*.js*", + ], + }, { id: "StackBlitz", platform: "all", @@ -469,6 +563,28 @@ const AVAILABLE_SHIMS = [ }, ], }, + { + id: "StickyAdsTV", + platform: "all", + name: "StickyAdsTV", + bug: "1717806", + matches: [ + { + patterns: [ + "*://ads.stickyadstv.com/auto-user-sync*", + "*://ads.stickyadstv.com/user-matching*", + ], + target: "https://redirect.firefox.etp/stickadstv", + types: ["image", "imageset", "xmlhttprequest"], + }, + { + patterns: ["https://redirect.firefox.etp/stickadstv"], + target: "tracking-pixel.png", + types: ["image", "imageset", "xmlhttprequest"], + }, + ], + onlyIfBlockedByETP: true, + }, { id: "Vidible", branch: ["nightly"], diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/data/ua_overrides.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/data/ua_overrides.js index c5614c5556d..8d1ae487d95 100644 --- a/components/feature/webcompat/src/main/assets/extensions/webcompat/data/ua_overrides.js +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/data/ua_overrides.js @@ -716,6 +716,7 @@ const AVAILABLE_UA_OVERRIDES = [ matches: [ "*://*.commerzbank.de/*", // Bug 1767630 "*://*.edf.com/*", // Bug 1764786 + "*://*.ibmserviceengage.com/*", // #105438 "*://*.wordpress.org/*", // Bug 1743431 "*://as.eservice.asus.com/*", // #104113 "*://bethesda.net/*", // #94607, @@ -726,6 +727,7 @@ const AVAILABLE_UA_OVERRIDES = [ "*://mon.allianzbanque.fr/*", // #101074 "*://online.citi.com/*", // #101268 "*://simperium.com/*", // #98934 + "*://survey.sogosurvey.com/*", // Bug 1765925 "*://ubank.com.au/*", // #104099 "*://wifi.sncf/*", // #100194 "*://www.accringtonobserver.co.uk/*", // Bug 1762928 (Reach Plc) @@ -789,6 +791,7 @@ const AVAILABLE_UA_OVERRIDES = [ "*://www.leeds-live.co.uk/*", // Bug 1762928 (Reach Plc) "*://www.leicestermercury.co.uk/*", // Bug 1762928 (Reach Plc) "*://www.lincolnshirelive.co.uk/*", // Bug 1762928 (Reach Plc) + "*://www.liveobserverpark.com/*", // #105244 "*://www.liverpool.com/*", // Bug 1762928 (Reach Plc) "*://www.liverpoolecho.co.uk/*", // Bug 1762928 (Reach Plc) "*://www.loughboroughecho.net/*", // Bug 1762928 (Reach Plc) @@ -811,7 +814,6 @@ const AVAILABLE_UA_OVERRIDES = [ "*://www.southportvisiter.co.uk/*", // Bug 1762928 (Reach Plc) "*://www.staffordshire-live.co.uk/*", // Bug 1762928 (Reach Plc) "*://www.stokesentinel.co.uk/*", // Bug 1762928 (Reach Plc) - "*://survey.sogosurvey.com/*", // Bug 1765925 "*://www.sussexlive.co.uk/*", // Bug 1762928 (Reach Plc) "*://www.tm-awx.com/*", // Bug 1762928 (Reach Plc) "*://www.walesonline.co.uk/*", // Bug 1762928 (Reach Plc) diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/injections/css/bug1774490-rainews.it-gallery-fix.css b/components/feature/webcompat/src/main/assets/extensions/webcompat/injections/css/bug1774490-rainews.it-gallery-fix.css new file mode 100644 index 00000000000..95dbf219c94 --- /dev/null +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/injections/css/bug1774490-rainews.it-gallery-fix.css @@ -0,0 +1,9 @@ +/** + * rainews.it - Image slideshow is not shown + * Bug #1774490 - https://bugzilla.mozilla.org/show_bug.cgi?id=1774490 + * WebCompat issue #105402 - https://webcompat.com/issues/105402 + */ + +.photogallery-swiper .swiper-slide { + height: auto; +} diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/injections/js/bug1711082-m.aliexpress.com-undisable-search.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/injections/js/bug1711082-m.aliexpress.com-undisable-search.js deleted file mode 100644 index 1fc0b3acaf3..00000000000 --- a/components/feature/webcompat/src/main/assets/extensions/webcompat/injections/js/bug1711082-m.aliexpress.com-undisable-search.js +++ /dev/null @@ -1,34 +0,0 @@ -"use strict"; - -/** - * Bug 1711082 - Cannot trigger search bar on AliExpress mobile page - * - * This patch ensures that the search input never has the [disabled] - * attribute, so that users may tap/click on it to search. - * - * See https://bugzilla.mozilla.org/show_bug.cgi?id=1711082 for details. - */ - -const SELECTOR = `[data-spm="header"] input[disabled]`; - -function check(target) { - if (target.nodeName === "INPUT" && target.matches(SELECTOR)) { - target.removeAttribute("disabled"); - return true; - } - return false; -} - -new MutationObserver(mutations => { - for (const { addedNodes, target, attributeName } of mutations) { - if (attributeName === "disabled") { - check(target); - } else { - addedNodes?.forEach(node => { - if (!check(node)) { - node.querySelector?.(SELECTOR)?.removeAttribute("disabled"); - } - }); - } - } -}).observe(document, { attributes: true, childList: true, subtree: true }); diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/injections/js/bug1756692-effectiveType-shim.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/injections/js/bug1756692-effectiveType-shim.js deleted file mode 100644 index d12be6305c7..00000000000 --- a/components/feature/webcompat/src/main/assets/extensions/webcompat/injections/js/bug1756692-effectiveType-shim.js +++ /dev/null @@ -1,23 +0,0 @@ -"use strict"; - -/** - * Bug 1756692 - Issues due to missing navigator.connection after - * https://bugzilla.mozilla.org/show_bug.cgi?id=1637922 landed. - * Webcompat issue #99671 - https://github.com/webcompat/web-bugs/issues/99671 - */ - -/* globals cloneInto, exportFunction */ - -console.info( - "navigator.connection has been shimmed for compatibility reasons. See https://bugzilla.mozilla.org/show_bug.cgi?id=1756692 for details." -); - -var connection = { - addEventListener: () => {}, - removeEventListener: () => {}, - effectiveType: "4g", -}; - -window.navigator.wrappedJSObject.connection = cloneInto(connection, window, { - cloneFunctions: true, -}); diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/injections/js/bug1774005-installtrigger-shim.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/injections/js/bug1774005-installtrigger-shim.js new file mode 100644 index 00000000000..750a72d051a --- /dev/null +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/injections/js/bug1774005-installtrigger-shim.js @@ -0,0 +1,22 @@ +"use strict"; + +/** + * Bug 1774005 - Generic window.InstallTrigger shim + * + * This interventions shims window.InstallTrigger to a string, which evaluates + * as `true` in web developers browser sniffing code. This intervention will + * be applied to multiple domains, see bug 1774005 for more information. + */ + +/* globals exportFunction */ + +console.info( + "The InstallTrigger has been shimmed for compatibility reasons. See https://bugzilla.mozilla.org/show_bug.cgi?id=1774005 for details." +); + +Object.defineProperty(window.wrappedJSObject, "InstallTrigger", { + get: exportFunction(function() { + return "This property has been shimed for Web Compatibility reasons."; + }, window), + set: exportFunction(function(_) {}, window), +}); diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/lib/shims.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/lib/shims.js index a129bb752ba..d0979576c4f 100644 --- a/components/feature/webcompat/src/main/assets/extensions/webcompat/lib/shims.js +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/lib/shims.js @@ -53,9 +53,11 @@ class Shim { this.notHosts = opts.notHosts; this.onlyIfBlockedByETP = opts.onlyIfBlockedByETP; this.onlyIfDFPIActive = opts.onlyIfDFPIActive; + this.onlyIfPrivateBrowsing = opts.onlyIfPrivateBrowsing; this._options = opts.options || {}; this.needsShimHelpers = opts.needsShimHelpers; this.platform = opts.platform || "all"; + this.runFirst = opts.runFirst; this.unblocksOnOptIn = unblocksOnOptIn; this.requestStorageAccessForRedirect = opts.requestStorageAccessForRedirect; @@ -519,7 +521,7 @@ class Shims { if (shim.isGoogleTrendsDFPIFix) { addTypePatterns(type, patterns, allHeaderChangingMatchTypePatterns); } - if (target || shim.file) { + if (target || shim.file || shim.runFirst) { addTypePatterns(type, patterns, allMatchTypePatterns); } } @@ -909,13 +911,19 @@ class Shims { for (const shim of this.shims.values()) { await shim.ready; - if (!shim.enabled || !shim.redirectsRequests) { + if (!shim.enabled || (!shim.redirectsRequests && !shim.runFirst)) { continue; } - if (shim.onlyIfDFPIActive) { + if (shim.onlyIfDFPIActive || shim.onlyIfPrivateBrowsing) { const isPB = (await browser.tabs.get(details.tabId)).incognito; - if (!(await browser.trackingProtection.isDFPIActive(isPB))) { + if (!isPB && shim.onlyIfPrivateBrowsing) { + continue; + } + if ( + shim.onlyIfDFPIActive && + !(await browser.trackingProtection.isDFPIActive(isPB)) + ) { continue; } } @@ -947,6 +955,8 @@ class Shims { } } + let runFirst = false; + if (shimToApply) { // Note that sites may request the same shim twice, but because the requests // may differ enough for some to fail (CSP/CORS/etc), we always let the request @@ -954,18 +964,32 @@ class Shims { const { target } = match; const { bug, file, id, name, needsShimHelpers } = shimToApply; + runFirst = shimToApply.runFirst; const redirect = target || file; warn( - `Shimming tracking ${type} ${url} on tab ${tabId} frame ${frameId} with ${redirect}` + `Shimming tracking ${type} ${url} on tab ${tabId} frame ${frameId} with ${redirect || + runFirst}` ); const warning = `${name} is being shimmed by Firefox. See https://bugzilla.mozilla.org/show_bug.cgi?id=${bug} for details.`; - try { - // For scripts, we also set up any needed shim helpers. - if (type === "script" && needsShimHelpers?.length) { + let needConsoleMessage = true; + + if (runFirst) { + try { + await browser.tabs.executeScript(tabId, { + file: `/shims/${runFirst}`, + frameId, + runAt: "document_start", + }); + } catch (_) {} + } + + // For scripts, we also set up any needed shim helpers. + if (type === "script" && needsShimHelpers?.length) { + try { await browser.tabs.executeScript(tabId, { file: "/lib/shim_messaging_helper.js", frameId, @@ -977,14 +1001,23 @@ class Shims { { origin, shimId: id, needsShimHelpers, warning }, { frameId } ); + needConsoleMessage = false; shimToApply.setActiveOnTab(tabId); - } else { + } catch (_) {} + } + + if (needConsoleMessage) { + try { await browser.tabs.executeScript(tabId, { code: `console.warn(${JSON.stringify(warning)})`, runAt: "document_start", }); - } - } catch (_) {} + } catch (_) {} + } + + if (!redirect.indexOf("http://") || !redirect.indexOf("https://")) { + return { redirectUrl: redirect }; + } // If any shims matched the request to replace it, then redirect to the local // file bundled with SmartBlock, so the request never hits the network. @@ -998,7 +1031,9 @@ class Shims { return { cancel: true }; } - debug(`ignoring ${url} on tab ${tabId} frame ${frameId}`); + if (!runFirst) { + debug(`ignoring ${url} on tab ${tabId} frame ${frameId}`); + } return undefined; } } diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/manifest.json b/components/feature/webcompat/src/main/assets/extensions/webcompat/manifest.json index 7a06c0bebd4..7906d11afdd 100644 --- a/components/feature/webcompat/src/main/assets/extensions/webcompat/manifest.json +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "Mozilla Android Components - Web Compatibility Interventions", "description": "Urgent post-release fixes for web compatibility.", - "version": "102.0.0", + "version": "103.0.0", "applications": { "gecko": { "id": "webcompat@mozilla.org", @@ -98,15 +98,18 @@ "shims/adsafeprotected-ima.js", "shims/apstag.js", "shims/bmauth.js", + "shims/branch.js", "shims/chartbeat.js", "shims/crave-ca.js", "shims/criteo.js", "shims/cxense.js", + "shims/doubleverify.js", "shims/eluminate.js", "shims/empty-script.js", "shims/empty-shim.txt", "shims/facebook-sdk.js", "shims/facebook.svg", + "shims/firebase.js", "shims/google-ads.js", "shims/google-analytics-and-tag-manager.js", "shims/google-analytics-ecommerce-plugin.js", @@ -118,6 +121,7 @@ "shims/hamropatro.js", "shims/history.js", "shims/humblebundle.js", + "shims/iam.js", "shims/iaspet.js", "shims/kinja.js", "shims/live-test-shim.js", @@ -127,8 +131,10 @@ "shims/mochitest-shim-1.js", "shims/mochitest-shim-2.js", "shims/mochitest-shim-3.js", + "shims/nielsen.js", "shims/optimizely.js", "shims/play.svg", + "shims/private-browsing-web-api-fixes.js", "shims/rambler-authenticator.js", "shims/rich-relevance.js", "shims/stackblitz.js", diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/apstag.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/apstag.js index 5cc00a7e015..7232d3f68c2 100644 --- a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/apstag.js +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/apstag.js @@ -36,7 +36,9 @@ if (!window.apstag?._getSlotIdToNameMapping) { if (!Array.isArray(cfg?.slots)) { return; } - cb(cfg.slots.map(s => newBid(s))); + setTimeout(() => { + cb(cfg.slots.map(s => newBid(s))); + }, 1); }, init() {}, punt() {}, diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/branch.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/branch.js new file mode 100644 index 00000000000..404ab78a8f3 --- /dev/null +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/branch.js @@ -0,0 +1,81 @@ +/* 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 1716220 - Shim Branch Web SDK + * + * Sites such as TataPlay may not load properly if Branch Web SDK is + * blocked. This shim stubs out its script so the page still loads. + */ + +if (!window?.branch?.b) { + const queue = window?.branch?._q || []; + window.branch = new (class { + V = {}; + g = 0; + X = "web2.62.0"; + b = { + A: {}, + clear() {}, + get() {}, + getAll() {}, + isEnabled: () => true, + remove() {}, + set() {}, + ca() {}, + g: [], + l: 0, + o: 0, + s: null, + }; + addListener() {} + applyCode() {} + autoAppIndex() {} + banner() {} + c() {} + closeBanner() {} + closeJourney() {} + constructor() {} + creditHistory() {} + credits() {} + crossPlatformIds() {} + data() {} + deepview() {} + deepviewCta() {} + disableTracking() {} + first() {} + getBrowserFingerprintId() {} + getCode() {} + init(key, cb) { + cb?.(undefined, {}); + } + lastAttributedTouchData() {} + link() {} + logEvent() {} + logout() {} + qrCode() {} + redeem() {} + referrals() {} + removeListener() {} + renderFinalize() {} + renderQueue() {} + sendSMS() {} + setAPIResponseCallback() {} + setBranchViewData() {} + setIdentity() {} + track() {} + trackCommerceEvent() {} + validateCode() {} + })(); + const push = (fn, args) => { + try { + window.branch[fn].apply(window.branch, args); + } catch (e) { + console.error(e); + } + }; + queue.forEach(push); +} diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/doubleverify.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/doubleverify.js new file mode 100644 index 00000000000..7f9ff42dce0 --- /dev/null +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/doubleverify.js @@ -0,0 +1,36 @@ +/* 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 1771557 - Shim DoubleVerify analytics + * + * Some sites such as Sports Illustrated expect DoubleVerify's + * analytics script to load, otherwise odd breakage may occur. + * This shim helps mitigate such breakage. + */ + +if (!window?.PQ?.loaded) { + const cmd = []; + cmd.push = function(c) { + try { + c?.(); + } catch (_) {} + }; + + window.apntag = { + anq: [], + }; + + window.PQ = { + cmd, + loaded: true, + getTargeting: (_, cb) => cb?.([]), + init: () => {}, + loadSignals: (_, cb) => cb?.(), + loadSignalsForSlots: (_, cb) => cb?.(), + PTS: {}, + }; +} diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/eluminate.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/eluminate.js index 37566ff9fd5..3fa65c048c2 100644 --- a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/eluminate.js +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/eluminate.js @@ -59,4 +59,37 @@ if (!window.CM_DDX) { w.cmSetupNormalization = noopfn; w.cmSetupOther = noopfn; w.cmStartTagSet = noopfn; + w.cmCreateConversionEventTag = noopfn; + w.cmCreateDefaultPageviewTag = noopfn; + w.cmCreateElementTag = noopfn; + w.cmCreateManualImpressionTag = noopfn; + w.cmCreateManualLinkClickTag = noopfn; + w.cmCreateManualPageviewTag = noopfn; + w.cmCreatePageElementTag = noopfn; + w.cmCreatePageviewTag = noopfn; + w.cmCreateProductElementTag = noopfn; + w.cmCreateProductviewTag = noopfn; + w.cmCreateTechPropsTag = noopfn; + w.cmLoadIOConfig = noopfn; + w.cmSetClientID = noopfn; + w.cmSetCurrencyCode = noopfn; + w.cmSetFirstPartyIDs = noopfn; + w.cmSetupCookieMigration = noopfn; + w.cmSetupNormalization = noopfn; + + w.cmSetupOther = b => { + for (const a in b) { + window[a] = b[a]; + } + }; + + const techProps = {}; + + w.coremetrics = { + cmLastReferencedPageID: "", + cmLoad: noopfn, + cmUpdateConfig: noopfn, + getTechProps: () => techProps, + isDef: c => typeof c !== "undefined" && c, + }; } diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/facebook-sdk.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/facebook-sdk.js index 4a4dc2db0a1..142f10ae334 100644 --- a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/facebook-sdk.js +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/facebook-sdk.js @@ -83,7 +83,7 @@ if (!window.FB) { // which try to match the examples and documentation here: // https://developers.facebook.com/docs/facebook-login/web/login-button/ - if (target.hasAttribute("fb-xfbml-state")) { + if (target.textContent || target.hasAttribute("fb-xfbml-state")) { return; } target.setAttribute("fb-xfbml-state", ""); @@ -392,6 +392,8 @@ if (!window.FB) { }, AppEvents: { activateApp() {}, + clearAppVersion() {}, + clearUserID() {}, EventNames: { ACHIEVED_LEVEL: "fb_mobile_level_achieved", ADDED_PAYMENT_INFO: "fb_mobile_add_payment_info", @@ -407,7 +409,11 @@ if (!window.FB) { UNLOCKED_ACHIEVEMENT: "fb_mobile_achievement_unlocked", VIEWED_CONTENT: "fb_mobile_content_view", }, + getAppVersion: () => "", + getUserID: () => "", + logEvent() {}, logPageView() {}, + logPurchase() {}, ParameterNames: { APP_USER_ID: "_app_user_id", APP_VERSION: "_appVersion", @@ -423,6 +429,9 @@ if (!window.FB) { SEARCH_STRING: "fb_search_string", SUCCESS: "fb_success", }, + setAppVersion() {}, + setUserID() {}, + updateUserProperties() {}, }, Canvas: { getHash: () => "", diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/firebase.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/firebase.js new file mode 100644 index 00000000000..b2ea5c54dfd --- /dev/null +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/firebase.js @@ -0,0 +1,39 @@ +/* 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 1767407 - Shim Firebase + * + * Sites relying on firebase-messaging.js will break in Private + * browsing mode because it assumes that they require service + * workers and indexedDB, when they generally do not. + */ + +/* globals cloneInto */ + +if (!window.wrappedJSObject.serviceWorker) { + const win = window.wrappedJSObject; + const emptyArr = new win.Array(); + const emptyMsg = cloneInto({ message: "" }, window); + + const idb = { + open: () => win.Promise.reject(emptyMsg), + }; + + const sw = { + addEventListener() {}, + getRegistrations: () => win.Promise.resolve(emptyArr), + register: () => win.Promise.reject(emptyMsg), + }; + + Object.defineProperty(win, "indexedDB", { + value: cloneInto(idb, window, { cloneFunctions: true }), + }); + + Object.defineProperty(navigator.wrappedJSObject, "serviceWorker", { + value: cloneInto(sw, window, { cloneFunctions: true }), + }); +} diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/google-ads.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/google-ads.js index b3ab38aa95e..a432186f43b 100644 --- a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/google-ads.js +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/google-ads.js @@ -71,3 +71,7 @@ if (window.gapi?._pl === undefined) { zoomableimage: stub, }; } + +for (const e of document.querySelectorAll("ins.adsbygoogle")) { + e.style.maxWidth = "0px"; +} diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/google-analytics-and-tag-manager.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/google-analytics-and-tag-manager.js index cde4aa61c1a..135b25a4989 100644 --- a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/google-analytics-and-tag-manager.js +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/google-analytics-and-tag-manager.js @@ -174,3 +174,14 @@ if (window[window.GoogleAnalyticsObject || "ga"]?.loaded === undefined) { // Run dataLayer.hide.end to handle asynchide (bug 1628151) run(window.dataLayer?.hide?.end); } + +if (!window?.gaplugins?.Linker) { + window.gaplugins = window.gaplugins || {}; + window.gaplugins.Linker = class { + autoLink() {} + decorate(url) { + return url; + } + passthrough() {} + }; +} diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/google-ima.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/google-ima.js index 0909b20cf73..d05538125ec 100644 --- a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/google-ima.js +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/google-ima.js @@ -12,7 +12,204 @@ */ if (!window.google?.ima?.VERSION) { - const VERSION = "3.453.0"; + const VERSION = "3.517.2"; + + const CheckCanAutoplay = (function() { + // Sourced from: https://searchfox.org/mozilla-central/source/dom/media/gtest/negative_duration.mp4 + const TEST_VIDEO = new Blob( + [ + new Uint32Array([ + 469762048, + 1887007846, + 1752392036, + 0, + 913273705, + 1717987696, + 828601953, + -1878917120, + 1987014509, + 1811939328, + 1684567661, + 0, + 0, + 0, + -402456576, + 0, + 256, + 1, + 0, + 0, + 256, + 0, + 0, + 0, + 256, + 0, + 0, + 0, + 64, + 0, + 0, + 0, + 0, + 0, + 0, + 33554432, + -201261056, + 1801548404, + 1744830464, + 1684564852, + 251658241, + 0, + 0, + 0, + 0, + 16777216, + 0, + -1, + -1, + 0, + 0, + 0, + 0, + 256, + 0, + 0, + 0, + 256, + 0, + 0, + 0, + 64, + 5, + 53250, + -2080309248, + 1634296941, + 738197504, + 1684563053, + 1, + 0, + 0, + 0, + 0, + -2137614336, + -1, + -1, + 50261, + 754974720, + 1919706216, + 0, + 0, + 1701079414, + 0, + 0, + 0, + 1701079382, + 1851869295, + 1919249508, + 16777216, + 1852402979, + 102, + 1752004116, + 100, + 1, + 0, + 0, + 1852400676, + 102, + 1701995548, + 102, + 0, + 1, + 1819440396, + 32, + 1, + 1651799011, + 108, + 1937011607, + 100, + 0, + 1, + 1668702599, + 49, + 0, + 1, + 0, + 0, + 0, + 33555712, + 4718800, + 4718592, + 0, + 65536, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16776984, + 1630601216, + 21193590, + -14745500, + 1729626337, + -1407254428, + 89161945, + 1049019, + 9453056, + -251611125, + 27269507, + -379058688, + -1329024392, + 268435456, + 1937011827, + 0, + 0, + 268435456, + 1668510835, + 0, + 0, + 335544320, + 2054386803, + 0, + 0, + 0, + 268435456, + 1868788851, + 0, + 0, + 671088640, + 2019915373, + 536870912, + 2019914356, + 0, + 16777216, + 16777216, + 0, + 0, + 0, + ]), + ], + { type: "video/mp4" } + ); + + let testVideo = undefined; + + return function() { + if (!testVideo) { + testVideo = document.createElement("video"); + testVideo.style = + "position:absolute; width:0; height:0; left:0; right:0; z-index:-1; border:0"; + testVideo.setAttribute("muted", "muted"); + testVideo.setAttribute("playsinline", "playsinline"); + testVideo.src = URL.createObjectURL(TEST_VIDEO); + document.body.appendChild(testVideo); + } + return testVideo.play(); + }; + })(); let ima = {}; @@ -95,8 +292,6 @@ if (!window.google?.ima?.VERSION) { INSECURE: 2, }; - let managerLoaded = false; - class EventHandler { #listeners = new Map(); @@ -134,13 +329,24 @@ if (!window.google?.ima?.VERSION) { return VERSION; } requestAds(r, c) { - if (!managerLoaded) { - managerLoaded = true; - requestAnimationFrame(() => { + // If autoplay is disabled and the page is trying to autoplay a tracking + // ad, then IMA fails with an error, and the page is expected to request + // ads again later when the user clicks to play. + CheckCanAutoplay.then( + () => { const { ADS_MANAGER_LOADED } = AdsManagerLoadedEvent.Type; this._dispatch(new ima.AdsManagerLoadedEvent(ADS_MANAGER_LOADED)); - }); - } + }, + () => { + const e = new ima.AdError( + "adPlayError", + 1205, + 1205, + "The browser prevented playback initiated without user interaction." + ); + this._dispatch(new ima.AdErrorEvent(e)); + } + ); } } @@ -360,21 +566,31 @@ if (!window.google?.ima?.VERSION) { } class AdError { + #errorCode = -1; + #message = ""; + #type = ""; + #vastErrorCode = -1; + constructor(type, code, vast, message) { + this.#errorCode = code; + this.#message = message; + this.#type = type; + this.#vastErrorCode = vast; + } getErrorCode() { - return 0; + return this.#errorCode; } getInnerError() {} getMessage() { - return ""; + return this.#message; } getType() { - return ""; + return this.#type; } getVastErrorCode() { - return 0; + return this.#vastErrorCode; } toString() { - return ""; + return `AdError ${this.#errorCode}: ${this.#message}`; } } AdError.ErrorCode = {}; @@ -440,7 +656,14 @@ if (!window.google?.ima?.VERSION) { }; class AdErrorEvent { - getError() {} + type = "adError"; + #error = ""; + constructor(error) { + this.#error = error; + } + getError() { + return this.#error; + } getUserRequestContext() { return {}; } diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/google-publisher-tags.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/google-publisher-tags.js index 709c5af3b79..2480c9539f9 100644 --- a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/google-publisher-tags.js +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/google-publisher-tags.js @@ -32,7 +32,7 @@ if (window.googletag?.apiReady === undefined) { requestAnimationFrame(() => { const size = [0, 0]; for (const cb of eventCallbacks.get(name) || []) { - cb({ isEmpty: false, size, slot }); + cb({ isEmpty: true, size, slot }); } resolve(); }); @@ -49,6 +49,8 @@ if (window.googletag?.apiReady === undefined) { f.srcdoc = ""; f.style = "position:absolute; width:0; height:0; left:0; right:0; z-index:-1; border:0"; + f.setAttribute("width", 0); + f.setAttribute("height", 0); node.appendChild(f); } }; @@ -94,6 +96,13 @@ if (window.googletag?.apiReady === undefined) { return this; }; + const removeEventListener = function(name, listener) { + if (eventCallbacks.has(name)) { + return eventCallbacks.get(name).delete(listener); + } + return false; + }; + const companionAdsService = { addEventListener, display, @@ -112,6 +121,7 @@ if (window.googletag?.apiReady === undefined) { notifyUnfilledSlots() {}, onImplementationLoaded() {}, refreshAllSlots() {}, + removeEventListener, set() {}, setRefreshUnfilledSlots() {}, setVideoSession() {}, @@ -121,6 +131,7 @@ if (window.googletag?.apiReady === undefined) { const contentService = { addEventListener, setContent() {}, + removeEventListener, }; const getTargetingValue = v => { @@ -143,6 +154,10 @@ if (window.googletag?.apiReady === undefined) { }; const newSlot = (adUnitPath, size, opt_div) => { + if (slotsById.has(opt_div)) { + document.getElementById(opt_div)?.remove(); + return undefined; + } const attributes = new Map(); const targeting = new Map(); const exclusions = new Set(); @@ -318,6 +333,7 @@ if (window.googletag?.apiReady === undefined) { } } }, + removeEventListener, set(k, v) { gAttributes[k] = v; return this; diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/iam.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/iam.js new file mode 100644 index 00000000000..84dee0e484d --- /dev/null +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/iam.js @@ -0,0 +1,39 @@ +/* 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 1761774 - Shim INFOnline IAM tracker + * + * Sites using IAM can break if it is blocked. This shim mitigates that + * breakage by loading a stand-in module. + */ + +if (!window.iom?.c) { + window.iom = { + c: () => {}, + consent: () => {}, + count: () => {}, + ct: () => {}, + deloptout: () => {}, + doo: () => {}, + e: () => {}, + event: () => {}, + getInvitation: () => {}, + getPlus: () => {}, + gi: () => {}, + gp: () => {}, + h: () => {}, + hybrid: () => {}, + i: () => {}, + init: () => {}, + oi: () => {}, + optin: () => {}, + setMultiIdentifier: () => {}, + setoptout: () => {}, + smi: () => {}, + soo: () => {}, + }; +} diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/nielsen.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/nielsen.js new file mode 100644 index 00000000000..5584a126cb2 --- /dev/null +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/nielsen.js @@ -0,0 +1,114 @@ +/* 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 1760754 - Shim Nielsen tracker + * + * Sites expecting the Nielsen tracker to load properly can break if it + * is blocked. This shim mitigates that breakage by loading a stand-in. + */ + +if (!window.nol_t) { + const cid = ""; + + let domain = ""; + let schemeHost = ""; + let scriptName = ""; + try { + const url = document?.currentScript?.src; + const { pathname, protocol, host } = new URL(url); + domain = host + .split(".") + .slice(0, -2) + .join("."); + schemeHost = `${protocol}//${host}/`; + scriptName = pathname.split("/").pop(); + } catch (_) {} + + const NolTracker = class { + CONST = { + max_tags: 20, + }; + feat = {}; + globals = { + cid, + content: "0", + defaultApidFile: "config250", + defaultErrorParams: { + nol_vcid: "c00", + nol_clientid: "", + }, + domain, + fpidSfCodeList: [""], + init() {}, + tagCurrRetry: -1, + tagMaxRetry: 3, + wlCurrRetry: -1, + wlMaxRetry: 3, + }; + pmap = []; + pvar = { + cid, + content: "0", + cookies_enabled: "n", + server: domain, + }; + scriptName = [scriptName]; + version = "6.0.107"; + + addScript() {} + catchLinkOverlay() {} + clickEvent() {} + clickTrack() {} + do_sample() {} + downloadEvent() {} + eventTrack() {} + filter() {} + fireToUrl() {} + getSchemeHost() { + return schemeHost; + } + getVersion() {} + iframe() {} + in_sample() { + return true; + } + injectBsdk() {} + invite() {} + linkTrack() {} + mergeFeatures() {} + pageEvent() {} + pause() {} + populateWhitelist() {} + post() {} + postClickTrack() {} + postData() {} + postEvent() {} + postEventTrack() {} + postLinkTrack() {} + prefix() { + return ""; + } + processDdrsSvc() {} + random() {} + record() { + return this; + } + regLinkOverlay() {} + regListen() {} + retrieveCiFileViaCors() {} + sectionEvent() {} + sendALink() {} + sendForm() {} + sendIt() {} + slideEvent() {} + whitelistAssigned() {} + }; + + window.nol_t = () => { + return new NolTracker(); + }; +} diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/private-browsing-web-api-fixes.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/private-browsing-web-api-fixes.js new file mode 100644 index 00000000000..bc45aeda26a --- /dev/null +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/private-browsing-web-api-fixes.js @@ -0,0 +1,17 @@ +/* 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 1714354 - Fix for site issues with web APIs in private browsing + * + * Some sites expect specific DOM APIs to work in specific ways, which + * is not always true, such as in private browsing mode. We work around + * related breakage by undefining those APIs entirely in private + * browsing mode for those sites. + */ + +delete window.wrappedJSObject.caches; +delete window.wrappedJSObject.indexedDB; diff --git a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/rich-relevance.js b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/rich-relevance.js index c1e7e686ee8..aea85c030a9 100644 --- a/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/rich-relevance.js +++ b/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/rich-relevance.js @@ -190,7 +190,11 @@ if (!window.r3_common) { charset: "UTF-8", checkParamCookieValue: () => null, d: document, - data: { JSON }, + data: { + JSON: { + placements: [], + }, + }, debugWindow() {}, set defaultCallback(fn) { call(fn);