Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
firefox / usr / lib / firefox / browser / features / webcompat@mozilla.org.xpi
Size: Mime:
PK
!<=ÇpöŠŠabout-compat/AboutCompat.jsm/* 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";

var EXPORTED_SYMBOLS = ["AboutCompat"];

const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");

const addonID = "webcompat@mozilla.org";
const addonPageRelativeURL = "/about-compat/aboutCompat.html";

function AboutCompat() {
  this.chromeURL = WebExtensionPolicy.getByID(addonID).getURL(
    addonPageRelativeURL
  );
}
AboutCompat.prototype = {
  QueryInterface: ChromeUtils.generateQI([Ci.nsIAboutModule]),
  getURIFlags() {
    return Ci.nsIAboutModule.URI_MUST_LOAD_IN_EXTENSION_PROCESS;
  },

  newChannel(aURI, aLoadInfo) {
    const uri = Services.io.newURI(this.chromeURL);
    const channel = Services.io.newChannelFromURIWithLoadInfo(uri, aLoadInfo);
    channel.originalURI = aURI;

    channel.owner = (Services.scriptSecurityManager.createContentPrincipal ||
      Services.scriptSecurityManager.createCodebasePrincipal)(
      uri,
      aLoadInfo.originAttributes
    );
    return channel;
  },
};
PK
!<9¸Cd
d
about-compat/aboutCompat.css@media (any-pointer: fine) {
  :root {
    font-family: sans-serif;
    margin: 40px auto;
    min-width: 30em;
    max-width: 60em;
  }

  table {
    width: 100%;
    padding-bottom: 2em;
  }

  .float-right {
    float: right;
  }

  .hidden {
    display: none;
  }

  .table-title-container {
    align-items: center;
    display: flex;
    justify-content: space-between;
  }

  .wide-button {
    display: block;
    min-height: 32px;
    padding-left: 30px;
    padding-right: 30px;
  }

  .submitting {
    background-image: url(chrome://global/skin/icons/loading.png);
    background-position: center;
    background-repeat: no-repeat;
    background-size: 16px;
  }

  .submitting .submit-crash-button-label {
    display: none;
  }

  .failed-to-submit {
    color: #ca8695;
  }

  a.button-as-link {
    -moz-appearance: none;
    min-height: 30px;
    color: var(--in-content-text-color) !important;
    border: 1px solid var(--in-content-box-border-color) !important;
    border-radius: 2px;
    background-color: var(--in-content-page-background);
    line-height: 30px;
    margin: 4px 8px;
    /* Ensure font-size isn't overridden by widget styling (e.g. in forms.css) */
    font-size: 1em;
  }

  a.button-as-link:hover {
    background-color: var(--in-content-box-background-hover) !important;
    text-decoration: none;
  }

  h2.lighter-font-weight {
    font-weight: lighter;
  }

  html[dir="ltr"] th {
    text-align: left;
  }

  html[dir="rtl"] th {
    text-align: right;
  }
}

@media (any-pointer: coarse), (any-pointer: none) {
  * {
    margin: 0;
    padding: 0;
  }

  html {
    font-family: sans-serif;
    font-size: 14px;
    -moz-text-size-adjust: none;
    background-color: #f5f5f5;
  }

  table,
  tr,
  p {
    display: block;
    background: #fff;
  }

  table {
    border-top: 2px solid #0a84ff;
    margin-top: -2px;
    position: absolute;
    width: 100%;
    z-index: 1;
    display: none;
  }

  tr {
    position: relative;
    border-bottom: 1px solid #d7d9db;
    padding: 1em;
  }

  a {
    color: #000;
    font-size: 94%;
  }

  .tab {
    cursor: pointer;
    position: relative;
    z-index: 2;
    display: inline-block;
    text-align: left;
    padding: 1em;
    font-weight: bold;
    border-top-left-radius: 3px;
    border-top-right-radius: 3px;
    border: 1px solid #d7d9db;
    border-bottom: 0;
    margin-bottom: 2px;
    background: #f5f5f5;
    color: #363b40;
    font-size: 1em;
    font-weight: bold;
    padding: 1em;
  }

  .tab.active {
    border-bottom-color: #fff;
    background: #fff;
    margin-bottom: 0;
    padding-bottom: calc(1em + 2px);
  }

  .tab.active + table {
    display: block;
  }

  td {
    display: block;
    position: relative;
  }
  td:dir(ltr) {
    padding-right: 6.5em;
  }
  td:dir(rtl) {
    padding-left: 6.5em;
  }

  td[colspan="4"] {
    padding: 1em;
    font-style: italic;
    text-align: center;
  }

  td:not([colspan]):nth-child(1) {
    font-weight: bold;
  }

  td:not([colspan]):nth-child(1) {
    padding-bottom: 0.25em;
  }

  td:nth-child(3) {
    display: contents;
  }

  button {
    background: #e8e8e7;
    position: absolute;
    top: 0;
    bottom: 0;
    width: 6em;
    border: 0;
    border-left: 1px solid #d7d9db;
    -moz-appearance: none;
    color: #000;
  }
  button:dir(ltr) {
    right: 0;
  }
  button:dir(rtl) {
    left: 0;
  }

  button::-moz-focus-inner {
    border: 0;
  }
}
PK
!<¹—}IIabout-compat/aboutCompat.html<!DOCTYPE HTML>
<html>
<head>
  <base/>

  <!-- If you change this script tag you must update the hash in the extension's
         `content_security_policy` 'sha256-MmZkN2QaIHhfRWPZ8TVRjijTn5Ci1iEabtTEWrt9CCo=' -->
  <script>/* globals browser */ document.head.firstElementChild.href = browser.runtime.getURL("");</script>

  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="about-compat/aboutCompat.css" />
  <link rel="stylesheet" media="screen and (pointer:fine), projection" type="text/css"
          href="chrome://global/skin/in-content/common.css"/>
  <link rel="localization" href="toolkit/about/aboutCompat.ftl"/>
  <title data-l10n-id="text-title"></title>
  <script src="about-compat/aboutCompat.js"></script>
  </head>
