Bug 1583225 - Import WebCompat GoFaster 6.1.0 sources; r=miketaylr, a=RyanVM
authorThomas Wisniewski <twisniewski@mozilla.com>
Tue, 24 Sep 2019 13:08:42 +0000
changeset 545318 8bba3b8515e02b393402c77ecee96dfd20bbb926
parent 545317 5f36ee95708ae40775c45b18e6712b26302ca27a
child 545319 dfac7620edac674b2afc3856c8d476f050739c76
push id2152
push userryanvm@gmail.com
push dateThu, 26 Sep 2019 16:56:47 +0000
treeherdermozilla-release@8bba3b8515e0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmiketaylr, RyanVM
bugs1583225
milestone69.0.2
Bug 1583225 - Import WebCompat GoFaster 6.1.0 sources; r=miketaylr, a=RyanVM Import WebCompat GoFaster 6.1.0 sources Differential Revision: https://phabricator.services.mozilla.com/D46814
browser/extensions/webcompat/data/injections.js
browser/extensions/webcompat/data/ua_overrides.js
browser/extensions/webcompat/experiment-apis/experiments.js
browser/extensions/webcompat/experiment-apis/experiments.json
browser/extensions/webcompat/experiment-apis/sharedPreferences.js
browser/extensions/webcompat/experiment-apis/sharedPreferences.json
browser/extensions/webcompat/injections/css/bug1561371-mail.google.com-allow-horizontal-scrolling.css
browser/extensions/webcompat/injections/css/bug1568908-console.cloud.google.com-scrollbar-fix.css
browser/extensions/webcompat/injections/css/bug1570119-teamcoco.com-scrollbar-width.css
browser/extensions/webcompat/injections/css/bug1570328-developer-apple.com-transform-scale.css
browser/extensions/webcompat/injections/css/bug1574973-patch.com-dropdown-menu-fix.css
browser/extensions/webcompat/injections/css/bug1575000-apply.lloydsbank.co.uk-radio-buttons-fix.css
browser/extensions/webcompat/injections/css/bug1575011-holiday-weather.com-scrolling-fix.css
browser/extensions/webcompat/injections/css/bug1575017-dunkindonuts.com-flex-basis.css
browser/extensions/webcompat/injections/css/bug1577270-binance.com-calc-height-fix.css
browser/extensions/webcompat/injections/css/bug1577297-kitkat.com.au-slider-width-fix.css
browser/extensions/webcompat/injections/js/bug1570856-medium.com-menu-isTier1.js
browser/extensions/webcompat/injections/js/bug1577245-salesforce-communities-hide-unsupported.js
browser/extensions/webcompat/injections/js/bug1579159-m.tailieu.vn-pdfjs-worker-disable.js
browser/extensions/webcompat/lib/custom_functions.js
browser/extensions/webcompat/lib/google.js
browser/extensions/webcompat/lib/injections.js
browser/extensions/webcompat/lib/ua_overrides.js
browser/extensions/webcompat/manifest.json
browser/extensions/webcompat/moz.build
browser/extensions/webcompat/run.js
mobile/android/extensions/webcompat/data/injections.js
mobile/android/extensions/webcompat/data/ua_overrides.js
mobile/android/extensions/webcompat/experiment-apis/experiments.js
mobile/android/extensions/webcompat/experiment-apis/experiments.json
mobile/android/extensions/webcompat/experiment-apis/sharedPreferences.js
mobile/android/extensions/webcompat/experiment-apis/sharedPreferences.json
mobile/android/extensions/webcompat/injections/css/bug1561371-mail.google.com-allow-horizontal-scrolling.css
mobile/android/extensions/webcompat/injections/css/bug1568908-console.cloud.google.com-scrollbar-fix.css
mobile/android/extensions/webcompat/injections/css/bug1570119-teamcoco.com-scrollbar-width.css
mobile/android/extensions/webcompat/injections/css/bug1570328-developer-apple.com-transform-scale.css
mobile/android/extensions/webcompat/injections/css/bug1574973-patch.com-dropdown-menu-fix.css
mobile/android/extensions/webcompat/injections/css/bug1575000-apply.lloydsbank.co.uk-radio-buttons-fix.css
mobile/android/extensions/webcompat/injections/css/bug1575011-holiday-weather.com-scrolling-fix.css
mobile/android/extensions/webcompat/injections/css/bug1575017-dunkindonuts.com-flex-basis.css
mobile/android/extensions/webcompat/injections/css/bug1577270-binance.com-calc-height-fix.css
mobile/android/extensions/webcompat/injections/css/bug1577297-kitkat.com.au-slider-width-fix.css
mobile/android/extensions/webcompat/injections/js/bug1570856-medium.com-menu-isTier1.js
mobile/android/extensions/webcompat/injections/js/bug1577245-salesforce-communities-hide-unsupported.js
mobile/android/extensions/webcompat/injections/js/bug1579159-m.tailieu.vn-pdfjs-worker-disable.js
mobile/android/extensions/webcompat/lib/custom_functions.js
mobile/android/extensions/webcompat/lib/google.js
mobile/android/extensions/webcompat/lib/injections.js
mobile/android/extensions/webcompat/lib/ua_overrides.js
mobile/android/extensions/webcompat/manifest.json
mobile/android/extensions/webcompat/moz.build
mobile/android/extensions/webcompat/run.js
--- a/browser/extensions/webcompat/data/injections.js
+++ b/browser/extensions/webcompat/data/injections.js
@@ -26,100 +26,147 @@ const AVAILABLE_INJECTIONS = [
           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/*"],
+      allFrames: true,
       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/*"],
+      allFrames: true,
       js: [
         {
           file:
             "injections/js/bug1482066-portalminasnet.com-window.sidebar-shim.js",
         },
       ],
-      runAt: "document_start",
+    },
+  },
+  {
+    id: "bug1570856",
+    platform: "android",
+    domain: "medium.com",
+    bug: "1570856",
+    contentScripts: {
+      matches: ["*://medium.com/*"],
+      js: [
+        {
+          file: "injections/js/bug1570856-medium.com-menu-isTier1.js",
+        },
+      ],
       allFrames: true,
     },
   },
   {
+    id: "bug1579159",
+    platform: "android",
+    domain: "m.tailieu.vn",
+    bug: "1579159",
+    contentScripts: {
+      matches: ["*://m.tailieu.vn/*", "*://m.elib.vn/*"],
+      js: [
+        {
+          file: "injections/js/bug1579159-m.tailieu.vn-pdfjs-worker-disable.js",
+        },
+      ],
+      allFrames: true,
+    },
+  },
+  {
+    id: "bug1577245",
+    platform: "android",
+    domain: "help.pandora.com",
+    bug: "1577245",
+    contentScripts: {
+      matches: [
+        "https://faq.usps.com/*",
+        "https://help.duo.com/*",
+        "https://help.hulu.com/*",
+        "https://help.pandora.com/*",
+        "https://my211.force.com/*",
+        "https://support.paypay.ne.jp/*",
+        "https://usps.force.com/*",
+      ],
+      js: [
+        {
+          file:
+            "injections/js/bug1577245-salesforce-communities-hide-unsupported.js",
+        },
+      ],
+    },
+  },
+  {
     id: "bug1526977",
     platform: "desktop",
     domain: "sreedharscce.in",
     bug: "1526977",
     contentScripts: {
       matches: ["*://*.sreedharscce.in/authenticate"],
       css: [
         {
@@ -142,20 +189,35 @@ const AVAILABLE_INJECTIONS = [
       ],
     },
   },
   {
     id: "bug1551672",
     platform: "android",
     domain: "Sites using PDK 5 video",
     bug: "1551672",
-    pdk5fix: {
+    data: {
       urls: ["https://*/*/tpPdk.js", "https://*/*/pdk/js/*/*.js"],
       types: ["script"],
     },
+    customFunc: "pdk5fix",
+  },
+  {
+    id: "bug1577870",
+    platform: "desktop",
+    domain: "slideshare.net",
+    bug: "1577870",
+    data: {
+      urls: ["https://*.linkedin.com/tscp-serving/dtag*"],
+      contentType: {
+        name: "content-type",
+        value: "text/html; charset=utf-8",
+      },
+    },
+    customFunc: "dtagFix",
   },
   {
     id: "bug1305028",
     platform: "desktop",
     domain: "gaming.youtube.com",
     bug: "1305028",
     contentScripts: {
       matches: ["*://gaming.youtube.com/*"],
@@ -212,17 +274,17 @@ const AVAILABLE_INJECTIONS = [
     },
   },
   {
     id: "bug1567610",
     platform: "all",
     domain: "dns.google.com",
     bug: "1567610",
     contentScripts: {
-      matches: ["*://dns.google.com/*"],
+      matches: ["*://dns.google.com/*", "*://dns.google/*"],
       css: [
         {
           file: "injections/css/bug1567610-dns.google.com-moz-fit-content.css",
         },
       ],
     },
   },
   {
@@ -234,11 +296,141 @@ const AVAILABLE_INJECTIONS = [
       matches: ["*://*.zertifikate.commerzbank.de/webforms/mobile/*"],
       css: [
         {
           file: "injections/css/bug1568256-zertifikate.commerzbank.de-flex.css",
         },
       ],
     },
   },
+  {
+    id: "bug1568908",
+    platform: "desktop",
+    domain: "console.cloud.google.com",
+    bug: "1568908",
+    contentScripts: {
+      matches: ["*://*.console.cloud.google.com/*"],
+      css: [
+        {
+          file:
+            "injections/css/bug1568908-console.cloud.google.com-scrollbar-fix.css",
+        },
+      ],
+    },
+  },
+  {
+    id: "bug1570119",
+    platform: "desktop",
+    domain: "teamcoco.com",
+    bug: "1570119",
+    contentScripts: {
+      matches: ["*://teamcoco.com/*"],
+      css: [
+        {
+          file: "injections/css/bug1570119-teamcoco.com-scrollbar-width.css",
+        },
+      ],
+    },
+  },
+  {
+    id: "bug1570328",
+    platform: "android",
+    domain: "developer.apple.com",
+    bug: "1570328",
+    contentScripts: {
+      matches: ["*://developer.apple.com/*"],
+      css: [
+        {
+          file:
+            "injections/css/bug1570328-developer-apple.com-transform-scale.css",
+        },
+      ],
+    },
+  },
+  {
+    id: "bug1574973",
+    platform: "android",
+    domain: "patch.com",
+    bug: "1574973",
+    contentScripts: {
+      matches: ["*://patch.com/*"],
+      css: [
+        {
+          file: "injections/css/bug1574973-patch.com-dropdown-menu-fix.css",
+        },
+      ],
+    },
+  },
+  {
+    id: "bug1575000",
+    platform: "all",
+    domain: "apply.lloydsbank.co.uk",
+    bug: "1575000",
+    contentScripts: {
+      matches: ["*://apply.lloydsbank.co.uk/*"],
+      css: [
+        {
+          file:
+            "injections/css/bug1575000-apply.lloydsbank.co.uk-radio-buttons-fix.css",
+        },
+      ],
+    },
+  },
+  {
+    id: "bug1575011",
+    platform: "android",
+    domain: "holiday-weather.com",
+    bug: "1575011",
+    contentScripts: {
+      matches: ["*://*.holiday-weather.com/*"],
+      css: [
+        {
+          file:
+            "injections/css/bug1575011-holiday-weather.com-scrolling-fix.css",
+        },
+      ],
+    },
+  },
+  {
+    id: "bug1575017",
+    platform: "desktop",
+    domain: "dunkindonuts.com",
+    bug: "1575017",
+    contentScripts: {
+      matches: ["*://*.dunkindonuts.com/en/sign-in*"],
+      css: [
+        {
+          file: "injections/css/bug1575017-dunkindonuts.com-flex-basis.css",
+        },
+      ],
+    },
+  },
+  {
+    id: "bug1577270",
+    platform: "android",
+    domain: "binance.com",
+    bug: "1577270",
+    contentScripts: {
+      matches: ["*://*.binance.com/*"],
+      css: [
+        {
+          file: "injections/css/bug1577270-binance.com-calc-height-fix.css",
+        },
+      ],
+    },
+  },
+  {
+    id: "bug1577297",
+    platform: "android",
+    domain: "kitkat.com.au",
+    bug: "1577297",
+    contentScripts: {
+      matches: ["*://*.kitkat.com.au/*"],
+      css: [
+        {
+          file: "injections/css/bug1577297-kitkat.com.au-slider-width-fix.css",
+        },
+      ],
+    },
+  },
 ];
 
 module.exports = AVAILABLE_INJECTIONS;
--- a/browser/extensions/webcompat/data/ua_overrides.js
+++ b/browser/extensions/webcompat/data/ua_overrides.js
@@ -1,41 +1,67 @@
 /* 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 */
