Bug 1568636 - Import WebCompat GoFaster 5.0.2 sources r=denschub,rhelmer

Differential Revision: https://phabricator.services.mozilla.com/D39351

--HG--
rename : browser/extensions/webcompat/AboutCompat.jsm => browser/extensions/webcompat/about-compat/AboutCompat.jsm
rename : browser/extensions/webcompat/aboutCompat.css => browser/extensions/webcompat/about-compat/aboutCompat.css
rename : browser/extensions/webcompat/aboutCompat.html => browser/extensions/webcompat/about-compat/aboutCompat.html
rename : browser/extensions/webcompat/aboutCompat.js => browser/extensions/webcompat/about-compat/aboutCompat.js
rename : browser/extensions/webcompat/aboutPage.js => browser/extensions/webcompat/about-compat/aboutPage.js
rename : browser/extensions/webcompat/aboutPage.json => browser/extensions/webcompat/about-compat/aboutPage.json
rename : browser/extensions/webcompat/aboutPageProcessScript.js => browser/extensions/webcompat/about-compat/aboutPageProcessScript.js
rename : browser/extensions/webcompat/ua_overrides.js => browser/extensions/webcompat/data/ua_overrides.js
rename : browser/extensions/webcompat/aboutConfigPrefs.js => browser/extensions/webcompat/experiment-apis/aboutConfigPrefs.js
rename : browser/extensions/webcompat/aboutConfigPrefs.json => browser/extensions/webcompat/experiment-apis/aboutConfigPrefs.json
rename : browser/extensions/webcompat/injections/css/bug0000000-dummy-css-injection.css => browser/extensions/webcompat/injections/css/bug0000000-testbed-css-injection.css
rename : mobile/android/extensions/webcompat/injections/js/bug0000000-dummy-js-injection.js => browser/extensions/webcompat/injections/js/bug0000000-testbed-js-injection.js
rename : mobile/android/extensions/webcompat/AboutCompat.jsm => mobile/android/extensions/webcompat/about-compat/AboutCompat.jsm
rename : browser/extensions/webcompat/aboutCompat.css => mobile/android/extensions/webcompat/about-compat/aboutCompat.css
rename : mobile/android/extensions/webcompat/aboutCompat.html => mobile/android/extensions/webcompat/about-compat/aboutCompat.html
rename : mobile/android/extensions/webcompat/aboutCompat.js => mobile/android/extensions/webcompat/about-compat/aboutCompat.js
rename : mobile/android/extensions/webcompat/aboutPage.js => mobile/android/extensions/webcompat/about-compat/aboutPage.js
rename : browser/extensions/webcompat/aboutPage.json => mobile/android/extensions/webcompat/about-compat/aboutPage.json
rename : browser/extensions/webcompat/aboutPageProcessScript.js => mobile/android/extensions/webcompat/about-compat/aboutPageProcessScript.js
rename : mobile/android/extensions/webcompat/ua_overrides.js => mobile/android/extensions/webcompat/data/ua_overrides.js
rename : browser/extensions/webcompat/aboutConfigPrefs.js => mobile/android/extensions/webcompat/experiment-apis/aboutConfigPrefs.js
rename : browser/extensions/webcompat/aboutConfigPrefs.json => mobile/android/extensions/webcompat/experiment-apis/aboutConfigPrefs.json
rename : browser/extensions/webcompat/injections/css/bug0000000-dummy-css-injection.css => mobile/android/extensions/webcompat/injections/css/bug0000000-testbed-css-injection.css
rename : mobile/android/extensions/webcompat/injections/js/bug0000000-dummy-js-injection.js => mobile/android/extensions/webcompat/injections/js/bug0000000-testbed-js-injection.js
extra : moz-landing-system : lando
This commit is contained in:
ksenia 2019-07-30 17:07:40 +00:00
parent 8f478ee1ea
commit 8f578bcca2
55 changed files with 1710 additions and 1202 deletions

View File