<body>
  <h2 class="tab active" data-l10n-id="label-overrides"></h2>
  <table id="overrides">
    <col/>
    <col/>
    <col/>
  </table>
  <h2 class="tab" data-l10n-id="label-interventions"></h2>
  <table id="interventions">
    <col/>
    <col/>
    <col/>
  </table>
</body>
</html>
PK
!<*¥Ç¨¨about-compat/aboutCompat.js/* 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 */

let availablePatches;

const portToAddon = (function() {
  let port;

  function connect() {
    port = browser.runtime.connect({ name: "AboutCompatTab" });
    port.onMessage.addListener(onMessageFromAddon);
    port.onDisconnect.addListener(e => {
      port = undefined;
    });
  }

  connect();

  async function send(message) {
    if (port) {
      return port.postMessage(message);
    }
    return Promise.reject("background script port disconnected");
  }

  return { send };
})();

const $ = function(sel) {
  return document.querySelector(sel);
};

const DOMContentLoadedPromise = new Promise(resolve => {
  document.addEventListener(
    "DOMContentLoaded",
    () => {
      resolve();
    },
    { once: true }
  );
});

Promise.all([
  browser.runtime.sendMessage("getOverridesAndInterventions"),
  DOMContentLoadedPromise,
]).then(([info]) => {
  document.body.addEventListener("click", async evt => {
    const ele = evt.target;
    if (ele.nodeName === "BUTTON") {
      const row = ele.closest("[data-id]");
      if (row) {
        evt.preventDefault();
        ele.disabled = true;
        const id = row.getAttribute("data-id");
        try {
          await browser.runtime.sendMessage({ command: "toggle", id });
        } catch (_) {
          ele.disabled = false;
        }
      }
    } else if (ele.classList.contains("tab")) {
      document.querySelectorAll(".tab").forEach(tab => {
        tab.classList.remove("active");
      });
      ele.classList.add("active");
    }
  });

  availablePatches = info;
  redraw();
});

function onMessageFromAddon(msg) {
  if ("interventionsChanged" in msg) {
    redrawTable($("#interventions"), msg.interventionsChanged);
  }

  if ("overridesChanged" in msg) {
    redrawTable($("#overrides"), msg.overridesChanged);
  }

  const id = msg.toggling || msg.toggled;
  const button = $(`[data-id="${id}"] button`);
  if (!button) {
    return;
  }
  const active = msg.active;
  document.l10n.setAttributes(
    button,
    active ? "label-disable" : "label-enable"
  );
  button.disabled = !!msg.toggling;
}

function redraw() {
  if (!availablePatches) {
    return;
  }
  const { overrides, interventions } = availablePatches;
  const showHidden = location.hash === "#all";
  redrawTable($("#overrides"), overrides, showHidden);
  redrawTable($("#interventions"), interventions, showHidden);
}

function redrawTable(table, data, showHidden = false) {
  const df = document.createDocumentFragment();
  table.querySelectorAll("tr").forEach(tr => {
    tr.remove();
  });

  let noEntriesMessage;
  if (data === false) {
    noEntriesMessage = "text-disabled-in-about-config";
  } else if (data.length === 0) {
    noEntriesMessage =
      table.id === "overrides" ? "text-no-overrides" : "text-no-interventions";
  }

  if (noEntriesMessage) {
    const tr = document.createElement("tr");
    df.appendChild(tr);

    const td = document.createElement("td");
    td.setAttribute("colspan", "3");
    document.l10n.setAttributes(td, noEntriesMessage);
    tr.appendChild(td);

    table.appendChild(df);
    return;
  }

  for (const row of data) {
    if (row.hidden && !showHidden) {
      continue;
    }

    const tr = document.createElement("tr");
    tr.setAttribute("data-id", row.id);
    df.appendChild(tr);

    let td = document.createElement("td");
    td.innerText = row.domain;
    tr.appendChild(td);

    td = document.createElement("td");
    const a = document.createElement("a");
    const bug = row.bug;
    a.href = `https://bugzilla.mozilla.org/show_bug.cgi?id=${bug}`;
    document.l10n.setAttributes(a, "label-more-information", { bug });
    a.target = "_blank";
    td.appendChild(a);
    tr.appendChild(td);

    td = document.createElement("td");
    tr.appendChild(td);
    const button = document.createElement("button");
    document.l10n.setAttributes(
      button,
      row.active ? "label-disable" : "label-enable"
    );
    td.appendChild(button);
  }
  table.appendChild(df);
}

window.onhashchange = redraw;
PK
!<v_t11about-compat/aboutPage.js/* 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 */

ChromeUtils.defineModuleGetter(
  this,
  "Services",
  "resource://gre/modules/Services.jsm"
);

XPCOMUtils.defineLazyServiceGetter(
  this,
  "resProto",
  "@mozilla.org/network/protocol;1?name=resource",
  "nsISubstitutingProtocolHandler"
);

const ResourceSubstitution = "webcompat";
const ProcessScriptURL = "resource://webcompat/aboutPageProcessScript.js";

this.aboutPage = class extends ExtensionAPI {
  onStartup() {
    const { rootURI } = this.extension;

    resProto.setSubstitution(
      ResourceSubstitution,
      Services.io.newURI("about-compat/", null, rootURI)
    );

    Services.ppmm.loadProcessScript(ProcessScriptURL, true);
  }

  onShutdown() {
    resProto.setSubstitution(ResourceSubstitution, null);

    Services.ppmm.removeDelayedProcessScript(ProcessScriptURL);
  }
};
PK
!<p›UéYYabout-compat/aboutPage.json[{
    "namespace": "aboutCompat",
    "description": "Enables the about:compat page"
}]
PK
!<î¶m!BB&about-compat/aboutPageProcessScript.js/* 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 Cm = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);

const classID = Components.ID("{97bf9550-2a7b-11e9-b56e-0800200c9a66}");

if (!Cm.isCIDRegistered(classID)) {
  const { XPCOMUtils } = ChromeUtils.import(
    "resource://gre/modules/XPCOMUtils.jsm"
  );

  const factory = XPCOMUtils.generateSingletonFactory(function() {
    const { AboutCompat } = ChromeUtils.import(
      "resource://webcompat/AboutCompat.jsm"
    );
    return new AboutCompat();
  });

  Cm.registerFactory(
    classID,
    "about:compat",
    "@mozilla.org/network/protocol/about;1?what=compat",
    factory
  );
}
PK
!<ÌÍÍdata/injections.js/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

/* globals module */

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