+/* globals getMatchPatternsForGoogleURL, 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_UA_OVERRIDES = [
   {
     id: "testbed-override",
     platform: "all",
     domain: "webcompat-addon-testbed.herokuapp.com",
     bug: "0000000",
-    hidden: true,
     config: {
+      hidden: true,
       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 for WebCompat"
         );
       },
     },
   },
   {
     /*
+     * Bug 1564594 - Create UA override for Enhanced Search on Firefox Android
+     *
+     * Enables the Chrome Google Search experience for Fennec users.
+     */
+    id: "bug1564594",
+    platform: "android",
+    domain: "Enhanced Search",
+    bug: "1567945",
+    config: {
+      matches: [
+        ...getMatchPatternsForGoogleURL("images.google"),
+        ...getMatchPatternsForGoogleURL("maps.google"),
+        ...getMatchPatternsForGoogleURL("news.google"),
+        ...getMatchPatternsForGoogleURL("www.google"),
+      ],
+      blocks: [...getMatchPatternsForGoogleURL("www.google", "serviceworker")],
+      permanentPref: "enable_enhanced_search",
+      telemetryKey: "enhancedSearch",
+      experiment: "enhanced-search",
+      uaTransformer: originalUA => {
+        return UAHelpers.getDeviceAppropriateChromeUA();
+      },
+    },
+  },
+  {
+    /*
      * Bug 1563839 - rolb.santanderbank.com - Build UA override
      * WebCompat issue #33462 - https://webcompat.com/issues/33462
      *
      * santanderbank expects UA to have 'like Gecko', otherwise it runs
      * xmlDoc.onload whose support has been dropped. It results in missing labels in forms
      * and some other issues.  Adding 'like Gecko' fixes those issues.
      */
     id: "bug1563839",
@@ -50,16 +76,82 @@ const AVAILABLE_UA_OVERRIDES = [
       ],
       uaTransformer: originalUA => {
         return originalUA.replace("Gecko", "like Gecko");
       },
     },
   },
   {
     /*
+     * Bug 1577179 - UA override for supportforms.embarcadero.com
+     * WebCompat issue #34682 - https://webcompat.com/issues/34682
+     *
+     * supportforms.embarcadero.com has a constant onchange event on a product selector
+     * which makes it unusable. Spoofing as Chrome allows to stop event from firing
+     */
+    id: "bug1577179",
+    platform: "all",
+    domain: "supportforms.embarcadero.com",
+    bug: "1577179",
+    config: {
+      matches: ["*://supportforms.embarcadero.com/*"],
+      uaTransformer: originalUA => {
+        return (
+          UAHelpers.getPrefix(originalUA) +
+          " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36"
+        );
+      },
+    },
+  },
+  {
+    /*
+     * Bug 1577519 - att.tv - Create a UA override for att.tv for playback on desktop
+     * WebCompat issue #3846 - https://webcompat.com/issues/3846
+     *
+     * att.tv (atttvnow.com) is blocking Firefox via UA sniffing. Spoofing as Chrome allows
+     * to access the site and playback works fine. This is former directvnow.com
+     */
+    id: "bug1577519",
+    platform: "desktop",
+    domain: "att.tv",
+    bug: "1577519",
+    config: {
+      matches: ["*://*.att.tv/*"],
+      uaTransformer: originalUA => {
+        return (
+          UAHelpers.getPrefix(originalUA) +
+          " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36"
+        );
+      },
+    },
+  },
+  {
+    /*
+     * Bug 1570108 - steamcommunity.com - UA override for steamcommunity.com
+     * WebCompat issue #34171 - https://webcompat.com/issues/34171
+     *
+     * steamcommunity.com blocks chat feature for Firefox users showing unsupported browser message.
+     * When spoofing as Chrome the chat works fine
+     */
+    id: "bug1570108",
+    platform: "desktop",
+    domain: "steamcommunity.com",
+    bug: "1570108",
+    config: {
+      matches: ["*://steamcommunity.com/chat*"],
+      uaTransformer: originalUA => {
+        return (
+          UAHelpers.getPrefix(originalUA) +
+          " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
+        );
+      },
+    },
+  },
+  {
+    /*
      * Bug 1480710 - m.imgur.com - Build UA override
      * WebCompat issue #13154 - https://webcompat.com/issues/13154
      *
      * imgur returns a 404 for requests to CSS and JS file if requested with a Fennec
      * User Agent. By removing the Fennec identifies and adding Chrome Mobile's, we
      * receive the correct CSS and JS files.
      */
     id: "bug1480710",
@@ -85,17 +177,21 @@ const AVAILABLE_UA_OVERRIDES = [
      * mobile experience to Firefox for Android users. Adding the AppleWebKit indicator
      * to the User Agent gets us the same experience.
      */
     id: "bug945963",
     platform: "android",
     domain: "tieba.baidu.com",
     bug: "945963",
     config: {
-      matches: ["*://tieba.baidu.com/*", "*://tiebac.baidu.com/*"],
+      matches: [
+        "*://tieba.baidu.com/*",
+        "*://tiebac.baidu.com/*",
+        "*://zhidao.baidu.com/*",
+      ],
       uaTransformer: originalUA => {
         return originalUA + " AppleWebKit/537.36 (KHTML, like Gecko)";
       },
     },
   },
   {
     /*
      * Bug 1177298 - Write UA overrides for top Japanese Sites
@@ -311,17 +407,144 @@ const AVAILABLE_UA_OVERRIDES = [
     bug: "1567945",
     config: {
       matches: ["*://beeg.com/*"],
       uaTransformer: originalUA => {
         return originalUA.replace(/Firefox.+$/, "");
       },
     },
   },
+  {
+    /*
+     * Bug 1574522 - UA override for enuri.com on Firefox for Android
+     * WebCompat issue #37139 - https://webcompat.com/issues/37139
+     *
+     * enuri.com returns a different template for Firefox on Android
+     * based on server side UA detection. This results in page content cut offs.
+     * Spoofing as Chrome fixes the issue
+     */
+    id: "bug1574522",
+    platform: "android",
+    domain: "enuri.com",
+    bug: "1574522",
+    config: {
+      matches: ["*://enuri.com/*"],
+      uaTransformer: _ => {
+        return "Mozilla/5.0 (Linux; Android 6.0.1; SM-G900M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.111 Mobile Safari/537.36";
+      },
+    },
+  },
+  {
+    /*
+     * Bug 1574564 - UA override for ceskatelevize.cz on Firefox for Android
+     * WebCompat issue #15467 - https://webcompat.com/issues/15467
+     *
+     * ceskatelevize sets streamingProtocol depending on the User-Agent it sees
+     * in the request headers, returning DASH for Chrome, HLS for iOS,
+     * and Flash for Fennec. Since Fennec has no Flash, the video doesn't work.
+     * Spoofing as Chrome makes the video play
+     */
+    id: "bug1574564",
+    platform: "android",
+    domain: "ceskatelevize.cz",
+    bug: "1574564",
+    config: {
+      matches: ["*://*.ceskatelevize.cz/*"],
+      uaTransformer: originalUA => {
+        return (
+          UAHelpers.getPrefix(originalUA) +
+          " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.111 Mobile Safari/537.36"
+        );
+      },
+    },
+  },
+  {
+    /*
+     * Bug 1577240 - UA override for heb.com on Firefox for Android
+     * WebCompat issue #33613 - https://webcompat.com/issues/33613
+     *
+     * heb.com shows desktop site on Firefox for Android for some pages based on
+     * UA detection. Spoofing as Chrome allows to get mobile site.
+     */
+    id: "bug1577240",
+    platform: "android",
+    domain: "heb.com",
+    bug: "1577240",
+    config: {
+      matches: ["*://*.heb.com/*"],
+      uaTransformer: originalUA => {
+        return (
+          UAHelpers.getPrefix(originalUA) +
+          " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.111 Mobile Safari/537.36"
+        );
+      },
+    },
+  },
+  {
+    /*
+     * Bug 1577250 - UA override for homebook.pl on Firefox for Android
+     * WebCompat issue #24044 - https://webcompat.com/issues/24044
+     *
+     * homebook.pl shows desktop site on Firefox for Android based on
+     * UA detection. Spoofing as Chrome allows to get mobile site.
+     */
+    id: "bug1577250",
+    platform: "android",
+    domain: "homebook.pl",
+    bug: "1577250",
+    config: {
+      matches: ["*://*.homebook.pl/*"],
+      uaTransformer: originalUA => {
+        return (
+          UAHelpers.getPrefix(originalUA) +
+          " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.111 Mobile Safari/537.36"
+        );
+      },
+    },
+  },
+  {
+    /*
+     * Bug 1577267 - UA override for metfone.com.kh on Firefox for Android
+     * WebCompat issue #16363 - https://webcompat.com/issues/16363
+     *
+     * metfone.com.kh has a server side UA detection which returns desktop site
+     * for Firefox for Android. Spoofing as Chrome allows to receive mobile version
+     */
+    id: "bug1577267",
+    platform: "android",
+    domain: "metfone.com.kh",
+    bug: "1577267",
+    config: {
+      matches: ["*://*.metfone.com.kh/*"],
+      uaTransformer: originalUA => {
+        return (
+          UAHelpers.getPrefix(originalUA) +
+          " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.111 Mobile Safari/537.36"
+        );
+      },
+    },
+  },
 ];
 
 const UAHelpers = {
+  getDeviceAppropriateChromeUA() {
+    if (!UAHelpers._deviceAppropriateChromeUA) {
+      const RunningFirefoxVersion = (navigator.userAgent.match(
+        /Firefox\/([0-9.]+)/
+      ) || ["", "58.0"])[1];
+      const RunningAndroidVersion =
+        navigator.userAgent.match(/Android\/[0-9.]+/) || "Android 6.0";
+      const ChromeVersionToMimic = "76.0.3809.111";
+      const ChromePhoneUA = `Mozilla/5.0 (Linux; ${RunningAndroidVersion}; Nexus 5 Build/MRA58N) FxQuantum/${RunningFirefoxVersion} AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${ChromeVersionToMimic} Mobile Safari/537.36`;
+      const ChromeTabletUA = `Mozilla/5.0 (Linux; ${RunningAndroidVersion}; Nexus 7 Build/JSS15Q) FxQuantum/${RunningFirefoxVersion} AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${ChromeVersionToMimic} Safari/537.36`;
+      const IsPhone = navigator.userAgent.includes("Mobile");
+      UAHelpers._deviceAppropriateChromeUA = IsPhone
+        ? ChromePhoneUA
+        : ChromeTabletUA;
+    }
+    return UAHelpers._deviceAppropriateChromeUA;
+  },
   getPrefix(originalUA) {
     return originalUA.substr(0, originalUA.indexOf(")") + 1);
   },
 };
 
 module.exports = AVAILABLE_UA_OVERRIDES;
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/experiment-apis/experiments.js
@@ -0,0 +1,34 @@
+/* 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 ExtensionAPI, Services, XPCOMUtils */
+
+XPCOMUtils.defineLazyModuleGetters(this, {
+  EventDispatcher: "resource://gre/modules/Messaging.jsm",
+  Services: "resource://gre/modules/Services.jsm",
+});
+
+this.experiments = class extends ExtensionAPI {
+  getAPI(context) {
+    function promiseActiveExperiments() {
+      return EventDispatcher.instance.sendRequestForResult({
+        type: "Experiments:GetActive",
+      });
+    }
+    return {
+      experiments: {
+        async isActive(name) {
+          if (!Services.androidBridge || !Services.androidBridge.isFennec) {
+            return undefined;
+          }
+          return promiseActiveExperiments().then(experiments => {
+            return experiments.includes(name);
+          });
+        },
+      },
+    };
+  }
+};
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/experiment-apis/experiments.json
@@ -0,0 +1,21 @@
+[
+  {
+    "namespace": "experiments",
+    "description": "experimental API extension to allow checking the status of Fennec experiments via Switchboard",
+    "functions": [
+      {
+        "name": "isActive",
+        "type": "function",
+        "description": "Determine if a given experiment is active.",
+        "parameters": [
+          {
+            "name": "name",
+            "type": "string",
+            "description": "The experiment's name"
+          }
+        ],
+        "async": true
+      }
+    ]
+  }
+]
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/experiment-apis/sharedPreferences.js
@@ -0,0 +1,27 @@
+/* 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 ExtensionAPI, Services, XPCOMUtils */
+
+XPCOMUtils.defineLazyModuleGetters(this, {
+  Services: "resource://gre/modules/Services.jsm",
+  SharedPreferences: "resource://gre/modules/SharedPreferences.jsm",
+});
+
+this.sharedPreferences = class extends ExtensionAPI {
+  getAPI(context) {
+    return {
+      sharedPreferences: {
+        async setBoolPref(name, value) {
+          if (!Services.androidBridge || !Services.androidBridge.isFennec) {
+            return;
+          }
+          SharedPreferences.forApp().setBoolPref(name, value);
+        },
+      },
+    };
+  }
+};
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/experiment-apis/sharedPreferences.json
@@ -0,0 +1,26 @@
+[
+  {
+    "namespace": "sharedPreferences",
+    "description": "experimental API extension to allow setting SharedPreferences on Fennec",
+    "functions": [
+      {
+        "name": "setBoolPref",
+        "type": "function",
+        "description": "Set the value of a boolean Fennec SharedPreference",
+        "parameters": [
+          {
+            "name": "name",
+            "type": "string",
+            "description": "The key name"
+          },
+          {
+            "name": "value",
+            "type": "boolean",
+            "description": "The new value"
+          }
+        ],
+        "async": true
+      }
+    ]
+  }
+]
--- a/browser/extensions/webcompat/injections/css/bug1561371-mail.google.com-allow-horizontal-scrolling.css
+++ b/browser/extensions/webcompat/injections/css/bug1561371-mail.google.com-allow-horizontal-scrolling.css
@@ -2,11 +2,11 @@
  * mail.google.com - The HTML email view does not allow horizontal scrolling
  * on Fennec due to a missing CSS rule which is only served to Chrome.
  * Bug #1561371 - https://bugzilla.mozilla.org/show_bug.cgi?id=1561371
  *
  * HTML emails may sometimes contain content that does not wrap, yet the
  * CSS served to Fennec does not permit scrolling horizontally. To prevent
  * this UX frustration, we enable horizontal scrolling.
  */