@ -9,7 +9,7 @@ var EXPORTED_SYMBOLS = ["AboutCompat"];
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const addonID = "webcompat@mozilla.org";
const addonPageRelativeURL = "/aboutCompat.html";
const addonPageRelativeURL = "/about-compat/aboutCompat.html";
function AboutCompat() {
this.chromeURL = WebExtensionPolicy.getByID(addonID).getURL(
@ -27,7 +27,8 @@ AboutCompat.prototype = {
const channel = Services.io.newChannelFromURIWithLoadInfo(uri, aLoadInfo);
channel.originalURI = aURI;
channel.owner = Services.scriptSecurityManager.createContentPrincipal(
channel.owner = (Services.scriptSecurityManager.createContentPrincipal ||
Services.scriptSecurityManager.createCodebasePrincipal)(
uri,
aLoadInfo.originAttributes
);

View File

@ -69,11 +69,11 @@
font-weight: lighter;
}
html[dir=ltr] th {
html[dir="ltr"] th {
text-align: left;
}
html[dir=rtl] th {
html[dir="rtl"] th {
text-align: right;
}
}
@ -91,7 +91,9 @@
background-color: #f5f5f5;
}
table, tr, p {
table,
tr,
p {
display: block;
background: #fff;
}

View File

@ -2,17 +2,19 @@
<html>
<head>
<base/>
<!-- If you change this script tag you must update the hash in the extension's
`content_security_policy` 'sha256-HbSjs39Y0thRGfO3RHrNzLPKyC/tq6FdIuP3jEBAcJQ=' -->
<script>document.head.firstElementChild.href = browser.runtime.getURL("");</script>
`content_security_policy` 'sha256-MmZkN2QaIHhfRWPZ8TVRjijTn5Ci1iEabtTEWrt9CCo=' -->
<script>/* globals browser */ document.head.firstElementChild.href = browser.runtime.getURL("");</script>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="aboutCompat.css" />
<link rel="stylesheet" href="about-compat/aboutCompat.css" />
<link rel="stylesheet" media="screen and (pointer:fine), projection" type="text/css"
href="chrome://global/skin/in-content/common.css"/>
<link rel="localization" href="toolkit/about/aboutCompat.ftl"/>
<title data-l10n-id="text-title"></title>
<script src="aboutCompat.js"></script>
<script src="about-compat/aboutCompat.js"></script>
</head>
<body>
<h2 class="tab active" data-l10n-id="label-overrides"></h2>

View File

@ -6,6 +6,8 @@
/* globals browser */
let availablePatches;
const portToAddon = (function() {
let port;
@ -69,7 +71,8 @@ Promise.all([
}
});
redraw(info);
availablePatches = info;
redraw();
});
function onMessageFromAddon(msg) {
@ -94,13 +97,17 @@ function onMessageFromAddon(msg) {
button.disabled = !!msg.toggling;
}
function redraw(info) {
const { overrides, interventions } = info;
redrawTable($("#overrides"), overrides);
redrawTable($("#interventions"), interventions);
function redraw() {
if (!availablePatches) {
return;
}
const { overrides, interventions } = availablePatches;
const showHidden = location.hash === "#all";
redrawTable($("#overrides"), overrides, showHidden);
redrawTable($("#interventions"), interventions, showHidden);
}
function redrawTable(table, data) {
function redrawTable(table, data, showHidden = false) {
const df = document.createDocumentFragment();
table.querySelectorAll("tr").forEach(tr => {
tr.remove();
@ -128,6 +135,10 @@ function redrawTable(table, data) {
}
for (const row of data) {
if (row.hidden && !showHidden) {
continue;
}
const tr = document.createElement("tr");
tr.setAttribute("data-id", row.id);
df.appendChild(tr);
@ -156,3 +167,5 @@ function redrawTable(table, data) {
}
table.appendChild(df);
}
window.onhashchange = redraw;

View File

@ -28,7 +28,7 @@ this.aboutPage = class extends ExtensionAPI {
resProto.setSubstitution(
ResourceSubstitution,
Services.io.newURI("chrome/res/", null, rootURI)
Services.io.newURI("about-compat/", null, rootURI)
);
Services.ppmm.loadProcessScript(ProcessScriptURL, true);

View File

@ -1,103 +0,0 @@
/* 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";
/* global browser, disableInjection, disableOverride, enableInjection,
enableOverride, InjectionsEnabled, UAOverridesEnabled */
const UAOverrides = [];
const Injections = [];
function getOverrideOrInterventionById(id) {
for (const [type, things] of Object.entries({
overrides: UAOverrides,
interventions: Injections,
})) {
for (const what of things) {
if (what.id === id) {
return { type, what };
}
}
}
return {};
}
const portsToAboutCompatTabs = (function() {
const ports = new Set();
browser.runtime.onConnect.addListener(port => {
ports.add(port);
port.onDisconnect.addListener(function() {
ports.delete(port);
});
});
async function broadcast(message) {
for (const port of ports) {
port.postMessage(message);
}
}
return { broadcast };
})();
function filterOverrides(overrides) {
return overrides
.filter(override => override.availableOnPlatform)
.map(override => {
const { id, active, bug, domain } = override;
return { id, active, bug, domain };
});
}
browser.runtime.onMessage.addListener(msg => {
switch (msg.command || msg) {
case "toggle": {
const id = msg.id;
const { type, what } = getOverrideOrInterventionById(id);
if (!what) {
return Promise.reject(
`No such override or intervention to toggle: ${id}`
);
}
portsToAboutCompatTabs
.broadcast({ toggling: id, active: what.active })
.then(async () => {
switch (type) {
case "interventions": {
if (what.active) {
await disableInjection(what);
} else {
await enableInjection(what);
}
break;
}
case "overrides": {
if (what.active) {
await disableOverride(what);
} else {
await enableOverride(what);
}
break;
}
}
portsToAboutCompatTabs.broadcast({
toggled: id,
active: what.active,
});
});
break;
}
case "getOverridesAndInterventions": {
return Promise.resolve({
overrides:
(UAOverridesEnabled && filterOverrides(UAOverrides)) || false,
interventions:
(InjectionsEnabled && filterOverrides(Injections)) || false,
});
}
}
return undefined;
});

View File

@ -0,0 +1,244 @@
/* 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 module */
/**
* For detailed information on our policies, and a documention on this format
* and its possibilites, please check the Mozilla-Wiki at
*
* https://wiki.mozilla.org/Compatibility/Go_Faster_Addon/Override_Policies_and_Workflows#User_Agent_overrides
*/
const AVAILABLE_INJECTIONS = [
{
id: "testbed-injection",
platform: "all",
domain: "webcompat-addon-testbed.herokuapp.com",
bug: "0000000",
hidden: true,
contentScripts: {
matches: ["*://webcompat-addon-testbed.herokuapp.com/*"],
css: [
{
file: "injections/css/bug0000000-testbed-css-injection.css",
},
],
js: [
{
file: "injections/js/bug0000000-testbed-js-injection.js",
},
],
runAt: "document_start",
},
},
{
id: "bug1452707",
platform: "desktop",
domain: "ib.absa.co.za",
bug: "1452707",
contentScripts: {
matches: ["https://ib.absa.co.za/*"],
js: [
{
file:
"injections/js/bug1452707-window.controllers-shim-ib.absa.co.za.js",
},
],
runAt: "document_start",
},
},
{
id: "bug1457335",
platform: "desktop",
domain: "histography.io",
bug: "1457335",
contentScripts: {
matches: ["*://histography.io/*"],
js: [
{
file: "injections/js/bug1457335-histography.io-ua-change.js",
},
],
runAt: "document_start",
},
},
{
id: "bug1472075",
platform: "desktop",
domain: "bankofamerica.com",
bug: "1472075",
contentScripts: {
matches: ["*://*.bankofamerica.com/*"],
js: [
{
file: "injections/js/bug1472075-bankofamerica.com-ua-change.js",
},
],
runAt: "document_start",
},
},
{
id: "bug1472081",
platform: "desktop",
domain: "election.gov.np",
bug: "1472081",
contentScripts: {
matches: ["http://202.166.205.141/bbvrs/*"],
js: [
{
file:
"injections/js/bug1472081-election.gov.np-window.sidebar-shim.js",
},
],
runAt: "document_start",
allFrames: true,
},
},
{
id: "bug1482066",
platform: "desktop",
domain: "portalminasnet.com",
bug: "1482066",
contentScripts: {
matches: ["*://portalminasnet.com/*"],
js: [
{
file:
"injections/js/bug1482066-portalminasnet.com-window.sidebar-shim.js",
},
],
runAt: "document_start",
allFrames: true,
},
},
{
id: "bug1526977",
platform: "desktop",
domain: "sreedharscce.in",
bug: "1526977",
contentScripts: {
matches: ["*://*.sreedharscce.in/authenticate"],
css: [
{
file: "injections/css/bug1526977-sreedharscce.in-login-fix.css",
},
],
},
},
{
id: "bug1518781",
platform: "desktop",
domain: "twitch.tv",
bug: "1518781",
contentScripts: {
matches: ["*://*.twitch.tv/*"],
css: [
{
file: "injections/css/bug1518781-twitch.tv-webkit-scrollbar.css",
},
],
},
},
{
id: "bug1551672",
platform: "android",
domain: "Sites using PDK 5 video",
bug: "1551672",
pdk5fix: {
urls: ["https://*/*/tpPdk.js", "https://*/*/pdk/js/*/*.js"],
types: ["script"],
},
},
{
id: "bug1305028",
platform: "desktop",
domain: "gaming.youtube.com",
bug: "1305028",
contentScripts: {
matches: ["*://gaming.youtube.com/*"],
css: [
{
file:
"injections/css/bug1305028-gaming.youtube.com-webkit-scrollbar.css",
},
],
},
},
{
id: "bug1432935-discord",
platform: "desktop",
domain: "discordapp.com",
bug: "1432935",
contentScripts: {
matches: ["*://discordapp.com/*"],
css: [
{
file:
"injections/css/bug1432935-discordapp.com-webkit-scorllbar-white-line.css",
},
],
},
},
{
id: "bug1432935-breitbart",
platform: "desktop",
domain: "breitbart.com",
bug: "1432935",
contentScripts: {
matches: ["*://*.breitbart.com/*"],
css: [
{
file: "injections/css/bug1432935-breitbart.com-webkit-scrollbar.css",
},
],
},
},
{
id: "bug1561371",
platform: "android",
domain: "mail.google.com",
bug: "1561371",
contentScripts: {
matches: ["*://mail.google.com/*"],
css: [
{
file:
"injections/css/bug1561371-mail.google.com-allow-horizontal-scrolling.css",
},
],
},
},
{
id: "bug1567610",
platform: "all",
domain: "dns.google.com",
bug: "1567610",
contentScripts: {
matches: ["*://dns.google.com/*"],
css: [
{
file: "injections/css/bug1567610-dns.google.com-moz-fit-content.css",
},
],
},
},
{
id: "bug1568256",
platform: "android",
domain: "zertifikate.commerzbank.de",
bug: "1568256",
contentScripts: {
matches: ["*://*.zertifikate.commerzbank.de/webforms/mobile/*"],
css: [
{
file: "injections/css/bug1568256-zertifikate.commerzbank.de-flex.css",
},
],
},
},
];
module.exports = AVAILABLE_INJECTIONS;

View File

@ -1,28 +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";
/* globals module */
/**
* For detailed information on our policies, and a documention on this format
* and its possibilites, please check the Mozilla-Wiki at
*
* https://wiki.mozilla.org/Compatibility/Go_Faster_Addon/Override_Policies_and_Workflows#User_Agent_overrides
*/
"use strict";
/* globals filterOverrides, portsToAboutCompatTabs, UAOverrides */
let UAOverridesEnabled = true;
for (const override of [
const AVAILABLE_UA_OVERRIDES = [
{
id: "testoverride",
id: "testbed-override",
platform: "all",
domain: "webcompat-addon-testcases.schub.io",
bug: "1287966",
domain: "webcompat-addon-testbed.herokuapp.com",
bug: "0000000",
hidden: true,
config: {
matches: ["*://webcompat-addon-testcases.schub.io/*"],
matches: ["*://webcompat-addon-testbed.herokuapp.com/*"],
uaTransformer: originalUA => {
return (
UAHelpers.getPrefix(originalUA) +
" AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36"
" AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36 for WebCompat"
);
},
},
@ -41,7 +43,11 @@ for (const override of [
domain: "rolb.santanderbank.com",
bug: "1563839",
config: {
matches: ["*://*.santander.co.uk/*", "*://rolb.santanderbank.com/*"],
matches: [
"*://*.santander.co.uk/*",
"*://bob.santanderbank.com/*",
"*://rolb.santanderbank.com/*",
],
uaTransformer: originalUA => {
return originalUA.replace("Gecko", "like Gecko");
},
@ -272,11 +278,45 @@ for (const override of [
},
},
},
]) {
UAOverrides.push(override);
}
/* globals browser */
{
/*
* Bug 1566253 - posts.google.com - Add UA override for posts.google.com
* WebCompat issue #17870 - https://webcompat.com/issues/17870
*
* posts.google.com displaying "Your browser doesn't support this page".
* Spoofing as Chrome works fine.
*/
id: "bug1566253",
platform: "android",
domain: "posts.google.com",
bug: "1566253",
config: {
matches: ["*://posts.google.com/*"],
uaTransformer: _ => {
return "Mozilla/5.0 (Linux; Android 6.0.1; SM-G900M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.101 Mobile Safari/537.36";
},
},
},
{
/*
* Bug 1567945 - Create UA override for beeg.com on Firefox Android
* WebCompat issue #16648 - https://webcompat.com/issues/16648
*
* beeg.com is hiding content of a page with video if Firefox exists in UA,
* replacing "Firefox" with an empty string makes the page load
*/
id: "bug1567945",
platform: "android",
domain: "beeg.com",
bug: "1567945",
config: {
matches: ["*://beeg.com/*"],
uaTransformer: originalUA => {
return originalUA.replace(/Firefox.+$/, "");
},
},
},
];
const UAHelpers = {
getPrefix(originalUA) {
@ -284,84 +324,4 @@ const UAHelpers = {
},
};
const ActiveListeners = new Map();
function enableOverride(override) {
if (override.active) {
return;
}
const { matches, uaTransformer } = override.config;
const listener = details => {
for (var header of details.requestHeaders) {
if (header.name.toLowerCase() === "user-agent") {
header.value = uaTransformer(header.value);
}
}
return { requestHeaders: details.requestHeaders };
};
browser.webRequest.onBeforeSendHeaders.addListener(
listener,
{ urls: matches },
["blocking", "requestHeaders"]
);
ActiveListeners.set(override, listener);
override.active = true;
}
async function registerUAOverrides() {
const platformMatches = ["all"];
let platformInfo = await browser.runtime.getPlatformInfo();
platformMatches.push(platformInfo.os == "android" ? "android" : "desktop");
for (const override of UAOverrides) {
if (platformMatches.includes(override.platform)) {
override.availableOnPlatform = true;
enableOverride(override);
}
}
UAOverridesEnabled = true;
portsToAboutCompatTabs.broadcast({
overridesChanged: filterOverrides(UAOverrides),
});
}
function unregisterUAOverrides() {
for (const override of UAOverrides) {
disableOverride(override);
}
UAOverridesEnabled = false;
portsToAboutCompatTabs.broadcast({ overridesChanged: false });
}
function disableOverride(override) {
if (!override.active) {
return;
}
browser.webRequest.onBeforeSendHeaders.removeListener(
ActiveListeners.get(override)
);
override.active = false;
ActiveListeners.delete(override);
}
const OVERRIDE_PREF = "perform_ua_overrides";
function checkOverridePref() {
browser.aboutConfigPrefs.getPref(OVERRIDE_PREF).then(value => {
if (value === undefined) {
browser.aboutConfigPrefs.setPref(OVERRIDE_PREF, true);
} else if (value === false) {
unregisterUAOverrides();
} else {
registerUAOverrides();
}
});
}
browser.aboutConfigPrefs.onPrefChange.addListener(
checkOverridePref,
OVERRIDE_PREF
);
checkOverridePref();
module.exports = AVAILABLE_UA_OVERRIDES;

View File

@ -1,339 +0,0 @@
/* 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/. */
/**
* For detailed information on our policies, and a documention on this format
* and its possibilites, please check the Mozilla-Wiki at
*
* https://wiki.mozilla.org/Compatibility/Go_Faster_Addon/Override_Policies_and_Workflows#User_Agent_overrides
*/
"use strict";
/* globals browser, filterOverrides, Injections, portsToAboutCompatTabs */
let InjectionsEnabled = true;
for (const injection of [
{
id: "testinjection",
platform: "all",
domain: "webcompat-addon-testcases.schub.io",
bug: "1287966",
contentScripts: {
matches: ["*://webcompat-addon-testcases.schub.io/*"],
css: [{ file: "injections/css/bug0000000-dummy-css-injection.css" }],
js: [{ file: "injections/js/bug0000000-dummy-js-injection.js" }],
runAt: "document_start",
},
},
{
id: "bug1452707",
platform: "desktop",
domain: "ib.absa.co.za",
bug: "1452707",
contentScripts: {
matches: ["https://ib.absa.co.za/*"],
js: [
{
file:
"injections/js/bug1452707-window.controllers-shim-ib.absa.co.za.js",
},
],
runAt: "document_start",
},
},
{
id: "bug1457335",
platform: "desktop",
domain: "histography.io",
bug: "1457335",
contentScripts: {
matches: ["*://histography.io/*"],
js: [{ file: "injections/js/bug1457335-histography.io-ua-change.js" }],
runAt: "document_start",
},
},
{
id: "bug1472075",
platform: "desktop",
domain: "bankofamerica.com",
bug: "1472075",
contentScripts: {
matches: ["*://*.bankofamerica.com/*"],
js: [{ file: "injections/js/bug1472075-bankofamerica.com-ua-change.js" }],
runAt: "document_start",
},
},
{
id: "bug1472081",
platform: "desktop",
domain: "election.gov.np",
bug: "1472081",
contentScripts: {
matches: ["http://202.166.205.141/bbvrs/*"],
js: [
{
file:
"injections/js/bug1472081-election.gov.np-window.sidebar-shim.js",
},
],
runAt: "document_start",
allFrames: true,
},
},
{
id: "bug1482066",
platform: "desktop",
domain: "portalminasnet.com",
bug: "1482066",
contentScripts: {
matches: ["*://portalminasnet.com/*"],
js: [
{
file:
"injections/js/bug1482066-portalminasnet.com-window.sidebar-shim.js",
},
],
runAt: "document_start",
allFrames: true,
},
},
{
id: "bug1526977",
platform: "desktop",
domain: "sreedharscce.in",
bug: "1526977",
contentScripts: {
matches: ["*://*.sreedharscce.in/authenticate"],
css: [
{ file: "injections/css/bug1526977-sreedharscce.in-login-fix.css" },
],
},
},
{
id: "bug1518781",
platform: "desktop",
domain: "twitch.tv",
bug: "1518781",
contentScripts: {
matches: ["*://*.twitch.tv/*"],
css: [
{ file: "injections/css/bug1518781-twitch.tv-webkit-scrollbar.css" },
],
},
},
{
id: "bug1551672",
platform: "android",
domain: "Sites using PDK 5 video",
bug: "1551672",
pdk5fix: {
urls: ["https://*/*/tpPdk.js", "https://*/*/pdk/js/*/*.js"],
types: ["script"],
},
},
{
id: "bug1305028",
platform: "desktop",
domain: "gaming.youtube.com",
bug: "1305028",
contentScripts: {
matches: ["*://gaming.youtube.com/*"],
css: [
{
file:
"injections/css/bug1305028-gaming.youtube.com-webkit-scrollbar.css",
},
],
},
},
{
id: "bug1432935-discord",
platform: "desktop",
domain: "discordapp.com",
bug: "1432935",
contentScripts: {
matches: ["*://discordapp.com/*"],
css: [
{
file:
"injections/css/bug1432935-discordapp.com-webkit-scorllbar-white-line.css",
},
],
},
},
{
id: "bug1432935-breitbart",
platform: "desktop",
domain: "breitbart.com",
bug: "1432935",
contentScripts: {
matches: ["*://*.breitbart.com/*"],
css: [
{
file: "injections/css/bug1432935-breitbart.com-webkit-scrollbar.css",
},
],
},
},
{
id: "bug1561371",
platform: "android",
domain: "mail.google.com",
bug: "1561371",
contentScripts: {
matches: ["*://mail.google.com/*"],
css: [
{
file:
"injections/css/bug1561371-mail.google.com-allow-horizontal-scrolling.css",
},
],
},
},
]) {
Injections.push(injection);
}
let port = browser.runtime.connect();
const ActiveInjections = new Map();
async function registerContentScripts() {
const platformMatches = ["all"];
let platformInfo = await browser.runtime.getPlatformInfo();
platformMatches.push(platformInfo.os == "android" ? "android" : "desktop");
for (const injection of Injections) {
if (platformMatches.includes(injection.platform)) {
injection.availableOnPlatform = true;
await enableInjection(injection);
}
}
InjectionsEnabled = true;
portsToAboutCompatTabs.broadcast({
interventionsChanged: filterOverrides(Injections),
});
}
function replaceStringInRequest(
requestId,
inString,
outString,
inEncoding = "utf-8"
) {
const filter = browser.webRequest.filterResponseData(requestId);
const decoder = new TextDecoder(inEncoding);
const encoder = new TextEncoder();
const RE = new RegExp(inString, "g");
const carryoverLength = inString.length;
let carryover = "";
filter.ondata = event => {
const replaced = (
carryover + decoder.decode(event.data, { stream: true })
).replace(RE, outString);
filter.write(encoder.encode(replaced.slice(0, -carryoverLength)));
carryover = replaced.slice(-carryoverLength);
};
filter.onstop = event => {
if (carryover.length) {
filter.write(encoder.encode(carryover));
}
filter.close();
};
}
async function enableInjection(injection) {
if (injection.active) {
return;
}
if ("pdk5fix" in injection) {
const { urls, types } = injection.pdk5fix;
const listener = (injection.pdk5fix.listener = ({ requestId }) => {
replaceStringInRequest(
requestId,
"VideoContextChromeAndroid",
"VideoContextAndroid"
);
return {};
});
browser.webRequest.onBeforeRequest.addListener(listener, { urls, types }, [
"blocking",
]);
injection.active = true;
return;
}
try {
const handle = await browser.contentScripts.register(
injection.contentScripts
);
ActiveInjections.set(injection, handle);
injection.active = true;
} catch (ex) {
console.error(
"Registering WebCompat GoFaster content scripts failed: ",
ex
);
}
}
function unregisterContentScripts() {
for (const injection of Injections) {
disableInjection(injection);
}
InjectionsEnabled = false;
portsToAboutCompatTabs.broadcast({ interventionsChanged: false });
}
async function disableInjection(injection) {
if (!injection.active) {
return;
}
if (injection.pdk5fix) {
const { listener } = injection.pdk5fix;
browser.webRequest.onBeforeRequest.removeListener(listener);
injection.active = false;
delete injection.pdk5fix.listener;
return;
}
const contentScript = ActiveInjections.get(injection);
await contentScript.unregister();
ActiveInjections.delete(injection);
injection.active = false;
}
port.onMessage.addListener(message => {
switch (message.type) {
case "injection-pref-changed":
if (message.prefState) {
registerContentScripts();
} else {
unregisterContentScripts();
}
break;
}
});
const INJECTION_PREF = "perform_injections";
function checkInjectionPref() {
browser.aboutConfigPrefs.getPref(INJECTION_PREF).then(value => {
if (value === undefined) {
browser.aboutConfigPrefs.setPref(INJECTION_PREF, true);
} else if (value === false) {
unregisterContentScripts();
} else {
registerContentScripts();
}
});
}
browser.aboutConfigPrefs.onPrefChange.addListener(
checkInjectionPref,
INJECTION_PREF
);
checkInjectionPref();

View File

@ -0,0 +1,12 @@
/**
* dns.google.com - Page content is shifted to the left side of the page
* Bug #1567610 - https://bugzilla.mozilla.org/show_bug.cgi?id=1567610
* WebCompat issue #22494 - https://webcompat.com/issues/22494
*
* Affected element is styled with width:fit-content; which is not
* supported by Firefox yet, see https://bugzilla.mozilla.org/show_bug.cgi?id=1495868
* Adding -moz-fit-content fixes the issue
*/
main > .ng-star-inserted > .centered {
width: -moz-fit-content;
}

View File

@ -0,0 +1,12 @@
/**
* zertifikate.commerzbank.de - clickable elements on the page are collapsed
* Bug #1568256 - https://bugzilla.mozilla.org/show_bug.cgi?id=1568256
* WebCompat issue #9102 - https://webcompat.com/issues/9102
*
* Affected elements have display:-webkit-box and display:flex applied, however,
* listed in wrong order, so display:-webkit-box is becoming the final say.
* Adding display: flex for those elements fixes the issue
*/
.x-layout-box {
display: flex !important;
}

View File

@ -1,7 +1,3 @@
/* 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";
/**

View File

@ -1,7 +1,3 @@
/* 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";
/**

View File

@ -1,7 +1,3 @@
/* 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";
/**

View File

@ -1,7 +1,3 @@
/* 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";
/**

View File

@ -1,7 +1,3 @@
/* 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";
/**

View File

@ -1,7 +0,0 @@
# 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/.
[features/webcompat@mozilla.org] chrome.jar:
res/AboutCompat.jsm (AboutCompat.jsm)
res/aboutPageProcessScript.js (aboutPageProcessScript.js)

View File

@ -0,0 +1,123 @@
/* 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";
/* global browser, module */
class AboutCompatBroker {
constructor(bindings) {
this.portsToAboutCompatTabs = this.buildPorts();
this._injections = bindings.injections;
this._injections.bindAboutCompatBroker(this);
this._uaOverrides = bindings.uaOverrides;
this._uaOverrides.bindAboutCompatBroker(this);
}
buildPorts() {
const ports = new Set();
browser.runtime.onConnect.addListener(port => {
ports.add(port);
port.onDisconnect.addListener(function() {
ports.delete(port);
});
});
async function broadcast(message) {
for (const port of ports) {
port.postMessage(message);
}
}
return { broadcast };
}
filterOverrides(overrides) {
return overrides
.filter(override => override.availableOnPlatform)
.map(override => {
const { id, active, bug, domain, hidden } = override;
return { id, active, bug, domain, hidden };
});
}
getOverrideOrInterventionById(id) {
for (const [type, things] of Object.entries({
overrides: this._uaOverrides.getAvailableOverrides(),
interventions: this._injections.getAvailableInjections(),
})) {
for (const what of things) {
if (what.id === id) {
return { type, what };
}
}
}
return {};
}
bootup() {
browser.runtime.onMessage.addListener(msg => {
switch (msg.command || msg) {
case "toggle": {
const id = msg.id;
const { type, what } = this.getOverrideOrInterventionById(id);
if (!what) {
return Promise.reject(
`No such override or intervention to toggle: ${id}`
);
}
this.portsToAboutCompatTabs
.broadcast({ toggling: id, active: what.active })
.then(async () => {
switch (type) {
case "interventions": {
if (what.active) {
await this._injections.disableInjection(what);
} else {
await this._injections.enableInjection(what);
}
break;
}
case "overrides": {
if (what.active) {
await this._uaOverrides.disableOverride(what);
} else {
await this._uaOverrides.enableOverride(what);
}
break;
}
}
this.portsToAboutCompatTabs.broadcast({
toggled: id,
active: what.active,
});
});
break;
}
case "getOverridesAndInterventions": {
return Promise.resolve({
overrides:
(this._uaOverrides.isEnabled() &&
this.filterOverrides(
this._uaOverrides.getAvailableOverrides()
)) ||
false,
interventions:
(this._injections.isEnabled() &&
this.filterOverrides(
this._injections.getAvailableInjections()
)) ||
false,
});
}
}
return undefined;
});
}
}
module.exports = AboutCompatBroker;

View File

@ -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";
/* globals browser, module */
class Injections {
constructor(availableInjections) {
this.INJECTION_PREF = "perform_injections";
this._injectionsEnabled = true;
this._availableInjections = availableInjections;
this._activeInjections = new Map();
}
bindAboutCompatBroker(broker) {
this._aboutCompatBroker = broker;
}
bootup() {
browser.aboutConfigPrefs.onPrefChange.addListener(() => {
this.checkInjectionPref();
}, this.INJECTION_PREF);
this.checkInjectionPref();
}
checkInjectionPref() {
browser.aboutConfigPrefs.getPref(this.INJECTION_PREF).then(value => {
if (value === undefined) {
browser.aboutConfigPrefs.setPref(this.INJECTION_PREF, true);
} else if (value === false) {
this.unregisterContentScripts();
} else {
this.registerContentScripts();
}
});
}
getAvailableInjections() {
return this._availableInjections;
}
isEnabled() {
return this._injectionsEnabled;
}
async registerContentScripts() {
const platformMatches = ["all"];
let platformInfo = await browser.runtime.getPlatformInfo();
platformMatches.push(platformInfo.os == "android" ? "android" : "desktop");
for (const injection of this._availableInjections) {
if (platformMatches.includes(injection.platform)) {
injection.availableOnPlatform = true;
await this.enableInjection(injection);
}
}
this._injectionsEnabled = true;
this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
interventionsChanged: this._aboutCompatBroker.filterOverrides(
this._availableInjections
),
});
}
replaceStringInRequest(requestId, inString, outString, inEncoding = "utf-8") {
const filter = browser.webRequest.filterResponseData(requestId);
const decoder = new TextDecoder(inEncoding);
const encoder = new TextEncoder();
const RE = new RegExp(inString, "g");
const carryoverLength = inString.length;
let carryover = "";
filter.ondata = event => {
const replaced = (
carryover + decoder.decode(event.data, { stream: true })
).replace(RE, outString);
filter.write(encoder.encode(replaced.slice(0, -carryoverLength)));
carryover = replaced.slice(-carryoverLength);
};
filter.onstop = event => {
if (carryover.length) {
filter.write(encoder.encode(carryover));
}
filter.close();
};
}
async enableInjection(injection) {
if (injection.active) {
return;
}
if ("pdk5fix" in injection) {
const { urls, types } = injection.pdk5fix;
const listener = (injection.pdk5fix.listener = ({ requestId }) => {
this.replaceStringInRequest(
requestId,
"VideoContextChromeAndroid",
"VideoContextAndroid"
);
return {};
});
browser.webRequest.onBeforeRequest.addListener(
listener,
{ urls, types },
["blocking"]
);
injection.active = true;
return;
}
try {
const handle = await browser.contentScripts.register(
injection.contentScripts
);
this._activeInjections.set(injection, handle);
injection.active = true;
} catch (ex) {
console.error(
"Registering WebCompat GoFaster content scripts failed: ",
ex
);
}
}
unregisterContentScripts() {
for (const injection of this._availableInjections) {
this.disableInjection(injection);
}
this._injectionsEnabled = false;
this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
interventionsChanged: false,
});
}
async disableInjection(injection) {
if (!injection.active) {
return;
}
if (injection.pdk5fix) {
const { listener } = injection.pdk5fix;
browser.webRequest.onBeforeRequest.removeListener(listener);
injection.active = false;
delete injection.pdk5fix.listener;
return;
}
const contentScript = this._activeInjections.get(injection);
await contentScript.unregister();
this._activeInjections.delete(injection);
injection.active = false;
}
}
module.exports = Injections;

View File

@ -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/. */
"use strict";
/**
* We cannot yet use proper JS modules within webextensions, as support for them
* is highly experimental and highly instable. So we end up just including all
* the JS files we need as separate background scripts, and since they all are
* executed within the same context, this works for our in-browser deployment.
*
* However, this code is tracked outside of mozilla-central, and we work on
* shipping this code in other products, like android-components as well.
* Because of that, we have automated tests running within that repository. To
* make our lives easier, we add `module.exports` statements to the JS source
* files, so we can easily import their contents into our NodeJS-based test
* suite.
*
* This works fine, but obviously, `module` is not defined when running
* in-browser. So let's use this empty object as a shim, so we don't run into
* runtime exceptions because of that.
*/
var module = {};

View File

@ -0,0 +1,119 @@
/* 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, module */
class UAOverrides {
constructor(availableOverrides) {
this.OVERRIDE_PREF = "perform_ua_overrides";
this._overridesEnabled = true;
this._availableOverrides = availableOverrides;
this._activeListeners = new Map();
}
bindAboutCompatBroker(broker) {
this._aboutCompatBroker = broker;
}
bootup() {
browser.aboutConfigPrefs.onPrefChange.addListener(() => {
this.checkOverridePref();
}, this.OVERRIDE_PREF);
this.checkOverridePref();
}
checkOverridePref() {
browser.aboutConfigPrefs.getPref(this.OVERRIDE_PREF).then(value => {
if (value === undefined) {
browser.aboutConfigPrefs.setPref(this.OVERRIDE_PREF, true);
} else if (value === false) {
this.unregisterUAOverrides();
} else {
this.registerUAOverrides();
}
});
}
getAvailableOverrides() {
return this._availableOverrides;
}
isEnabled() {
return this._overridesEnabled;
}
enableOverride(override) {
if (override.active) {
return;
}
const { matches, uaTransformer } = override.config;
const listener = details => {
for (const header of details.requestHeaders) {
if (header.name.toLowerCase() === "user-agent") {
header.value = uaTransformer(header.value);
}
}
return { requestHeaders: details.requestHeaders };
};
browser.webRequest.onBeforeSendHeaders.addListener(
listener,
{ urls: matches },
["blocking", "requestHeaders"]
);
this._activeListeners.set(override, listener);
override.active = true;
}
async registerUAOverrides() {
const platformMatches = ["all"];
let platformInfo = await browser.runtime.getPlatformInfo();
platformMatches.push(platformInfo.os == "android" ? "android" : "desktop");
for (const override of this._availableOverrides) {
if (platformMatches.includes(override.platform)) {
override.availableOnPlatform = true;
this.enableOverride(override);
}
}
this._overridesEnabled = true;
this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
overridesChanged: this._aboutCompatBroker.filterOverrides(
this._availableOverrides
),
});
}
unregisterUAOverrides() {
for (const override of this._availableOverrides) {
this.disableOverride(override);
}
this._overridesEnabled = false;
this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
overridesChanged: false,
});
}
disableOverride(override) {
if (!override.active) {
return;
}
browser.webRequest.onBeforeSendHeaders.removeListener(
this._activeListeners.get(override)
);
override.active = false;
this._activeListeners.delete(override);
}
}
module.exports = UAOverrides;

View File

@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "Web Compat",
"description": "Urgent post-release fixes for web compatibility.",
"version": "4.4.0",
"version": "5.0.2",
"applications": {
"gecko": {
@ -13,24 +13,24 @@
"experiment_apis": {
"aboutConfigPrefs": {
"schema": "aboutConfigPrefs.json",
"schema": "experiment-apis/aboutConfigPrefs.json",
"parent": {
"scopes": ["addon_parent"],
"script": "aboutConfigPrefs.js",
"script": "experiment-apis/aboutConfigPrefs.js",
"paths": [["aboutConfigPrefs"]]
}
},
"aboutPage": {
"schema": "aboutPage.json",
"schema": "about-compat/aboutPage.json",
"parent": {
"scopes": ["addon_parent"],
"script": "aboutPage.js",
"script": "about-compat/aboutPage.js",
"events": ["startup"]
}
}
},
"content_security_policy": "script-src 'self' 'sha256-HbSjs39Y0thRGfO3RHrNzLPKyC/tq6FdIuP3jEBAcJQ='; default-src 'self'; base-uri moz-extension://*;",
"content_security_policy": "script-src 'self' 'sha256-MmZkN2QaIHhfRWPZ8TVRjijTn5Ci1iEabtTEWrt9CCo='; default-src 'self'; base-uri moz-extension://*;",
"permissions": [
"webRequest",
@ -40,9 +40,13 @@
"background": {
"scripts": [
"background.js",
"injections.js",
"ua_overrides.js"
"lib/module_shim.js",
"data/injections.js",
"data/ua_overrides.js",
"lib/about_compat_broker.js",
"lib/injections.js",
"lib/ua_overrides.js",
"run.js"
]
}
}

View File

@ -8,31 +8,44 @@ DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION']
FINAL_TARGET_FILES.features['webcompat@mozilla.org'] += [
'aboutCompat.css',
'aboutCompat.html',
'aboutCompat.js',
'aboutConfigPrefs.js',
'aboutConfigPrefs.json',
'aboutPage.js',
'aboutPage.json',
'background.js',
'injections.js',
'manifest.json',
'ua_overrides.js'
'run.js'
]
FINAL_TARGET_FILES.features['webcompat@mozilla.org']['about-compat'] += [
'about-compat/aboutCompat.css',
'about-compat/aboutCompat.html',
'about-compat/aboutCompat.js',
'about-compat/AboutCompat.jsm',
'about-compat/aboutPage.js',
'about-compat/aboutPage.json',
'about-compat/aboutPageProcessScript.js'
]
FINAL_TARGET_FILES.features['webcompat@mozilla.org']['data'] += [
'data/injections.js',
'data/ua_overrides.js'
]
FINAL_TARGET_FILES.features['webcompat@mozilla.org']['experiment-apis'] += [
'experiment-apis/aboutConfigPrefs.js',
'experiment-apis/aboutConfigPrefs.json'
]
FINAL_TARGET_FILES.features['webcompat@mozilla.org']['injections']['css'] += [
'injections/css/bug0000000-dummy-css-injection.css',
'injections/css/bug0000000-testbed-css-injection.css',
'injections/css/bug1305028-gaming.youtube.com-webkit-scrollbar.css',
'injections/css/bug1432935-breitbart.com-webkit-scrollbar.css',
'injections/css/bug1432935-discordapp.com-webkit-scorllbar-white-line.css',
'injections/css/bug1518781-twitch.tv-webkit-scrollbar.css',
'injections/css/bug1526977-sreedharscce.in-login-fix.css',
'injections/css/bug1561371-mail.google.com-allow-horizontal-scrolling.css'
'injections/css/bug1561371-mail.google.com-allow-horizontal-scrolling.css',
'injections/css/bug1567610-dns.google.com-moz-fit-content.css',
'injections/css/bug1568256-zertifikate.commerzbank.de-flex.css'
]
FINAL_TARGET_FILES.features['webcompat@mozilla.org']['injections']['js'] += [
'injections/js/bug0000000-dummy-js-injection.js',
'injections/js/bug0000000-testbed-js-injection.js',
'injections/js/bug1452707-window.controllers-shim-ib.absa.co.za.js',
'injections/js/bug1457335-histography.io-ua-change.js',
'injections/js/bug1472075-bankofamerica.com-ua-change.js',
@ -40,7 +53,12 @@ FINAL_TARGET_FILES.features['webcompat@mozilla.org']['injections']['js'] += [
'injections/js/bug1482066-portalminasnet.com-window.sidebar-shim.js'
]
JAR_MANIFESTS += ['jar.mn']
FINAL_TARGET_FILES.features['webcompat@mozilla.org']['lib'] += [
'lib/about_compat_broker.js',
'lib/injections.js',
'lib/module_shim.js',
'lib/ua_overrides.js'
]
with Files('**'):
BUG_COMPONENT = ('Web Compatibility Tools', 'Go Faster')

View File

@ -0,0 +1,20 @@
/* 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 AVAILABLE_INJECTIONS, AVAILABLE_UA_OVERRIDES, AboutCompatBroker,
Injections, UAOverrides */
const injections = new Injections(AVAILABLE_INJECTIONS);
const uaOverrides = new UAOverrides(AVAILABLE_UA_OVERRIDES);
const aboutCompatBroker = new AboutCompatBroker({
injections,
uaOverrides,
});
aboutCompatBroker.bootup();
injections.bootup();
uaOverrides.bootup();

View File

@ -9,7 +9,7 @@ var EXPORTED_SYMBOLS = ["AboutCompat"];
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const addonID = "webcompat@mozilla.org";
const addonPageRelativeURL = "/aboutCompat.html";
const addonPageRelativeURL = "/about-compat/aboutCompat.html";
function AboutCompat() {
this.chromeURL = WebExtensionPolicy.getByID(addonID).getURL(
@ -27,7 +27,8 @@ AboutCompat.prototype = {
const channel = Services.io.newChannelFromURIWithLoadInfo(uri, aLoadInfo);
channel.originalURI = aURI;
channel.owner = Services.scriptSecurityManager.createContentPrincipal(
channel.owner = (Services.scriptSecurityManager.createContentPrincipal ||
Services.scriptSecurityManager.createCodebasePrincipal)(
uri,
aLoadInfo.originAttributes
);

View File

@ -69,11 +69,11 @@
font-weight: lighter;
}
html[dir=ltr] th {
html[dir="ltr"] th {
text-align: left;
}
html[dir=rtl] th {
html[dir="rtl"] th {
text-align: right;
}
}
@ -91,7 +91,9 @@
background-color: #f5f5f5;
}
table, tr, p {
table,
tr,
p {
display: block;
background: #fff;
}

View File

@ -1,22 +1,20 @@
<!-- 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/. -->
<!DOCTYPE HTML>
<html>
<head>
<base/>
<!-- If you change this script tag you must update the hash in the extension's
`content_security_policy` 'sha256-HbSjs39Y0thRGfO3RHrNzLPKyC/tq6FdIuP3jEBAcJQ=' -->
<script>document.head.firstElementChild.href = browser.runtime.getURL("");</script>
`content_security_policy` 'sha256-MmZkN2QaIHhfRWPZ8TVRjijTn5Ci1iEabtTEWrt9CCo=' -->
<script>/* globals browser */ document.head.firstElementChild.href = browser.runtime.getURL("");</script>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="aboutCompat.css" />
<link rel="stylesheet" href="about-compat/aboutCompat.css" />
<link rel="stylesheet" media="screen and (pointer:fine), projection" type="text/css"
href="chrome://global/skin/in-content/common.css"/>
<link rel="localization" href="toolkit/about/aboutCompat.ftl"/>
<title data-l10n-id="text-title"></title>
<script src="aboutCompat.js"></script>
<script src="about-compat/aboutCompat.js"></script>
</head>
<body>
<h2 class="tab active" data-l10n-id="label-overrides"></h2>

View File

@ -6,6 +6,8 @@
/* globals browser */
let availablePatches;
const portToAddon = (function() {
let port;
@ -69,7 +71,8 @@ Promise.all([
}
});
redraw(info);
availablePatches = info;
redraw();
});
function onMessageFromAddon(msg) {
@ -94,13 +97,17 @@ function onMessageFromAddon(msg) {
button.disabled = !!msg.toggling;
}
function redraw(info) {
const { overrides, interventions } = info;
redrawTable($("#overrides"), overrides);
redrawTable($("#interventions"), interventions);
function redraw() {
if (!availablePatches) {
return;
}
const { overrides, interventions } = availablePatches;
const showHidden = location.hash === "#all";
redrawTable($("#overrides"), overrides, showHidden);
redrawTable($("#interventions"), interventions, showHidden);
}
function redrawTable(table, data) {
function redrawTable(table, data, showHidden = false) {
const df = document.createDocumentFragment();
table.querySelectorAll("tr").forEach(tr => {
tr.remove();
@ -128,6 +135,10 @@ function redrawTable(table, data) {
}
for (const row of data) {
if (row.hidden && !showHidden) {
continue;
}
const tr = document.createElement("tr");
tr.setAttribute("data-id", row.id);
df.appendChild(tr);
@ -156,3 +167,5 @@ function redrawTable(table, data) {
}
table.appendChild(df);
}
window.onhashchange = redraw;

View File

@ -28,7 +28,7 @@ this.aboutPage = class extends ExtensionAPI {
resProto.setSubstitution(
ResourceSubstitution,
Services.io.newURI("chrome/res/", null, rootURI)
Services.io.newURI("about-compat/", null, rootURI)
);
Services.ppmm.loadProcessScript(ProcessScriptURL, true);

View File

@ -1,103 +0,0 @@
/* 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";
/* global browser, disableInjection, disableOverride, enableInjection,
enableOverride, InjectionsEnabled, UAOverridesEnabled */
const UAOverrides = [];
const Injections = [];
function getOverrideOrInterventionById(id) {
for (const [type, things] of Object.entries({
overrides: UAOverrides,
interventions: Injections,
})) {
for (const what of things) {
if (what.id === id) {
return { type, what };
}
}
}
return {};
}
const portsToAboutCompatTabs = (function() {
const ports = new Set();
browser.runtime.onConnect.addListener(port => {
ports.add(port);
port.onDisconnect.addListener(function() {
ports.delete(port);
});
});
async function broadcast(message) {
for (const port of ports) {
port.postMessage(message);
}
}
return { broadcast };
})();
function filterOverrides(overrides) {
return overrides
.filter(override => override.availableOnPlatform)
.map(override => {
const { id, active, bug, domain } = override;
return { id, active, bug, domain };
});
}
browser.runtime.onMessage.addListener(msg => {
switch (msg.command || msg) {
case "toggle": {
const id = msg.id;
const { type, what } = getOverrideOrInterventionById(id);
if (!what) {
return Promise.reject(
`No such override or intervention to toggle: ${id}`
);
}
portsToAboutCompatTabs
.broadcast({ toggling: id, active: what.active })
.then(async () => {
switch (type) {
case "interventions": {
if (what.active) {
await disableInjection(what);
} else {
await enableInjection(what);
}
break;
}
case "overrides": {
if (what.active) {
await disableOverride(what);
} else {
await enableOverride(what);
}
break;
}
}
portsToAboutCompatTabs.broadcast({
toggled: id,
active: what.active,
});
});
break;
}
case "getOverridesAndInterventions": {
return Promise.resolve({
overrides:
(UAOverridesEnabled && filterOverrides(UAOverrides)) || false,
interventions:
(InjectionsEnabled && filterOverrides(Injections)) || false,
});
}
}
return undefined;
});

View File

@ -0,0 +1,244 @@
/* 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 module */
/**
* For detailed information on our policies, and a documention on this format
* and its possibilites, please check the Mozilla-Wiki at
*
* https://wiki.mozilla.org/Compatibility/Go_Faster_Addon/Override_Policies_and_Workflows#User_Agent_overrides
*/
const AVAILABLE_INJECTIONS = [
{
id: "testbed-injection",
platform: "all",
domain: "webcompat-addon-testbed.herokuapp.com",
bug: "0000000",
hidden: true,
contentScripts: {
matches: ["*://webcompat-addon-testbed.herokuapp.com/*"],
css: [
{
file: "injections/css/bug0000000-testbed-css-injection.css",
},
],
js: [
{
file: "injections/js/bug0000000-testbed-js-injection.js",
},
],
runAt: "document_start",
},
},
{
id: "bug1452707",
platform: "desktop",
domain: "ib.absa.co.za",
bug: "1452707",
contentScripts: {
matches: ["https://ib.absa.co.za/*"],
js: [
{
file:
"injections/js/bug1452707-window.controllers-shim-ib.absa.co.za.js",
},
],
runAt: "document_start",
},
},
{
id: "bug1457335",
platform: "desktop",
domain: "histography.io",
bug: "1457335",
contentScripts: {
matches: ["*://histography.io/*"],
js: [
{
file: "injections/js/bug1457335-histography.io-ua-change.js",
},
],
runAt: "document_start",
},
},
{
id: "bug1472075",
platform: "desktop",
domain: "bankofamerica.com",
bug: "1472075",
contentScripts: {
matches: ["*://*.bankofamerica.com/*"],
js: [
{
file: "injections/js/bug1472075-bankofamerica.com-ua-change.js",
},
],
runAt: "document_start",
},
},
{
id: "bug1472081",
platform: "desktop",
domain: "election.gov.np",
bug: "1472081",
contentScripts: {
matches: ["http://202.166.205.141/bbvrs/*"],
js: [
{
file:
"injections/js/bug1472081-election.gov.np-window.sidebar-shim.js",
},
],
runAt: "document_start",
allFrames: true,
},
},
{
id: "bug1482066",
platform: "desktop",
domain: "portalminasnet.com",
bug: "1482066",
contentScripts: {
matches: ["*://portalminasnet.com/*"],
js: [
{
file:
"injections/js/bug1482066-portalminasnet.com-window.sidebar-shim.js",
},
],
runAt: "document_start",
allFrames: true,
},
},
{
id: "bug1526977",
platform: "desktop",
domain: "sreedharscce.in",
bug: "1526977",
contentScripts: {
matches: ["*://*.sreedharscce.in/authenticate"],
css: [
{
file: "injections/css/bug1526977-sreedharscce.in-login-fix.css",
},
],
},
},
{
id: "bug1518781",
platform: "desktop",
domain: "twitch.tv",
bug: "1518781",
contentScripts: {
matches: ["*://*.twitch.tv/*"],
css: [
{
file: "injections/css/bug1518781-twitch.tv-webkit-scrollbar.css",
},
],
},
},
{
id: "bug1551672",
platform: "android",
domain: "Sites using PDK 5 video",
bug: "1551672",
pdk5fix: {
urls: ["https://*/*/tpPdk.js", "https://*/*/pdk/js/*/*.js"],
types: ["script"],
},
},
{
id: "bug1305028",
platform: "desktop",
domain: "gaming.youtube.com",
bug: "1305028",
contentScripts: {
matches: ["*://gaming.youtube.com/*"],
css: [
{
file:
"injections/css/bug1305028-gaming.youtube.com-webkit-scrollbar.css",
},
],
},
},
{
id: "bug1432935-discord",
platform: "desktop",
domain: "discordapp.com",
bug: "1432935",
contentScripts: {
matches: ["*://discordapp.com/*"],
css: [
{
file:
"injections/css/bug1432935-discordapp.com-webkit-scorllbar-white-line.css",
},
],
},
},
{
id: "bug1432935-breitbart",
platform: "desktop",
domain: "breitbart.com",
bug: "1432935",
contentScripts: {
matches: ["*://*.breitbart.com/*"],
css: [
{
file: "injections/css/bug1432935-breitbart.com-webkit-scrollbar.css",
},
],
},
},
{
id: "bug1561371",
platform: "android",
domain: "mail.google.com",
bug: "1561371",
contentScripts: {
matches: ["*://mail.google.com/*"],
css: [
{
file:
"injections/css/bug1561371-mail.google.com-allow-horizontal-scrolling.css",
},
],
},
},
{
id: "bug1567610",
platform: "all",
domain: "dns.google.com",
bug: "1567610",
contentScripts: {
matches: ["*://dns.google.com/*"],
css: [
{
file: "injections/css/bug1567610-dns.google.com-moz-fit-content.css",
},
],
},
},
{
id: "bug1568256",
platform: "android",
domain: "zertifikate.commerzbank.de",
bug: "1568256",
contentScripts: {
matches: ["*://*.zertifikate.commerzbank.de/webforms/mobile/*"],
css: [
{
file: "injections/css/bug1568256-zertifikate.commerzbank.de-flex.css",
},
],
},
},
];
module.exports = AVAILABLE_INJECTIONS;

View File

@ -1,6 +1,10 @@
/* 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/. */
* 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 module */
/**
* For detailed information on our policies, and a documention on this format
@ -8,25 +12,19 @@
*
* https://wiki.mozilla.org/Compatibility/Go_Faster_Addon/Override_Policies_and_Workflows#User_Agent_overrides
*/
"use strict";
/* globals filterOverrides, portsToAboutCompatTabs, UAOverrides */
let UAOverridesEnabled = true;
for (const override of [
const AVAILABLE_UA_OVERRIDES = [
{
id: "testoverride",
id: "testbed-override",
platform: "all",
domain: "webcompat-addon-testcases.schub.io",
bug: "1287966",
domain: "webcompat-addon-testbed.herokuapp.com",
bug: "0000000",
hidden: true,
config: {
matches: ["*://webcompat-addon-testcases.schub.io/*"],
matches: ["*://webcompat-addon-testbed.herokuapp.com/*"],
uaTransformer: originalUA => {
return (
UAHelpers.getPrefix(originalUA) +
" AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36"
" AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36 for WebCompat"
);
},
},
@ -45,7 +43,11 @@ for (const override of [
domain: "rolb.santanderbank.com",
bug: "1563839",
config: {
matches: ["*://*.santander.co.uk/*", "*://rolb.santanderbank.com/*"],
matches: [
"*://*.santander.co.uk/*",
"*://bob.santanderbank.com/*",
"*://rolb.santanderbank.com/*",
],
uaTransformer: originalUA => {
return originalUA.replace("Gecko", "like Gecko");
},
@ -276,11 +278,45 @@ for (const override of [
},
},
},
]) {
UAOverrides.push(override);
}
/* globals browser */
{
/*
* Bug 1566253 - posts.google.com - Add UA override for posts.google.com
* WebCompat issue #17870 - https://webcompat.com/issues/17870
*
* posts.google.com displaying "Your browser doesn't support this page".
* Spoofing as Chrome works fine.
*/
id: "bug1566253",
platform: "android",
domain: "posts.google.com",
bug: "1566253",
config: {
matches: ["*://posts.google.com/*"],
uaTransformer: _ => {
return "Mozilla/5.0 (Linux; Android 6.0.1; SM-G900M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.101 Mobile Safari/537.36";
},
},
},
{
/*
* Bug 1567945 - Create UA override for beeg.com on Firefox Android
* WebCompat issue #16648 - https://webcompat.com/issues/16648
*
* beeg.com is hiding content of a page with video if Firefox exists in UA,
* replacing "Firefox" with an empty string makes the page load
*/
id: "bug1567945",
platform: "android",
domain: "beeg.com",
bug: "1567945",
config: {
matches: ["*://beeg.com/*"],
uaTransformer: originalUA => {
return originalUA.replace(/Firefox.+$/, "");
},
},
},
];
const UAHelpers = {
getPrefix(originalUA) {
@ -288,84 +324,4 @@ const UAHelpers = {
},
};
const ActiveListeners = new Map();
function enableOverride(override) {
if (override.active) {
return;
}
const { matches, uaTransformer } = override.config;
const listener = details => {
for (var header of details.requestHeaders) {
if (header.name.toLowerCase() === "user-agent") {
header.value = uaTransformer(header.value);
}
}
return { requestHeaders: details.requestHeaders };
};
browser.webRequest.onBeforeSendHeaders.addListener(
listener,
{ urls: matches },
["blocking", "requestHeaders"]
);
ActiveListeners.set(override, listener);
override.active = true;
}
async function registerUAOverrides() {
const platformMatches = ["all"];
let platformInfo = await browser.runtime.getPlatformInfo();
platformMatches.push(platformInfo.os == "android" ? "android" : "desktop");
for (const override of UAOverrides) {
if (platformMatches.includes(override.platform)) {
override.availableOnPlatform = true;
enableOverride(override);
}
}
UAOverridesEnabled = true;
portsToAboutCompatTabs.broadcast({
overridesChanged: filterOverrides(UAOverrides),
});
}
function unregisterUAOverrides() {
for (const override of UAOverrides) {
disableOverride(override);
}
UAOverridesEnabled = false;
portsToAboutCompatTabs.broadcast({ overridesChanged: false });
}
function disableOverride(override) {
if (!override.active) {
return;
}
browser.webRequest.onBeforeSendHeaders.removeListener(
ActiveListeners.get(override)
);
override.active = false;
ActiveListeners.delete(override);
}
const OVERRIDE_PREF = "perform_ua_overrides";
function checkOverridePref() {
browser.aboutConfigPrefs.getPref(OVERRIDE_PREF).then(value => {
if (value === undefined) {
browser.aboutConfigPrefs.setPref(OVERRIDE_PREF, true);
} else if (value === false) {
unregisterUAOverrides();
} else {
registerUAOverrides();
}
});
}
browser.aboutConfigPrefs.onPrefChange.addListener(
checkOverridePref,
OVERRIDE_PREF
);
checkOverridePref();
module.exports = AVAILABLE_UA_OVERRIDES;

View File

@ -1,335 +0,0 @@
/**
* For detailed information on our policies, and a documention on this format
* and its possibilites, please check the Mozilla-Wiki at
*
* https://wiki.mozilla.org/Compatibility/Go_Faster_Addon/Override_Policies_and_Workflows#User_Agent_overrides
*/
"use strict";
/* globals browser, filterOverrides, Injections, portsToAboutCompatTabs */
let InjectionsEnabled = true;
for (const injection of [
{
id: "testinjection",
platform: "all",
domain: "webcompat-addon-testcases.schub.io",
bug: "1287966",
contentScripts: {
matches: ["*://webcompat-addon-testcases.schub.io/*"],
css: [{ file: "injections/css/bug0000000-dummy-css-injection.css" }],
js: [{ file: "injections/js/bug0000000-dummy-js-injection.js" }],
runAt: "document_start",
},
},
{
id: "bug1452707",
platform: "desktop",
domain: "ib.absa.co.za",
bug: "1452707",
contentScripts: {
matches: ["https://ib.absa.co.za/*"],
js: [
{
file:
"injections/js/bug1452707-window.controllers-shim-ib.absa.co.za.js",
},
],
runAt: "document_start",
},
},
{
id: "bug1457335",
platform: "desktop",
domain: "histography.io",
bug: "1457335",
contentScripts: {
matches: ["*://histography.io/*"],
js: [{ file: "injections/js/bug1457335-histography.io-ua-change.js" }],
runAt: "document_start",
},
},
{
id: "bug1472075",
platform: "desktop",
domain: "bankofamerica.com",
bug: "1472075",
contentScripts: {
matches: ["*://*.bankofamerica.com/*"],
js: [{ file: "injections/js/bug1472075-bankofamerica.com-ua-change.js" }],
runAt: "document_start",
},
},
{
id: "bug1472081",
platform: "desktop",
domain: "election.gov.np",
bug: "1472081",
contentScripts: {
matches: ["http://202.166.205.141/bbvrs/*"],
js: [
{
file:
"injections/js/bug1472081-election.gov.np-window.sidebar-shim.js",
},
],
runAt: "document_start",
allFrames: true,
},
},
{
id: "bug1482066",
platform: "desktop",
domain: "portalminasnet.com",
bug: "1482066",
contentScripts: {
matches: ["*://portalminasnet.com/*"],
js: [
{
file:
"injections/js/bug1482066-portalminasnet.com-window.sidebar-shim.js",
},
],
runAt: "document_start",
allFrames: true,
},
},
{
id: "bug1526977",
platform: "desktop",
domain: "sreedharscce.in",
bug: "1526977",
contentScripts: {
matches: ["*://*.sreedharscce.in/authenticate"],
css: [
{ file: "injections/css/bug1526977-sreedharscce.in-login-fix.css" },
],
},
},
{
id: "bug1518781",
platform: "desktop",
domain: "twitch.tv",
bug: "1518781",
contentScripts: {
matches: ["*://*.twitch.tv/*"],
css: [
{ file: "injections/css/bug1518781-twitch.tv-webkit-scrollbar.css" },
],
},
},
{
id: "bug1551672",
platform: "android",
domain: "Sites using PDK 5 video",
bug: "1551672",
pdk5fix: {
urls: ["https://*/*/tpPdk.js", "https://*/*/pdk/js/*/*.js"],
types: ["script"],
},
},
{
id: "bug1305028",
platform: "desktop",
domain: "gaming.youtube.com",
bug: "1305028",
contentScripts: {
matches: ["*://gaming.youtube.com/*"],
css: [
{
file:
"injections/css/bug1305028-gaming.youtube.com-webkit-scrollbar.css",
},
],
},
},
{
id: "bug1432935-discord",
platform: "desktop",
domain: "discordapp.com",
bug: "1432935",
contentScripts: {
matches: ["*://discordapp.com/*"],
css: [
{
file:
"injections/css/bug1432935-discordapp.com-webkit-scorllbar-white-line.css",
},
],
},
},
{
id: "bug1432935-breitbart",
platform: "desktop",
domain: "breitbart.com",
bug: "1432935",
contentScripts: {
matches: ["*://*.breitbart.com/*"],
css: [
{
file: "injections/css/bug1432935-breitbart.com-webkit-scrollbar.css",
},
],
},
},
{
id: "bug1561371",
platform: "android",
domain: "mail.google.com",
bug: "1561371",
contentScripts: {
matches: ["*://mail.google.com/*"],
css: [
{
file:
"injections/css/bug1561371-mail.google.com-allow-horizontal-scrolling.css",
},
],
},
},
]) {
Injections.push(injection);
}
let port = browser.runtime.connect();
const ActiveInjections = new Map();
async function registerContentScripts() {
const platformMatches = ["all"];
let platformInfo = await browser.runtime.getPlatformInfo();
platformMatches.push(platformInfo.os == "android" ? "android" : "desktop");
for (const injection of Injections) {
if (platformMatches.includes(injection.platform)) {
injection.availableOnPlatform = true;
await enableInjection(injection);
}
}
InjectionsEnabled = true;
portsToAboutCompatTabs.broadcast({
interventionsChanged: filterOverrides(Injections),
});
}
function replaceStringInRequest(
requestId,
inString,
outString,
inEncoding = "utf-8"
) {
const filter = browser.webRequest.filterResponseData(requestId);
const decoder = new TextDecoder(inEncoding);
const encoder = new TextEncoder();
const RE = new RegExp(inString, "g");
const carryoverLength = inString.length;
let carryover = "";
filter.ondata = event => {
const replaced = (
carryover + decoder.decode(event.data, { stream: true })
).replace(RE, outString);
filter.write(encoder.encode(replaced.slice(0, -carryoverLength)));
carryover = replaced.slice(-carryoverLength);
};
filter.onstop = event => {
if (carryover.length) {
filter.write(encoder.encode(carryover));
}
filter.close();
};
}
async function enableInjection(injection) {
if (injection.active) {
return;
}
if ("pdk5fix" in injection) {
const { urls, types } = injection.pdk5fix;
const listener = (injection.pdk5fix.listener = ({ requestId }) => {
replaceStringInRequest(
requestId,
"VideoContextChromeAndroid",
"VideoContextAndroid"
);
return {};
});
browser.webRequest.onBeforeRequest.addListener(listener, { urls, types }, [
"blocking",
]);
injection.active = true;
return;
}
try {
const handle = await browser.contentScripts.register(
injection.contentScripts
);
ActiveInjections.set(injection, handle);
injection.active = true;
} catch (ex) {
console.error(
"Registering WebCompat GoFaster content scripts failed: ",
ex
);
}
}
function unregisterContentScripts() {
for (const injection of Injections) {
disableInjection(injection);
}
InjectionsEnabled = false;
portsToAboutCompatTabs.broadcast({ interventionsChanged: false });
}
async function disableInjection(injection) {
if (!injection.active) {
return;
}
if (injection.pdk5fix) {
const { listener } = injection.pdk5fix;
browser.webRequest.onBeforeRequest.removeListener(listener);
injection.active = false;
delete injection.pdk5fix.listener;
return;
}
const contentScript = ActiveInjections.get(injection);
await contentScript.unregister();
ActiveInjections.delete(injection);
injection.active = false;
}
port.onMessage.addListener(message => {
switch (message.type) {
case "injection-pref-changed":
if (message.prefState) {
registerContentScripts();
} else {
unregisterContentScripts();
}
break;
}
});
const INJECTION_PREF = "perform_injections";
function checkInjectionPref() {
browser.aboutConfigPrefs.getPref(INJECTION_PREF).then(value => {
if (value === undefined) {
browser.aboutConfigPrefs.setPref(INJECTION_PREF, true);
} else if (value === false) {
unregisterContentScripts();
} else {
registerContentScripts();
}
});
}
browser.aboutConfigPrefs.onPrefChange.addListener(
checkInjectionPref,
INJECTION_PREF
);
checkInjectionPref();

View File

@ -0,0 +1,12 @@
/**
* dns.google.com - Page content is shifted to the left side of the page
* Bug #1567610 - https://bugzilla.mozilla.org/show_bug.cgi?id=1567610
* WebCompat issue #22494 - https://webcompat.com/issues/22494
*
* Affected element is styled with width:fit-content; which is not
* supported by Firefox yet, see https://bugzilla.mozilla.org/show_bug.cgi?id=1495868
* Adding -moz-fit-content fixes the issue
*/
main > .ng-star-inserted > .centered {
width: -moz-fit-content;
}

View File

@ -0,0 +1,12 @@
/**
* zertifikate.commerzbank.de - clickable elements on the page are collapsed
* Bug #1568256 - https://bugzilla.mozilla.org/show_bug.cgi?id=1568256
* WebCompat issue #9102 - https://webcompat.com/issues/9102
*
* Affected elements have display:-webkit-box and display:flex applied, however,
* listed in wrong order, so display:-webkit-box is becoming the final say.
* Adding display: flex for those elements fixes the issue
*/
.x-layout-box {
display: flex !important;
}

View File

@ -1,7 +1,3 @@
/* 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 exportFunction */

View File

@ -1,7 +0,0 @@
# 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/.
[features/webcompat@mozilla.org] chrome.jar:
res/AboutCompat.jsm (AboutCompat.jsm)
res/aboutPageProcessScript.js (aboutPageProcessScript.js)

View File

@ -0,0 +1,123 @@
/* 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";
/* global browser, module */
class AboutCompatBroker {
constructor(bindings) {
this.portsToAboutCompatTabs = this.buildPorts();
this._injections = bindings.injections;
this._injections.bindAboutCompatBroker(this);
this._uaOverrides = bindings.uaOverrides;
this._uaOverrides.bindAboutCompatBroker(this);
}
buildPorts() {
const ports = new Set();
browser.runtime.onConnect.addListener(port => {
ports.add(port);
port.onDisconnect.addListener(function() {
ports.delete(port);
});
});
async function broadcast(message) {
for (const port of ports) {
port.postMessage(message);
}
}
return { broadcast };
}
filterOverrides(overrides) {
return overrides
.filter(override => override.availableOnPlatform)
.map(override => {
const { id, active, bug, domain, hidden } = override;
return { id, active, bug, domain, hidden };
});
}
getOverrideOrInterventionById(id) {
for (const [type, things] of Object.entries({
overrides: this._uaOverrides.getAvailableOverrides(),
interventions: this._injections.getAvailableInjections(),
})) {
for (const what of things) {
if (what.id === id) {
return { type, what };
}
}
}
return {};
}
bootup() {
browser.runtime.onMessage.addListener(msg => {
switch (msg.command || msg) {
case "toggle": {
const id = msg.id;
const { type, what } = this.getOverrideOrInterventionById(id);
if (!what) {
return Promise.reject(
`No such override or intervention to toggle: ${id}`
);
}
this.portsToAboutCompatTabs
.broadcast({ toggling: id, active: what.active })
.then(async () => {
switch (type) {
case "interventions": {
if (what.active) {
await this._injections.disableInjection(what);
} else {
await this._injections.enableInjection(what);
}
break;
}
case "overrides": {
if (what.active) {
await this._uaOverrides.disableOverride(what);
} else {
await this._uaOverrides.enableOverride(what);
}
break;
}
}
this.portsToAboutCompatTabs.broadcast({
toggled: id,
active: what.active,
});
});
break;
}
case "getOverridesAndInterventions": {
return Promise.resolve({
overrides:
(this._uaOverrides.isEnabled() &&
this.filterOverrides(
this._uaOverrides.getAvailableOverrides()
)) ||
false,
interventions:
(this._injections.isEnabled() &&
this.filterOverrides(
this._injections.getAvailableInjections()
)) ||
false,
});
}
}
return undefined;
});
}
}
module.exports = AboutCompatBroker;

View File

@ -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";
/* globals browser, module */
class Injections {
constructor(availableInjections) {
this.INJECTION_PREF = "perform_injections";
this._injectionsEnabled = true;
this._availableInjections = availableInjections;
this._activeInjections = new Map();
}
bindAboutCompatBroker(broker) {
this._aboutCompatBroker = broker;
}
bootup() {
browser.aboutConfigPrefs.onPrefChange.addListener(() => {
this.checkInjectionPref();
}, this.INJECTION_PREF);
this.checkInjectionPref();
}
checkInjectionPref() {
browser.aboutConfigPrefs.getPref(this.INJECTION_PREF).then(value => {
if (value === undefined) {
browser.aboutConfigPrefs.setPref(this.INJECTION_PREF, true);
} else if (value === false) {
this.unregisterContentScripts();
} else {
this.registerContentScripts();
}
});
}
getAvailableInjections() {
return this._availableInjections;
}
isEnabled() {
return this._injectionsEnabled;
}
async registerContentScripts() {
const platformMatches = ["all"];
let platformInfo = await browser.runtime.getPlatformInfo();
platformMatches.push(platformInfo.os == "android" ? "android" : "desktop");
for (const injection of this._availableInjections) {
if (platformMatches.includes(injection.platform)) {
injection.availableOnPlatform = true;
await this.enableInjection(injection);
}
}
this._injectionsEnabled = true;
this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
interventionsChanged: this._aboutCompatBroker.filterOverrides(
this._availableInjections
),
});
}
replaceStringInRequest(requestId, inString, outString, inEncoding = "utf-8") {
const filter = browser.webRequest.filterResponseData(requestId);
const decoder = new TextDecoder(inEncoding);
const encoder = new TextEncoder();
const RE = new RegExp(inString, "g");
const carryoverLength = inString.length;
let carryover = "";
filter.ondata = event => {
const replaced = (
carryover + decoder.decode(event.data, { stream: true })
).replace(RE, outString);
filter.write(encoder.encode(replaced.slice(0, -carryoverLength)));
carryover = replaced.slice(-carryoverLength);
};
filter.onstop = event => {
if (carryover.length) {
filter.write(encoder.encode(carryover));
}
filter.close();
};
}
async enableInjection(injection) {
if (injection.active) {
return;
}
if ("pdk5fix" in injection) {
const { urls, types } = injection.pdk5fix;
const listener = (injection.pdk5fix.listener = ({ requestId }) => {
this.replaceStringInRequest(
requestId,
"VideoContextChromeAndroid",
"VideoContextAndroid"
);
return {};
});
browser.webRequest.onBeforeRequest.addListener(
listener,
{ urls, types },
["blocking"]
);
injection.active = true;
return;
}
try {
const handle = await browser.contentScripts.register(
injection.contentScripts
);
this._activeInjections.set(injection, handle);
injection.active = true;
} catch (ex) {
console.error(
"Registering WebCompat GoFaster content scripts failed: ",
ex
);
}
}
unregisterContentScripts() {
for (const injection of this._availableInjections) {
this.disableInjection(injection);
}
this._injectionsEnabled = false;
this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
interventionsChanged: false,
});
}
async disableInjection(injection) {
if (!injection.active) {
return;
}
if (injection.pdk5fix) {
const { listener } = injection.pdk5fix;
browser.webRequest.onBeforeRequest.removeListener(listener);
injection.active = false;
delete injection.pdk5fix.listener;
return;
}
const contentScript = this._activeInjections.get(injection);
await contentScript.unregister();
this._activeInjections.delete(injection);
injection.active = false;
}
}
module.exports = Injections;

View File

@ -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/. */
"use strict";
/**
* We cannot yet use proper JS modules within webextensions, as support for them
* is highly experimental and highly instable. So we end up just including all
* the JS files we need as separate background scripts, and since they all are
* executed within the same context, this works for our in-browser deployment.
*
* However, this code is tracked outside of mozilla-central, and we work on
* shipping this code in other products, like android-components as well.
* Because of that, we have automated tests running within that repository. To
* make our lives easier, we add `module.exports` statements to the JS source
* files, so we can easily import their contents into our NodeJS-based test
* suite.
*
* This works fine, but obviously, `module` is not defined when running
* in-browser. So let's use this empty object as a shim, so we don't run into
* runtime exceptions because of that.
*/
var module = {};

View File

@ -0,0 +1,119 @@
/* 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, module */
class UAOverrides {
constructor(availableOverrides) {
this.OVERRIDE_PREF = "perform_ua_overrides";
this._overridesEnabled = true;
this._availableOverrides = availableOverrides;
this._activeListeners = new Map();
}
bindAboutCompatBroker(broker) {
this._aboutCompatBroker = broker;
}
bootup() {
browser.aboutConfigPrefs.onPrefChange.addListener(() => {
this.checkOverridePref();
}, this.OVERRIDE_PREF);
this.checkOverridePref();
}
checkOverridePref() {
browser.aboutConfigPrefs.getPref(this.OVERRIDE_PREF).then(value => {
if (value === undefined) {
browser.aboutConfigPrefs.setPref(this.OVERRIDE_PREF, true);
} else if (value === false) {
this.unregisterUAOverrides();
} else {
this.registerUAOverrides();
}
});
}
getAvailableOverrides() {
return this._availableOverrides;
}
isEnabled() {
return this._overridesEnabled;
}
enableOverride(override) {
if (override.active) {
return;
}
const { matches, uaTransformer } = override.config;
const listener = details => {
for (const header of details.requestHeaders) {
if (header.name.toLowerCase() === "user-agent") {
header.value = uaTransformer(header.value);
}
}
return { requestHeaders: details.requestHeaders };
};
browser.webRequest.onBeforeSendHeaders.addListener(
listener,
{ urls: matches },
["blocking", "requestHeaders"]
);
this._activeListeners.set(override, listener);
override.active = true;
}
async registerUAOverrides() {
const platformMatches = ["all"];
let platformInfo = await browser.runtime.getPlatformInfo();
platformMatches.push(platformInfo.os == "android" ? "android" : "desktop");
for (const override of this._availableOverrides) {
if (platformMatches.includes(override.platform)) {
override.availableOnPlatform = true;
this.enableOverride(override);
}
}
this._overridesEnabled = true;
this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
overridesChanged: this._aboutCompatBroker.filterOverrides(
this._availableOverrides
),
});
}
unregisterUAOverrides() {
for (const override of this._availableOverrides) {
this.disableOverride(override);
}
this._overridesEnabled = false;
this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
overridesChanged: false,
});
}
disableOverride(override) {
if (!override.active) {
return;
}
browser.webRequest.onBeforeSendHeaders.removeListener(
this._activeListeners.get(override)
);
override.active = false;
this._activeListeners.delete(override);
}
}
module.exports = UAOverrides;

View File

@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "Web Compat",
"description": "Urgent post-release fixes for web compatibility.",
"version": "4.4.0",
"version": "5.0.2",
"applications": {
"gecko": {
@ -13,24 +13,24 @@
"experiment_apis": {
"aboutConfigPrefs": {
"schema": "aboutConfigPrefs.json",
"schema": "experiment-apis/aboutConfigPrefs.json",
"parent": {
"scopes": ["addon_parent"],
"script": "aboutConfigPrefs.js",
"script": "experiment-apis/aboutConfigPrefs.js",
"paths": [["aboutConfigPrefs"]]
}
},
"aboutPage": {
"schema": "aboutPage.json",
"schema": "about-compat/aboutPage.json",
"parent": {
"scopes": ["addon_parent"],
"script": "aboutPage.js",
"script": "about-compat/aboutPage.js",
"events": ["startup"]
}
}
},
"content_security_policy": "script-src 'self' 'sha256-HbSjs39Y0thRGfO3RHrNzLPKyC/tq6FdIuP3jEBAcJQ='; default-src 'self'; base-uri moz-extension://*;",
"content_security_policy": "script-src 'self' 'sha256-MmZkN2QaIHhfRWPZ8TVRjijTn5Ci1iEabtTEWrt9CCo='; default-src 'self'; base-uri moz-extension://*;",
"permissions": [
"webRequest",
@ -40,9 +40,13 @@
"background": {
"scripts": [
"background.js",
"injections.js",
"ua_overrides.js"
"lib/module_shim.js",
"data/injections.js",
"data/ua_overrides.js",
"lib/about_compat_broker.js",
"lib/injections.js",
"lib/ua_overrides.js",
"run.js"
]
}
}

View File

@ -8,31 +8,44 @@ DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION']
FINAL_TARGET_FILES.features['webcompat@mozilla.org'] += [
'aboutCompat.css',
'aboutCompat.html',
'aboutCompat.js',
'aboutConfigPrefs.js',
'aboutConfigPrefs.json',
'aboutPage.js',
'aboutPage.json',
'background.js',
'injections.js',
'manifest.json',
'ua_overrides.js'
'run.js'
]
FINAL_TARGET_FILES.features['webcompat@mozilla.org']['about-compat'] += [
'about-compat/aboutCompat.css',
'about-compat/aboutCompat.html',
'about-compat/aboutCompat.js',
'about-compat/AboutCompat.jsm',
'about-compat/aboutPage.js',
'about-compat/aboutPage.json',
'about-compat/aboutPageProcessScript.js'
]
FINAL_TARGET_FILES.features['webcompat@mozilla.org']['data'] += [
'data/injections.js',
'data/ua_overrides.js'
]
FINAL_TARGET_FILES.features['webcompat@mozilla.org']['experiment-apis'] += [
'experiment-apis/aboutConfigPrefs.js',
'experiment-apis/aboutConfigPrefs.json'
]
FINAL_TARGET_FILES.features['webcompat@mozilla.org']['injections']['css'] += [
'injections/css/bug0000000-dummy-css-injection.css',
'injections/css/bug0000000-testbed-css-injection.css',
'injections/css/bug1305028-gaming.youtube.com-webkit-scrollbar.css',
'injections/css/bug1432935-breitbart.com-webkit-scrollbar.css',
'injections/css/bug1432935-discordapp.com-webkit-scorllbar-white-line.css',
'injections/css/bug1518781-twitch.tv-webkit-scrollbar.css',
'injections/css/bug1526977-sreedharscce.in-login-fix.css',
'injections/css/bug1561371-mail.google.com-allow-horizontal-scrolling.css'
'injections/css/bug1561371-mail.google.com-allow-horizontal-scrolling.css',
'injections/css/bug1567610-dns.google.com-moz-fit-content.css',
'injections/css/bug1568256-zertifikate.commerzbank.de-flex.css'
]
FINAL_TARGET_FILES.features['webcompat@mozilla.org']['injections']['js'] += [
'injections/js/bug0000000-dummy-js-injection.js',
'injections/js/bug0000000-testbed-js-injection.js',
'injections/js/bug1452707-window.controllers-shim-ib.absa.co.za.js',
'injections/js/bug1457335-histography.io-ua-change.js',
'injections/js/bug1472075-bankofamerica.com-ua-change.js',
@ -40,7 +53,12 @@ FINAL_TARGET_FILES.features['webcompat@mozilla.org']['injections']['js'] += [
'injections/js/bug1482066-portalminasnet.com-window.sidebar-shim.js'
]
JAR_MANIFESTS += ['jar.mn']
FINAL_TARGET_FILES.features['webcompat@mozilla.org']['lib'] += [
'lib/about_compat_broker.js',
'lib/injections.js',
'lib/module_shim.js',
'lib/ua_overrides.js'
]
with Files('**'):
BUG_COMPONENT = ('Web Compatibility Tools', 'Go Faster')

View File

@ -0,0 +1,20 @@
/* 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 AVAILABLE_INJECTIONS, AVAILABLE_UA_OVERRIDES, AboutCompatBroker,
Injections, UAOverrides */
const injections = new Injections(AVAILABLE_INJECTIONS);
const uaOverrides = new UAOverrides(AVAILABLE_UA_OVERRIDES);
const aboutCompatBroker = new AboutCompatBroker({
injections,
uaOverrides,
});
aboutCompatBroker.bootup();
injections.bootup();
uaOverrides.bootup();