module.exports = AVAILABLE_INJECTIONS;
PK
!<ÏEæîù'ù'data/ua_overrides.js/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

/* globals module */

/**
 * For detailed information on our policies, and a documention on this format
 * and its possibilites, please check the Mozilla-Wiki at
 *
 * https://wiki.mozilla.org/Compatibility/Go_Faster_Addon/Override_Policies_and_Workflows#User_Agent_overrides
 */
const AVAILABLE_UA_OVERRIDES = [
  {
    id: "testbed-override",
    platform: "all",
    domain: "webcompat-addon-testbed.herokuapp.com",
    bug: "0000000",
    hidden: true,
    config: {
      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 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",
    platform: "all",
    domain: "rolb.santanderbank.com",
    bug: "1563839",
    config: {
      matches: [
        "*://*.santander.co.uk/*",
        "*://bob.santanderbank.com/*",
        "*://rolb.santanderbank.com/*",
      ],
      uaTransformer: originalUA => {
        return originalUA.replace("Gecko", "like Gecko");
      },
    },
  },
  {
    /*
     * 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",
    platform: "android",
    domain: "m.imgur.com",
    bug: "1480710",
    config: {
      matches: ["*://m.imgur.com/*"],
      uaTransformer: originalUA => {
        return (
          UAHelpers.getPrefix(originalUA) +
          " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.85 Mobile Safari/537.36"
        );
      },
    },
  },
  {
    /*
     * Bug 945963 - tieba.baidu.com serves simplified mobile content to Firefox Android
     * WebCompat issue #18455 - https://webcompat.com/issues/18455
     *
     * tieba.baidu.com and tiebac.baidu.com serve a heavily simplified and less functional
     * 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/*"],
      uaTransformer: originalUA => {
        return originalUA + " AppleWebKit/537.36 (KHTML, like Gecko)";
      },
    },
  },
  {
    /*
     * Bug 1177298 - Write UA overrides for top Japanese Sites
     * (Imported from ua-update.json.in)
     *
     * To receive the proper mobile version instead of the desktop version or
     * a lower grade mobile experience, the UA is spoofed.
     */
    id: "bug1177298-2",
    platform: "android",
    domain: "lohaco.jp",
    bug: "1177298",
    config: {
      matches: ["*://*.lohaco.jp/*"],
      uaTransformer: _ => {
        return "Mozilla/5.0 (Linux; Android 5.0.2; Galaxy Nexus Build/IMM76B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.93 Mobile Safari/537.36";
      },
    },
  },
  {
    /*
     * Bug 1177298 - Write UA overrides for top Japanese Sites
     * (Imported from ua-update.json.in)
     *
     * To receive the proper mobile version instead of the desktop version or
     * a lower grade mobile experience, the UA is spoofed.
     */
    id: "bug1177298-3",
    platform: "android",
    domain: "nhk.or.jp",
    bug: "1177298",
    config: {
      matches: ["*://*.nhk.or.jp/*"],
      uaTransformer: originalUA => {
        return originalUA + " AppleWebKit";
      },
    },
  },
  {
    /*
     * Bug 1338260 - Add UA override for directTV
     * (Imported from ua-update.json.in)
     *
     * DirectTV has issues with scrolling and cut-off images. Pretending to be
     * Chrome for Android fixes those issues.
     */
    id: "bug1338260",
    platform: "android",
    domain: "directv.com",
    bug: "1338260",
    config: {
      matches: ["*://*.directv.com/*"],
      uaTransformer: _ => {
        return "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36";
      },
    },
  },
  {
    /*
     * Bug 1385206 - Create UA override for rakuten.co.jp on Firefox Android
     * (Imported from ua-update.json.in)
     *
     * rakuten.co.jp serves a Desktop version if Firefox is included in the UA.
     */
    id: "bug1385206",
    platform: "android",
    domain: "rakuten.co.jp",
    bug: "1385206",
    config: {
      matches: ["*://*.rakuten.co.jp/*"],
      uaTransformer: originalUA => {
        return originalUA.replace(/Firefox.+$/, "");
      },
    },
  },
  {
    /*
     * Bug 969844 - mobile.de sends desktop site to Firefox on Android
     *
     * mobile.de sends the desktop site to Fennec. Spooing as Chrome works fine.
     */
    id: "bug969844",
    platform: "android",
    domain: "mobile.de",
    bug: "969844",
    config: {
      matches: ["*://*.mobile.de/*"],
      uaTransformer: _ => {
        return "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36";
      },
    },
  },
  {
    /*
     * Bug 1509831 - cc.com - Add UA override for CC.com
     * WebCompat issue #329 - https://webcompat.com/issues/329
     *
     * ComedyCentral blocks Firefox for not being able to play HLS, which was
     * true in previous versions, but no longer is. With a spoofed Chrome UA,
     * the site works just fine.
     */
    id: "bug1509831",
    platform: "android",
    domain: "cc.com",
    bug: "1509831",
    config: {
      matches: ["*://*.cc.com/*"],
      uaTransformer: _ => {
        return "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36";
      },
    },
  },
  {
    /*
     * Bug 1508516 - cineflix.com.br - Add UA override for cineflix.com.br/m/
     * WebCompat issue #21553 - https://webcompat.com/issues/21553
     *
     * The site renders a blank page with any Firefox snipped in the UA as it
     * is running into an exception. Spoofing as Chrome makes the site work
     * fine.
     */
    id: "bug1508516",
    platform: "android",
    domain: "cineflix.com.br",
    bug: "1508516",
    config: {
      matches: ["*://*.cineflix.com.br/m/*"],
      uaTransformer: originalUA => {
        return (
          UAHelpers.getPrefix(originalUA) +
          " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36"
        );
      },
    },
  },
  {
    /*
     * Bug 1509852 - redbull.com - Add UA override for redbull.com
     * WebCompat issue #21439 - https://webcompat.com/issues/21439
     *
     * Redbull.com blocks some features, for example the live video player, for
     * Fennec. Spoofing as Chrome results in us rendering the video just fine,
     * and everything else works as well.
     */
    id: "bug1509852",
    platform: "android",
    domain: "redbull.com",
    bug: "1509852",
    config: {
      matches: ["*://*.redbull.com/*"],
      uaTransformer: originalUA => {
        return (
          UAHelpers.getPrefix(originalUA) +
          " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36"
        );
      },
    },
  },
  {
    /*
     * Bug 1509873 - zmags.com - Add UA override for secure.viewer.zmags.com
     * WebCompat issue #21576 - https://webcompat.com/issues/21576
     *
     * The zmags viewer locks out Fennec with a "Browser unsupported" message,
     * but tests showed that it works just fine with a Chrome UA. Outreach
     * attempts were unsuccessful, and as the site has a relatively high rank,
     * we alter the UA.
     */
    id: "bug1509873",
    platform: "android",
    domain: "zmags.com",
    bug: "1509873",
    config: {
      matches: ["*://*.viewer.zmags.com/*"],
      uaTransformer: originalUA => {
        return (
          UAHelpers.getPrefix(originalUA) +
          " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36"
        );
      },
    },
  },
  {
    /*
     * Bug 1566253 - posts.google.com - Add UA override for posts.google.com
     * WebCompat issue #17870 - https://webcompat.com/issues/17870
     *
     * posts.google.com displaying "Your browser doesn't support this page".
     * Spoofing as Chrome works fine.
     */
    id: "bug1566253",
    platform: "android",
    domain: "posts.google.com",
    bug: "1566253",
    config: {
      matches: ["*://posts.google.com/*"],
      uaTransformer: _ => {
        return "Mozilla/5.0 (Linux; Android 6.0.1; SM-G900M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.101 Mobile Safari/537.36";
      },
    },
  },
  {
    /*
     * Bug 1567945 - Create UA override for beeg.com on Firefox Android
     * WebCompat issue #16648 - https://webcompat.com/issues/16648
     *
     * beeg.com is hiding content of a page with video if Firefox exists in UA,
     * replacing "Firefox" with an empty string makes the page load
     */
    id: "bug1567945",
    platform: "android",
    domain: "beeg.com",
    bug: "1567945",
    config: {
      matches: ["*://beeg.com/*"],
      uaTransformer: originalUA => {
        return originalUA.replace(/Firefox.+$/, "");
      },
    },
  },
];

const UAHelpers = {
  getPrefix(originalUA) {
    return originalUA.substr(0, originalUA.indexOf(")") + 1);
  },
};

module.exports = AVAILABLE_UA_OVERRIDES;
PK
!<÷Õ|%\\#experiment-apis/aboutConfigPrefs.js/* 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, ExtensionCommon, Services, XPCOMUtils */

XPCOMUtils.defineLazyModuleGetters(this, {
  Services: "resource://gre/modules/Services.jsm",
});

this.aboutConfigPrefs = class extends ExtensionAPI {
  getAPI(context) {
    const EventManager = ExtensionCommon.EventManager;
    const extensionIDBase = context.extension.id.split("@")[0];
    const extensionPrefNameBase = `extensions.${extensionIDBase}.`;

    return {
      aboutConfigPrefs: {
        onPrefChange: new EventManager({
          context,
          name: "aboutConfigPrefs.onUAOverridesPrefChange",
          register: (fire, name) => {
            const prefName = `${extensionPrefNameBase}${name}`;
            const callback = () => {
              fire.async(name).catch(() => {}); // ignore Message Manager disconnects
            };
            Services.prefs.addObserver(prefName, callback);
            return () => {
              Services.prefs.removeObserver(prefName, callback);
            };
          },
        }).api(),
        async getPref(name) {
          try {
            return Services.prefs.getBoolPref(
              `${extensionPrefNameBase}${name}`
            );
          } catch (_) {
            return undefined;
          }
        },
        async setPref(name, value) {
          Services.prefs.setBoolPref(`${extensionPrefNameBase}${name}`, value);
        },
      },
    };
  }
};
PK
!<ñ Î%experiment-apis/aboutConfigPrefs.json[
  {
    "namespace": "aboutConfigPrefs",
    "description": "experimental API extension to allow access to about:config preferences",
    "events": [
      {
        "name": "onPrefChange",
        "type": "function",
        "parameters": [{
          "name": "name",
          "type": "string",
          "description": "The preference which changed"
        }],
        "extraParameters": [{
          "name": "name",
          "type": "string",
          "description": "The preference to monitor"
        }]
      }
    ],
    "functions": [
      {
        "name": "getPref",
        "type": "function",
        "description": "Get a preference's value",
        "parameters": [{
          "name": "name",
          "type": "string",
          "description": "The preference name"
        }],
        "async": true
      },
      {
        "name": "setPref",
        "type": "function",
        "description": "Set a preference's value",
        "parameters": [
          {
            "name": "name",
            "type": "string",
            "description": "The preference name"
          },
          {
            "name": "value",
            "type": "boolean",
            "description": "The new value"
          }
        ],
        "async": true
      }
    ]
  }
]
PK
!<{y×ò113injections/css/bug0000000-testbed-css-injection.css#css-injection.red {
  background-color: #0f0;
}
PK
!<ߣNNAinjections/css/bug1305028-gaming.youtube.com-webkit-scrollbar.css/**
 * gaming.youtube.com - The vertical scrollbar displayed for the main pane is
 * partially overlapped by the video itself
 * Bug #1305028 - https://bugzilla.mozilla.org/show_bug.cgi?id=1305028
 *
 * The scrollbar in the main player area is overlapped by the player, making the
 * design look broken. In Chrome, YouTube is using ::-webkit-scrollbar to style
 * the bar to match their expectations, but this doesn't work in Firefox.
 * To make it look less broken, we hide the scrollbar for the main video pane
 * entirely.
 */
ytg-scroll-pane.ytg-watch-page {
  scrollbar-width: none;
}
PK
!<ÐÐß88<injections/css/bug1432935-breitbart.com-webkit-scrollbar.css/**
 * breitbart.com - -webkit-scrollbar dependency causes scrollbar in the header
 * Part of Bug #1432935 - https://bugzilla.mozilla.org/show_bug.cgi?id=1432935
 * WebCompat issue #25156 - https://webcompat.com/issues/25156
 *
 * This site is using -webkit-scrollbar to hide a header in ther "scrollable
 * via JS" header navigation. This breaks in Firefox, and causes a visible
 * scrollbar to appear which overlaps large portions of the navigation content.
 * While we wait for an outreach response, let's fix it ourselves.
 */
#HWT ul {
  scrollbar-width: none;
}
PK
!<sž]–¦¦Hinjections/css/bug1432935-discordapp.com-webkit-scorllbar-white-line.css/**
 * discordapp.com - -webkit-scrollbar dependency causes visible white line
 * Part of Bug #1432935 - https://bugzilla.mozilla.org/show_bug.cgi?id=1432935
 * WebCompat issue #7919 - https://webcompat.com/issues/7919
 *
 * Discord depends on -webkit-scrollbar for styling and hiding their scrollbars
 * in the UI. Previously, the scrollbars overlapped content permanently.
 * However, this issue seems to be addressed now, but a small white line
 * still remains. While Discord is working on this, let's get rid of these
 * lines.
 */