-body > #views > div {
+body > #views {
   overflow: auto;
 }
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/injections/css/bug1568908-console.cloud.google.com-scrollbar-fix.css
@@ -0,0 +1,16 @@
+/**
+ * console.cloud.google.com - Double scrollbar visisible on long pages
+ * Bug #1568908 - https://bugzilla.mozilla.org/show_bug.cgi?id=1568908
+ * WebCompat issue #33164 - https://webcompat.com/issues/33164
+ *
+ * For pages that have contents heigher than the page's height, a secondary
+ * scrollbar outside the scrollable content area is visible. This is caused
+ * by a difference in Flexbox behavior, which is being addressed in
+ * https://bugs.chromium.org/p/chromium/issues/detail?id=981134
+ *
+ * Until this fix hits release and Google has updated their UI properly,
+ * this intervention addresses the differences.
+ */
+central-page-area {
+  min-height: 0;
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/injections/css/bug1570119-teamcoco.com-scrollbar-width.css
@@ -0,0 +1,11 @@
+/**
+ * teamcoco.com - a scrollbar at the top covering navigation menu
+ * Bug #1570119 - https://bugzilla.mozilla.org/show_bug.cgi?id=1570119
+ *
+ * The scrollbar is covering navigation items making them unusable.
+ * There are ::-webkit-scrollbar css rules already applied to the scrollbar,
+ * hiding it in Chrome. Adding the scrollbar-width: none fixes the issue in Firefox.
+ */
+.css-bdnz85 {
+  scrollbar-width: none;
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/injections/css/bug1570328-developer-apple.com-transform-scale.css
@@ -0,0 +1,17 @@
+/**
+ * developer.apple.com - content of the page is shifted to the left
+ * Bug #1570328 - https://bugzilla.mozilla.org/show_bug.cgi?id=1570328
+ * WebCompat issue #4070 - https://webcompat.com/issues/4070
+ *
+ * The site is relying on zoom property which is not supported by Mozilla,
+ * see https://bugzilla.mozilla.org/show_bug.cgi?id=390936. Adding a combination
+ * of transform: scale(1.4), transform-origin and width fixes the issue
+ */
+@media only screen and (min-device-width: 320px) and (max-device-width: 980px),
+  (min-device-width: 1024px) and (max-device-width: 1024px) and (min-device-height: 1366px) and (max-device-height: 1366px) and (min-width: 320px) and (max-width: 980px) {
+  #tocContainer {
+    transform-origin: 0 0;
+    transform: scale(1.4);
+    width: 71.4%;
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/injections/css/bug1574973-patch.com-dropdown-menu-fix.css
@@ -0,0 +1,13 @@
+/**
+ * patch.com - sub-menu expands at the bottom of the page and overlaps other elements.
+ * Bug #1574973 - https://bugzilla.mozilla.org/show_bug.cgi?id=1574973
+ * WebCompat issue #25384 - https://webcompat.com/issues/25384
+ *
+ * patch.con has a top:100% style on the relatively-positioned element
+ * with class="dropdown-menu", and Firefox is incorrectly honoring that
+ * style (resolving it to something nonzero), whereas Chrome just treats it as "auto"
+ * see https://bugzilla.mozilla.org/show_bug.cgi?id=1092007
+ */
+#patch-nav-secondary .dropdown-menu {
+  top: auto;
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/injections/css/bug1575000-apply.lloydsbank.co.uk-radio-buttons-fix.css
@@ -0,0 +1,11 @@
+/**
+ * apply.lloydsbank.co.uk - radio buttons are misplaced
+ * Bug #1575000 - https://bugzilla.mozilla.org/show_bug.cgi?id=1575000
+ * WebCompat issue #34969 - https://webcompat.com/issues/34969
+ *
+ * Radio buttons are displaced to the left due to positioning issue of ::before
+ * pseudo element, adding position relative to it's parent fixes the issue.
+ */
+.radio-content-field .radio.inline label span.text {
+  position: relative;
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/injections/css/bug1575011-holiday-weather.com-scrolling-fix.css
@@ -0,0 +1,15 @@
+/**
+ * holiday-weather.com - page is not scrollable
+ * Bug #1575011 - https://bugzilla.mozilla.org/show_bug.cgi?id=1575011
+ * WebCompat issue #18478 - https://webcompat.com/issues/18478
+ *
+ * the page won't scroll since the flex container is too high,
+ * adding min height to parent containers fixes the issue
+ */
+.page-container-style__pageContent {
+  min-height: 0;
+}
+
+.widgets-style__root {
+  min-height: 0;
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/injections/css/bug1575017-dunkindonuts.com-flex-basis.css
@@ -0,0 +1,11 @@
+/**
+ * dunkindonuts.com - form input fields are small and misaligned
+ * Bug #1575017 - https://bugzilla.mozilla.org/show_bug.cgi?id=1575017
+ * WebCompat issue #28742 - https://webcompat.com/issues/28742
+ *
+ * Form input fields are small and misaligned due to flex-basis: min-content;
+ * applied on their parent element. Setting it to auto fixes the issue
+ */
+.grid__item {
+  flex-basis: auto;
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/injections/css/bug1577270-binance.com-calc-height-fix.css
@@ -0,0 +1,12 @@
+/**
+ * binance.com - can't see the full site
+ * Bug #1577270 - https://bugzilla.mozilla.org/show_bug.cgi?id=1577270
+ * WebCompat issue #17810 - https://webcompat.com/issues/17810
+ *
+ * The site does not have a doctype and is rendered in quirks mode. The calc() percentage
+ * height is applied on the .main-page .viewWrap element, but its parent does not have
+ * a specified height property. Adding a height of 100% to the parent fixes the issue.
+ */
+#tradeDiv {
+  height: 100%;
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/injections/css/bug1577297-kitkat.com.au-slider-width-fix.css
@@ -0,0 +1,11 @@
+/**
+ * kitkat.com.au - can't see the content
+ * Bug #1577297 - https://bugzilla.mozilla.org/show_bug.cgi?id=1577297
+ * WebCompat issue #28992 - https://webcompat.com/issues/28992
+ *
+ * Affected element is too wide due to https://bugzilla.mozilla.org/show_bug.cgi?id=1316534.
+ * Adding min-width: 0; fixes the issue
+ */
+.columns .column.main {
+  min-width: 0;
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/injections/js/bug1570856-medium.com-menu-isTier1.js
@@ -0,0 +1,34 @@
+"use strict";
+
+/**
+ * medium.com - Override window.GLOBALS.useragent.isTier1 to be true
+ * WebCompat issue #25844 - https://webcompat.com/issues/25844
+ *
+ * This site is not showing main menu when scrolling. There is a GLOBALS variable
+ * at the bottom of the template being defined based on a server side UA detection.
+ * Setting window.GLOBALS.useragent.isTier1 to true makes the menu appear when scrolling
+ */
+
+/* globals exportFunction */
+
+console.info(
+  "window.GLOBALS.useragent.isTier1 has been set to true for compatibility reasons. See https://webcompat.com/issues/25844 for details."
+);
+
+let globals = {};
+
+Object.defineProperty(window.wrappedJSObject, "GLOBALS", {
+  get: exportFunction(function() {
+    return globals;
+  }, window),
+
+  set: exportFunction(function(value = {}) {
+    globals = value;
+
+    if (!globals.useragent) {
+      globals.useragent = {};
+    }
+
+    globals.useragent.isTier1 = true;
+  }, window),
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/injections/js/bug1577245-salesforce-communities-hide-unsupported.js
@@ -0,0 +1,49 @@
+"use strict";
+
+/**
+ * help.pandora.com - Hide unsupported message in Firefox for Android
+ * WebCompat issue #38433 - https://webcompat.com/issues/38433
+ *
+ * SalesForce Communities are showing unsupported message
+ * for help.pandora.com and some more sites. See the full list here:
+ * https://github.com/webcompat/web-bugs/issues?utf8=%E2%9C%93&q=doNotShowUnsupportedBrowserModal
+ */
+
+console.info(
+  "Unsupported message has been hidden for compatibility reasons. See https://webcompat.com/issues/38433 for details."
+);
+
+const NOTIFICATIONS_LIMIT = 20;
+
+const createObserver = callback => {
+  return new MutationObserver(callback).observe(document, {
+    childList: true,
+    subtree: true,
+  });
+};
+
+const removeElementWhenReady = elementId => {
+  const element = document.getElementById(elementId);
+  if (element) {
+    element.remove();
+    return;
+  }
+
+  let n = 0;
+  createObserver(function(records, observer) {
+    const _element = document.getElementById(elementId);
+    if (_element) {
+      _element.remove();
+      observer.disconnect();
+      return;
+    }
+
+    if (n > NOTIFICATIONS_LIMIT) {
+      observer.disconnect();
+    }
+
+    n++;
+  });
+};
+
+removeElementWhenReady("community-browser-not-support-message");
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/injections/js/bug1579159-m.tailieu.vn-pdfjs-worker-disable.js
@@ -0,0 +1,28 @@
+"use strict";
+
+/**
+ * m.tailieu.vn - Override PDFJS.disableWorker to be true
+ * WebCompat issue #39057 - https://webcompat.com/issues/39057
+ *
+ * Custom viewer built with PDF.js is not working in Firefox for Android
+ * Disabling worker to match Chrome behavior fixes the issue
+ */
+
+/* globals exportFunction */
+
+console.info(
+  "window.PDFJS.disableWorker has been set to true for compatibility reasons. See https://webcompat.com/issues/39057 for details."
+);
+
+let globals = {};
+
+Object.defineProperty(window.wrappedJSObject, "PDFJS", {
+  get: exportFunction(function() {
+    return globals;
+  }, window),
+
+  set: exportFunction(function(value = {}) {
+    globals = value;
+    globals.disableWorker = true;
+  }, window),
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/lib/custom_functions.js
@@ -0,0 +1,77 @@
+/* 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 */
+
+const 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();
+  };
+};
+
+const CUSTOM_FUNCTIONS = {
+  dtagFix: injection => {
+    const { urls, contentType } = injection.data;
+    const listener = (injection.data.listener = e => {
+      e.responseHeaders.push(contentType);
+      return { responseHeaders: e.responseHeaders };
+    });
+
+    browser.webRequest.onHeadersReceived.addListener(listener, { urls }, [
+      "blocking",
+      "responseHeaders",
+    ]);
+  },
+  dtagFixDisable: injection => {
+    const { listener } = injection.data;
+    browser.webRequest.onHeadersReceived.removeListener(listener);
+    delete injection.data.listener;
+  },
+  pdk5fix: injection => {
+    const { urls, types } = injection.data;
+    const listener = (injection.data.listener = ({ requestId }) => {
+      replaceStringInRequest(
+        requestId,
+        "VideoContextChromeAndroid",
+        "VideoContextAndroid"
+      );
+      return {};
+    });
+    browser.webRequest.onBeforeRequest.addListener(listener, { urls, types }, [
+      "blocking",
+    ]);
+  },
+  pdk5fixDisable: injection => {
+    const { listener } = injection.data;
+    browser.webRequest.onBeforeRequest.removeListener(listener);
+    delete injection.data.listener;
+  },
+};
+
+module.exports = CUSTOM_FUNCTIONS;
new file mode 100644
--- /dev/null
+++ b/browser/extensions/webcompat/lib/google.js
@@ -0,0 +1,211 @@
+/* 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";
+
+const GOOGLE_TLDS = [
+  "com",
+  "ac",
+  "ad",
+  "ae",
+  "com.af",
+  "com.ag",
+  "com.ai",
+  "al",
+  "am",
+  "co.ao",
+  "com.ar",
+  "as",
+  "at",
+  "com.au",
+  "az",
+  "ba",
+  "com.bd",
+  "be",
+  "bf",
+  "bg",
+  "com.bh",
+  "bi",
+  "bj",
+  "com.bn",
+  "com.bo",
+  "com.br",
+  "bs",
+  "bt",
+  "co.bw",
+  "by",
+  "com.bz",
+  "ca",
+  "com.kh",
+  "cc",
+  "cd",
+  "cf",
+  "cat",
+  "cg",
+  "ch",
+  "ci",
+  "co.ck",
+  "cl",
+  "cm",
+  "cn",
+  "com.co",
+  "co.cr",
+  "com.cu",
+  "cv",
+  "com.cy",
+  "cz",
+  "de",
+  "dj",
+  "dk",
+  "dm",
+  "com.do",
+  "dz",
+  "com.ec",
+  "ee",
+  "com.eg",
+  "es",
+  "com.et",
+  "fi",
+  "com.fj",
+  "fm",
+  "fr",
+  "ga",
+  "ge",
+  "gf",
+  "gg",
+  "com.gh",
+  "com.gi",
+  "gl",
+  "gm",
+  "gp",
+  "gr",
+  "com.gt",
+  "gy",
+  "com.hk",
+  "hn",
+  "hr",
+  "ht",
+  "hu",
+  "co.id",
+  "iq",
+  "ie",
+  "co.il",
+  "im",
+  "co.in",
+  "io",
+  "is",
+  "it",
+  "je",
+  "com.jm",
+  "jo",
+  "co.jp",
+  "co.ke",
+  "ki",
+  "kg",
+  "co.kr",
+  "com.kw",
+  "kz",
+  "la",
+  "com.lb",
+  "com.lc",
+  "li",
+  "lk",
+  "co.ls",
+  "lt",
+  "lu",
+  "lv",
+  "com.ly",
+  "co.ma",
+  "md",
+  "me",
+  "mg",
+  "mk",
+  "ml",
+  "com.mm",
+  "mn",
+  "ms",
+  "com.mt",
+  "mu",
+  "mv",
+  "mw",
+  "com.mx",
+  "com.my",
+  "co.mz",
+  "com.na",
+  "ne",
+  "com.nf",
+  "com.ng",
+  "com.ni",
+  "nl",
+  "no",
+  "com.np",
+  "nr",
+  "nu",
+  "co.nz",
+  "com.om",
+  "com.pk",
+  "com.pa",
+  "com.pe",
+  "com.ph",
+  "pl",
+  "com.pg",
+  "pn",
+  "com.pr",
+  "ps",
+  "pt",
+  "com.py",
+  "com.qa",
+  "ro",
+  "rs",
+  "ru",
+  "rw",
+  "com.sa",
+  "com.sb",
+  "sc",
+  "se",
+  "com.sg",
+  "sh",
+  "si",
+  "sk",
+  "com.sl",
+  "sn",
+  "sm",
+  "so",
+  "st",
+  "sr",
+  "com.sv",
+  "td",
+  "tg",
+  "co.th",
+  "com.tj",
+  "tk",
+  "tl",
+  "tm",
+  "to",
+  "tn",
+  "com.tr",
+  "tt",
+  "com.tw",
+  "co.tz",
+  "com.ua",
+  "co.ug",
+  "co.uk",
+  "com",
+  "com.uy",
+  "co.uz",
+  "com.vc",
+  "co.ve",
+  "vg",
+  "co.vi",
+  "com.vn",
+  "vu",
+  "ws",
+  "co.za",
+  "co.zm",
+  "co.zw",
+];
+
+function getMatchPatternsForGoogleURL(url, path = "*") {
+  return GOOGLE_TLDS.map(domain => `*://${url}.${domain}/${path}`);
+}
--- a/browser/extensions/webcompat/lib/injections.js
+++ b/browser/extensions/webcompat/lib/injections.js
@@ -2,23 +2,24 @@
  * 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) {
+  constructor(availableInjections, customFunctions) {
     this.INJECTION_PREF = "perform_injections";
 
     this._injectionsEnabled = true;
 
     this._availableInjections = availableInjections;
     this._activeInjections = new Map();
+    this._customFunctions = customFunctions;
   }
 
   bindAboutCompatBroker(broker) {
     this._aboutCompatBroker = broker;
   }
 
   bootup() {
     browser.aboutConfigPrefs.onPrefChange.addListener(() => {
@@ -62,67 +63,55 @@ class Injections {
     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 = "";
+  assignContentScriptDefaults(contentScripts) {
+    let finalConfig = Object.assign({}, contentScripts);
 
-    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);
-    };
+    if (!finalConfig.runAt) {
+      finalConfig.runAt = "document_start";
+    }
 
-    filter.onstop = event => {
-      if (carryover.length) {
-        filter.write(encoder.encode(carryover));
-      }
-      filter.close();
-    };
+    return finalConfig;
   }
 
   async enableInjection(injection) {
     if (injection.active) {
-      return;
+      return undefined;
+    }
+
+    if (injection.customFunc) {
+      return this.enableCustomInjection(injection);
     }
 
-    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"]
+    return this.enableContentScripts(injection);
+  }
+
+  enableCustomInjection(injection) {
+    if (injection.customFunc in this._customFunctions) {
+      this._customFunctions[injection.customFunc](injection);
+      injection.active = true;
+    } else {
+      console.error(
+        `Provided function ${
+          injection.customFunc
+        } wasn't found in functions list`
       );
-      injection.active = true;
-      return;
     }
+  }
 
+  async enableContentScripts(injection) {
     try {
       const handle = await browser.contentScripts.register(
-        injection.contentScripts
+        this.assignContentScriptDefaults(injection.contentScripts)
       );
       this._activeInjections.set(injection, handle);
       injection.active = true;
     } catch (ex) {
       console.error(
         "Registering WebCompat GoFaster content scripts failed: ",
         ex
       );
@@ -137,27 +126,40 @@ class Injections {
     this._injectionsEnabled = false;
     this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
       interventionsChanged: false,
     });
   }
 
   async disableInjection(injection) {
     if (!injection.active) {
-      return;
+      return undefined;
+    }
+
+    if (injection.customFunc) {
+      return this.disableCustomInjections(injection);
     }
 
-    if (injection.pdk5fix) {
-      const { listener } = injection.pdk5fix;
-      browser.webRequest.onBeforeRequest.removeListener(listener);
+    return this.disableContentScripts(injection);
+  }
+
+  disableCustomInjections(injection) {
+    const disableFunc = injection.customFunc + "Disable";
+
+    if (disableFunc in this._customFunctions) {
+      this._customFunctions[disableFunc](injection);
       injection.active = false;
-      delete injection.pdk5fix.listener;
-      return;
+    } else {
+      console.error(
+        `Provided function ${disableFunc} for disabling injection wasn't found in functions list`
+      );
     }
+  }
 
+  async disableContentScripts(injection) {
     const contentScript = this._activeInjections.get(injection);
     await contentScript.unregister();
     this._activeInjections.delete(injection);
     injection.active = false;
   }
 }
 
 module.exports = Injections;
--- a/browser/extensions/webcompat/lib/ua_overrides.js
+++ b/browser/extensions/webcompat/lib/ua_overrides.js
@@ -47,45 +47,153 @@ class UAOverrides {
     return this._overridesEnabled;
   }
 
   enableOverride(override) {
     if (override.active) {
       return;
     }
 
-    const { matches, uaTransformer } = override.config;
+    const { blocks, matches, telemetryKey, uaTransformer } = override.config;
     const listener = details => {
-      for (const header of details.requestHeaders) {
-        if (header.name.toLowerCase() === "user-agent") {
-          header.value = uaTransformer(header.value);
+      // Don't actually override the UA for an experiment if the user is not
+      // part of the experiment (unless they force-enabed the override).
+      if (
+        !override.config.experiment ||
+        override.experimentActive ||
+        override.permanentPrefEnabled === true
+      ) {
+        if (telemetryKey && !details.frameId) {
+          // For now, we only care about Telemetry on Fennec, where telemetry
+          // is sent in Java code (as part of the core ping). That code must
+          // be aware of each key we send, which we send as a SharedPreference.
+          browser.sharedPreferences.setBoolPref(`${telemetryKey}Used`, true);
+        }
+
+        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);
+    const listeners = { onBeforeSendHeaders: listener };
+    if (blocks) {
+      const blistener = details => {
+        return { cancel: true };
+      };
+
+      browser.webRequest.onBeforeRequest.addListener(
+        blistener,
+        { urls: blocks },
+        ["blocking"]
+      );
+
+      listeners.onBeforeRequest = blistener;
+    }
+    this._activeListeners.set(override, listeners);
     override.active = true;
+
+    // If collecting telemetry on the override, note that it was activated.
+    if (telemetryKey) {
+      browser.sharedPreferences.setBoolPref(`${telemetryKey}Ready`, true);
+    }
+  }
+
+  onOverrideConfigChanged(override) {
+    // Check whether the override should be hidden from about:compat.
+    override.hidden = override.config.hidden;
+
+    // Also hide if the override is in an experiment the user is not part of.
+    if (override.config.experiment && !override.experimentActive) {
+      override.hidden = true;
+    }
+
+    // Setting the override's permanent pref overrules whether it is hidden.
+    if (override.permanentPrefEnabled !== undefined) {
+      override.hidden = !override.permanentPrefEnabled;
+    }
+
+    // Also check whether the override should be active.
+    let shouldBeActive = true;
+
+    // Overrides can be force-deactivated by their permanent preference.
+    if (override.permanentPrefEnabled === false) {
+      shouldBeActive = false;
+    }
+
+    // Overrides gated behind an experiment the user is not part of do not
+    // have to be activated, unless they are gathering telemetry, or the
+    // user has force-enabled them with their permanent pref.
+    if (
+      override.config.experiment &&
+      !override.experimentActive &&
+      !override.config.telemetryKey &&
+      override.permanentPrefEnabled !== true
+    ) {
+      shouldBeActive = false;
+    }
+
+    if (shouldBeActive) {
+      this.enableOverride(override);
+    } else {
+      this.disableOverride(override);
+    }
+
+    if (this._overridesEnabled) {
+      this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
+        overridesChanged: this._aboutCompatBroker.filterOverrides(
+          this._availableOverrides
+        ),
+      });
+    }
   }
 
   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);
+
+        // If there is a specific experiment running for
+        // this override, get its state.
+        const experiment = override.config.experiment;
+        override.experimentActive =
+          experiment && (await browser.experiments.isActive(experiment));
+
+        // If there is a specific about:config preference governing
+        // this override, monitor its state.
+        const pref = override.config.permanentPref;
+        override.permanentPrefEnabled =
+          pref && (await browser.aboutConfigPrefs.getPref(pref));
+        if (pref) {
+          const checkOverridePref = () => {
+            browser.aboutConfigPrefs.getPref(pref).then(value => {
+              override.permanentPrefEnabled = value;
+              this.onOverrideConfigChanged(override);
+            });
+          };
+          browser.aboutConfigPrefs.onPrefChange.addListener(
+            checkOverridePref,
+            pref
+          );
+        }
+
+        this.onOverrideConfigChanged(override);
       }
     }
 
     this._overridesEnabled = true;
     this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
       overridesChanged: this._aboutCompatBroker.filterOverrides(
         this._availableOverrides
       ),
@@ -103,17 +211,18 @@ class UAOverrides {
     });
   }
 
   disableOverride(override) {
     if (!override.active) {
       return;
     }
 
-    browser.webRequest.onBeforeSendHeaders.removeListener(
-      this._activeListeners.get(override)
-    );
+    const listeners = this._activeListeners.get(override);
+    for (const [name, listener] of Object.entries(listeners)) {
+      browser.webRequest[name].removeListener(listener);
+    }
     override.active = false;
     this._activeListeners.delete(override);
   }
 }
 
 module.exports = UAOverrides;
--- a/browser/extensions/webcompat/manifest.json
+++ b/browser/extensions/webcompat/manifest.json
@@ -1,13 +1,13 @@
 {
   "manifest_version": 2,
   "name": "Web Compat",
   "description": "Urgent post-release fixes for web compatibility.",
-  "version": "5.0.2",
+  "version": "6.1.0",
 
   "applications": {
     "gecko": {
       "id": "webcompat@mozilla.org",
       "strict_min_version": "59.0b5"
     }
   },
 
@@ -22,31 +22,49 @@
     },
     "aboutPage": {
       "schema": "about-compat/aboutPage.json",
       "parent": {
         "scopes": ["addon_parent"],
         "script": "about-compat/aboutPage.js",
         "events": ["startup"]
       }
+    },
+    "experiments": {
+      "schema": "experiment-apis/experiments.json",
+      "parent": {
+        "scopes": ["addon_parent"],
+        "script": "experiment-apis/experiments.js",
+        "paths": [["experiments"]]
+      }
+    },
+    "sharedPreferences": {
+      "schema": "experiment-apis/sharedPreferences.json",
+      "parent": {
+        "scopes": ["addon_parent"],
+        "script": "experiment-apis/sharedPreferences.js",
+        "paths": [["sharedPreferences"]]
+      }
     }
   },
 
   "content_security_policy": "script-src 'self' 'sha256-MmZkN2QaIHhfRWPZ8TVRjijTn5Ci1iEabtTEWrt9CCo='; default-src 'self'; base-uri moz-extension://*;",
 
   "permissions": [
     "webRequest",
     "webRequestBlocking",
     "<all_urls>"
   ],
 
   "background": {
     "scripts": [
       "lib/module_shim.js",
+      "lib/google.js",
       "data/injections.js",
       "data/ua_overrides.js",
       "lib/about_compat_broker.js",
+      "lib/custom_functions.js",
       "lib/injections.js",
       "lib/ua_overrides.js",
       "run.js"
     ]
   }
 }
--- a/browser/extensions/webcompat/moz.build
+++ b/browser/extensions/webcompat/moz.build
@@ -4,61 +4,79 @@
 # 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/.
 
 DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
 DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION']
 
 FINAL_TARGET_FILES.features['webcompat@mozilla.org'] += [
   'manifest.json',
-  'run.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'
+  'about-compat/aboutPageProcessScript.js',
 ]
 
 FINAL_TARGET_FILES.features['webcompat@mozilla.org']['data'] += [
   'data/injections.js',
-  'data/ua_overrides.js'
+  'data/ua_overrides.js',
 ]
 
 FINAL_TARGET_FILES.features['webcompat@mozilla.org']['experiment-apis'] += [
   'experiment-apis/aboutConfigPrefs.js',
-  'experiment-apis/aboutConfigPrefs.json'
+  'experiment-apis/aboutConfigPrefs.json',
+  'experiment-apis/experiments.js',
+  'experiment-apis/experiments.json',
+  'experiment-apis/sharedPreferences.js',
+  'experiment-apis/sharedPreferences.json',
 ]
 
 FINAL_TARGET_FILES.features['webcompat@mozilla.org']['injections']['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/bug1567610-dns.google.com-moz-fit-content.css',
-  'injections/css/bug1568256-zertifikate.commerzbank.de-flex.css'
+  'injections/css/bug1568256-zertifikate.commerzbank.de-flex.css',
+  'injections/css/bug1568908-console.cloud.google.com-scrollbar-fix.css',
+  'injections/css/bug1570119-teamcoco.com-scrollbar-width.css',
+  'injections/css/bug1570328-developer-apple.com-transform-scale.css',
+  'injections/css/bug1574973-patch.com-dropdown-menu-fix.css',
+  'injections/css/bug1575000-apply.lloydsbank.co.uk-radio-buttons-fix.css',
+  'injections/css/bug1575011-holiday-weather.com-scrolling-fix.css',
+  'injections/css/bug1575017-dunkindonuts.com-flex-basis.css',
+  'injections/css/bug1577270-binance.com-calc-height-fix.css',
+  'injections/css/bug1577297-kitkat.com.au-slider-width-fix.css'
 ]
 
 FINAL_TARGET_FILES.features['webcompat@mozilla.org']['injections']['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',
   'injections/js/bug1472081-election.gov.np-window.sidebar-shim.js',
-  'injections/js/bug1482066-portalminasnet.com-window.sidebar-shim.js'
+  'injections/js/bug1482066-portalminasnet.com-window.sidebar-shim.js',
+  'injections/js/bug1570856-medium.com-menu-isTier1.js',
+  'injections/js/bug1577245-salesforce-communities-hide-unsupported.js',
+  'injections/js/bug1579159-m.tailieu.vn-pdfjs-worker-disable.js'
 ]
 
 FINAL_TARGET_FILES.features['webcompat@mozilla.org']['lib'] += [
   'lib/about_compat_broker.js',
+  'lib/custom_functions.js',
+  'lib/google.js',
   'lib/injections.js',
   'lib/module_shim.js',
-  'lib/ua_overrides.js'
+  'lib/ua_overrides.js',
 ]
 
 with Files('**'):
   BUG_COMPONENT = ('Web Compatibility Tools', 'Go Faster')
--- a/browser/extensions/webcompat/run.js
+++ b/browser/extensions/webcompat/run.js
@@ -1,18 +1,18 @@
 /* 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 */
+           Injections, UAOverrides, CUSTOM_FUNCTIONS */
 
-const injections = new Injections(AVAILABLE_INJECTIONS);
+const injections = new Injections(AVAILABLE_INJECTIONS, CUSTOM_FUNCTIONS);
 const uaOverrides = new UAOverrides(AVAILABLE_UA_OVERRIDES);
 
 const aboutCompatBroker = new AboutCompatBroker({
   injections,
   uaOverrides,
 });
 
 aboutCompatBroker.bootup();
--- a/mobile/android/extensions/webcompat/data/injections.js
+++ b/mobile/android/extensions/webcompat/data/injections.js
@@ -26,100 +26,147 @@ const AVAILABLE_INJECTIONS = [
           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/*"],
+      allFrames: true,
       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/*"],
+      allFrames: true,
       js: [
         {
           file:
             "injections/js/bug1482066-portalminasnet.com-window.sidebar-shim.js",
         },
       ],
-      runAt: "document_start",
+    },
+  },
+  {
+    id: "bug1570856",
+    platform: "android",
+    domain: "medium.com",
+    bug: "1570856",
+    contentScripts: {
+      matches: ["*://medium.com/*"],
+      js: [
+        {
+          file: "injections/js/bug1570856-medium.com-menu-isTier1.js",
+        },
+      ],
       allFrames: true,
     },
   },
   {
+    id: "bug1579159",
+    platform: "android",
+    domain: "m.tailieu.vn",
+    bug: "1579159",
+    contentScripts: {
+      matches: ["*://m.tailieu.vn/*", "*://m.elib.vn/*"],
+      js: [
+        {
+          file: "injections/js/bug1579159-m.tailieu.vn-pdfjs-worker-disable.js",
+        },
+      ],
+      allFrames: true,
+    },
+  },
+  {
+    id: "bug1577245",
+    platform: "android",
+    domain: "help.pandora.com",
+    bug: "1577245",
+    contentScripts: {
+      matches: [
+        "https://faq.usps.com/*",
+        "https://help.duo.com/*",
+        "https://help.hulu.com/*",
+        "https://help.pandora.com/*",
+        "https://my211.force.com/*",
+        "https://support.paypay.ne.jp/*",
+        "https://usps.force.com/*",
+      ],
+      js: [
+        {
+          file:
+            "injections/js/bug1577245-salesforce-communities-hide-unsupported.js",
+        },
+      ],
+    },
+  },
+  {
     id: "bug1526977",
     platform: "desktop",
     domain: "sreedharscce.in",
     bug: "1526977",
     contentScripts: {
       matches: ["*://*.sreedharscce.in/authenticate"],
       css: [
         {
@@ -142,20 +189,35 @@ const AVAILABLE_INJECTIONS = [
       ],
     },
   },
   {
     id: "bug1551672",
     platform: "android",
     domain: "Sites using PDK 5 video",
     bug: "1551672",
-    pdk5fix: {
+    data: {
       urls: ["https://*/*/tpPdk.js", "https://*/*/pdk/js/*/*.js"],
       types: ["script"],
     },
+    customFunc: "pdk5fix",
+  },
+  {
+    id: "bug1577870",
+    platform: "desktop",
+    domain: "slideshare.net",
+    bug: "1577870",
+    data: {
+      urls: ["https://*.linkedin.com/tscp-serving/dtag*"],
+      contentType: {
+        name: "content-type",
+        value: "text/html; charset=utf-8",
+      },
+    },
+    customFunc: "dtagFix",
   },
   {
     id: "bug1305028",
     platform: "desktop",
     domain: "gaming.youtube.com",
     bug: "1305028",
     contentScripts: {
       matches: ["*://gaming.youtube.com/*"],
@@ -212,17 +274,17 @@ const AVAILABLE_INJECTIONS = [
     },
   },
   {
     id: "bug1567610",
     platform: "all",
     domain: "dns.google.com",
     bug: "1567610",
     contentScripts: {
-      matches: ["*://dns.google.com/*"],
+      matches: ["*://dns.google.com/*", "*://dns.google/*"],
       css: [
         {
           file: "injections/css/bug1567610-dns.google.com-moz-fit-content.css",
         },
       ],
     },
   },
   {
@@ -234,11 +296,141 @@ const AVAILABLE_INJECTIONS = [
       matches: ["*://*.zertifikate.commerzbank.de/webforms/mobile/*"],
       css: [
         {
           file: "injections/css/bug1568256-zertifikate.commerzbank.de-flex.css",
         },
       ],
     },
   },
+  {
+    id: "bug1568908",
+    platform: "desktop",
+    domain: "console.cloud.google.com",
+    bug: "1568908",
+    contentScripts: {
+      matches: ["*://*.console.cloud.google.com/*"],
+      css: [
+        {
+          file:
+            "injections/css/bug1568908-console.cloud.google.com-scrollbar-fix.css",
+        },
+      ],
+    },
+  },
+  {
+    id: "bug1570119",
+    platform: "desktop",
+    domain: "teamcoco.com",
+    bug: "1570119",
+    contentScripts: {
+      matches: ["*://teamcoco.com/*"],
+      css: [
+        {
+          file: "injections/css/bug1570119-teamcoco.com-scrollbar-width.css",
+        },
+      ],
+    },
+  },
+  {
+    id: "bug1570328",
+    platform: "android",
+    domain: "developer.apple.com",
+    bug: "1570328",
+    contentScripts: {
+      matches: ["*://developer.apple.com/*"],
+      css: [
+        {
+          file:
+            "injections/css/bug1570328-developer-apple.com-transform-scale.css",
+        },
+      ],
+    },
+  },
+  {
+    id: "bug1574973",
+    platform: "android",
+    domain: "patch.com",
+    bug: "1574973",
+    contentScripts: {
+      matches: ["*://patch.com/*"],
+      css: [
+        {
+          file: "injections/css/bug1574973-patch.com-dropdown-menu-fix.css",
+        },
+      ],
+    },
+  },
+  {
+    id: "bug1575000",
+    platform: "all",
+    domain: "apply.lloydsbank.co.uk",
+    bug: "1575000",
+    contentScripts: {
+      matches: ["*://apply.lloydsbank.co.uk/*"],
+      css: [
+        {
+          file:
+            "injections/css/bug1575000-apply.lloydsbank.co.uk-radio-buttons-fix.css",
+        },
+      ],
+    },
+  },
+  {
+    id: "bug1575011",
+    platform: "android",
+    domain: "holiday-weather.com",
+    bug: "1575011",
+    contentScripts: {
+      matches: ["*://*.holiday-weather.com/*"],
+      css: [
+        {
+          file:
+            "injections/css/bug1575011-holiday-weather.com-scrolling-fix.css",
+        },
+      ],
+    },
+  },
+  {
+    id: "bug1575017",
+    platform: "desktop",
+    domain: "dunkindonuts.com",
+    bug: "1575017",
+    contentScripts: {
+      matches: ["*://*.dunkindonuts.com/en/sign-in*"],
+      css: [
+        {
+          file: "injections/css/bug1575017-dunkindonuts.com-flex-basis.css",
+        },
+      ],
+    },
+  },
+  {
+    id: "bug1577270",
+    platform: "android",
+    domain: "binance.com",
+    bug: "1577270",
+    contentScripts: {
+      matches: ["*://*.binance.com/*"],
+      css: [
+        {
+          file: "injections/css/bug1577270-binance.com-calc-height-fix.css",
+        },
+      ],
+    },
+  },
+  {
+    id: "bug1577297",
+    platform: "android",
+    domain: "kitkat.com.au",
+    bug: "1577297",
+    contentScripts: {
+      matches: ["*://*.kitkat.com.au/*"],
+      css: [
+        {
+          file: "injections/css/bug1577297-kitkat.com.au-slider-width-fix.css",
+        },
+      ],
+    },
+  },
 ];
 
 module.exports = AVAILABLE_INJECTIONS;
--- a/mobile/android/extensions/webcompat/data/ua_overrides.js
+++ b/mobile/android/extensions/webcompat/data/ua_overrides.js
@@ -1,41 +1,67 @@
 /* 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 */
+/* globals getMatchPatternsForGoogleURL, 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_UA_OVERRIDES = [
   {
     id: "testbed-override",
     platform: "all",
     domain: "webcompat-addon-testbed.herokuapp.com",
     bug: "0000000",
-    hidden: true,
     config: {
+      hidden: true,
       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 for WebCompat"
         );
       },
     },
   },
   {
     /*
+     * Bug 1564594 - Create UA override for Enhanced Search on Firefox Android
+     *
+     * Enables the Chrome Google Search experience for Fennec users.
+     */
+    id: "bug1564594",
+    platform: "android",
+    domain: "Enhanced Search",
+    bug: "1567945",
+    config: {
+      matches: [
+        ...getMatchPatternsForGoogleURL("images.google"),
+        ...getMatchPatternsForGoogleURL("maps.google"),
+        ...getMatchPatternsForGoogleURL("news.google"),
+        ...getMatchPatternsForGoogleURL("www.google"),
+      ],
+      blocks: [...getMatchPatternsForGoogleURL("www.google", "serviceworker")],
+      permanentPref: "enable_enhanced_search",
+      telemetryKey: "enhancedSearch",
+      experiment: "enhanced-search",
+      uaTransformer: originalUA => {
+        return UAHelpers.getDeviceAppropriateChromeUA();
+      },
+    },
+  },
+  {
+    /*
      * Bug 1563839 - rolb.santanderbank.com - Build UA override
      * WebCompat issue #33462 - https://webcompat.com/issues/33462
      *
      * santanderbank expects UA to have 'like Gecko', otherwise it runs
      * xmlDoc.onload whose support has been dropped. It results in missing labels in forms
      * and some other issues.  Adding 'like Gecko' fixes those issues.
      */
     id: "bug1563839",
@@ -50,16 +76,82 @@ const AVAILABLE_UA_OVERRIDES = [
       ],
       uaTransformer: originalUA => {
         return originalUA.replace("Gecko", "like Gecko");
       },
     },
   },
   {
     /*
+     * Bug 1577179 - UA override for supportforms.embarcadero.com
+     * WebCompat issue #34682 - https://webcompat.com/issues/34682
+     *
+     * supportforms.embarcadero.com has a constant onchange event on a product selector
+     * which makes it unusable. Spoofing as Chrome allows to stop event from firing
+     */
+    id: "bug1577179",
+    platform: "all",
+    domain: "supportforms.embarcadero.com",
+    bug: "1577179",
+    config: {
+      matches: ["*://supportforms.embarcadero.com/*"],
+      uaTransformer: originalUA => {
+        return (
+          UAHelpers.getPrefix(originalUA) +
+          " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36"
+        );
+      },
+    },
+  },
+  {
+    /*
+     * Bug 1577519 - att.tv - Create a UA override for att.tv for playback on desktop
+     * WebCompat issue #3846 - https://webcompat.com/issues/3846
+     *
+     * att.tv (atttvnow.com) is blocking Firefox via UA sniffing. Spoofing as Chrome allows
+     * to access the site and playback works fine. This is former directvnow.com
+     */
+    id: "bug1577519",
+    platform: "desktop",
+    domain: "att.tv",
+    bug: "1577519",
+    config: {
+      matches: ["*://*.att.tv/*"],
+      uaTransformer: originalUA => {
+        return (
+          UAHelpers.getPrefix(originalUA) +
+          " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36"
+        );
+      },
+    },
+  },
+  {
+    /*
+     * Bug 1570108 - steamcommunity.com - UA override for steamcommunity.com
+     * WebCompat issue #34171 - https://webcompat.com/issues/34171
+     *
+     * steamcommunity.com blocks chat feature for Firefox users showing unsupported browser message.
+     * When spoofing as Chrome the chat works fine
+     */
+    id: "bug1570108",
+    platform: "desktop",
+    domain: "steamcommunity.com",
+    bug: "1570108",
+    config: {
+      matches: ["*://steamcommunity.com/chat*"],
+      uaTransformer: originalUA => {
+        return (
+          UAHelpers.getPrefix(originalUA) +
+          " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
+        );
+      },
+    },
+  },
+  {
+    /*
      * Bug 1480710 - m.imgur.com - Build UA override
      * WebCompat issue #13154 - https://webcompat.com/issues/13154
      *
      * imgur returns a 404 for requests to CSS and JS file if requested with a Fennec
      * User Agent. By removing the Fennec identifies and adding Chrome Mobile's, we
      * receive the correct CSS and JS files.
      */
     id: "bug1480710",
@@ -85,17 +177,21 @@ const AVAILABLE_UA_OVERRIDES = [
      * mobile experience to Firefox for Android users. Adding the AppleWebKit indicator
      * to the User Agent gets us the same experience.
      */
     id: "bug945963",
     platform: "android",
     domain: "tieba.baidu.com",
     bug: "945963",
     config: {
-      matches: ["*://tieba.baidu.com/*", "*://tiebac.baidu.com/*"],
+      matches: [
+        "*://tieba.baidu.com/*",
+        "*://tiebac.baidu.com/*",
+        "*://zhidao.baidu.com/*",
+      ],
       uaTransformer: originalUA => {
         return originalUA + " AppleWebKit/537.36 (KHTML, like Gecko)";
       },
     },
   },
   {
     /*
      * Bug 1177298 - Write UA overrides for top Japanese Sites
@@ -311,17 +407,144 @@ const AVAILABLE_UA_OVERRIDES = [
     bug: "1567945",
     config: {
       matches: ["*://beeg.com/*"],
       uaTransformer: originalUA => {
         return originalUA.replace(/Firefox.+$/, "");
       },
     },
   },
+  {
+    /*
+     * Bug 1574522 - UA override for enuri.com on Firefox for Android
+     * WebCompat issue #37139 - https://webcompat.com/issues/37139
+     *
+     * enuri.com returns a different template for Firefox on Android
+     * based on server side UA detection. This results in page content cut offs.
+     * Spoofing as Chrome fixes the issue
+     */
+    id: "bug1574522",
+    platform: "android",
+    domain: "enuri.com",
+    bug: "1574522",
+    config: {
+      matches: ["*://enuri.com/*"],
+      uaTransformer: _ => {
+        return "Mozilla/5.0 (Linux; Android 6.0.1; SM-G900M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.111 Mobile Safari/537.36";
+      },
+    },
+  },
+  {
+    /*
+     * Bug 1574564 - UA override for ceskatelevize.cz on Firefox for Android
+     * WebCompat issue #15467 - https://webcompat.com/issues/15467
+     *
+     * ceskatelevize sets streamingProtocol depending on the User-Agent it sees
+     * in the request headers, returning DASH for Chrome, HLS for iOS,
+     * and Flash for Fennec. Since Fennec has no Flash, the video doesn't work.
+     * Spoofing as Chrome makes the video play
+     */
+    id: "bug1574564",
+    platform: "android",
+    domain: "ceskatelevize.cz",
+    bug: "1574564",
+    config: {
+      matches: ["*://*.ceskatelevize.cz/*"],
+      uaTransformer: originalUA => {
+        return (
+          UAHelpers.getPrefix(originalUA) +
+          " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.111 Mobile Safari/537.36"
+        );
+      },
+    },
+  },
+  {
+    /*
+     * Bug 1577240 - UA override for heb.com on Firefox for Android
+     * WebCompat issue #33613 - https://webcompat.com/issues/33613
+     *
+     * heb.com shows desktop site on Firefox for Android for some pages based on
+     * UA detection. Spoofing as Chrome allows to get mobile site.
+     */
+    id: "bug1577240",
+    platform: "android",
+    domain: "heb.com",
+    bug: "1577240",
+    config: {
+      matches: ["*://*.heb.com/*"],
+      uaTransformer: originalUA => {
+        return (
+          UAHelpers.getPrefix(originalUA) +
+          " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.111 Mobile Safari/537.36"
+        );
+      },
+    },
+  },
+  {
+    /*
+     * Bug 1577250 - UA override for homebook.pl on Firefox for Android
+     * WebCompat issue #24044 - https://webcompat.com/issues/24044
+     *
+     * homebook.pl shows desktop site on Firefox for Android based on
+     * UA detection. Spoofing as Chrome allows to get mobile site.
+     */
+    id: "bug1577250",
+    platform: "android",
+    domain: "homebook.pl",
+    bug: "1577250",
+    config: {
+      matches: ["*://*.homebook.pl/*"],
+      uaTransformer: originalUA => {
+        return (
+          UAHelpers.getPrefix(originalUA) +
+          " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.111 Mobile Safari/537.36"
+        );
+      },
+    },
+  },
+  {
+    /*
+     * Bug 1577267 - UA override for metfone.com.kh on Firefox for Android
+     * WebCompat issue #16363 - https://webcompat.com/issues/16363
+     *
+     * metfone.com.kh has a server side UA detection which returns desktop site
+     * for Firefox for Android. Spoofing as Chrome allows to receive mobile version
+     */
+    id: "bug1577267",
+    platform: "android",
+    domain: "metfone.com.kh",
+    bug: "1577267",
+    config: {
+      matches: ["*://*.metfone.com.kh/*"],
+      uaTransformer: originalUA => {
+        return (
+          UAHelpers.getPrefix(originalUA) +
+          " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.111 Mobile Safari/537.36"
+        );
+      },
+    },
+  },
 ];
 
 const UAHelpers = {
+  getDeviceAppropriateChromeUA() {
+    if (!UAHelpers._deviceAppropriateChromeUA) {
+      const RunningFirefoxVersion = (navigator.userAgent.match(
+        /Firefox\/([0-9.]+)/
+      ) || ["", "58.0"])[1];
+      const RunningAndroidVersion =
+        navigator.userAgent.match(/Android\/[0-9.]+/) || "Android 6.0";
+      const ChromeVersionToMimic = "76.0.3809.111";
+      const ChromePhoneUA = `Mozilla/5.0 (Linux; ${RunningAndroidVersion}; Nexus 5 Build/MRA58N) FxQuantum/${RunningFirefoxVersion} AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${ChromeVersionToMimic} Mobile Safari/537.36`;
+      const ChromeTabletUA = `Mozilla/5.0 (Linux; ${RunningAndroidVersion}; Nexus 7 Build/JSS15Q) FxQuantum/${RunningFirefoxVersion} AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${ChromeVersionToMimic} Safari/537.36`;
+      const IsPhone = navigator.userAgent.includes("Mobile");
+      UAHelpers._deviceAppropriateChromeUA = IsPhone
+        ? ChromePhoneUA
+        : ChromeTabletUA;
+    }
+    return UAHelpers._deviceAppropriateChromeUA;
+  },
   getPrefix(originalUA) {
     return originalUA.substr(0, originalUA.indexOf(")") + 1);
   },
 };
 
 module.exports = AVAILABLE_UA_OVERRIDES;
new file mode 100644
--- /dev/null
+++ b/mobile/android/extensions/webcompat/experiment-apis/experiments.js
@@ -0,0 +1,34 @@
+/* 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 ExtensionAPI, Services, XPCOMUtils */
+
+XPCOMUtils.defineLazyModuleGetters(this, {
+  EventDispatcher: "resource://gre/modules/Messaging.jsm",
+  Services: "resource://gre/modules/Services.jsm",
+});
+
+this.experiments = class extends ExtensionAPI {
+  getAPI(context) {
+    function promiseActiveExperiments() {
+      return EventDispatcher.instance.sendRequestForResult({
+        type: "Experiments:GetActive",
+      });
+    }
+    return {
+      experiments: {
+        async isActive(name) {
+          if (!Services.androidBridge || !Services.androidBridge.isFennec) {
+            return undefined;
+          }
+          return promiseActiveExperiments().then(experiments => {
+            return experiments.includes(name);
+          });
+        },
+      },
+    };
+  }
+};
new file mode 100644
--- /dev/null
+++ b/mobile/android/extensions/webcompat/experiment-apis/experiments.json
@@ -0,0 +1,21 @@
+[
+  {
+    "namespace": "experiments",
+    "description": "experimental API extension to allow checking the status of Fennec experiments via Switchboard",
+    "functions": [
+      {
+        "name": "isActive",
+        "type": "function",
+        "description": "Determine if a given experiment is active.",
+        "parameters": [
+          {
+            "name": "name",
+            "type": "string",
+            "description": "The experiment's name"
+          }
+        ],
+        "async": true
+      }
+    ]
+  }
+]
new file mode 100644
--- /dev/null
+++ b/mobile/android/extensions/webcompat/experiment-apis/sharedPreferences.js
@@ -0,0 +1,27 @@
+/* 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 ExtensionAPI, Services, XPCOMUtils */
+
+XPCOMUtils.defineLazyModuleGetters(this, {
+  Services: "resource://gre/modules/Services.jsm",
+  SharedPreferences: "resource://gre/modules/SharedPreferences.jsm",
+});
+
+this.sharedPreferences = class extends ExtensionAPI {
+  getAPI(context) {
+    return {
+      sharedPreferences: {
+        async setBoolPref(name, value) {
+          if (!Services.androidBridge || !Services.androidBridge.isFennec) {
+            return;
+          }
+          SharedPreferences.forApp().setBoolPref(name, value);
+        },
+      },
+    };
+  }
+};
new file mode 100644
--- /dev/null
+++ b/mobile/android/extensions/webcompat/experiment-apis/sharedPreferences.json
@@ -0,0 +1,26 @@
+[
+  {
+    "namespace": "sharedPreferences",
+    "description": "experimental API extension to allow setting SharedPreferences on Fennec",
+    "functions": [
+      {
+        "name": "setBoolPref",
+        "type": "function",
+        "description": "Set the value of a boolean Fennec SharedPreference",
+        "parameters": [
+          {
+            "name": "name",
+            "type": "string",
+            "description": "The key name"
+          },
+          {
+            "name": "value",
+            "type": "boolean",
+            "description": "The new value"
+          }
+        ],
+        "async": true
+      }
+    ]
+  }
+]
--- a/mobile/android/extensions/webcompat/injections/css/bug1561371-mail.google.com-allow-horizontal-scrolling.css
+++ b/mobile/android/extensions/webcompat/injections/css/bug1561371-mail.google.com-allow-horizontal-scrolling.css
@@ -2,11 +2,11 @@
  * mail.google.com - The HTML email view does not allow horizontal scrolling
  * on Fennec due to a missing CSS rule which is only served to Chrome.
  * Bug #1561371 - https://bugzilla.mozilla.org/show_bug.cgi?id=1561371
  *
  * HTML emails may sometimes contain content that does not wrap, yet the
  * CSS served to Fennec does not permit scrolling horizontally. To prevent
  * this UX frustration, we enable horizontal scrolling.
  */
-body > #views > div {
+body > #views {
   overflow: auto;
 }
new file mode 100644
--- /dev/null
+++ b/mobile/android/extensions/webcompat/injections/css/bug1568908-console.cloud.google.com-scrollbar-fix.css
@@ -0,0 +1,16 @@
+/**
+ * console.cloud.google.com - Double scrollbar visisible on long pages
+ * Bug #1568908 - https://bugzilla.mozilla.org/show_bug.cgi?id=1568908
+ * WebCompat issue #33164 - https://webcompat.com/issues/33164
+ *
+ * For pages that have contents heigher than the page's height, a secondary
+ * scrollbar outside the scrollable content area is visible. This is caused
+ * by a difference in Flexbox behavior, which is being addressed in
+ * https://bugs.chromium.org/p/chromium/issues/detail?id=981134
+ *
+ * Until this fix hits release and Google has updated their UI properly,
+ * this intervention addresses the differences.
+ */
+central-page-area {
+  min-height: 0;
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/extensions/webcompat/injections/css/bug1570119-teamcoco.com-scrollbar-width.css
@@ -0,0 +1,11 @@
+/**
+ * teamcoco.com - a scrollbar at the top covering navigation menu
+ * Bug #1570119 - https://bugzilla.mozilla.org/show_bug.cgi?id=1570119
+ *
+ * The scrollbar is covering navigation items making them unusable.
+ * There are ::-webkit-scrollbar css rules already applied to the scrollbar,
+ * hiding it in Chrome. Adding the scrollbar-width: none fixes the issue in Firefox.
+ */
+.css-bdnz85 {
+  scrollbar-width: none;
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/extensions/webcompat/injections/css/bug1570328-developer-apple.com-transform-scale.css
@@ -0,0 +1,17 @@
+/**
+ * developer.apple.com - content of the page is shifted to the left
+ * Bug #1570328 - https://bugzilla.mozilla.org/show_bug.cgi?id=1570328
+ * WebCompat issue #4070 - https://webcompat.com/issues/4070
+ *
+ * The site is relying on zoom property which is not supported by Mozilla,
+ * see https://bugzilla.mozilla.org/show_bug.cgi?id=390936. Adding a combination
+ * of transform: scale(1.4), transform-origin and width fixes the issue
+ */
+@media only screen and (min-device-width: 320px) and (max-device-width: 980px),
+  (min-device-width: 1024px) and (max-device-width: 1024px) and (min-device-height: 1366px) and (max-device-height: 1366px) and (min-width: 320px) and (max-width: 980px) {
+  #tocContainer {
+    transform-origin: 0 0;
+    transform: scale(1.4);
+    width: 71.4%;
+  }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/extensions/webcompat/injections/css/bug1574973-patch.com-dropdown-menu-fix.css
@@ -0,0 +1,13 @@
+/**
+ * patch.com - sub-menu expands at the bottom of the page and overlaps other elements.
+ * Bug #1574973 - https://bugzilla.mozilla.org/show_bug.cgi?id=1574973
+ * WebCompat issue #25384 - https://webcompat.com/issues/25384
+ *
+ * patch.con has a top:100% style on the relatively-positioned element
+ * with class="dropdown-menu", and Firefox is incorrectly honoring that
+ * style (resolving it to something nonzero), whereas Chrome just treats it as "auto"
+ * see https://bugzilla.mozilla.org/show_bug.cgi?id=1092007
+ */
+#patch-nav-secondary .dropdown-menu {
+  top: auto;
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/extensions/webcompat/injections/css/bug1575000-apply.lloydsbank.co.uk-radio-buttons-fix.css
@@ -0,0 +1,11 @@
+/**
+ * apply.lloydsbank.co.uk - radio buttons are misplaced
+ * Bug #1575000 - https://bugzilla.mozilla.org/show_bug.cgi?id=1575000
+ * WebCompat issue #34969 - https://webcompat.com/issues/34969
+ *
+ * Radio buttons are displaced to the left due to positioning issue of ::before
+ * pseudo element, adding position relative to it's parent fixes the issue.
+ */
+.radio-content-field .radio.inline label span.text {
+  position: relative;
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/extensions/webcompat/injections/css/bug1575011-holiday-weather.com-scrolling-fix.css
@@ -0,0 +1,15 @@
+/**
+ * holiday-weather.com - page is not scrollable
+ * Bug #1575011 - https://bugzilla.mozilla.org/show_bug.cgi?id=1575011
+ * WebCompat issue #18478 - https://webcompat.com/issues/18478
+ *
+ * the page won't scroll since the flex container is too high,
+ * adding min height to parent containers fixes the issue
+ */
+.page-container-style__pageContent {
+  min-height: 0;
+}
+
+.widgets-style__root {
+  min-height: 0;
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/extensions/webcompat/injections/css/bug1575017-dunkindonuts.com-flex-basis.css
@@ -0,0 +1,11 @@
+/**
+ * dunkindonuts.com - form input fields are small and misaligned
+ * Bug #1575017 - https://bugzilla.mozilla.org/show_bug.cgi?id=1575017
+ * WebCompat issue #28742 - https://webcompat.com/issues/28742
+ *
+ * Form input fields are small and misaligned due to flex-basis: min-content;
+ * applied on their parent element. Setting it to auto fixes the issue
+ */
+.grid__item {
+  flex-basis: auto;
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/extensions/webcompat/injections/css/bug1577270-binance.com-calc-height-fix.css
@@ -0,0 +1,12 @@
+/**
+ * binance.com - can't see the full site
+ * Bug #1577270 - https://bugzilla.mozilla.org/show_bug.cgi?id=1577270
+ * WebCompat issue #17810 - https://webcompat.com/issues/17810
+ *
+ * The site does not have a doctype and is rendered in quirks mode. The calc() percentage
+ * height is applied on the .main-page .viewWrap element, but its parent does not have
+ * a specified height property. Adding a height of 100% to the parent fixes the issue.
+ */
+#tradeDiv {
+  height: 100%;
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/extensions/webcompat/injections/css/bug1577297-kitkat.com.au-slider-width-fix.css
@@ -0,0 +1,11 @@
+/**
+ * kitkat.com.au - can't see the content
+ * Bug #1577297 - https://bugzilla.mozilla.org/show_bug.cgi?id=1577297
+ * WebCompat issue #28992 - https://webcompat.com/issues/28992
+ *
+ * Affected element is too wide due to https://bugzilla.mozilla.org/show_bug.cgi?id=1316534.
+ * Adding min-width: 0; fixes the issue
+ */
+.columns .column.main {
+  min-width: 0;
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/extensions/webcompat/injections/js/bug1570856-medium.com-menu-isTier1.js
@@ -0,0 +1,34 @@
+"use strict";
+
+/**
+ * medium.com - Override window.GLOBALS.useragent.isTier1 to be true
+ * WebCompat issue #25844 - https://webcompat.com/issues/25844
+ *
+ * This site is not showing main menu when scrolling. There is a GLOBALS variable
+ * at the bottom of the template being defined based on a server side UA detection.
+ * Setting window.GLOBALS.useragent.isTier1 to true makes the menu appear when scrolling
+ */
+
+/* globals exportFunction */
+
+console.info(
+  "window.GLOBALS.useragent.isTier1 has been set to true for compatibility reasons. See https://webcompat.com/issues/25844 for details."
+);
+
+let globals = {};
+
+Object.defineProperty(window.wrappedJSObject, "GLOBALS", {
+  get: exportFunction(function() {
+    return globals;
+  }, window),
+
+  set: exportFunction(function(value = {}) {
+    globals = value;
+
+    if (!globals.useragent) {
+      globals.useragent = {};
+    }
+
+    globals.useragent.isTier1 = true;
+  }, window),
+});
new file mode 100644
--- /dev/null
+++ b/mobile/android/extensions/webcompat/injections/js/bug1577245-salesforce-communities-hide-unsupported.js
@@ -0,0 +1,49 @@
+"use strict";
+
+/**
+ * help.pandora.com - Hide unsupported message in Firefox for Android
+ * WebCompat issue #38433 - https://webcompat.com/issues/38433
+ *
+ * SalesForce Communities are showing unsupported message
+ * for help.pandora.com and some more sites. See the full list here:
+ * https://github.com/webcompat/web-bugs/issues?utf8=%E2%9C%93&q=doNotShowUnsupportedBrowserModal
+ */
+
+console.info(
+  "Unsupported message has been hidden for compatibility reasons. See https://webcompat.com/issues/38433 for details."
+);
+
+const NOTIFICATIONS_LIMIT = 20;
+
+const createObserver = callback => {
+  return new MutationObserver(callback).observe(document, {
+    childList: true,
+    subtree: true,
+  });
+};
+
+const removeElementWhenReady = elementId => {
+  const element = document.getElementById(elementId);
+  if (element) {
+    element.remove();
+    return;
+  }
+
+  let n = 0;
+  createObserver(function(records, observer) {
+    const _element = document.getElementById(elementId);
+    if (_element) {
+      _element.remove();
+      observer.disconnect();
+      return;
+    }
+
+    if (n > NOTIFICATIONS_LIMIT) {
+      observer.disconnect();
+    }
+
+    n++;
+  });
+};
+
+removeElementWhenReady("community-browser-not-support-message");
new file mode 100644
--- /dev/null
+++ b/mobile/android/extensions/webcompat/injections/js/bug1579159-m.tailieu.vn-pdfjs-worker-disable.js
@@ -0,0 +1,28 @@
+"use strict";
+
+/**
+ * m.tailieu.vn - Override PDFJS.disableWorker to be true
+ * WebCompat issue #39057 - https://webcompat.com/issues/39057
+ *
+ * Custom viewer built with PDF.js is not working in Firefox for Android
+ * Disabling worker to match Chrome behavior fixes the issue
+ */
+
+/* globals exportFunction */
+
+console.info(
+  "window.PDFJS.disableWorker has been set to true for compatibility reasons. See https://webcompat.com/issues/39057 for details."
+);
+
+let globals = {};
+
+Object.defineProperty(window.wrappedJSObject, "PDFJS", {
+  get: exportFunction(function() {
+    return globals;
+  }, window),
+
+  set: exportFunction(function(value = {}) {
+    globals = value;
+    globals.disableWorker = true;
+  }, window),
+});
new file mode 100644
--- /dev/null
+++ b/mobile/android/extensions/webcompat/lib/custom_functions.js
@@ -0,0 +1,77 @@
+/* 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 */
+
+const 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();
+  };
+};
+
+const CUSTOM_FUNCTIONS = {
+  dtagFix: injection => {
+    const { urls, contentType } = injection.data;
+    const listener = (injection.data.listener = e => {
+      e.responseHeaders.push(contentType);
+      return { responseHeaders: e.responseHeaders };
+    });
+
+    browser.webRequest.onHeadersReceived.addListener(listener, { urls }, [
+      "blocking",
+      "responseHeaders",
+    ]);
+  },
+  dtagFixDisable: injection => {
+    const { listener } = injection.data;
+    browser.webRequest.onHeadersReceived.removeListener(listener);
+    delete injection.data.listener;
+  },
+  pdk5fix: injection => {
+    const { urls, types } = injection.data;
+    const listener = (injection.data.listener = ({ requestId }) => {
+      replaceStringInRequest(
+        requestId,
+        "VideoContextChromeAndroid",
+        "VideoContextAndroid"
+      );
+      return {};
+    });
+    browser.webRequest.onBeforeRequest.addListener(listener, { urls, types }, [
+      "blocking",
+    ]);
+  },
+  pdk5fixDisable: injection => {
+    const { listener } = injection.data;
+    browser.webRequest.onBeforeRequest.removeListener(listener);
+    delete injection.data.listener;
+  },
+};
+
+module.exports = CUSTOM_FUNCTIONS;
new file mode 100644
--- /dev/null
+++ b/mobile/android/extensions/webcompat/lib/google.js
@@ -0,0 +1,211 @@
+/* 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";
+
+const GOOGLE_TLDS = [
+  "com",
+  "ac",
+  "ad",
+  "ae",
+  "com.af",
+  "com.ag",
+  "com.ai",
+  "al",
+  "am",
+  "co.ao",
+  "com.ar",
+  "as",
+  "at",
+  "com.au",
+  "az",
+  "ba",
+  "com.bd",
+  "be",
+  "bf",
+  "bg",
+  "com.bh",
+  "bi",
+  "bj",
+  "com.bn",
+  "com.bo",
+  "com.br",
+  "bs",
+  "bt",
+  "co.bw",
+  "by",
+  "com.bz",
+  "ca",
+  "com.kh",
+  "cc",
+  "cd",
+  "cf",
+  "cat",
+  "cg",
+  "ch",
+  "ci",
+  "co.ck",
+  "cl",
+  "cm",
+  "cn",
+  "com.co",
+  "co.cr",
+  "com.cu",
+  "cv",
+  "com.cy",
+  "cz",
+  "de",
+  "dj",
+  "dk",
+  "dm",
+  "com.do",
+  "dz",
+  "com.ec",
+  "ee",
+  "com.eg",
+  "es",
+  "com.et",
+  "fi",
+  "com.fj",
+  "fm",
+  "fr",
+  "ga",
+  "ge",
+  "gf",
+  "gg",
+  "com.gh",
+  "com.gi",
+  "gl",
+  "gm",
+  "gp",
+  "gr",
+  "com.gt",
+  "gy",
+  "com.hk",
+  "hn",
+  "hr",
+  "ht",
+  "hu",
+  "co.id",
+  "iq",
+  "ie",
+  "co.il",
+  "im",
+  "co.in",
+  "io",
+  "is",
+  "it",
+  "je",
+  "com.jm",
+  "jo",
+  "co.jp",
+  "co.ke",
+  "ki",
+  "kg",
+  "co.kr",
+  "com.kw",
+  "kz",
+  "la",
+  "com.lb",
+  "com.lc",
+  "li",
+  "lk",
+  "co.ls",
+  "lt",
+  "lu",
+  "lv",
+  "com.ly",
+  "co.ma",
+  "md",
+  "me",
+  "mg",
+  "mk",
+  "ml",
+  "com.mm",
+  "mn",
+  "ms",
+  "com.mt",
+  "mu",
+  "mv",
+  "mw",
+  "com.mx",
+  "com.my",
+  "co.mz",
+  "com.na",
+  "ne",
+  "com.nf",
+  "com.ng",
+  "com.ni",
+  "nl",
+  "no",
+  "com.np",
+  "nr",
+  "nu",
+  "co.nz",
+  "com.om",
+  "com.pk",
+  "com.pa",
+  "com.pe",
+  "com.ph",
+  "pl",
+  "com.pg",
+  "pn",
+  "com.pr",
+  "ps",
+  "pt",
+  "com.py",
+  "com.qa",
+  "ro",
+  "rs",
+  "ru",
+  "rw",
+  "com.sa",
+  "com.sb",
+  "sc",
+  "se",
+  "com.sg",
+  "sh",
+  "si",
+  "sk",
+  "com.sl",
+  "sn",
+  "sm",
+  "so",
+  "st",
+  "sr",
+  "com.sv",
+  "td",
+  "tg",
+  "co.th",
+  "com.tj",
+  "tk",
+  "tl",
+  "tm",
+  "to",
+  "tn",
+  "com.tr",
+  "tt",
+  "com.tw",
+  "co.tz",
+  "com.ua",
+  "co.ug",
+  "co.uk",
+  "com",
+  "com.uy",
+  "co.uz",
+  "com.vc",
+  "co.ve",
+  "vg",
+  "co.vi",
+  "com.vn",
+  "vu",
+  "ws",
+  "co.za",
+  "co.zm",
+  "co.zw",
+];
+
+function getMatchPatternsForGoogleURL(url, path = "*") {
+  return GOOGLE_TLDS.map(domain => `*://${url}.${domain}/${path}`);
+}
--- a/mobile/android/extensions/webcompat/lib/injections.js
+++ b/mobile/android/extensions/webcompat/lib/injections.js
@@ -2,23 +2,24 @@
  * 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) {
+  constructor(availableInjections, customFunctions) {
     this.INJECTION_PREF = "perform_injections";
 
     this._injectionsEnabled = true;
 
     this._availableInjections = availableInjections;
     this._activeInjections = new Map();
+    this._customFunctions = customFunctions;
   }
 
   bindAboutCompatBroker(broker) {
     this._aboutCompatBroker = broker;
   }
 
   bootup() {
     browser.aboutConfigPrefs.onPrefChange.addListener(() => {
@@ -62,67 +63,55 @@ class Injections {
     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 = "";
+  assignContentScriptDefaults(contentScripts) {
+    let finalConfig = Object.assign({}, contentScripts);
 
-    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);
-    };
+    if (!finalConfig.runAt) {
+      finalConfig.runAt = "document_start";
+    }
 
-    filter.onstop = event => {
-      if (carryover.length) {
-        filter.write(encoder.encode(carryover));
-      }
-      filter.close();
-    };
+    return finalConfig;
   }
 
   async enableInjection(injection) {
     if (injection.active) {
-      return;
+      return undefined;
+    }
+
+    if (injection.customFunc) {
+      return this.enableCustomInjection(injection);
     }
 
-    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"]
+    return this.enableContentScripts(injection);
+  }
+
+  enableCustomInjection(injection) {
+    if (injection.customFunc in this._customFunctions) {
+      this._customFunctions[injection.customFunc](injection);
+      injection.active = true;
+    } else {
+      console.error(
+        `Provided function ${
+          injection.customFunc
+        } wasn't found in functions list`
       );
-      injection.active = true;
-      return;
     }
+  }
 
+  async enableContentScripts(injection) {
     try {
       const handle = await browser.contentScripts.register(
-        injection.contentScripts
+        this.assignContentScriptDefaults(injection.contentScripts)
       );
       this._activeInjections.set(injection, handle);
       injection.active = true;
     } catch (ex) {
       console.error(
         "Registering WebCompat GoFaster content scripts failed: ",
         ex
       );
@@ -137,27 +126,40 @@ class Injections {
     this._injectionsEnabled = false;
     this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
       interventionsChanged: false,
     });
   }
 
   async disableInjection(injection) {
     if (!injection.active) {
-      return;
+      return undefined;
+    }
+
+    if (injection.customFunc) {
+      return this.disableCustomInjections(injection);
     }
 
-    if (injection.pdk5fix) {
-      const { listener } = injection.pdk5fix;
-      browser.webRequest.onBeforeRequest.removeListener(listener);
+    return this.disableContentScripts(injection);
+  }
+
+  disableCustomInjections(injection) {
+    const disableFunc = injection.customFunc + "Disable";
+
+    if (disableFunc in this._customFunctions) {
+      this._customFunctions[disableFunc](injection);
       injection.active = false;
-      delete injection.pdk5fix.listener;
-      return;
+    } else {
+      console.error(
+        `Provided function ${disableFunc} for disabling injection wasn't found in functions list`
+      );
     }
+  }
 
+  async disableContentScripts(injection) {
     const contentScript = this._activeInjections.get(injection);
     await contentScript.unregister();
     this._activeInjections.delete(injection);
     injection.active = false;
   }
 }
 
 module.exports = Injections;
--- a/mobile/android/extensions/webcompat/lib/ua_overrides.js
+++ b/mobile/android/extensions/webcompat/lib/ua_overrides.js
@@ -47,45 +47,153 @@ class UAOverrides {
     return this._overridesEnabled;
   }
 
   enableOverride(override) {
     if (override.active) {
       return;
     }
 
-    const { matches, uaTransformer } = override.config;
+    const { blocks, matches, telemetryKey, uaTransformer } = override.config;
     const listener = details => {
-      for (const header of details.requestHeaders) {
-        if (header.name.toLowerCase() === "user-agent") {
-          header.value = uaTransformer(header.value);
+      // Don't actually override the UA for an experiment if the user is not
+      // part of the experiment (unless they force-enabed the override).
+      if (
+        !override.config.experiment ||
+        override.experimentActive ||
+        override.permanentPrefEnabled === true
+      ) {
+        if (telemetryKey && !details.frameId) {
+          // For now, we only care about Telemetry on Fennec, where telemetry
+          // is sent in Java code (as part of the core ping). That code must
+          // be aware of each key we send, which we send as a SharedPreference.
+          browser.sharedPreferences.setBoolPref(`${telemetryKey}Used`, true);
+        }
+
+        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);
+    const listeners = { onBeforeSendHeaders: listener };
+    if (blocks) {
+      const blistener = details => {
+        return { cancel: true };
+      };
+
+      browser.webRequest.onBeforeRequest.addListener(
+        blistener,
+        { urls: blocks },
+        ["blocking"]
+      );
+
+      listeners.onBeforeRequest = blistener;
+    }
+    this._activeListeners.set(override, listeners);
     override.active = true;
+
+    // If collecting telemetry on the override, note that it was activated.
+    if (telemetryKey) {
+      browser.sharedPreferences.setBoolPref(`${telemetryKey}Ready`, true);
+    }
+  }
+
+  onOverrideConfigChanged(override) {
+    // Check whether the override should be hidden from about:compat.
+    override.hidden = override.config.hidden;
+
+    // Also hide if the override is in an experiment the user is not part of.
+    if (override.config.experiment && !override.experimentActive) {
+      override.hidden = true;
+    }
+
+    // Setting the override's permanent pref overrules whether it is hidden.
+    if (override.permanentPrefEnabled !== undefined) {
+      override.hidden = !override.permanentPrefEnabled;
+    }
+
+    // Also check whether the override should be active.
+    let shouldBeActive = true;
+
+    // Overrides can be force-deactivated by their permanent preference.
+    if (override.permanentPrefEnabled === false) {
+      shouldBeActive = false;
+    }
+
+    // Overrides gated behind an experiment the user is not part of do not
+    // have to be activated, unless they are gathering telemetry, or the
+    // user has force-enabled them with their permanent pref.
+    if (
+      override.config.experiment &&
+      !override.experimentActive &&
+      !override.config.telemetryKey &&
+      override.permanentPrefEnabled !== true
+    ) {
+      shouldBeActive = false;
+    }
+
+    if (shouldBeActive) {
+      this.enableOverride(override);
+    } else {
+      this.disableOverride(override);
+    }
+
+    if (this._overridesEnabled) {
+      this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
+        overridesChanged: this._aboutCompatBroker.filterOverrides(
+          this._availableOverrides
+        ),
+      });
+    }
   }
 
   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);
+
+        // If there is a specific experiment running for
+        // this override, get its state.
+        const experiment = override.config.experiment;
+        override.experimentActive =
+          experiment && (await browser.experiments.isActive(experiment));
+
+        // If there is a specific about:config preference governing
+        // this override, monitor its state.
+        const pref = override.config.permanentPref;
+        override.permanentPrefEnabled =
+          pref && (await browser.aboutConfigPrefs.getPref(pref));
+        if (pref) {
+          const checkOverridePref = () => {
+            browser.aboutConfigPrefs.getPref(pref).then(value => {
+              override.permanentPrefEnabled = value;
+              this.onOverrideConfigChanged(override);
+            });
+          };
+          browser.aboutConfigPrefs.onPrefChange.addListener(
+            checkOverridePref,
+            pref
+          );
+        }
+
+        this.onOverrideConfigChanged(override);
       }
     }
 
     this._overridesEnabled = true;
     this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
       overridesChanged: this._aboutCompatBroker.filterOverrides(
         this._availableOverrides
       ),
@@ -103,17 +211,18 @@ class UAOverrides {
     });
   }
 
   disableOverride(override) {
     if (!override.active) {
       return;
     }
 
-    browser.webRequest.onBeforeSendHeaders.removeListener(
-      this._activeListeners.get(override)
-    );
+    const listeners = this._activeListeners.get(override);
+    for (const [name, listener] of Object.entries(listeners)) {
+      browser.webRequest[name].removeListener(listener);
+    }
     override.active = false;
     this._activeListeners.delete(override);
   }
 }
 
 module.exports = UAOverrides;
--- a/mobile/android/extensions/webcompat/manifest.json
+++ b/mobile/android/extensions/webcompat/manifest.json
@@ -1,13 +1,13 @@
 {
   "manifest_version": 2,
   "name": "Web Compat",
   "description": "Urgent post-release fixes for web compatibility.",
-  "version": "5.0.2",
+  "version": "6.1.0",
 
   "applications": {
     "gecko": {
       "id": "webcompat@mozilla.org",
       "strict_min_version": "59.0b5"
     }
   },
 
@@ -22,31 +22,49 @@
     },
     "aboutPage": {
       "schema": "about-compat/aboutPage.json",
       "parent": {
         "scopes": ["addon_parent"],
         "script": "about-compat/aboutPage.js",
         "events": ["startup"]
       }
+    },
+    "experiments": {
+      "schema": "experiment-apis/experiments.json",
+      "parent": {
+        "scopes": ["addon_parent"],
+        "script": "experiment-apis/experiments.js",
+        "paths": [["experiments"]]
+      }
+    },
+    "sharedPreferences": {
+      "schema": "experiment-apis/sharedPreferences.json",
+      "parent": {
+        "scopes": ["addon_parent"],
+        "script": "experiment-apis/sharedPreferences.js",
+        "paths": [["sharedPreferences"]]
+      }
     }
   },
 
   "content_security_policy": "script-src 'self' 'sha256-MmZkN2QaIHhfRWPZ8TVRjijTn5Ci1iEabtTEWrt9CCo='; default-src 'self'; base-uri moz-extension://*;",
 
   "permissions": [
     "webRequest",
     "webRequestBlocking",
     "<all_urls>"
   ],
 
   "background": {
     "scripts": [
       "lib/module_shim.js",
+      "lib/google.js",
       "data/injections.js",
       "data/ua_overrides.js",
       "lib/about_compat_broker.js",
+      "lib/custom_functions.js",
       "lib/injections.js",
       "lib/ua_overrides.js",
       "run.js"
     ]
   }
 }
--- a/mobile/android/extensions/webcompat/moz.build
+++ b/mobile/android/extensions/webcompat/moz.build
@@ -4,61 +4,79 @@
 # 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/.
 
 DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
 DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION']
 
 FINAL_TARGET_FILES.features['webcompat@mozilla.org'] += [
   'manifest.json',
-  'run.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'
+  'about-compat/aboutPageProcessScript.js',
 ]
 
 FINAL_TARGET_FILES.features['webcompat@mozilla.org']['data'] += [
   'data/injections.js',
-  'data/ua_overrides.js'
+  'data/ua_overrides.js',
 ]
 
 FINAL_TARGET_FILES.features['webcompat@mozilla.org']['experiment-apis'] += [
   'experiment-apis/aboutConfigPrefs.js',
-  'experiment-apis/aboutConfigPrefs.json'
+  'experiment-apis/aboutConfigPrefs.json',
+  'experiment-apis/experiments.js',
+  'experiment-apis/experiments.json',
+  'experiment-apis/sharedPreferences.js',
+  'experiment-apis/sharedPreferences.json',
 ]
 
 FINAL_TARGET_FILES.features['webcompat@mozilla.org']['injections']['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/bug1567610-dns.google.com-moz-fit-content.css',
-  'injections/css/bug1568256-zertifikate.commerzbank.de-flex.css'
+  'injections/css/bug1568256-zertifikate.commerzbank.de-flex.css',
+  'injections/css/bug1568908-console.cloud.google.com-scrollbar-fix.css',
+  'injections/css/bug1570119-teamcoco.com-scrollbar-width.css',
+  'injections/css/bug1570328-developer-apple.com-transform-scale.css',
+  'injections/css/bug1574973-patch.com-dropdown-menu-fix.css',
+  'injections/css/bug1575000-apply.lloydsbank.co.uk-radio-buttons-fix.css',
+  'injections/css/bug1575011-holiday-weather.com-scrolling-fix.css',
+  'injections/css/bug1575017-dunkindonuts.com-flex-basis.css',
+  'injections/css/bug1577270-binance.com-calc-height-fix.css',
+  'injections/css/bug1577297-kitkat.com.au-slider-width-fix.css'
 ]
 
 FINAL_TARGET_FILES.features['webcompat@mozilla.org']['injections']['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',
   'injections/js/bug1472081-election.gov.np-window.sidebar-shim.js',
-  'injections/js/bug1482066-portalminasnet.com-window.sidebar-shim.js'
+  'injections/js/bug1482066-portalminasnet.com-window.sidebar-shim.js',
+  'injections/js/bug1570856-medium.com-menu-isTier1.js',
+  'injections/js/bug1577245-salesforce-communities-hide-unsupported.js',
+  'injections/js/bug1579159-m.tailieu.vn-pdfjs-worker-disable.js'
 ]
 
 FINAL_TARGET_FILES.features['webcompat@mozilla.org']['lib'] += [
   'lib/about_compat_broker.js',
+  'lib/custom_functions.js',
+  'lib/google.js',
   'lib/injections.js',
   'lib/module_shim.js',
-  'lib/ua_overrides.js'
+  'lib/ua_overrides.js',
 ]
 
 with Files('**'):
   BUG_COMPONENT = ('Web Compatibility Tools', 'Go Faster')
--- a/mobile/android/extensions/webcompat/run.js
+++ b/mobile/android/extensions/webcompat/run.js
@@ -1,18 +1,18 @@
 /* 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 */
+           Injections, UAOverrides, CUSTOM_FUNCTIONS */
 
-const injections = new Injections(AVAILABLE_INJECTIONS);
+const injections = new Injections(AVAILABLE_INJECTIONS, CUSTOM_FUNCTIONS);
 const uaOverrides = new UAOverrides(AVAILABLE_UA_OVERRIDES);
 
 const aboutCompatBroker = new AboutCompatBroker({
   injections,
   uaOverrides,
 });
 
 aboutCompatBroker.bootup();