.themeGhostHairline-DBD-2d .pad-29zQak,
.themeGhostHairlineChannels-3G0x9_ .pad-29zQak {
  width: 3px !important;
  left: -3px !important;
}
PK
!<šª4V8injections/css/bug1518781-twitch.tv-webkit-scrollbar.css/**
 * twitch.tv - Comment interaction button is overlayed by scrollbar
 * Bug #1518781 - https://bugzilla.mozilla.org/show_bug.cgi?id=1518781
 *
 * The interaction buttons in Twitch' chat are partly overlayed by the
 * scrollbar, which makes them hard to use. Twitch uses
 * ::-webkit-scrollbar to make the scrollbar thinner, which isn't working in
 * Firefox.
 * Given that even scrollbar-width: thin; is not enough (see Bugzilla), let's
 * remove it entirely.
 */
.video-chat__message-list-wrapper {
  scrollbar-width: none;
}
PK
!<Ò?ÎÃÃ7injections/css/bug1526977-sreedharscce.in-login-fix.css/**
 * sreedharscce.in - Fix login form with CSS intervention
 * Bug #1526977 - https://bugzilla.mozilla.org/show_bug.cgi?id=1526977
 * WebCompat issue #21505 - https://webcompat.com/issues/21505
 *
 * The login form is partly moved out of the screen on sreedharscce.in in
 * Firefox. Enforcing the body height to the full viewport fixes this issue,
 * as the login form itself is posititoned with `position: absolute;`.
 */
body {
  height: 100vh;
}
PK
!<RìiÜÜHinjections/css/bug1561371-mail.google.com-allow-horizontal-scrolling.css/**
 * 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 {
  overflow: auto;
}
PK
!<.V”ïââ<injections/css/bug1567610-dns.google.com-moz-fit-content.css/**
 * dns.google.com - Page content is shifted to the left side of the page
 * Bug #1567610 - https://bugzilla.mozilla.org/show_bug.cgi?id=1567610
 * WebCompat issue #22494 - https://webcompat.com/issues/22494
 *
 * Affected element is styled with width:fit-content; which is not
 * supported by Firefox yet, see https://bugzilla.mozilla.org/show_bug.cgi?id=1495868
 * Adding -moz-fit-content fixes the issue
 */
main > .ng-star-inserted > .centered {
  width: -moz-fit-content;
}
PK
!<õ~Fââ=injections/css/bug1568256-zertifikate.commerzbank.de-flex.css/**
 * zertifikate.commerzbank.de - clickable elements on the page are collapsed
 * Bug #1568256 - https://bugzilla.mozilla.org/show_bug.cgi?id=1568256
 * WebCompat issue #9102 - https://webcompat.com/issues/9102
 *
 * Affected elements have display:-webkit-box and display:flex applied, however,
 * listed in wrong order, so display:-webkit-box is becoming the final say.
 * Adding display: flex for those elements fixes the issue
 */
.x-layout-box {
  display: flex !important;
}
PK
!<
nu3ìì0injections/js/bug0000000-testbed-js-injection.js"use strict";

/* globals exportFunction */

Object.defineProperty(window.wrappedJSObject, "isTestFeatureSupported", {
  get: exportFunction(function() {
    return true;
  }, window),

  set: exportFunction(function() {}, window),
});
PK
!<ý-ŸŸAinjections/js/bug1452707-window.controllers-shim-ib.absa.co.za.js"use strict";

/**
 * Bug 1452707 - Build site patch for ib.absa.co.za
 * WebCompat issue #16401 - https://webcompat.com/issues/16401
 *
 * The online banking at ib.absa.co.za detect if window.controllers is a
 * non-falsy value to detect if the current browser is Firefox or something
 * else. In bug 1448045, this shim has been disabled for Firefox Nightly 61+,
 * which breaks the UA detection on this site and results in a "Browser
 * unsuppored" error message.
 *
 * This site patch simply sets window.controllers to a string, resulting in
 * their check to work again.
 */

/* globals exportFunction */

console.info(
  "window.controllers has been shimmed for compatibility reasons. See https://webcompat.com/issues/16401 for details."
);

Object.defineProperty(window.wrappedJSObject, "controllers", {
  get: exportFunction(function() {
    return true;
  }, window),

  set: exportFunction(function() {}, window),
});
PK
!<չAÊÊ4injections/js/bug1457335-histography.io-ua-change.js"use strict";

/**
 * Bug 1457335 - histography.io - Override UA & navigator.vendor
 * WebCompat issue #1804 - https://webcompat.com/issues/1804
 *
 * This site is using a strict matching of navigator.userAgent and
 * navigator.vendor to allow access for Safari or Chrome. Here, we set the
 * values appropriately so we get recognized as Chrome.
 */

/* globals exportFunction */

console.info(
  "The user agent has been overridden for compatibility reasons. See https://webcompat.com/issues/1804 for details."
);

const CHROME_UA = navigator.userAgent + " Chrome for WebCompat";

Object.defineProperty(window.navigator.wrappedJSObject, "userAgent", {
  get: exportFunction(function() {
    return CHROME_UA;
  }, window),

  set: exportFunction(function() {}, window),
});

Object.defineProperty(window.navigator.wrappedJSObject, "vendor", {
  get: exportFunction(function() {
    return "Google Inc.";
  }, window),

  set: exportFunction(function() {}, window),
});
PK
!<¡ëM8^^7injections/js/bug1472075-bankofamerica.com-ua-change.js"use strict";

/**
 * Bug 1472075 - Build UA override for Bank of America for OSX & Linux
 * WebCompat issue #2787 - https://webcompat.com/issues/2787
 *
 * BoA is showing a red warning to Linux and macOS users, while accepting
 * Windows users without warning. From our side, there is no difference here
 * and we receive a lot of user complains about the warnings, so we spoof
 * as Firefox on Windows in those cases.
 */

/* globals exportFunction */

if (!navigator.platform.includes("Win")) {
  console.info(
    "The user agent has been overridden for compatibility reasons. See https://webcompat.com/issues/2787 for details."
  );

  const WINDOWS_UA = navigator.userAgent.replace(
    /\(.*; rv:/i,
    "(Windows NT 10.0; Win64; x64; rv:"
  );

  Object.defineProperty(window.navigator.wrappedJSObject, "userAgent", {
    get: exportFunction(function() {
      return WINDOWS_UA;
    }, window),

    set: exportFunction(function() {}, window),
  });

  Object.defineProperty(window.navigator.wrappedJSObject, "appVersion", {
    get: exportFunction(function() {
      return "appVersion";
    }, window),

    set: exportFunction(function() {}, window),
  });

  Object.defineProperty(window.navigator.wrappedJSObject, "platform", {
    get: exportFunction(function() {
      return "Win64";
    }, window),

    set: exportFunction(function() {}, window),
  });
}
PK
!<ðüçùù?injections/js/bug1472081-election.gov.np-window.sidebar-shim.js"use strict";

/**
 * Bug 1472081 - election.gov.np - Override window.sidebar with something falsey
 * WebCompat issue #11622 - https://webcompat.com/issues/11622
 *
 * This site is blocking onmousedown and onclick if window.sidebar is something
 * that evaluates to true, rendering the form fields unusable. This patch
 * overrides window.sidebar with false, so the blocking event handlers won't
 * get registered.
 */

/* globals exportFunction */

console.info(
  "window.sidebar has been shimmed for compatibility reasons. See https://webcompat.com/issues/11622 for details."
);

Object.defineProperty(window.wrappedJSObject, "sidebar", {
  get: exportFunction(function() {
    return false;
  }, window),

  set: exportFunction(function() {}, window),
});
PK
!<œSȌèèBinjections/js/bug1482066-portalminasnet.com-window.sidebar-shim.js"use strict";

/**
 * portalminasnet.com - Override window.sidebar with something falsey
 * WebCompat issue #18143 - https://webcompat.com/issues/18143
 *
 * This site is blocking onmousedown and onclick if window.sidebar is something
 * that evaluates to true, rendering the login unusable. This patch overrides
 * window.sidebar with false, so the blocking event handlers won't get
 * registered.
 */

/* globals exportFunction */

console.info(
  "window.sidebar has been shimmed for compatibility reasons. See https://webcompat.com/issues/18143 for details."
);

Object.defineProperty(window.wrappedJSObject, "sidebar", {
  get: exportFunction(function() {
    return false;
  }, window),

  set: exportFunction(function() {}, window),
});
PK
!<cÇrƒ®
®
lib/about_compat_broker.js/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

/* global browser, module */

class AboutCompatBroker {
  constructor(bindings) {
    this.portsToAboutCompatTabs = this.buildPorts();

    this._injections = bindings.injections;
    this._injections.bindAboutCompatBroker(this);

    this._uaOverrides = bindings.uaOverrides;
    this._uaOverrides.bindAboutCompatBroker(this);
  }

  buildPorts() {
    const ports = new Set();

    browser.runtime.onConnect.addListener(port => {
      ports.add(port);
      port.onDisconnect.addListener(function() {
        ports.delete(port);
      });
    });

    async function broadcast(message) {
      for (const port of ports) {
        port.postMessage(message);
      }
    }

    return { broadcast };
  }

  filterOverrides(overrides) {
    return overrides
      .filter(override => override.availableOnPlatform)
      .map(override => {
        const { id, active, bug, domain, hidden } = override;
        return { id, active, bug, domain, hidden };
      });
  }

  getOverrideOrInterventionById(id) {
    for (const [type, things] of Object.entries({
      overrides: this._uaOverrides.getAvailableOverrides(),
      interventions: this._injections.getAvailableInjections(),
    })) {
      for (const what of things) {
        if (what.id === id) {
          return { type, what };
        }
      }
    }
    return {};
  }

  bootup() {
    browser.runtime.onMessage.addListener(msg => {
      switch (msg.command || msg) {
        case "toggle": {
          const id = msg.id;
          const { type, what } = this.getOverrideOrInterventionById(id);
          if (!what) {
            return Promise.reject(
              `No such override or intervention to toggle: ${id}`
            );
          }
          this.portsToAboutCompatTabs
            .broadcast({ toggling: id, active: what.active })
            .then(async () => {
              switch (type) {
                case "interventions": {
                  if (what.active) {
                    await this._injections.disableInjection(what);
                  } else {
                    await this._injections.enableInjection(what);
                  }
                  break;
                }
                case "overrides": {
                  if (what.active) {
                    await this._uaOverrides.disableOverride(what);
                  } else {
                    await this._uaOverrides.enableOverride(what);
                  }
                  break;
                }
              }
              this.portsToAboutCompatTabs.broadcast({
                toggled: id,
                active: what.active,
              });
            });
          break;
        }
        case "getOverridesAndInterventions": {
          return Promise.resolve({
            overrides:
              (this._uaOverrides.isEnabled() &&
                this.filterOverrides(
                  this._uaOverrides.getAvailableOverrides()
                )) ||
              false,
            interventions:
              (this._injections.isEnabled() &&
                this.filterOverrides(
                  this._injections.getAvailableInjections()
                )) ||
              false,
          });
        }
      }
      return undefined;
    });
  }
}

module.exports = AboutCompatBroker;
PK
!<f=GGlib/injections.js/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

/* globals browser, module */

class Injections {
  constructor(availableInjections) {
    this.INJECTION_PREF = "perform_injections";

    this._injectionsEnabled = true;

    this._availableInjections = availableInjections;
    this._activeInjections = new Map();
  }

  bindAboutCompatBroker(broker) {
    this._aboutCompatBroker = broker;
  }

  bootup() {
    browser.aboutConfigPrefs.onPrefChange.addListener(() => {
      this.checkInjectionPref();
    }, this.INJECTION_PREF);
    this.checkInjectionPref();
  }

  checkInjectionPref() {
    browser.aboutConfigPrefs.getPref(this.INJECTION_PREF).then(value => {
      if (value === undefined) {
        browser.aboutConfigPrefs.setPref(this.INJECTION_PREF, true);
      } else if (value === false) {
        this.unregisterContentScripts();
      } else {
        this.registerContentScripts();
      }
    });
  }

  getAvailableInjections() {
    return this._availableInjections;
  }

  isEnabled() {
    return this._injectionsEnabled;
  }

  async registerContentScripts() {
    const platformMatches = ["all"];
    let platformInfo = await browser.runtime.getPlatformInfo();
    platformMatches.push(platformInfo.os == "android" ? "android" : "desktop");

    for (const injection of this._availableInjections) {
      if (platformMatches.includes(injection.platform)) {
        injection.availableOnPlatform = true;
        await this.enableInjection(injection);
      }
    }

    this._injectionsEnabled = true;
    this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
      interventionsChanged: this._aboutCompatBroker.filterOverrides(
        this._availableInjections
      ),
    });
  }

  replaceStringInRequest(requestId, inString, outString, inEncoding = "utf-8") {
    const filter = browser.webRequest.filterResponseData(requestId);
    const decoder = new TextDecoder(inEncoding);
    const encoder = new TextEncoder();
    const RE = new RegExp(inString, "g");
    const carryoverLength = inString.length;
    let carryover = "";

    filter.ondata = event => {
      const replaced = (
        carryover + decoder.decode(event.data, { stream: true })
      ).replace(RE, outString);
      filter.write(encoder.encode(replaced.slice(0, -carryoverLength)));
      carryover = replaced.slice(-carryoverLength);
    };

    filter.onstop = event => {
      if (carryover.length) {
        filter.write(encoder.encode(carryover));
      }
      filter.close();
    };
  }

  async enableInjection(injection) {
    if (injection.active) {
      return;
    }

    if ("pdk5fix" in injection) {
      const { urls, types } = injection.pdk5fix;
      const listener = (injection.pdk5fix.listener = ({ requestId }) => {
        this.replaceStringInRequest(
          requestId,
          "VideoContextChromeAndroid",
          "VideoContextAndroid"
        );
        return {};
      });
      browser.webRequest.onBeforeRequest.addListener(
        listener,
        { urls, types },
        ["blocking"]
      );
      injection.active = true;
      return;
    }

    try {
      const handle = await browser.contentScripts.register(
        injection.contentScripts
      );
      this._activeInjections.set(injection, handle);
      injection.active = true;
    } catch (ex) {
      console.error(
        "Registering WebCompat GoFaster content scripts failed: ",
        ex
      );
    }
  }

  unregisterContentScripts() {
    for (const injection of this._availableInjections) {
      this.disableInjection(injection);
    }

    this._injectionsEnabled = false;
    this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
      interventionsChanged: false,
    });
  }

  async disableInjection(injection) {
    if (!injection.active) {
      return;
    }

    if (injection.pdk5fix) {
      const { listener } = injection.pdk5fix;
      browser.webRequest.onBeforeRequest.removeListener(listener);
      injection.active = false;
      delete injection.pdk5fix.listener;
      return;
    }

    const contentScript = this._activeInjections.get(injection);
    await contentScript.unregister();
    this._activeInjections.delete(injection);
    injection.active = false;
  }
}

module.exports = Injections;
PK
!<rž€€lib/module_shim.js/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

/**
 * We cannot yet use proper JS modules within webextensions, as support for them
 * is highly experimental and highly instable. So we end up just including all
 * the JS files we need as separate background scripts, and since they all are
 * executed within the same context, this works for our in-browser deployment.
 *
 * However, this code is tracked outside of mozilla-central, and we work on
 * shipping this code in other products, like android-components as well.
 * Because of that, we have automated tests running within that repository. To
 * make our lives easier, we add `module.exports` statements to the JS source
 * files, so we can easily import their contents into our NodeJS-based test
 * suite.
 *
 * This works fine, but obviously, `module` is not defined when running
 * in-browser. So let's use this empty object as a shim, so we don't run into
 * runtime exceptions because of that.
 */
var module = {};
PK
!<©–‚¸òòlib/ua_overrides.js/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

/* globals browser, module */

class UAOverrides {
  constructor(availableOverrides) {
    this.OVERRIDE_PREF = "perform_ua_overrides";

    this._overridesEnabled = true;

    this._availableOverrides = availableOverrides;
    this._activeListeners = new Map();
  }

  bindAboutCompatBroker(broker) {
    this._aboutCompatBroker = broker;
  }

  bootup() {
    browser.aboutConfigPrefs.onPrefChange.addListener(() => {
      this.checkOverridePref();
    }, this.OVERRIDE_PREF);
    this.checkOverridePref();
  }

  checkOverridePref() {
    browser.aboutConfigPrefs.getPref(this.OVERRIDE_PREF).then(value => {
      if (value === undefined) {
        browser.aboutConfigPrefs.setPref(this.OVERRIDE_PREF, true);
      } else if (value === false) {
        this.unregisterUAOverrides();
      } else {
        this.registerUAOverrides();
      }
    });
  }

  getAvailableOverrides() {
    return this._availableOverrides;
  }

  isEnabled() {
    return this._overridesEnabled;
  }

  enableOverride(override) {
    if (override.active) {
      return;
    }

    const { matches, uaTransformer } = override.config;
    const listener = details => {
      for (const header of details.requestHeaders) {
        if (header.name.toLowerCase() === "user-agent") {
          header.value = uaTransformer(header.value);
        }
      }
      return { requestHeaders: details.requestHeaders };
    };

    browser.webRequest.onBeforeSendHeaders.addListener(
      listener,
      { urls: matches },
      ["blocking", "requestHeaders"]
    );

    this._activeListeners.set(override, listener);
    override.active = true;
  }

  async registerUAOverrides() {
    const platformMatches = ["all"];
    let platformInfo = await browser.runtime.getPlatformInfo();
    platformMatches.push(platformInfo.os == "android" ? "android" : "desktop");

    for (const override of this._availableOverrides) {
      if (platformMatches.includes(override.platform)) {
        override.availableOnPlatform = true;
        this.enableOverride(override);
      }
    }

    this._overridesEnabled = true;
    this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
      overridesChanged: this._aboutCompatBroker.filterOverrides(
        this._availableOverrides
      ),
    });
  }

  unregisterUAOverrides() {
    for (const override of this._availableOverrides) {
      this.disableOverride(override);
    }

    this._overridesEnabled = false;
    this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
      overridesChanged: false,
    });
  }

  disableOverride(override) {
    if (!override.active) {
      return;
    }

    browser.webRequest.onBeforeSendHeaders.removeListener(
      this._activeListeners.get(override)
    );
    override.active = false;
    this._activeListeners.delete(override);
  }
}

module.exports = UAOverrides;
PK
!<'䄄
manifest.json{
  "manifest_version": 2,
  "name": "Web Compat",
  "description": "Urgent post-release fixes for web compatibility.",
  "version": "5.0.2",

  "applications": {
    "gecko": {
      "id": "webcompat@mozilla.org",
      "strict_min_version": "59.0b5"
    }
  },

  "experiment_apis": {
    "aboutConfigPrefs": {
      "schema": "experiment-apis/aboutConfigPrefs.json",
      "parent": {
        "scopes": ["addon_parent"],
        "script": "experiment-apis/aboutConfigPrefs.js",
        "paths": [["aboutConfigPrefs"]]
      }
    },
    "aboutPage": {
      "schema": "about-compat/aboutPage.json",
      "parent": {
        "scopes": ["addon_parent"],
        "script": "about-compat/aboutPage.js",
        "events": ["startup"]
      }
    }
  },

  "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",
      "data/injections.js",
      "data/ua_overrides.js",
      "lib/about_compat_broker.js",
      "lib/injections.js",
      "lib/ua_overrides.js",
      "run.js"
    ]
  }
}
PK
!<ïJ;Ñbbrun.js/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

/* globals AVAILABLE_INJECTIONS, AVAILABLE_UA_OVERRIDES, AboutCompatBroker,
           Injections, UAOverrides */

const injections = new Injections(AVAILABLE_INJECTIONS);
const uaOverrides = new UAOverrides(AVAILABLE_UA_OVERRIDES);

const aboutCompatBroker = new AboutCompatBroker({
  injections,
  uaOverrides,
});

aboutCompatBroker.bootup();
injections.bootup();
uaOverrides.bootup();
PK
!<=ÇpöŠŠ¤about-compat/AboutCompat.jsmPK
!<9¸Cd
d
¤Äabout-compat/aboutCompat.cssPK
!<¹—}II¤babout-compat/aboutCompat.htmlPK
!<*¥Ç¨¨¤æabout-compat/aboutCompat.jsPK
!<v_t11¤Ç'about-compat/aboutPage.jsPK
!<p›UéYY¤/,about-compat/aboutPage.jsonPK
!<î¶m!BB&¤Á,about-compat/aboutPageProcessScript.jsPK
!<ÌÍͤG0data/injections.jsPK
!<ÏEæîù'ù'¤DFdata/ua_overrides.jsPK
!<÷Õ|%\\#¤onexperiment-apis/aboutConfigPrefs.jsPK
!<ñ Î%¤uexperiment-apis/aboutConfigPrefs.jsonPK
!<{y×ò113¤Qzinjections/css/bug0000000-testbed-css-injection.cssPK
!<ߣNNA¤Ózinjections/css/bug1305028-gaming.youtube.com-webkit-scrollbar.cssPK
!<ÐÐß88<¤€}injections/css/bug1432935-breitbart.com-webkit-scrollbar.cssPK
!<sž]–¦¦H¤€injections/css/bug1432935-discordapp.com-webkit-scorllbar-white-line.cssPK
!<šª4V8¤ƒinjections/css/bug1518781-twitch.tv-webkit-scrollbar.cssPK
!<Ò?ÎÃÃ7¤†…injections/css/bug1526977-sreedharscce.in-login-fix.cssPK
!<RìiÜÜH¤ž‡injections/css/bug1561371-mail.google.com-allow-horizontal-scrolling.cssPK
!<.V”ïââ<¤à‰injections/css/bug1567610-dns.google.com-moz-fit-content.cssPK
!<õ~Fââ=¤Œinjections/css/bug1568256-zertifikate.commerzbank.de-flex.cssPK
!<
nu3ìì0¤YŽinjections/js/bug0000000-testbed-js-injection.jsPK
!<ý-ŸŸA¤“injections/js/bug1452707-window.controllers-shim-ib.absa.co.za.jsPK
!<չAÊÊ4¤‘“injections/js/bug1457335-histography.io-ua-change.jsPK
!<¡ëM8^^7¤­—injections/js/bug1472075-bankofamerica.com-ua-change.jsPK
!<ðüçùù?¤`injections/js/bug1472081-election.gov.np-window.sidebar-shim.jsPK
!<œSȌèèB¤¶ injections/js/bug1482066-portalminasnet.com-window.sidebar-shim.jsPK
!<cÇrƒ®
®
¤þ£lib/about_compat_broker.jsPK
!<f=GG¤ä±lib/injections.jsPK
!<rž€€¤ZÃlib/module_shim.jsPK
!<©–‚¸òò¤
Èlib/ua_overrides.jsPK
!<'䄄
¤-Ômanifest.jsonPK
!<ïJ;Ñbb¤)Ùrun.jsPK  à
¯Û