Bug 1589182 - remove mobile/android/extensions/ and /mobile/android/chrome/content (Fennec leftovers); r=snorp,agi
authorThomas Wisniewski <twisniewski@mozilla.com>
Mon, 04 Nov 2019 20:32:10 +0000
changeset 500448 fa1fe1088a5e415df857e6b0767442e0e9ceae25
parent 500447 586c8dec24bbf51a16c924e0f70596aea085758e
child 500449 a44bfb190d80487c84b216aac35150c6aa098cff
push id114164
push useraiakab@mozilla.com
push dateTue, 05 Nov 2019 10:06:15 +0000
treeherdermozilla-inbound@4d585c7edc76 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp, agi
bugs1589182
milestone72.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1589182 - remove mobile/android/extensions/ and /mobile/android/chrome/content (Fennec leftovers); r=snorp,agi Remove mobile/android/extensions/ and /mobile/android/chrome/content from mozilla-central (Fennec leftovers) Differential Revision: https://phabricator.services.mozilla.com/D51194
.eslintignore
mobile/android/chrome/content/.eslintrc.js
mobile/android/chrome/content/CastingApps.js
mobile/android/chrome/content/ConsoleAPI.js
mobile/android/chrome/content/EmbedRT.js
mobile/android/chrome/content/ExtensionPermissions.js
mobile/android/chrome/content/FeedHandler.js
mobile/android/chrome/content/Feedback.js
mobile/android/chrome/content/FindHelper.js
mobile/android/chrome/content/Linkify.js
mobile/android/chrome/content/MasterPassword.js
mobile/android/chrome/content/MemoryObserver.js
mobile/android/chrome/content/OfflineApps.js
mobile/android/chrome/content/PermissionsHelper.js
mobile/android/chrome/content/PresentationView.js
mobile/android/chrome/content/PresentationView.xul
mobile/android/chrome/content/PrintHelper.js
mobile/android/chrome/content/Reader.js
mobile/android/chrome/content/RemoteDebugger.js
mobile/android/chrome/content/about.js
mobile/android/chrome/content/about.xhtml
mobile/android/chrome/content/aboutAccounts.js
mobile/android/chrome/content/aboutAccounts.xhtml
mobile/android/chrome/content/aboutAddons.js
mobile/android/chrome/content/aboutAddons.xhtml
mobile/android/chrome/content/aboutCertError.xhtml
mobile/android/chrome/content/aboutDownloads.js
mobile/android/chrome/content/aboutDownloads.xhtml
mobile/android/chrome/content/aboutExperiments.js
mobile/android/chrome/content/aboutExperiments.xhtml
mobile/android/chrome/content/aboutHome.xhtml
mobile/android/chrome/content/aboutLogins.js
mobile/android/chrome/content/aboutLogins.xhtml
mobile/android/chrome/content/aboutPrivateBrowsing.js
mobile/android/chrome/content/aboutPrivateBrowsing.xhtml
mobile/android/chrome/content/aboutRights.xhtml
mobile/android/chrome/content/blockedSite.xhtml
mobile/android/chrome/content/browser.css
mobile/android/chrome/content/browser.js
mobile/android/chrome/content/browser.xul
mobile/android/chrome/content/content.js
mobile/android/chrome/content/languages.properties
mobile/android/chrome/content/netError.xhtml
mobile/android/chrome/jar.mn
mobile/android/chrome/moz.build
mobile/android/extensions/moz.build
mobile/android/extensions/report-site-issue/.eslintrc.js
mobile/android/extensions/report-site-issue/background.js
mobile/android/extensions/report-site-issue/experimentalAPIs/aboutConfigPrefs.js
mobile/android/extensions/report-site-issue/experimentalAPIs/aboutConfigPrefs.json
mobile/android/extensions/report-site-issue/experimentalAPIs/browserInfo.js
mobile/android/extensions/report-site-issue/experimentalAPIs/browserInfo.json
mobile/android/extensions/report-site-issue/experimentalAPIs/l10n.js
mobile/android/extensions/report-site-issue/experimentalAPIs/l10n.json
mobile/android/extensions/report-site-issue/experimentalAPIs/nativeMenu.js
mobile/android/extensions/report-site-issue/experimentalAPIs/nativeMenu.json
mobile/android/extensions/report-site-issue/experimentalAPIs/snackbars.js
mobile/android/extensions/report-site-issue/experimentalAPIs/snackbars.json
mobile/android/extensions/report-site-issue/experimentalAPIs/tabExtras.js
mobile/android/extensions/report-site-issue/experimentalAPIs/tabExtras.json
mobile/android/extensions/report-site-issue/manifest.json
mobile/android/extensions/report-site-issue/moz.build
mobile/android/extensions/webcompat/about-compat/AboutCompat.jsm
mobile/android/extensions/webcompat/about-compat/aboutCompat.css
mobile/android/extensions/webcompat/about-compat/aboutCompat.html
mobile/android/extensions/webcompat/about-compat/aboutCompat.js
mobile/android/extensions/webcompat/about-compat/aboutPage.js
mobile/android/extensions/webcompat/about-compat/aboutPage.json
mobile/android/extensions/webcompat/about-compat/aboutPageProcessScript.js
mobile/android/extensions/webcompat/data/injections.js
mobile/android/extensions/webcompat/data/ua_overrides.js
mobile/android/extensions/webcompat/experiment-apis/aboutConfigPrefs.js
mobile/android/extensions/webcompat/experiment-apis/aboutConfigPrefs.json
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/bug0000000-testbed-css-injection.css
mobile/android/extensions/webcompat/injections/css/bug1305028-gaming.youtube.com-webkit-scrollbar.css
mobile/android/extensions/webcompat/injections/css/bug1432935-discordapp.com-webkit-scorllbar-white-line.css
mobile/android/extensions/webcompat/injections/css/bug1518781-twitch.tv-webkit-scrollbar.css
mobile/android/extensions/webcompat/injections/css/bug1526977-sreedharscce.in-login-fix.css
mobile/android/extensions/webcompat/injections/css/bug1561371-mail.google.com-allow-horizontal-scrolling.css
mobile/android/extensions/webcompat/injections/css/bug1567610-dns.google.com-moz-fit-content.css
mobile/android/extensions/webcompat/injections/css/bug1568256-zertifikate.commerzbank.de-flex.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/bug0000000-testbed-js-injection.js
mobile/android/extensions/webcompat/injections/js/bug1452707-window.controllers-shim-ib.absa.co.za.js
mobile/android/extensions/webcompat/injections/js/bug1457335-histography.io-ua-change.js
mobile/android/extensions/webcompat/injections/js/bug1472075-bankofamerica.com-ua-change.js
mobile/android/extensions/webcompat/injections/js/bug1472081-election.gov.np-window.sidebar-shim.js
mobile/android/extensions/webcompat/injections/js/bug1482066-portalminasnet.com-window.sidebar-shim.js
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/about_compat_broker.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/module_shim.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
mobile/android/moz.build
tools/lint/license.yml
--- a/.eslintignore
+++ b/.eslintignore
@@ -217,19 +217,16 @@ media/webrtc/trunk/
 
 # mobile/android/ exclusions
 mobile/android/tests/browser/chrome/tp5/
 
 # Uses `#filter substitution`
 mobile/android/app/mobile.js
 mobile/android/app/geckoview-prefs.js
 
-# Uses `#expand`
-mobile/android/chrome/content/about.js
-
 # Not much JS to lint and non-standard at that
 mobile/android/installer/
 mobile/android/locales/
 
 # Pre-processed/pref files
 modules/libpref/greprefs.js
 modules/libpref/init/all.js
 modules/libpref/test/unit/*data/
deleted file mode 100644
--- a/mobile/android/chrome/content/.eslintrc.js
+++ /dev/null
@@ -1,12 +0,0 @@
-"use strict";
-
-module.exports = {
-  "rules": {
-    "complexity": ["error", 20],
-
-    // Disabled stuff
-    "no-console": 0, // TODO: Can we use console?
-    "no-cond-assign": 0,
-    "no-fallthrough": 0,
-  }
-};
deleted file mode 100644
--- a/mobile/android/chrome/content/CastingApps.js
+++ /dev/null
@@ -1,857 +0,0 @@
-// -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
-/* 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";
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "PageActions",
-  "resource://gre/modules/PageActions.jsm"
-);
-
-// Define service devices. We should consider moving these to their respective
-// JSM files, but we left them here to allow for better lazy JSM loading.
-var rokuDevice = {
-  id: "roku:ecp",
-  target: "roku:ecp",
-  factory: function(aService) {
-    const { RokuApp } = ChromeUtils.import(
-      "resource://gre/modules/RokuApp.jsm"
-    );
-    return new RokuApp(aService);
-  },
-  types: ["video/mp4"],
-  extensions: ["mp4"],
-};
-
-var mediaPlayerDevice = {
-  id: "media:router",
-  target: "media:router",
-  factory: function(aService) {
-    const { MediaPlayerApp } = ChromeUtils.import(
-      "resource://gre/modules/MediaPlayerApp.jsm"
-    );
-    return new MediaPlayerApp(aService);
-  },
-  types: ["video/mp4", "video/webm", "application/x-mpegurl"],
-  extensions: ["mp4", "webm", "m3u", "m3u8"],
-  init: function() {
-    GlobalEventDispatcher.registerListener(this, [
-      "MediaPlayer:Added",
-      "MediaPlayer:Changed",
-      "MediaPlayer:Removed",
-    ]);
-  },
-  onEvent: function(event, data, callback) {
-    if (event === "MediaPlayer:Added") {
-      let service = this.toService(data);
-      SimpleServiceDiscovery.addService(service);
-    } else if (event === "MediaPlayer:Changed") {
-      let service = this.toService(data);
-      SimpleServiceDiscovery.updateService(service);
-    } else if (event === "MediaPlayer:Removed") {
-      SimpleServiceDiscovery.removeService(data.id);
-    }
-  },
-  toService: function(display) {
-    // Convert the native data into something matching what is created in _processService()
-    return {
-      location: display.location,
-      target: "media:router",
-      friendlyName: display.friendlyName,
-      uuid: display.uuid,
-      manufacturer: display.manufacturer,
-      modelName: display.modelName,
-    };
-  },
-};
-
-var CastingApps = {
-  _castMenuId: -1,
-  _blocked: null,
-  _bound: null,
-  _interval: 120 * 1000, // 120 seconds
-
-  init: function ca_init() {
-    if (!this.isCastingEnabled()) {
-      return;
-    }
-
-    // Register targets
-    SimpleServiceDiscovery.registerDevice(rokuDevice);
-
-    // MediaPlayerDevice will notify us any time the native device list changes.
-    mediaPlayerDevice.init();
-    SimpleServiceDiscovery.registerDevice(mediaPlayerDevice);
-
-    // Search for devices continuously
-    SimpleServiceDiscovery.search(this._interval);
-
-    this._castMenuId = NativeWindow.contextmenus.add(
-      Strings.browser.GetStringFromName("contextmenu.sendToDevice"),
-      this.filterCast,
-      this.handleContextMenu.bind(this)
-    );
-
-    GlobalEventDispatcher.registerListener(this, [
-      "Casting:Play",
-      "Casting:Pause",
-      "Casting:Stop",
-    ]);
-
-    Services.obs.addObserver(this, "ssdp-service-found");
-    Services.obs.addObserver(this, "ssdp-service-lost");
-    Services.obs.addObserver(this, "application-background");
-    Services.obs.addObserver(this, "application-foreground");
-
-    BrowserApp.deck.addEventListener("TabSelect", this, true);
-    BrowserApp.deck.addEventListener("pageshow", this, true);
-    BrowserApp.deck.addEventListener("playing", this, true);
-    BrowserApp.deck.addEventListener("ended", this, true);
-    BrowserApp.deck.addEventListener("MozAutoplayMediaBlocked", this, true);
-    // Note that the XBL binding is untrusted
-    BrowserApp.deck.addEventListener(
-      "MozNoControlsVideoBindingAttached",
-      this,
-      true,
-      true
-    );
-  },
-
-  _mirrorStarted: function(stopMirrorCallback) {
-    this.stopMirrorCallback = stopMirrorCallback;
-    NativeWindow.menu.update(this.mirrorStartMenuId, { visible: false });
-    NativeWindow.menu.update(this.mirrorStopMenuId, { visible: true });
-  },
-
-  serviceAdded: function(aService) {},
-
-  serviceLost: function(aService) {},
-
-  isCastingEnabled: function isCastingEnabled() {
-    return Services.prefs.getBoolPref("browser.casting.enabled");
-  },
-
-  onEvent: function(event, message, callback) {
-    switch (event) {
-      case "Casting:Play":
-        if (this.session && this.session.remoteMedia.status == "paused") {
-          this.session.remoteMedia.play();
-        }
-        break;
-      case "Casting:Pause":
-        if (this.session && this.session.remoteMedia.status == "started") {
-          this.session.remoteMedia.pause();
-        }
-        break;
-      case "Casting:Stop":
-        if (this.session) {
-          this.closeExternal();
-        }
-        break;
-    }
-  },
-
-  observe: function(aSubject, aTopic, aData) {
-    switch (aTopic) {
-      case "ssdp-service-found":
-        this.serviceAdded(SimpleServiceDiscovery.findServiceForID(aData));
-        break;
-      case "ssdp-service-lost":
-        this.serviceLost(SimpleServiceDiscovery.findServiceForID(aData));
-        break;
-      case "application-background":
-        // Turn off polling while in the background
-        this._interval = SimpleServiceDiscovery.search(0);
-        SimpleServiceDiscovery.stopSearch();
-        break;
-      case "application-foreground":
-        // Turn polling on when app comes back to foreground
-        SimpleServiceDiscovery.search(this._interval);
-        break;
-    }
-  },
-
-  handleEvent: function(aEvent) {
-    switch (aEvent.type) {
-      case "TabSelect": {
-        let tab = BrowserApp.getTabForBrowser(aEvent.target);
-        this._updatePageActionForTab(tab, aEvent);
-        break;
-      }
-      case "pageshow": {
-        let tab = BrowserApp.getTabForWindow(aEvent.originalTarget.defaultView);
-        this._updatePageActionForTab(tab, aEvent);
-        break;
-      }
-      case "playing":
-      case "ended": {
-        let video = aEvent.target;
-        if (video instanceof HTMLVideoElement) {
-          // If playing, send the <video>, but if ended we send nothing to shutdown the pageaction
-          this._updatePageActionForVideo(
-            aEvent.type === "playing" ? video : null
-          );
-        }
-        break;
-      }
-      case "MozAutoplayMediaBlocked": {
-        if (this._bound && this._bound.has(aEvent.target)) {
-          aEvent.target.dispatchEvent(
-            new aEvent.target.ownerGlobal.CustomEvent(
-              "MozNoControlsBlockedVideo"
-            )
-          );
-        } else {
-          if (!this._blocked) {
-            this._blocked = new WeakMap();
-          }
-          this._blocked.set(aEvent.target, true);
-        }
-        break;
-      }
-      case "MozNoControlsVideoBindingAttached": {
-        if (!this._bound) {
-          this._bound = new WeakMap();
-        }
-
-        let video = this._findVideoFromEventTarget(aEvent.target);
-        if (!video) {
-          return;
-        }
-
-        this._bound.set(video, true);
-        if (this._blocked && this._blocked.has(video)) {
-          this._blocked.delete(video);
-          video.dispatchEvent(
-            new video.ownerGlobal.CustomEvent("MozNoControlsBlockedVideo")
-          );
-        }
-        break;
-      }
-    }
-  },
-
-  _findVideoFromEventTarget(aTarget) {
-    if (
-      typeof ShadowRoot !== "undefined" &&
-      aTarget.parentNode instanceof ShadowRoot &&
-      aTarget.parentNode.host instanceof HTMLVideoElement
-    ) {
-      // aTarget is <div class="videocontrols"> inside UA Widget Shadow Root
-      return aTarget.parentNode.host;
-    }
-
-    if (aTarget instanceof HTMLVideoElement) {
-      // aTarget is <video>.
-      return aTarget;
-    }
-
-    return null;
-  },
-
-  _sendEventToVideo: function _sendEventToVideo(aElement, aData) {
-    let event = aElement.ownerDocument.createEvent("CustomEvent");
-    event.initCustomEvent(
-      "media-videoCasting",
-      false,
-      true,
-      JSON.stringify(aData)
-    );
-    aElement.dispatchEvent(event);
-  },
-
-  handleVideoBindingAttached: function handleVideoBindingAttached(
-    aTab,
-    aEvent
-  ) {
-    // Let's figure out if we have everything needed to cast a video. The binding
-    // defaults to |false| so we only need to send an event if |true|.
-    let video = this._findVideoFromEventTarget(aEvent.target);
-    if (!video) {
-      return;
-    }
-
-    if (SimpleServiceDiscovery.services.length == 0) {
-      return;
-    }
-
-    this.getVideo(video, 0, 0, aBundle => {
-      // Let the binding know casting is allowed
-      if (aBundle) {
-        this._sendEventToVideo(aBundle.element, { allow: true });
-      }
-    });
-  },
-
-  handleVideoBindingCast: function handleVideoBindingCast(aTab, aEvent) {
-    // The binding wants to start a casting session
-    let video = this._findVideoFromEventTarget(aEvent.target);
-    if (!video) {
-      return;
-    }
-
-    // Close an existing session first. closeExternal has checks for an exsting
-    // session and handles remote and video binding shutdown.
-    this.closeExternal();
-
-    // Start the new session
-    UITelemetry.addEvent("cast.1", "button", null);
-    this.openExternal(video, 0, 0);
-  },
-
-  makeURI: function makeURI(aURL, aOriginCharset, aBaseURI) {
-    return Services.io.newURI(aURL, aOriginCharset, aBaseURI);
-  },
-
-  allowableExtension: function(aURI, aExtensions) {
-    return (
-      aURI instanceof Ci.nsIURL && aExtensions.includes(aURI.fileExtension)
-    );
-  },
-
-  allowableMimeType: function(aType, aTypes) {
-    return aTypes.includes(aType);
-  },
-
-  // This method will look at the aElement (or try to find a video at aX, aY) that has
-  // a castable source. If found, aCallback will be called with a JSON meta bundle. If
-  // no castable source was found, aCallback is called with null.
-  getVideo: function(aElement, aX, aY, aCallback) {
-    let extensions = SimpleServiceDiscovery.getSupportedExtensions();
-    let types = SimpleServiceDiscovery.getSupportedMimeTypes();
-
-    // Fast path: Is the given element a video element?
-    if (aElement instanceof HTMLVideoElement) {
-      // If we found a video element, no need to look further, even if no
-      // castable video source is found.
-      this._getVideo(aElement, types, extensions, aCallback);
-      return;
-    }
-
-    // Maybe this is an overlay, with the video element under it.
-    // Use the (x, y) location to guess at a <video> element.
-
-    // The context menu system will keep walking up the DOM giving us a chance
-    // to find an element we match. When it hits <html> things can go BOOM.
-    try {
-      let elements = aElement.ownerDocument.querySelectorAll("video");
-      for (let element of elements) {
-        // Look for a video element contained in the overlay bounds
-        let rect = element.getBoundingClientRect();
-        if (
-          aY >= rect.top &&
-          aX >= rect.left &&
-          aY <= rect.bottom &&
-          aX <= rect.right
-        ) {
-          // Once we find a <video> under the overlay, we check it and exit.
-          this._getVideo(element, types, extensions, aCallback);
-          return;
-        }
-      }
-    } catch (e) {}
-  },
-
-  _getContentTypeForURI: function(aURI, aElement, aCallback) {
-    let channel;
-    try {
-      let secFlags = Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS;
-      if (aElement.crossOrigin) {
-        secFlags = Ci.nsILoadInfo.SEC_REQUIRE_CORS_DATA_INHERITS;
-        if (aElement.crossOrigin === "use-credentials") {
-          secFlags |= Ci.nsILoadInfo.SEC_COOKIES_INCLUDE;
-        }
-      }
-      channel = NetUtil.newChannel({
-        uri: aURI,
-        loadingNode: aElement,
-        securityFlags: secFlags,
-        contentPolicyType: Ci.nsIContentPolicy.TYPE_INTERNAL_VIDEO,
-      });
-    } catch (e) {
-      aCallback(null);
-      return;
-    }
-
-    let listener = {
-      onStartRequest: function(request) {
-        switch (channel.responseStatus) {
-          case 301:
-          case 302:
-          case 303:
-            request.cancel(0);
-            let location = channel.getResponseHeader("Location");
-            CastingApps._getContentTypeForURI(
-              CastingApps.makeURI(location),
-              aElement,
-              aCallback
-            );
-            break;
-          default:
-            aCallback(channel.contentType);
-            request.cancel(0);
-            break;
-        }
-      },
-      onStopRequest: function(request, statusCode) {},
-      onDataAvailable: function(request, stream, offset, count) {},
-    };
-
-    if (channel) {
-      channel.asyncOpen(listener);
-    } else {
-      aCallback(null);
-    }
-  },
-
-  // Because this method uses a callback, make sure we return ASAP if we know
-  // we have a castable video source.
-  _getVideo: function(aElement, aTypes, aExtensions, aCallback) {
-    // Keep a list of URIs we need for an async mimetype check
-    let asyncURIs = [];
-
-    // Grab the poster attribute from the <video>
-    let posterURL = aElement.poster;
-
-    // First, look to see if the <video> has a src attribute
-    let sourceURL = aElement.src;
-
-    // If empty, try the currentSrc
-    if (!sourceURL) {
-      sourceURL = aElement.currentSrc;
-    }
-
-    if (sourceURL) {
-      // Use the file extension to guess the mime type
-      let sourceURI = this.makeURI(
-        sourceURL,
-        null,
-        this.makeURI(aElement.baseURI)
-      );
-      if (this.allowableExtension(sourceURI, aExtensions)) {
-        aCallback({
-          element: aElement,
-          source: sourceURI.spec,
-          poster: posterURL,
-          sourceURI: sourceURI,
-        });
-        return;
-      }
-
-      if (aElement.type) {
-        // Fast sync check
-        if (this.allowableMimeType(aElement.type, aTypes)) {
-          aCallback({
-            element: aElement,
-            source: sourceURI.spec,
-            poster: posterURL,
-            sourceURI: sourceURI,
-            type: aElement.type,
-          });
-          return;
-        }
-      }
-
-      // Delay the async check until we sync scan all possible URIs
-      asyncURIs.push(sourceURI);
-    }
-
-    // Next, look to see if there is a <source> child element that meets
-    // our needs
-    let sourceNodes = aElement.getElementsByTagName("source");
-    for (let sourceNode of sourceNodes) {
-      let sourceURI = this.makeURI(
-        sourceNode.src,
-        null,
-        this.makeURI(sourceNode.baseURI)
-      );
-
-      // Using the type attribute is our ideal way to guess the mime type. Otherwise,
-      // fallback to using the file extension to guess the mime type
-      if (this.allowableExtension(sourceURI, aExtensions)) {
-        aCallback({
-          element: aElement,
-          source: sourceURI.spec,
-          poster: posterURL,
-          sourceURI: sourceURI,
-          type: sourceNode.type,
-        });
-        return;
-      }
-
-      if (sourceNode.type) {
-        // Fast sync check
-        if (this.allowableMimeType(sourceNode.type, aTypes)) {
-          aCallback({
-            element: aElement,
-            source: sourceURI.spec,
-            poster: posterURL,
-            sourceURI: sourceURI,
-            type: sourceNode.type,
-          });
-          return;
-        }
-      }
-
-      // Delay the async check until we sync scan all possible URIs
-      asyncURIs.push(sourceURI);
-    }
-
-    // Helper method that walks the array of possible URIs, fetching the mimetype as we go.
-    // As soon as we find a good sourceURL, avoid firing the callback any further
-    var _getContentTypeForURIs = aURIs => {
-      // Do an async fetch to figure out the mimetype of the source video
-      let sourceURI = aURIs.pop();
-      this._getContentTypeForURI(sourceURI, aElement, aType => {
-        if (this.allowableMimeType(aType, aTypes)) {
-          // We found a supported mimetype.
-          aCallback({
-            element: aElement,
-            source: sourceURI.spec,
-            poster: posterURL,
-            sourceURI: sourceURI,
-            type: aType,
-          });
-        } else if (aURIs.length > 0) {
-          // This URI was not a supported mimetype, so let's try the next, if we have more.
-          _getContentTypeForURIs(aURIs);
-        } else {
-          // We were not able to find a supported mimetype.
-          aCallback(null);
-        }
-      });
-    };
-
-    // If we didn't find a good URI directly, let's look using async methods.
-    if (asyncURIs.length > 0) {
-      _getContentTypeForURIs(asyncURIs);
-    }
-  },
-
-  // This code depends on handleVideoBindingAttached setting mozAllowCasting
-  // so we can quickly figure out if the video is castable
-  isVideoCastable: function(aElement, aX, aY) {
-    // Use the flag set when the <video> binding was created as the check
-    if (aElement instanceof HTMLVideoElement) {
-      return aElement.mozAllowCasting;
-    }
-
-    // This is called by the context menu system and the system will keep
-    // walking up the DOM giving us a chance to find an element we match.
-    // When it hits <html> things can go BOOM.
-    try {
-      // Maybe this is an overlay, with the video element under it
-      // Use the (x, y) location to guess at a <video> element
-      let elements = aElement.ownerDocument.querySelectorAll("video");
-      for (let element of elements) {
-        // Look for a video element contained in the overlay bounds
-        let rect = element.getBoundingClientRect();
-        if (
-          aY >= rect.top &&
-          aX >= rect.left &&
-          aY <= rect.bottom &&
-          aX <= rect.right
-        ) {
-          // Use the flag set when the <video> binding was created as the check
-          return element.mozAllowCasting;
-        }
-      }
-    } catch (e) {}
-
-    return false;
-  },
-
-  filterCast: {
-    matches: function(aElement, aX, aY) {
-      // This behavior matches the pageaction: As long as a video is castable,
-      // we can cast it, even if it's already being cast to a device.
-      if (SimpleServiceDiscovery.services.length == 0) {
-        return false;
-      }
-      return CastingApps.isVideoCastable(aElement, aX, aY);
-    },
-  },
-
-  pageAction: {
-    click: function() {
-      // Since this is a pageaction, we use the selected browser
-      let browser = BrowserApp.selectedBrowser;
-      if (!browser) {
-        return;
-      }
-
-      // Look for a castable <video> that is playing, and start casting it
-      let videos = browser.contentDocument.querySelectorAll("video");
-      for (let video of videos) {
-        if (!video.paused && video.mozAllowCasting) {
-          UITelemetry.addEvent("cast.1", "pageaction", null);
-          CastingApps.openExternal(video, 0, 0);
-          return;
-        }
-      }
-    },
-  },
-
-  _findCastableVideo: function _findCastableVideo(aBrowser) {
-    if (!aBrowser) {
-      return null;
-    }
-
-    // Scan for a <video> being actively cast. Also look for a castable <video>
-    // on the page.
-    let castableVideo = null;
-    let videos = aBrowser.contentDocument.querySelectorAll("video");
-    for (let video of videos) {
-      if (video.mozIsCasting) {
-        // This <video> is cast-active. Break out of loop.
-        return video;
-      }
-
-      if (!video.paused && video.mozAllowCasting) {
-        // This <video> is cast-ready. Keep looking so cast-active could be found.
-        castableVideo = video;
-      }
-    }
-
-    // Could be null
-    return castableVideo;
-  },
-
-  _updatePageActionForTab: function _updatePageActionForTab(aTab, aEvent) {
-    // We only care about events on the selected tab
-    if (aTab != BrowserApp.selectedTab) {
-      return;
-    }
-
-    // Update the page action, scanning for a castable <video>
-    this._updatePageAction();
-  },
-
-  _updatePageActionForVideo: function _updatePageActionForVideo(aVideo) {
-    this._updatePageAction(aVideo);
-  },
-
-  _updatePageAction: function _updatePageAction(aVideo) {
-    // Remove any exising pageaction first, in case state changes or we don't have
-    // a castable video
-    if (this.pageAction.id) {
-      PageActions.remove(this.pageAction.id);
-      delete this.pageAction.id;
-    }
-
-    if (!aVideo) {
-      aVideo = this._findCastableVideo(BrowserApp.selectedBrowser);
-      if (!aVideo) {
-        return;
-      }
-    }
-
-    // We only show pageactions if the <video> is from the selected tab
-    if (
-      BrowserApp.selectedTab !=
-      BrowserApp.getTabForWindow(aVideo.ownerGlobal.top)
-    ) {
-      return;
-    }
-
-    // We check for two state here:
-    // 1. The video is actively being cast
-    // 2. The video is allowed to be cast and is currently playing
-    // Both states have the same action: Show the cast page action
-    if (aVideo.mozIsCasting) {
-      this.pageAction.id = PageActions.add({
-        title: Strings.browser.GetStringFromName("contextmenu.sendToDevice"),
-        icon: "drawable://casting_active",
-        clickCallback: this.pageAction.click,
-        important: true,
-        useTint: false,
-      });
-    } else if (aVideo.mozAllowCasting) {
-      this.pageAction.id = PageActions.add({
-        title: Strings.browser.GetStringFromName("contextmenu.sendToDevice"),
-        icon: "drawable://casting",
-        clickCallback: this.pageAction.click,
-        important: true,
-        useTint: true,
-      });
-    }
-  },
-
-  prompt: function(aWindow, aCallback, aFilterFunc) {
-    let items = [];
-    let filteredServices = [];
-    SimpleServiceDiscovery.services.forEach(function(aService) {
-      let item = {
-        label: aService.friendlyName,
-        selected: false,
-      };
-      if (!aFilterFunc || aFilterFunc(aService)) {
-        filteredServices.push(aService);
-        items.push(item);
-      }
-    });
-
-    if (items.length == 0) {
-      return;
-    }
-
-    let prompt = new Prompt({
-      window: aWindow,
-      title: Strings.browser.GetStringFromName("casting.sendToDevice"),
-    })
-      .setSingleChoiceItems(items)
-      .show(function(data) {
-        let selected = data.button;
-        let service = selected == -1 ? null : filteredServices[selected];
-        if (aCallback) {
-          aCallback(service);
-        }
-      });
-  },
-
-  handleContextMenu: function(aElement, aX, aY) {
-    UITelemetry.addEvent("action.1", "contextmenu", null, "web_cast");
-    UITelemetry.addEvent("cast.1", "contextmenu", null);
-    this.openExternal(aElement, aX, aY);
-  },
-
-  openExternal: function(aElement, aX, aY) {
-    // Start a second screen media service
-    this.getVideo(aElement, aX, aY, this._openExternal.bind(this));
-  },
-
-  _openExternal: function(aVideo) {
-    if (!aVideo) {
-      return;
-    }
-
-    function filterFunc(aService) {
-      return (
-        this.allowableExtension(aVideo.sourceURI, aService.extensions) ||
-        this.allowableMimeType(aVideo.type, aService.types)
-      );
-    }
-
-    this.prompt(
-      aVideo.element.ownerGlobal,
-      aService => {
-        if (!aService) {
-          return;
-        }
-
-        // Make sure we have a player app for the given service
-        let app = SimpleServiceDiscovery.findAppForService(aService);
-        if (!app) {
-          return;
-        }
-
-        if (aVideo.element) {
-          aVideo.title = aVideo.element.ownerGlobal.top.document.title;
-
-          // If the video is currently playing on the device, pause it
-          if (!aVideo.element.paused) {
-            aVideo.element.pause();
-          }
-        }
-
-        app.stop(() => {
-          app.start(aStarted => {
-            if (!aStarted) {
-              dump("CastingApps: Unable to start app");
-              return;
-            }
-
-            app.remoteMedia(aRemoteMedia => {
-              if (!aRemoteMedia) {
-                dump("CastingApps: Failed to create remotemedia");
-                return;
-              }
-
-              this.session = {
-                service: aService,
-                app: app,
-                remoteMedia: aRemoteMedia,
-                data: {
-                  title: aVideo.title,
-                  source: aVideo.source,
-                  poster: aVideo.poster,
-                },
-                videoRef: Cu.getWeakReference(aVideo.element),
-              };
-            }, this);
-          });
-        });
-      },
-      filterFunc.bind(this)
-    );
-  },
-
-  closeExternal: function() {
-    if (!this.session) {
-      return;
-    }
-
-    this.session.remoteMedia.shutdown();
-    this._shutdown();
-  },
-
-  _shutdown: function() {
-    if (!this.session) {
-      return;
-    }
-
-    this.session.app.stop();
-    let video = this.session.videoRef.get();
-    if (video) {
-      this._sendEventToVideo(video, { active: false });
-      this._updatePageAction();
-    }
-
-    delete this.session;
-  },
-
-  // RemoteMedia callback API methods
-  onRemoteMediaStart: function(aRemoteMedia) {
-    if (!this.session) {
-      return;
-    }
-
-    aRemoteMedia.load(this.session.data);
-    GlobalEventDispatcher.sendRequest({
-      type: "Casting:Started",
-      device: this.session.service.friendlyName,
-    });
-
-    let video = this.session.videoRef.get();
-    if (video) {
-      this._sendEventToVideo(video, { active: true });
-      this._updatePageAction(video);
-    }
-  },
-
-  onRemoteMediaStop: function(aRemoteMedia) {
-    GlobalEventDispatcher.sendRequest({ type: "Casting:Stopped" });
-    this._shutdown();
-  },
-
-  onRemoteMediaStatus: function(aRemoteMedia) {
-    if (!this.session) {
-      return;
-    }
-
-    let status = aRemoteMedia.status;
-    switch (status) {
-      case "started":
-        GlobalEventDispatcher.sendRequest({ type: "Casting:Playing" });
-        break;
-      case "paused":
-        GlobalEventDispatcher.sendRequest({ type: "Casting:Paused" });
-        break;
-      case "completed":
-        this.closeExternal();
-        break;
-    }
-  },
-};
deleted file mode 100644
--- a/mobile/android/chrome/content/ConsoleAPI.js
+++ /dev/null
@@ -1,145 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-var ConsoleAPI = {
-  observe: function observe(aMessage, aTopic, aData) {
-    aMessage = aMessage.wrappedJSObject;
-
-    let mappedArguments = Array.from(
-      aMessage.arguments,
-      this.formatResult,
-      this
-    );
-    let joinedArguments = mappedArguments.join(" ");
-
-    if (aMessage.level == "error" || aMessage.level == "warn") {
-      let flag =
-        aMessage.level == "error"
-          ? Ci.nsIScriptError.errorFlag
-          : Ci.nsIScriptError.warningFlag;
-      let consoleMsg = Cc["@mozilla.org/scripterror;1"].createInstance(
-        Ci.nsIScriptError
-      );
-      consoleMsg.init(
-        joinedArguments,
-        null,
-        null,
-        0,
-        0,
-        flag,
-        "content javascript"
-      );
-      Services.console.logMessage(consoleMsg);
-    } else if (aMessage.level == "trace") {
-      let bundle = Services.strings.createBundle(
-        "chrome://browser/locale/browser.properties"
-      );
-      let args = aMessage.arguments;
-      let filename = this.abbreviateSourceURL(args[0].filename);
-      let functionName =
-        args[0].functionName ||
-        bundle.GetStringFromName("stacktrace.anonymousFunction");
-      let lineNumber = args[0].lineNumber;
-
-      let body = bundle.formatStringFromName("stacktrace.outputMessage", [
-        filename,
-        functionName,
-        lineNumber,
-      ]);
-      body += "\n";
-      args.forEach(function(aFrame) {
-        let functionName =
-          aFrame.functionName ||
-          bundle.GetStringFromName("stacktrace.anonymousFunction");
-        body +=
-          "  " +
-          aFrame.filename +
-          " :: " +
-          functionName +
-          " :: " +
-          aFrame.lineNumber +
-          "\n";
-      });
-
-      Services.console.logStringMessage(body);
-    } else if (aMessage.level == "time" && aMessage.arguments) {
-      let bundle = Services.strings.createBundle(
-        "chrome://browser/locale/browser.properties"
-      );
-      let body = bundle.formatStringFromName("timer.start", [
-        aMessage.arguments.name,
-      ]);
-      Services.console.logStringMessage(body);
-    } else if (aMessage.level == "timeEnd" && aMessage.arguments) {
-      let bundle = Services.strings.createBundle(
-        "chrome://browser/locale/browser.properties"
-      );
-      let body = bundle.formatStringFromName("timer.end", [
-        aMessage.arguments.name,
-        aMessage.arguments.duration,
-      ]);
-      Services.console.logStringMessage(body);
-    } else if (
-      ["group", "groupCollapsed", "groupEnd"].includes(aMessage.level)
-    ) {
-      // Do nothing yet
-    } else {
-      Services.console.logStringMessage(joinedArguments);
-    }
-  },
-
-  getResultType: function getResultType(aResult) {
-    let type = aResult === null ? "null" : typeof aResult;
-    if (type == "object" && aResult.constructor && aResult.constructor.name) {
-      type = aResult.constructor.name;
-    }
-    return type.toLowerCase();
-  },
-
-  formatResult: function formatResult(aResult) {
-    let output = "";
-    let type = this.getResultType(aResult);
-    switch (type) {
-      case "string":
-      case "boolean":
-      case "date":
-      case "error":
-      case "number":
-      case "regexp":
-        output = aResult.toString();
-        break;
-      case "null":
-      case "undefined":
-        output = type;
-        break;
-      default:
-        output = aResult.toString();
-        break;
-    }
-
-    return output;
-  },
-
-  abbreviateSourceURL: function abbreviateSourceURL(aSourceURL) {
-    // Remove any query parameters.
-    let hookIndex = aSourceURL.indexOf("?");
-    if (hookIndex > -1) {
-      aSourceURL = aSourceURL.substring(0, hookIndex);
-    }
-
-    // Remove a trailing "/".
-    if (aSourceURL[aSourceURL.length - 1] == "/") {
-      aSourceURL = aSourceURL.substring(0, aSourceURL.length - 1);
-    }
-
-    // Remove all but the last path component.
-    let slashIndex = aSourceURL.lastIndexOf("/");
-    if (slashIndex > -1) {
-      aSourceURL = aSourceURL.substring(slashIndex + 1);
-    }
-
-    return aSourceURL;
-  },
-};
deleted file mode 100644
--- a/mobile/android/chrome/content/EmbedRT.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "ConsoleAPI",
-  "resource://gre/modules/Console.jsm"
-);
-
-/*
- * Collection of methods and features specific to using a GeckoView instance.
- * The code is isolated from browser.js for code size and performance reasons.
- */
-var EmbedRT = {
-  _scopes: {},
-
-  onEvent: function(event, data, callback) {
-    switch (event) {
-      case "GeckoView:ImportScript":
-        this.importScript(data.scriptURL);
-        break;
-    }
-  },
-
-  /*
-   * Loads a script file into a sandbox and calls an optional load function
-   */
-  importScript: function(scriptURL) {
-    if (scriptURL in this._scopes) {
-      return;
-    }
-
-    let principal = Cc["@mozilla.org/systemprincipal;1"].createInstance(
-      Ci.nsIPrincipal
-    );
-
-    let sandbox = new Cu.Sandbox(principal, {
-      sandboxName: scriptURL,
-      wantGlobalProperties: ["indexedDB"],
-    });
-
-    sandbox.console = new ConsoleAPI({ consoleID: "script/" + scriptURL });
-
-    // As we don't want our caller to control the JS version used for the
-    // script file, we run loadSubScript within the context of the
-    // sandbox with the latest JS version set explicitly.
-    sandbox.__SCRIPT_URI_SPEC__ = scriptURL;
-    Cu.evalInSandbox(
-      "Components.classes['@mozilla.org/moz/jssubscript-loader;1'].createInstance(Components.interfaces.mozIJSSubScriptLoader).loadSubScript(__SCRIPT_URI_SPEC__);",
-      sandbox,
-      "ECMAv5"
-    );
-
-    this._scopes[scriptURL] = sandbox;
-
-    if ("load" in sandbox) {
-      let params = {
-        window: window,
-        resourceURI: scriptURL,
-      };
-
-      try {
-        sandbox.load(params);
-      } catch (e) {
-        dump(
-          "Exception calling 'load' method in script: " + scriptURL + "\n" + e
-        );
-      }
-    }
-  },
-};
deleted file mode 100644
--- a/mobile/android/chrome/content/ExtensionPermissions.js
+++ /dev/null
@@ -1,158 +0,0 @@
-"use strict";
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "ExtensionData",
-  "resource://gre/modules/Extension.jsm"
-);
-
-var ExtensionPermissions = {
-  // id -> object containing update details (see applyUpdate() )
-  updates: new Map(),
-
-  // Prepare the strings needed for a permission notification.
-  _prepareStrings(info) {
-    let appName = Strings.brand.GetStringFromName("brandShortName");
-    let info2 = Object.assign({ appName }, info);
-    let strings = ExtensionData.formatPermissionStrings(info2, Strings.browser);
-
-    // We dump the main body of the dialog into a big android
-    // TextView.  Build a big string with the full contents here.
-    let message = "";
-    if (strings.msgs.length > 0) {
-      message = [
-        strings.listIntro,
-        ...strings.msgs.map(s => `\u2022 ${s}`),
-      ].join("\n");
-    }
-
-    return {
-      header: strings.header.replace("<>", info.addonName),
-      message,
-      acceptText: strings.acceptText,
-      cancelText: strings.cancelText,
-    };
-  },
-
-  // Prepare an icon for a permission notification
-  _prepareIcon(iconURL) {
-    // We can render pngs with ResourceDrawableUtils
-    if (iconURL.endsWith(".png")) {
-      return iconURL;
-    }
-
-    // If we can't render an icon, show the default
-    return "DEFAULT";
-  },
-
-  async observe(subject, topic, data) {
-    switch (topic) {
-      case "webextension-permission-prompt": {
-        let { target, info } = subject.wrappedJSObject;
-        let stringInfo = Object.assign({ addonName: info.addon.name }, info);
-        let details = this._prepareStrings(stringInfo);
-        details.icon = this._prepareIcon(info.icon);
-        details.type = "Extension:PermissionPrompt";
-        let accepted = await EventDispatcher.instance.sendRequestForResult(
-          details
-        );
-
-        if (accepted) {
-          info.resolve();
-        } else {
-          info.reject();
-        }
-        break;
-      }
-
-      case "webextension-update-permissions":
-        let info = subject.wrappedJSObject;
-        let { addon, resolve, reject } = info;
-        let stringInfo = Object.assign(
-          {
-            type: "update",
-            addonName: addon.name,
-          },
-          info
-        );
-
-        let details = this._prepareStrings(stringInfo);
-
-        // If there are no promptable permissions, just apply the update
-        if (details.message.length == 0) {
-          resolve();
-          return;
-        }
-
-        // Store all the details about the update until the user chooses to
-        // look at update, at which point we will pick up in this.applyUpdate()
-        details.icon = this._prepareIcon(addon.iconURL || "dummy.svg");
-
-        let first = this.updates.size == 0;
-        this.updates.set(addon.id, { details, resolve, reject });
-
-        if (first) {
-          EventDispatcher.instance.sendRequest({
-            type: "Extension:ShowUpdateIcon",
-            value: true,
-          });
-        }
-        break;
-
-      case "webextension-optional-permission-prompt": {
-        let info = subject.wrappedJSObject;
-        let { name, resolve } = info;
-        let stringInfo = Object.assign(
-          {
-            type: "optional",
-            addonName: name,
-          },
-          info
-        );
-
-        let details = this._prepareStrings(stringInfo);
-
-        // If there are no promptable permissions, just apply the update
-        if (details.message.length == 0) {
-          resolve(true);
-          return;
-        }
-
-        // Store all the details about the update until the user chooses to
-        // look at update, at which point we will pick up in this.applyUpdate()
-        details.icon = this._prepareIcon(info.icon || "dummy.svg");
-
-        details.type = "Extension:PermissionPrompt";
-        let accepted = await EventDispatcher.instance.sendRequestForResult(
-          details
-        );
-        resolve(accepted);
-      }
-    }
-  },
-
-  async applyUpdate(id) {
-    if (!this.updates.has(id)) {
-      return;
-    }
-
-    let update = this.updates.get(id);
-    this.updates.delete(id);
-    if (this.updates.size == 0) {
-      EventDispatcher.instance.sendRequest({
-        type: "Extension:ShowUpdateIcon",
-        value: false,
-      });
-    }
-
-    let { details } = update;
-    details.type = "Extension:PermissionPrompt";
-
-    let accepted = await EventDispatcher.instance.sendRequestForResult(details);
-    if (accepted) {
-      update.resolve();
-    } else {
-      update.reject();
-    }
-  },
-};
deleted file mode 100644
--- a/mobile/android/chrome/content/FeedHandler.js
+++ /dev/null
@@ -1,147 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-var FeedHandler = {
-  PREF_CONTENTHANDLERS_BRANCH: "browser.contentHandlers.types.",
-  TYPE_MAYBE_FEED: "application/vnd.mozilla.maybe.feed",
-
-  _contentTypes: null,
-
-  getContentHandlers: function fh_getContentHandlers(contentType) {
-    if (!this._contentTypes) {
-      this.loadContentHandlers();
-    }
-
-    if (!(contentType in this._contentTypes)) {
-      return [];
-    }
-
-    return this._contentTypes[contentType];
-  },
-
-  loadContentHandlers: function fh_loadContentHandlers() {
-    this._contentTypes = {};
-
-    let kids = Services.prefs
-      .getBranch(this.PREF_CONTENTHANDLERS_BRANCH)
-      .getChildList("");
-
-    // First get the numbers of the providers by getting all ###.uri prefs
-    let nums = [];
-    for (let i = 0; i < kids.length; i++) {
-      let match = /^(\d+)\.uri$/.exec(kids[i]);
-      if (!match) {
-        continue;
-      } else {
-        nums.push(match[1]);
-      }
-    }
-
-    // Sort them, to get them back in order
-    nums.sort(function(a, b) {
-      return a - b;
-    });
-
-    // Now register them
-    for (let i = 0; i < nums.length; i++) {
-      let branch = Services.prefs.getBranch(
-        this.PREF_CONTENTHANDLERS_BRANCH + nums[i] + "."
-      );
-      let vals = branch.getChildList("");
-      if (vals.length == 0) {
-        return;
-      }
-
-      try {
-        let type = branch.getCharPref("type");
-        let uri = branch.getComplexValue("uri", Ci.nsIPrefLocalizedString).data;
-        let title = branch.getComplexValue("title", Ci.nsIPrefLocalizedString)
-          .data;
-
-        if (!(type in this._contentTypes)) {
-          this._contentTypes[type] = [];
-        }
-        this._contentTypes[type].push({
-          contentType: type,
-          uri: uri,
-          name: title,
-        });
-      } catch (ex) {}
-    }
-  },
-
-  onEvent: function fh_onEvent(event, args, callback) {
-    if (event === "Feeds:Subscribe") {
-      let tab = BrowserApp.getTabForId(args.tabId);
-      if (!tab) {
-        return;
-      }
-
-      let browser = tab.browser;
-      let feeds = browser.feeds;
-      if (feeds == null) {
-        return;
-      }
-
-      // First, let's decide on which feed to subscribe
-      let feedIndex = -1;
-      if (feeds.length > 1) {
-        let p = new Prompt({
-          window: browser.contentWindow,
-          title: Strings.browser.GetStringFromName("feedHandler.chooseFeed"),
-        })
-          .setSingleChoiceItems(
-            feeds.map(function(feed) {
-              return { label: feed.title || feed.href };
-            })
-          )
-          .show(data => {
-            feedIndex = data.button;
-            if (feedIndex == -1) {
-              return;
-            }
-
-            this.loadFeed(feeds[feedIndex], browser);
-          });
-        return;
-      }
-
-      this.loadFeed(feeds[0], browser);
-    }
-  },
-
-  loadFeed: function fh_loadFeed(aFeed, aBrowser) {
-    let feedURL = aFeed.href;
-
-    // Next, we decide on which service to send the feed
-    let handlers = this.getContentHandlers(this.TYPE_MAYBE_FEED);
-    if (handlers.length == 0) {
-      return;
-    }
-
-    // JSON for Prompt
-    let p = new Prompt({
-      window: aBrowser.contentWindow,
-      title: Strings.browser.GetStringFromName("feedHandler.subscribeWith"),
-    })
-      .setSingleChoiceItems(
-        handlers.map(function(handler) {
-          return { label: handler.name };
-        })
-      )
-      .show(function(data) {
-        if (data.button == -1) {
-          return;
-        }
-
-        // Merge the handler URL and the feed URL
-        let readerURL = handlers[data.button].uri;
-        readerURL = readerURL.replace(/%s/gi, encodeURIComponent(feedURL));
-
-        // Open the resultant URL in a new tab
-        BrowserApp.addTab(readerURL, { parentId: BrowserApp.selectedTab.id });
-      });
-  },
-};
deleted file mode 100644
--- a/mobile/android/chrome/content/Feedback.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-var Feedback = {
-  get _feedbackURL() {
-    delete this._feedbackURL;
-    return (this._feedbackURL = Services.urlFormatter.formatURLPref(
-      "app.feedbackURL"
-    ));
-  },
-
-  onEvent: function(event, data, callback) {
-    if (event !== "Feedback:Show") {
-      return;
-    }
-
-    // Don't prompt for feedback in distribution builds.
-    try {
-      Services.prefs.getCharPref("distribution.id");
-      return;
-    } catch (e) {}
-
-    let url = this._feedbackURL;
-    let browser = BrowserApp.selectOrAddTab(url, {
-      parentId: BrowserApp.selectedTab.id,
-    }).browser;
-
-    browser.addEventListener("FeedbackClose", this, false, true);
-    browser.addEventListener("FeedbackMaybeLater", this, false, true);
-
-    // Dispatch a custom event to the page content when feedback is prompted by the browser.
-    // This will be used by the page to determine it's being loaded directly by the browser,
-    // instead of by the user visiting the page, e.g. through browser history.
-    function loadListener(event) {
-      browser.removeEventListener("DOMContentLoaded", loadListener);
-      browser.contentDocument.dispatchEvent(
-        new CustomEvent("FeedbackPrompted")
-      );
-    }
-    browser.addEventListener("DOMContentLoaded", loadListener);
-  },
-
-  handleEvent: function(event) {
-    if (!this._isAllowed(event.target)) {
-      return;
-    }
-
-    switch (event.type) {
-      case "FeedbackClose":
-        // Do nothing.
-        break;
-
-      case "FeedbackMaybeLater":
-        GlobalEventDispatcher.sendRequest({ type: "Feedback:MaybeLater" });
-        break;
-    }
-
-    let win = event.target.ownerGlobal.top;
-    BrowserApp.closeTab(BrowserApp.getTabForWindow(win));
-  },
-
-  _isAllowed: function(node) {
-    let uri = node.ownerDocument.documentURIObject;
-    let feedbackURI = Services.io.newURI(this._feedbackURL);
-    return uri.prePath === feedbackURI.prePath;
-  },
-};
deleted file mode 100644
--- a/mobile/android/chrome/content/FindHelper.js
+++ /dev/null
@@ -1,231 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-var FindHelper = {
-  _finder: null,
-  _targetTab: null,
-  _initialViewport: null,
-  _viewportChanged: false,
-  _result: null,
-
-  // Start of nsIObserver implementation.
-
-  onEvent: function(event, data, callback) {
-    switch (event) {
-      case "FindInPage:Opened": {
-        this._findOpened();
-        break;
-      }
-
-      case "FindInPage:Closed": {
-        this._uninit();
-        this._findClosed();
-        break;
-      }
-
-      case "Tab:Selected": {
-        // Allow for page switching.
-        this._uninit();
-        break;
-      }
-
-      case "FindInPage:Find": {
-        this.doFind(data.searchString);
-        break;
-      }
-
-      case "FindInPage:Next": {
-        this.findAgain(data.searchString, false);
-        break;
-      }
-
-      case "FindInPage:Prev": {
-        this.findAgain(data.searchString, true);
-        break;
-      }
-    }
-  },
-
-  /**
-   * When the FindInPageBar opens/ becomes visible, it's time to:
-   * 1. Add listeners for other message types sent from the FindInPageBar
-   * 2. initialize the Finder instance, if necessary.
-   */
-  _findOpened: function() {
-    GlobalEventDispatcher.registerListener(this, [
-      "FindInPage:Find",
-      "FindInPage:Next",
-      "FindInPage:Prev",
-    ]);
-
-    // Initialize the finder component for the current page by performing a fake find.
-    this._init();
-    this._finder.requestMatchesCount("");
-  },
-
-  /**
-   * Fetch the Finder instance from the active tabs' browser and start tracking
-   * the active viewport.
-   */
-  _init: function() {
-    // If there's no find in progress, start one.
-    if (this._finder) {
-      return;
-    }
-
-    this._targetTab = BrowserApp.selectedTab;
-    try {
-      this._finder = this._targetTab.browser.finder;
-    } catch (e) {
-      throw new Error(
-        "FindHelper: " +
-          e +
-          "\n" +
-          "JS stack: \n" +
-          (e.stack || Components.stack.formattedStack)
-      );
-    }
-
-    this._finder.addResultListener(this);
-    this._initialViewport = JSON.stringify(this._targetTab.getViewport());
-    this._viewportChanged = false;
-
-    WindowEventDispatcher.registerListener(this, ["Tab:Selected"]);
-  },
-
-  /**
-   * Detach from the Finder instance (so stop listening for messages) and stop
-   * tracking the active viewport.
-   */
-  _uninit: function() {
-    // If there's no find in progress, there's nothing to clean up.
-    if (!this._finder) {
-      return;
-    }
-
-    this._finder.removeSelection();
-    this._finder.removeResultListener(this);
-    this._finder = null;
-    this._targetTab = null;
-    this._initialViewport = null;
-    this._viewportChanged = false;
-
-    WindowEventDispatcher.unregisterListener(this, ["Tab:Selected"]);
-  },
-
-  /**
-   * When the FindInPageBar closes, it's time to stop listening for its messages.
-   */
-  _findClosed: function() {
-    GlobalEventDispatcher.unregisterListener(this, [
-      "FindInPage:Find",
-      "FindInPage:Next",
-      "FindInPage:Prev",
-    ]);
-  },
-
-  /**
-   * Start an asynchronous find-in-page operation, using the current Finder
-   * instance and request to count the amount of matches.
-   * If no Finder instance is currently active, we'll lazily initialize it here.
-   *
-   * @param  {String} searchString Word to search for in the current document
-   * @return {Object}              Echo of the current find action
-   */
-  doFind: function(searchString) {
-    if (!this._finder) {
-      this._init();
-    }
-
-    this._finder.fastFind(searchString, false);
-    return { searchString, findBackwards: false };
-  },
-
-  /**
-   * Restart the same find-in-page operation as before via `doFind()`. If we
-   * haven't called `doFind()`, we simply kick off a regular find.
-   *
-   * @param  {String}  searchString  Word to search for in the current document
-   * @param  {Boolean} findBackwards Direction to search in
-   * @return {Object}                Echo of the current find action
-   */
-  findAgain: function(searchString, findBackwards) {
-    // This always happens if the user taps next/previous after re-opening the
-    // search bar, and not only forces _init() but also an initial fastFind(STRING)
-    // before any findAgain(DIRECTION).
-    if (!this._finder) {
-      return this.doFind(searchString);
-    }
-
-    this._finder.findAgain(searchString, findBackwards, false, false);
-    return { searchString, findBackwards };
-  },
-
-  // Start of Finder.jsm listener implementation.
-
-  /**
-   * Pass along the count results to FindInPageBar for display. The result that
-   * is sent to the FindInPageBar is augmented with the current find-in-page count
-   * limit.
-   *
-   * @param {Object} result Result coming from the Finder instance that contains
-   *                        the following properties:
-   *                        - {Number} total   The total amount of matches found
-   *                        - {Number} current The index of current found range
-   *                                           in the document
-   */
-  onMatchesCountResult: function(result) {
-    this._result = result;
-
-    GlobalEventDispatcher.sendRequest(
-      Object.assign(
-        {
-          type: "FindInPage:MatchesCountResult",
-        },
-        this._result
-      )
-    );
-  },
-
-  /**
-   * When a find-in-page action finishes, this method is invoked. This is mainly
-   * used at the moment to detect if the current viewport has changed, which might
-   * be indicated by not finding a string in the current page.
-   *
-   * @param {Object} aData A dictionary, representing the find result, which
-   *                       contains the following properties:
-   *                       - {String}  searchString  Word that was searched for
-   *                                                 in the current document
-   *                       - {Number}  result        One of the following
-   *                                                 Ci.nsITypeAheadFind.* result
-   *                                                 indicators: FIND_FOUND,
-   *                                                 FIND_NOTFOUND, FIND_WRAPPED,
-   *                                                 FIND_PENDING
-   *                       - {Boolean} findBackwards Whether the search direction
-   *                                                 was backwards
-   *                       - {Boolean} findAgain     Whether the previous search
-   *                                                 was repeated
-   *                       - {Boolean} drawOutline   Whether we may (re-)draw the
-   *                                                 outline of a hyperlink
-   *                       - {Boolean} linksOnly     Whether links-only mode was
-   *                                                 active
-   */
-  onFindResult: function(aData) {
-    if (aData.result == Ci.nsITypeAheadFind.FIND_NOTFOUND) {
-      if (this._viewportChanged) {
-        if (this._targetTab != BrowserApp.selectedTab) {
-          // this should never happen
-          Cu.reportError("Warning: selected tab changed during find!");
-          // fall through and restore viewport on the initial tab anyway
-        }
-        this._targetTab.sendViewportUpdate();
-      }
-    } else {
-      // Disabled until bug 1014113 is fixed
-      // ZoomHelper.zoomToRect(aData.rect);
-      this._viewportChanged = true;
-    }
-  },
-};
deleted file mode 100644
--- a/mobile/android/chrome/content/Linkify.js
+++ /dev/null
@@ -1,127 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const LINKIFY_TIMEOUT = 0;
-
-function Linkifier() {
-  this._linkifyTimer = null;
-  this._phoneRegex = /(?:\s|^)[\+]?(\(?\d{1,8}\)?)?([- ]+\(?\d{1,8}\)?)+( ?(x|ext) ?\d{1,3})?(?:\s|$)/g;
-}
-
-Linkifier.prototype = {
-  _buildAnchor: function(aDoc, aNumberText) {
-    let anchorNode = aDoc.createElement("a");
-    let cleanedText = "";
-    for (let i = 0; i < aNumberText.length; i++) {
-      let c = aNumberText.charAt(i);
-      if ((c >= "0" && c <= "9") || c == "+") {
-        // assuming there is only the leading '+'.
-        cleanedText += c;
-      }
-    }
-    anchorNode.setAttribute("href", "tel:" + cleanedText);
-    let nodeText = aDoc.createTextNode(aNumberText);
-    anchorNode.appendChild(nodeText);
-    return anchorNode;
-  },
-
-  _linkifyNodeNumbers: function(aNodeToProcess, aDoc) {
-    let parent = aNodeToProcess.parentNode;
-    let nodeText = aNodeToProcess.nodeValue;
-
-    // Replacing the original text node with a sequence of
-    // |text before number|anchor with number|text after number nodes.
-    // Each step a couple of (optional) text node and anchor node are appended.
-    let anchorNode = null;
-    let m = null;
-    let startIndex = 0;
-    let prevNode = null;
-    while ((m = this._phoneRegex.exec(nodeText))) {
-      anchorNode = this._buildAnchor(
-        aDoc,
-        nodeText.substr(m.index, m[0].length)
-      );
-
-      let textExistsBeforeNumber = m.index > startIndex;
-      let nodeToAdd = null;
-      if (textExistsBeforeNumber) {
-        nodeToAdd = aDoc.createTextNode(
-          nodeText.substr(startIndex, m.index - startIndex)
-        );
-      } else {
-        nodeToAdd = anchorNode;
-      }
-
-      if (!prevNode) {
-        // first time, need to replace the whole node with the first new one.
-        parent.replaceChild(nodeToAdd, aNodeToProcess);
-      } else {
-        parent.insertBefore(nodeToAdd, prevNode.nextSibling);
-      } // inserts after.
-
-      if (textExistsBeforeNumber) {
-        // if we added the text node before the anchor, we still need to add the anchor node.
-        parent.insertBefore(anchorNode, nodeToAdd.nextSibling);
-      }
-
-      // next nodes need to be appended to this node.
-      prevNode = anchorNode;
-      startIndex = m.index + m[0].length;
-    }
-
-    // if some text is remaining after the last anchor.
-    if (startIndex > 0 && startIndex < nodeText.length) {
-      let lastNode = aDoc.createTextNode(nodeText.substr(startIndex));
-      parent.insertBefore(lastNode, prevNode.nextSibling);
-      return lastNode;
-    }
-    return anchorNode;
-  },
-
-  linkifyNumbers: function(aDoc) {
-    // Removing any installed timer in case the page has changed and a previous timer is still running.
-    if (this._linkifyTimer) {
-      clearTimeout(this._linkifyTimer);
-      this._linkifyTimer = null;
-    }
-
-    let filterNode = function(node) {
-      if (
-        node.parentNode.tagName != "A" &&
-        node.parentNode.tagName != "SCRIPT" &&
-        node.parentNode.tagName != "NOSCRIPT" &&
-        node.parentNode.tagName != "STYLE" &&
-        node.parentNode.tagName != "APPLET" &&
-        node.parentNode.tagName != "TEXTAREA"
-      ) {
-        return NodeFilter.FILTER_ACCEPT;
-      }
-      return NodeFilter.FILTER_REJECT;
-    };
-
-    let nodeWalker = aDoc.createTreeWalker(
-      aDoc.body,
-      NodeFilter.SHOW_TEXT,
-      filterNode,
-      false
-    );
-    let parseNode = () => {
-      let node = nodeWalker.nextNode();
-      if (!node) {
-        this._linkifyTimer = null;
-        return;
-      }
-      let lastAddedNode = this._linkifyNodeNumbers(node, aDoc);
-      // we assign a different timeout whether the node was processed or not.
-      if (lastAddedNode) {
-        nodeWalker.currentNode = lastAddedNode;
-        this._linkifyTimer = setTimeout(parseNode, LINKIFY_TIMEOUT);
-      } else {
-        this._linkifyTimer = setTimeout(parseNode, LINKIFY_TIMEOUT);
-      }
-    };
-
-    this._linkifyTimer = setTimeout(parseNode, LINKIFY_TIMEOUT);
-  },
-};
deleted file mode 100644
--- a/mobile/android/chrome/content/MasterPassword.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "Snackbars",
-  "resource://gre/modules/Snackbars.jsm"
-);
-
-var MasterPassword = {
-  pref: "privacy.masterpassword.enabled",
-
-  get _pk11DB() {
-    delete this._pk11DB;
-    return (this._pk11DB = Cc["@mozilla.org/security/pk11tokendb;1"].getService(
-      Ci.nsIPK11TokenDB
-    ));
-  },
-
-  get enabled() {
-    let token = this._pk11DB.getInternalKeyToken();
-    if (token) {
-      return token.hasPassword;
-    }
-    return false;
-  },
-
-  setPassword: function setPassword(aPassword) {
-    try {
-      let token = this._pk11DB.getInternalKeyToken();
-      if (token.needsUserInit) {
-        token.initPassword(aPassword);
-      } else if (!token.needsLogin()) {
-        token.changePassword("", aPassword);
-      }
-
-      return true;
-    } catch (e) {
-      dump("MasterPassword.setPassword: " + e);
-    }
-    return false;
-  },
-
-  removePassword: function removePassword(aOldPassword) {
-    try {
-      let token = this._pk11DB.getInternalKeyToken();
-      if (token.checkPassword(aOldPassword)) {
-        token.changePassword(aOldPassword, "");
-        return true;
-      }
-    } catch (e) {
-      dump("MasterPassword.removePassword: " + e + "\n");
-    }
-    Snackbars.show(
-      Strings.browser.GetStringFromName("masterPassword.incorrect"),
-      Snackbars.LENGTH_LONG
-    );
-    return false;
-  },
-};
deleted file mode 100644
--- a/mobile/android/chrome/content/MemoryObserver.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-const MAX_CONTENT_VIEWERS_PREF = "browser.sessionhistory.max_total_viewers";
-
-var MemoryObserver = {
-  // When we turn off the bfcache by overwriting the old default value, we want
-  // to be able to restore it later on if memory pressure decreases again.
-  _defaultMaxContentViewers: -1,
-
-  observe: function mo_observe(aSubject, aTopic, aData) {
-    if (aTopic == "memory-pressure") {
-      if (aData != "heap-minimize") {
-        this.handleLowMemory();
-      }
-      // The JS engine would normally GC on this notification, but since we
-      // disabled that in favor of this method (bug 669346), we should gc here.
-      // See bug 784040 for when this code was ported from XUL to native Fennec.
-      this.gc();
-    } else if (aTopic == "memory-pressure-stop") {
-      this.handleEnoughMemory();
-    } else if (aTopic == "Memory:Dump") {
-      this.dumpMemoryStats(aData);
-    }
-  },
-
-  handleLowMemory: function() {
-    // do things to reduce memory usage here
-    if (
-      !Services.prefs.getBoolPref("browser.tabs.disableBackgroundZombification")
-    ) {
-      let tabs = BrowserApp.tabs;
-      let selected = BrowserApp.selectedTab;
-      for (let i = 0; i < tabs.length; i++) {
-        if (tabs[i] != selected && !tabs[i].playingAudio) {
-          tabs[i].zombify();
-        }
-      }
-    }
-
-    // Change some preferences temporarily for only this session
-    let defaults = Services.prefs.getDefaultBranch(null);
-
-    // Stop using the bfcache
-    if (
-      !Services.prefs.getBoolPref(
-        "browser.sessionhistory.bfcacheIgnoreMemoryPressure"
-      )
-    ) {
-      this._defaultMaxContentViewers = defaults.getIntPref(
-        MAX_CONTENT_VIEWERS_PREF
-      );
-      defaults.setIntPref(MAX_CONTENT_VIEWERS_PREF, 0);
-    }
-  },
-
-  handleEnoughMemory: function() {
-    // Re-enable the bfcache
-    let defaults = Services.prefs.getDefaultBranch(null);
-    if (
-      !Services.prefs.getBoolPref(
-        "browser.sessionhistory.bfcacheIgnoreMemoryPressure"
-      )
-    ) {
-      defaults.setIntPref(
-        MAX_CONTENT_VIEWERS_PREF,
-        this._defaultMaxContentViewers
-      );
-    }
-  },
-
-  gc: function() {
-    window.windowUtils.garbageCollect();
-    Cu.forceGC();
-  },
-
-  dumpMemoryStats: function(aLabel) {
-    let memDumper = Cc["@mozilla.org/memory-info-dumper;1"].getService(
-      Ci.nsIMemoryInfoDumper
-    );
-    memDumper.dumpMemoryInfoToTempDir(
-      aLabel,
-      /* anonymize = */ false,
-      /* minimize = */ false
-    );
-  },
-};
deleted file mode 100644
--- a/mobile/android/chrome/content/OfflineApps.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-var OfflineApps = {
-  allowSite: function(aDocument) {
-    Services.perms.addFromPrincipal(
-      aDocument.nodePrincipal,
-      "offline-app",
-      Services.perms.ALLOW_ACTION
-    );
-
-    // When a site is enabled while loading, manifest resources will
-    // start fetching immediately.  This one time we need to do it
-    // ourselves.
-    this._startFetching(aDocument);
-  },
-
-  disallowSite: function(aDocument) {
-    Services.perms.addFromPrincipal(
-      aDocument.nodePrincipal,
-      "offline-app",
-      Services.perms.DENY_ACTION
-    );
-  },
-
-  _startFetching: function(aDocument) {
-    if (!aDocument.documentElement) {
-      return;
-    }
-
-    let manifest = aDocument.documentElement.getAttribute("manifest");
-    if (!manifest) {
-      return;
-    }
-
-    let manifestURI = Services.io.newURI(
-      manifest,
-      aDocument.characterSet,
-      aDocument.documentURIObject
-    );
-    let updateService = Cc[
-      "@mozilla.org/offlinecacheupdate-service;1"
-    ].getService(Ci.nsIOfflineCacheUpdateService);
-    updateService.scheduleUpdate(
-      manifestURI,
-      aDocument.documentURIObject,
-      aDocument.nodePrincipal,
-      window
-    );
-  },
-};
deleted file mode 100644
--- a/mobile/android/chrome/content/PermissionsHelper.js
+++ /dev/null
@@ -1,204 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-var PermissionsHelper = {
-  _permissonTypes: [
-    "password",
-    "geolocation",
-    "popup",
-    "indexedDB",
-    "offline-app",
-    "desktop-notification",
-    "plugins",
-    "native-intent",
-  ],
-  _permissionStrings: {
-    password: {
-      label: "password.logins",
-      allowed: "password.save",
-      denied: "password.dontSave",
-    },
-    geolocation: {
-      label: "geolocation.location",
-      allowed: "geolocation.allow",
-      denied: "geolocation.dontAllow",
-    },
-    popup: {
-      label: "blockPopups.label2",
-      allowed: "popup.show",
-      denied: "popup.dontShow",
-    },
-    indexedDB: {
-      label: "offlineApps.offlineData",
-      allowed: "offlineApps.allow",
-      denied: "offlineApps.dontAllow2",
-    },
-    "offline-app": {
-      label: "offlineApps.offlineData",
-      allowed: "offlineApps.allow",
-      denied: "offlineApps.dontAllow2",
-    },
-    "desktop-notification": {
-      label: "desktopNotification.notifications",
-      allowed: "desktopNotification2.allow",
-      denied: "desktopNotification2.dontAllow",
-    },
-    plugins: {
-      label: "clickToPlayPlugins.plugins",
-      allowed: "clickToPlayPlugins.activate",
-      denied: "clickToPlayPlugins.dontActivate",
-    },
-    "native-intent": {
-      label: "helperapps.openWithList2",
-      allowed: "helperapps.always",
-      denied: "helperapps.never",
-    },
-  },
-
-  onEvent: function onEvent(event, data, callback) {
-    let principal = BrowserApp.selectedBrowser.contentPrincipal;
-    let check = false;
-
-    switch (event) {
-      case "Permissions:Check":
-        check = true;
-      // fall-through
-
-      case "Permissions:Get":
-        let permissions = [];
-        for (let i = 0; i < this._permissonTypes.length; i++) {
-          let type = this._permissonTypes[i];
-          let value = this.getPermission(principal, type);
-
-          // Only add the permission if it was set by the user
-          if (value == Services.perms.UNKNOWN_ACTION) {
-            continue;
-          }
-
-          if (check) {
-            GlobalEventDispatcher.sendRequest({
-              type: "Permissions:CheckResult",
-              hasPermissions: true,
-            });
-            return;
-          }
-          // Get the strings that correspond to the permission type
-          let typeStrings = this._permissionStrings[type];
-          let label = Strings.browser.GetStringFromName(typeStrings.label);
-
-          // Get the key to look up the appropriate string entity
-          let valueKey =
-            value == Services.perms.ALLOW_ACTION ? "allowed" : "denied";
-          let valueString = Strings.browser.GetStringFromName(
-            typeStrings[valueKey]
-          );
-
-          permissions.push({
-            type: type,
-            setting: label,
-            value: valueString,
-          });
-        }
-
-        if (check) {
-          GlobalEventDispatcher.sendRequest({
-            type: "Permissions:CheckResult",
-            hasPermissions: false,
-          });
-          return;
-        }
-
-        // Keep track of permissions, so we know which ones to clear
-        this._currentPermissions = permissions;
-
-        WindowEventDispatcher.sendRequest({
-          type: "Permissions:Data",
-          permissions: permissions,
-        });
-        break;
-
-      case "Permissions:Clear":
-        // An array of the indices of the permissions we want to clear
-        let permissionsToClear = data.permissions;
-        let privacyContext = BrowserApp.selectedBrowser.docShell.QueryInterface(
-          Ci.nsILoadContext
-        );
-
-        for (let i = 0; i < permissionsToClear.length; i++) {
-          let indexToClear = permissionsToClear[i];
-          let permissionType = this._currentPermissions[indexToClear].type;
-          this.clearPermission(uri, permissionType, privacyContext);
-        }
-        break;
-    }
-  },
-
-  /**
-   * Gets the permission value stored for a specified permission type.
-   *
-   * @param aType
-   *        The permission type string stored in permission manager.
-   *        e.g. "geolocation", "indexedDB", "popup"
-   *
-   * @return A permission value defined in nsIPermissionManager.
-   */
-  getPermission: function getPermission(aPrincipal, aType) {
-    let aURI = BrowserApp.selectedBrowser.lastURI;
-    // Password saving isn't a nsIPermissionManager permission type, so handle
-    // it seperately.
-    if (aType == "password") {
-      // By default, login saving is enabled, so if it is disabled, the
-      // user selected the never remember option
-      if (!Services.logins.getLoginSavingEnabled(aURI.displayPrePath)) {
-        return Services.perms.DENY_ACTION;
-      }
-
-      // Check to see if the user ever actually saved a login
-      if (Services.logins.countLogins(aURI.displayPrePath, "", "")) {
-        return Services.perms.ALLOW_ACTION;
-      }
-
-      return Services.perms.UNKNOWN_ACTION;
-    }
-
-    // Geolocation consumers use testExactPermissionForPrincipal
-    if (aType == "geolocation") {
-      return Services.perms.testExactPermissionFromPrincipal(aPrincipal, aType);
-    }
-
-    return Services.perms.testPermissionFromPrincipal(aPrincipal, aType);
-  },
-
-  /**
-   * Clears a user-set permission value for the site given a permission type.
-   *
-   * @param aType
-   *        The permission type string stored in permission manager.
-   *        e.g. "geolocation", "indexedDB", "popup"
-   */
-  clearPermission: function clearPermission(aPrincipal, aType, aContext) {
-    // Password saving isn't a nsIPermissionManager permission type, so handle
-    // it seperately.
-    if (aType == "password") {
-      // Get rid of exisiting stored logings
-      let logins = Services.logins.findLogins(aURI.displayPrePath, "", "");
-      for (let i = 0; i < logins.length; i++) {
-        Services.logins.removeLogin(logins[i]);
-      }
-      // Re-set login saving to enabled
-      Services.logins.setLoginSavingEnabled(aURI.displayPrePath, true);
-    } else {
-      Services.perms.removeFromPrincipal(aPrincipal, aType);
-      // Clear content prefs set in ContentPermissionPrompt.js
-      Cc["@mozilla.org/content-pref/service;1"]
-        .getService(Ci.nsIContentPrefService2)
-        .removeByDomainAndName(
-          aURI.spec,
-          aType + ".request.remember",
-          aContext
-        );
-    }
-  },
-};
deleted file mode 100644
--- a/mobile/android/chrome/content/PresentationView.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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 TOPIC_PRESENTATION_VIEW_READY = "presentation-view-ready";
-const TOPIC_PRESENTATION_RECEIVER_LAUNCH = "presentation-receiver:launch";
-const TOPIC_PRESENTATION_RECEIVER_LAUNCH_RESPONSE =
-  "presentation-receiver:launch:response";
-
-// globals Services
-const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-function log(str) {
-  // dump("-*- PresentationView.js -*-: " + str + "\n");
-}
-
-let PresentationView = {
-  _id: null,
-
-  startup: function startup() {
-    // use hash as the ID of this top level window
-    this._id = window.location.hash.substr(1);
-
-    // Listen "presentation-receiver:launch" sent from
-    // PresentationRequestUIGlue.
-    Services.obs.addObserver(this, TOPIC_PRESENTATION_RECEIVER_LAUNCH);
-
-    // Notify PresentationView is ready.
-    Services.obs.notifyObservers(null, TOPIC_PRESENTATION_VIEW_READY, this._id);
-  },
-
-  stop: function stop() {
-    Services.obs.removeObserver(this, TOPIC_PRESENTATION_RECEIVER_LAUNCH);
-  },
-
-  observe: function observe(aSubject, aTopic, aData) {
-    log("Got observe: aTopic=" + aTopic);
-
-    let requestData = JSON.parse(aData);
-    if (this._id != requestData.windowId) {
-      return;
-    }
-
-    let browser = document.getElementById("content");
-    browser.setAttribute("mozpresentation", requestData.url);
-    try {
-      browser.loadURI(requestData.url);
-      Services.obs.notifyObservers(
-        browser,
-        TOPIC_PRESENTATION_RECEIVER_LAUNCH_RESPONSE,
-        JSON.stringify({ result: "success", requestId: requestData.requestId })
-      );
-    } catch (e) {
-      Services.obs.notifyObservers(
-        null,
-        TOPIC_PRESENTATION_RECEIVER_LAUNCH_RESPONSE,
-        JSON.stringify({ result: "error", reason: e.message })
-      );
-    }
-  },
-};
deleted file mode 100644
--- a/mobile/android/chrome/content/PresentationView.xul
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - License, v. 2.0. If a copy of the MPL was not distributed with this
-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<window id="presentation-window"
-        onload="PresentationView.startup();"
-        onunload="PresentationView.stop();"
-        windowtype="navigator:browser"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-  <browser id="content" type="content" src="about:blank" flex="1"/>
-
-  <script type="application/javascript" src="chrome://browser/content/PresentationView.js"/>
-</window>
deleted file mode 100644
--- a/mobile/android/chrome/content/PrintHelper.js
+++ /dev/null
@@ -1,92 +0,0 @@
-// -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
-/* 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";
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "Snackbars",
-  "resource://gre/modules/Snackbars.jsm"
-);
-
-var PrintHelper = {
-  onEvent: function(event, data, callback) {
-    let browser = BrowserApp.selectedBrowser;
-
-    switch (event) {
-      case "Print:PDF":
-        this.generatePDF(browser).then(
-          data => callback.onSuccess(data),
-          error => callback.onError(error)
-        );
-        break;
-    }
-  },
-
-  generatePDF: function(aBrowser) {
-    // Create the final destination file location
-    let fileName = ContentAreaUtils.getDefaultFileName(
-      aBrowser.contentTitle,
-      aBrowser.currentURI,
-      null,
-      null
-    );
-    fileName = fileName.trim() + ".pdf";
-
-    let file = Services.dirsvc.get("TmpD", Ci.nsIFile);
-    file.append(fileName);
-    file.createUnique(file.NORMAL_FILE_TYPE, parseInt("666", 8));
-
-    let printSettings = Cc[
-      "@mozilla.org/gfx/printsettings-service;1"
-    ].getService(Ci.nsIPrintSettingsService).newPrintSettings;
-    printSettings.printSilent = true;
-    printSettings.showPrintProgress = false;
-    printSettings.printBGImages = false;
-    printSettings.printBGColors = false;
-    printSettings.printToFile = true;
-    printSettings.toFileName = file.path;
-    printSettings.outputFormat = Ci.nsIPrintSettings.kOutputFormatPDF;
-
-    let webBrowserPrint = aBrowser.contentWindow.getInterface(
-      Ci.nsIWebBrowserPrint
-    );
-
-    return new Promise((resolve, reject) => {
-      webBrowserPrint.print(printSettings, {
-        onStateChange: function(webProgress, request, stateFlags, status) {
-          // We get two STATE_START calls, one for STATE_IS_DOCUMENT and one for STATE_IS_NETWORK
-          if (
-            stateFlags & Ci.nsIWebProgressListener.STATE_START &&
-            stateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK
-          ) {
-            // Let the user know something is happening. Generating the PDF can take some time.
-            Snackbars.show(
-              Strings.browser.GetStringFromName("alertPrintjobToast"),
-              Snackbars.LENGTH_LONG
-            );
-          }
-
-          // We get two STATE_STOP calls, one for STATE_IS_DOCUMENT and one for STATE_IS_NETWORK
-          if (
-            stateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
-            stateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK
-          ) {
-            if (Components.isSuccessCode(status)) {
-              // Send the details to Java
-              resolve({ file: file.path, title: fileName });
-            } else {
-              reject();
-            }
-          }
-        },
-        onProgressChange: function() {},
-        onLocationChange: function() {},
-        onStatusChange: function() {},
-        onSecurityChange: function() {},
-        onContentBlockingEvent: function() {},
-      });
-    });
-  },
-};
deleted file mode 100644
--- a/mobile/android/chrome/content/Reader.js
+++ /dev/null
@@ -1,342 +0,0 @@
-// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
-/* 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";
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "Snackbars",
-  "resource://gre/modules/Snackbars.jsm"
-);
-
-/* globals MAX_URI_LENGTH, MAX_TITLE_LENGTH */
-
-var Reader = {
-  // These values should match those defined in BrowserContract.java.
-  STATUS_UNFETCHED: 0,
-  STATUS_FETCH_FAILED_TEMPORARY: 1,
-  STATUS_FETCH_FAILED_PERMANENT: 2,
-  STATUS_FETCH_FAILED_UNSUPPORTED_FORMAT: 3,
-  STATUS_FETCHED_ARTICLE: 4,
-
-  get _hasUsedToolbar() {
-    delete this._hasUsedToolbar;
-    return (this._hasUsedToolbar = Services.prefs.getBoolPref(
-      "reader.has_used_toolbar"
-    ));
-  },
-
-  /**
-   * BackPressListener (listeners / ReaderView Ids).
-   */
-  _backPressListeners: [],
-  _backPressViewIds: [],
-
-  /**
-   * Set a backPressListener for this tabId / ReaderView Id pair.
-   */
-  _addBackPressListener: function(tabId, viewId, listener) {
-    this._backPressListeners[tabId] = listener;
-    this._backPressViewIds[viewId] = tabId;
-  },
-
-  /**
-   * Remove a backPressListener for this ReaderView Id.
-   */
-  _removeBackPressListener: function(viewId) {
-    let tabId = this._backPressViewIds[viewId];
-    if (tabId != undefined) {
-      this._backPressListeners[tabId] = null;
-      delete this._backPressViewIds[viewId];
-    }
-  },
-
-  /**
-   * If the requested tab has a backPress listener, return its results, else false.
-   */
-  onBackPress: function(tabId) {
-    let listener = this._backPressListeners[tabId];
-    return { handled: listener ? listener() : false };
-  },
-
-  onEvent: function Reader_onEvent(event, data, callback) {
-    switch (event) {
-      case "Reader:RemoveFromCache": {
-        ReaderMode.removeArticleFromCache(data.url).catch(e =>
-          Cu.reportError("Error removing article from cache: " + e)
-        );
-        break;
-      }
-
-      case "Reader:AddToCache": {
-        let tab = BrowserApp.getTabForId(data.tabID);
-        if (!tab) {
-          throw new Error(
-            "No tab for tabID = " +
-              data.tabID +
-              " when trying to save reader view article"
-          );
-        }
-
-        // If the article is coming from reader mode, we must have fetched it already.
-        this._getArticleData(tab.browser)
-          .then(article => {
-            ReaderMode.storeArticleInCache(article);
-          })
-          .catch(e => Cu.reportError("Error storing article in cache: " + e));
-        break;
-      }
-    }
-  },
-
-  receiveMessage: function(message) {
-    switch (message.name) {
-      case "Reader:ArticleGet":
-        this._getArticle(message.data.url).then(
-          article => {
-            // Make sure the target browser is still alive before trying to send data back.
-            if (message.target.messageManager) {
-              message.target.messageManager.sendAsyncMessage(
-                "Reader:ArticleData",
-                { article: article }
-              );
-            }
-          },
-          e => {
-            if (e && e.newURL) {
-              message.target.loadURI(
-                "about:reader?url=" + encodeURIComponent(e.newURL)
-              );
-            }
-          }
-        );
-        break;
-
-      // On DropdownClosed in ReaderView, we cleanup / clear existing BackPressListener.
-      case "Reader:DropdownClosed": {
-        this._removeBackPressListener(message.data);
-        break;
-      }
-
-      // On DropdownOpened in ReaderView, we add BackPressListener to handle a subsequent BACK request.
-      case "Reader:DropdownOpened": {
-        let tabId = BrowserApp.selectedTab.id;
-        this._addBackPressListener(tabId, message.data, () => {
-          // User hit BACK key while ReaderView has the banner font-dropdown opened.
-          // Close it and return prevent-default.
-          if (message.target.messageManager) {
-            message.target.messageManager.sendAsyncMessage(
-              "Reader:CloseDropdown"
-            );
-            return true;
-          }
-          // We can assume ReaderView banner's font-dropdown doesn't need to be closed.
-          return false;
-        });
-
-        break;
-      }
-
-      case "Reader:FaviconRequest": {
-        GlobalEventDispatcher.sendRequestForResult({
-          type: "Reader:FaviconRequest",
-          url: message.data.url,
-        }).then(data => {
-          message.target.messageManager.sendAsyncMessage(
-            "Reader:FaviconReturn",
-            data
-          );
-        });
-        break;
-      }
-
-      case "Reader:SystemUIVisibility":
-        this._showSystemUI(message.data.visible);
-        break;
-
-      case "Reader:ToolbarHidden":
-        if (!this._hasUsedToolbar) {
-          Snackbars.show(
-            Strings.browser.GetStringFromName("readerMode.toolbarTip"),
-            Snackbars.LENGTH_LONG
-          );
-          Services.prefs.setBoolPref("reader.has_used_toolbar", true);
-          this._hasUsedToolbar = true;
-        }
-        break;
-
-      case "Reader:UpdateReaderButton": {
-        let tab = BrowserApp.getTabForBrowser(message.target);
-        tab.browser.isArticle = message.data.isArticle;
-        this.updatePageAction(tab);
-        break;
-      }
-    }
-  },
-
-  pageAction: {
-    readerModeCallback: function(browser) {
-      let url = browser.currentURI.spec;
-      if (url.startsWith("about:reader")) {
-        UITelemetry.addEvent("action.1", "button", null, "reader_exit");
-      } else {
-        UITelemetry.addEvent("action.1", "button", null, "reader_enter");
-      }
-      browser.messageManager.sendAsyncMessage("Reader:ToggleReaderMode");
-    },
-  },
-
-  updatePageAction: function(tab) {
-    if (!tab.getActive()) {
-      return;
-    }
-
-    if (this.pageAction.id) {
-      PageActions.remove(this.pageAction.id);
-      delete this.pageAction.id;
-    }
-
-    let showPageAction = (icon, title, useTint) => {
-      this.pageAction.id = PageActions.add({
-        icon: icon,
-        title: title,
-        clickCallback: () => this.pageAction.readerModeCallback(browser),
-        important: true,
-        useTint: useTint,
-      });
-    };
-
-    let browser = tab.browser;
-    if (browser.currentURI.spec.startsWith("about:reader")) {
-      showPageAction(
-        "drawable://ic_readermode_on",
-        Strings.reader.GetStringFromName("readerView.close"),
-        false
-      );
-      // Only start a reader session if the viewer is in the foreground. We do
-      // not track background reader viewers.
-      UITelemetry.startSession("reader.1", null);
-      return;
-    }
-
-    // not in ReaderMode, to make sure System UI is visible, not dimmed.
-    this._showSystemUI(true);
-
-    // Only stop a reader session if the foreground viewer is not visible.
-    UITelemetry.stopSession("reader.1", "", null);
-
-    if (browser.isArticle) {
-      showPageAction(
-        "drawable://ic_readermode",
-        Strings.reader.GetStringFromName("readerView.enter"),
-        true
-      );
-      UITelemetry.addEvent("show.1", "button", null, "reader_available");
-      this._sendMmaEvent("reader_available");
-    } else {
-      UITelemetry.addEvent("show.1", "button", null, "reader_unavailable");
-    }
-  },
-
-  _sendMmaEvent: function(event) {
-    WindowEventDispatcher.sendRequest({
-      type: "Mma:" + event,
-    });
-  },
-
-  _showSystemUI: function(visibility) {
-    WindowEventDispatcher.sendRequest({
-      type: "SystemUI:Visibility",
-      visible: visibility,
-    });
-  },
-
-  /**
-   * Gets an article for a given URL. This method will download and parse a document
-   * if it does not find the article in the cache.
-   *
-   * @param url The article URL.
-   * @return {Promise}
-   * @resolves JS object representing the article, or null if no article is found.
-   */
-  async _getArticle(url) {
-    // First try to find a parsed article in the cache.
-    let article = await ReaderMode.getArticleFromCache(url);
-    if (article) {
-      return article;
-    }
-
-    // Article hasn't been found in the cache, we need to
-    // download the page and parse the article out of it.
-    return ReaderMode.downloadAndParseDocument(url).catch(e => {
-      if (e && e.newURL) {
-        // Pass up the error so we can navigate the browser in question to the new URL:
-        throw e;
-      }
-      Cu.reportError("Error downloading and parsing document: " + e);
-      return null;
-    });
-  },
-
-  _getArticleData: function(browser) {
-    return new Promise((resolve, reject) => {
-      if (browser == null) {
-        reject("_getArticleData needs valid browser");
-      }
-
-      let mm = browser.messageManager;
-      let listener = message => {
-        mm.removeMessageListener("Reader:StoredArticleData", listener);
-        resolve(message.data.article);
-      };
-      mm.addMessageListener("Reader:StoredArticleData", listener);
-      mm.sendAsyncMessage("Reader:GetStoredArticleData");
-    });
-  },
-
-  /**
-   * Migrates old indexedDB reader mode cache to new JSON cache.
-   */
-  async migrateCache() {
-    let cacheDB = await new Promise((resolve, reject) => {
-      let request = window.indexedDB.open("about:reader", 1);
-      request.onsuccess = event => resolve(event.target.result);
-      request.onerror = event => reject(request.error);
-
-      // If there is no DB to migrate, don't do anything.
-      request.onupgradeneeded = event => resolve(null);
-    });
-
-    if (!cacheDB) {
-      return;
-    }
-
-    let articles = await new Promise((resolve, reject) => {
-      let articles = [];
-
-      let transaction = cacheDB.transaction(cacheDB.objectStoreNames);
-      let store = transaction.objectStore(cacheDB.objectStoreNames[0]);
-
-      let request = store.openCursor();
-      request.onsuccess = event => {
-        let cursor = event.target.result;
-        if (!cursor) {
-          resolve(articles);
-        } else {
-          articles.push(cursor.value);
-          cursor.continue();
-        }
-      };
-      request.onerror = event => reject(request.error);
-    });
-
-    for (let article of articles) {
-      await ReaderMode.storeArticleInCache(article);
-    }
-
-    // Delete the database.
-    window.indexedDB.deleteDatabase("about:reader");
-  },
-};
deleted file mode 100644
--- a/mobile/android/chrome/content/RemoteDebugger.js
+++ /dev/null
@@ -1,406 +0,0 @@
-// -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
-/* 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/. */
-/* globals DebuggerServer */
-"use strict";
-
-XPCOMUtils.defineLazyGetter(this, "require", () => {
-  let { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm");
-  return require;
-});
-
-XPCOMUtils.defineLazyGetter(this, "DebuggerServer", () => {
-  let { DebuggerServer } = require("devtools/server/debugger-server");
-  return DebuggerServer;
-});
-XPCOMUtils.defineLazyGetter(this, "SocketListener", () => {
-  let { SocketListener } = require("devtools/shared/security/socket");
-  return SocketListener;
-});
-
-var RemoteDebugger = {
-  init(aWindow) {
-    this._windowType = "navigator:browser";
-
-    USBRemoteDebugger.init();
-    WiFiRemoteDebugger.init();
-
-    const listener = event => {
-      if (event.target !== aWindow) {
-        return;
-      }
-
-      const newType =
-        event.type === "activate" ? "navigator:browser" : "navigator:geckoview";
-      if (this._windowType === newType) {
-        return;
-      }
-
-      this._windowType = newType;
-      if (this.isAnyEnabled) {
-        this.initServer();
-      }
-    };
-    aWindow.addEventListener("activate", listener, { mozSystemGroup: true });
-    aWindow.addEventListener("deactivate", listener, { mozSystemGroup: true });
-  },
-
-  get isAnyEnabled() {
-    return USBRemoteDebugger.isEnabled || WiFiRemoteDebugger.isEnabled;
-  },
-
-  /**
-   * Prompt the user to accept or decline the incoming connection.
-   *
-   * @param session object
-   *        The session object will contain at least the following fields:
-   *        {
-   *          authentication,
-   *          client: {
-   *            host,
-   *            port
-   *          },
-   *          server: {
-   *            host,
-   *            port
-   *          }
-   *        }
-   *        Specific authentication modes may include additional fields.  Check
-   *        the different |allowConnection| methods in
-   *        devtools/shared/security/auth.js.
-   * @return An AuthenticationResult value.
-   *         A promise that will be resolved to the above is also allowed.
-   */
-  allowConnection(session) {
-    if (this._promptingForAllow) {
-      // Don't stack connection prompts if one is already open
-      return DebuggerServer.AuthenticationResult.DENY;
-    }
-
-    if (!session.server.port) {
-      this._promptingForAllow = this._promptForUSB(session);
-    } else {
-      this._promptingForAllow = this._promptForTCP(session);
-    }
-    this._promptingForAllow.then(() => (this._promptingForAllow = null));
-
-    return this._promptingForAllow;
-  },
-
-  _promptForUSB(session) {
-    if (session.authentication !== "PROMPT") {
-      // This dialog is not prepared for any other authentication method at
-      // this time.
-      return DebuggerServer.AuthenticationResult.DENY;
-    }
-
-    return new Promise(resolve => {
-      let title = Strings.browser.GetStringFromName(
-        "remoteIncomingPromptTitle"
-      );
-      let msg = Strings.browser.GetStringFromName("remoteIncomingPromptUSB");
-      let allow = Strings.browser.GetStringFromName(
-        "remoteIncomingPromptAllow"
-      );
-      let deny = Strings.browser.GetStringFromName("remoteIncomingPromptDeny");
-
-      // Make prompt. Note: button order is in reverse.
-      let prompt = new Prompt({
-        window: null,
-        hint: "remotedebug",
-        title: title,
-        message: msg,
-        buttons: [allow, deny],
-        priority: 1,
-      });
-
-      prompt.show(data => {
-        let result = data.button;
-        if (result === 0) {
-          resolve(DebuggerServer.AuthenticationResult.ALLOW);
-        } else {
-          resolve(DebuggerServer.AuthenticationResult.DENY);
-        }
-      });
-    });
-  },
-
-  _promptForTCP(session) {
-    if (session.authentication !== "OOB_CERT" || !session.client.cert) {
-      // This dialog is not prepared for any other authentication method at
-      // this time.
-      return DebuggerServer.AuthenticationResult.DENY;
-    }
-
-    return new Promise(resolve => {
-      let title = Strings.browser.GetStringFromName(
-        "remoteIncomingPromptTitle"
-      );
-      let msg = Strings.browser.formatStringFromName(
-        "remoteIncomingPromptTCP",
-        [session.client.host, session.client.port]
-      );
-      let scan = Strings.browser.GetStringFromName("remoteIncomingPromptScan");
-      let scanAndRemember = Strings.browser.GetStringFromName(
-        "remoteIncomingPromptScanAndRemember"
-      );
-      let deny = Strings.browser.GetStringFromName("remoteIncomingPromptDeny");
-
-      // Make prompt. Note: button order is in reverse.
-      let prompt = new Prompt({
-        window: null,
-        hint: "remotedebug",
-        title: title,
-        message: msg,
-        buttons: [scan, scanAndRemember, deny],
-        priority: 1,
-      });
-
-      prompt.show(data => {
-        let result = data.button;
-        if (result === 0) {
-          resolve(DebuggerServer.AuthenticationResult.ALLOW);
-        } else if (result === 1) {
-          resolve(DebuggerServer.AuthenticationResult.ALLOW_PERSIST);
-        } else {
-          resolve(DebuggerServer.AuthenticationResult.DENY);
-        }
-      });
-    });
-  },
-
-  /**
-   * During OOB_CERT authentication, the user must transfer some data through
-   * some out of band mechanism from the client to the server to authenticate
-   * the devices.
-   *
-   * This implementation instructs Fennec to invoke a QR decoder and return the
-   * the data it contains back here.
-   *
-   * @return An object containing:
-   *         * sha256: hash(ClientCert)
-   *         * k     : K(random 128-bit number)
-   *         A promise that will be resolved to the above is also allowed.
-   */
-  receiveOOB() {
-    if (this._receivingOOB) {
-      return this._receivingOOB;
-    }
-
-    this._receivingOOB = WindowEventDispatcher.sendRequestForResult({
-      type: "DevToolsAuth:Scan",
-    }).then(
-      data => {
-        return JSON.parse(data);
-      },
-      () => {
-        let title = Strings.browser.GetStringFromName(
-          "remoteQRScanFailedPromptTitle"
-        );
-        let msg = Strings.browser.GetStringFromName(
-          "remoteQRScanFailedPromptMessage"
-        );
-        let ok = Strings.browser.GetStringFromName(
-          "remoteQRScanFailedPromptOK"
-        );
-        let prompt = new Prompt({
-          window: null,
-          hint: "remotedebug",
-          title: title,
-          message: msg,
-          buttons: [ok],
-          priority: 1,
-        });
-        prompt.show();
-      }
-    );
-
-    this._receivingOOB.then(() => (this._receivingOOB = null));
-
-    return this._receivingOOB;
-  },
-
-  initServer: function() {
-    DebuggerServer.init();
-
-    // Add browser and Fennec specific actors
-    DebuggerServer.registerAllActors();
-    const {
-      createRootActor,
-    } = require("resource://gre/modules/dbg-browser-actors.js");
-    DebuggerServer.setRootActor(createRootActor);
-
-    // Allow debugging of chrome for any process
-    DebuggerServer.allowChromeProcess = true;
-    DebuggerServer.chromeWindowType = this._windowType;
-    // Force the Server to stay alive even if there are no connections at the moment.
-    DebuggerServer.keepAlive = true;
-  },
-};
-
-RemoteDebugger.allowConnection = RemoteDebugger.allowConnection.bind(
-  RemoteDebugger
-);
-RemoteDebugger.receiveOOB = RemoteDebugger.receiveOOB.bind(RemoteDebugger);
-
-var USBRemoteDebugger = {
-  init() {
-    Services.prefs.addObserver("devtools.", this);
-
-    if (this.isEnabled) {
-      this.start();
-    }
-  },
-
-  observe(subject, topic, data) {
-    if (topic != "nsPref:changed") {
-      return;
-    }
-
-    switch (data) {
-      case "devtools.remote.usb.enabled":
-        Services.prefs.setBoolPref(
-          "devtools.debugger.remote-enabled",
-          RemoteDebugger.isAnyEnabled
-        );
-        if (this.isEnabled) {
-          this.start();
-        } else {
-          this.stop();
-        }
-        break;
-
-      case "devtools.debugger.remote-port":
-      case "devtools.debugger.unix-domain-socket":
-        if (this.isEnabled) {
-          this.stop();
-          this.start();
-        }
-        break;
-    }
-  },
-
-  get isEnabled() {
-    return Services.prefs.getBoolPref("devtools.remote.usb.enabled");
-  },
-
-  start: function() {
-    if (this._listener) {
-      return;
-    }
-
-    RemoteDebugger.initServer();
-
-    const portOrPath =
-      Services.prefs.getCharPref("devtools.debugger.unix-domain-socket") ||
-      Services.prefs.getIntPref("devtools.debugger.remote-port");
-
-    try {
-      dump("Starting USB debugger on " + portOrPath);
-      const AuthenticatorType = DebuggerServer.Authenticators.get("PROMPT");
-      const authenticator = new AuthenticatorType.Server();
-      authenticator.allowConnection = RemoteDebugger.allowConnection;
-      const socketOptions = { authenticator, portOrPath };
-      this._listener = new SocketListener(DebuggerServer, socketOptions);
-      this._listener.open();
-    } catch (e) {
-      dump("Unable to start USB debugger server: " + e);
-    }
-  },
-
-  stop: function() {
-    if (!this._listener) {
-      return;
-    }
-
-    try {
-      this._listener.close();
-      this._listener = null;
-    } catch (e) {
-      dump("Unable to stop USB debugger server: " + e);
-    }
-  },
-};
-
-var WiFiRemoteDebugger = {
-  init() {
-    Services.prefs.addObserver("devtools.", this);
-
-    if (this.isEnabled) {
-      this.start();
-    }
-  },
-
-  observe(subject, topic, data) {
-    if (topic != "nsPref:changed") {
-      return;
-    }
-
-    switch (data) {
-      case "devtools.remote.wifi.enabled":
-        Services.prefs.setBoolPref(
-          "devtools.debugger.remote-enabled",
-          RemoteDebugger.isAnyEnabled
-        );
-        // Allow remote debugging on non-local interfaces when WiFi debug is
-        // enabled
-        // TODO: Bug 1034411: Lock down to WiFi interface only
-        Services.prefs.setBoolPref(
-          "devtools.debugger.force-local",
-          !this.isEnabled
-        );
-        if (this.isEnabled) {
-          this.start();
-        } else {
-          this.stop();
-        }
-        break;
-    }
-  },
-
-  get isEnabled() {
-    return Services.prefs.getBoolPref("devtools.remote.wifi.enabled");
-  },
-
-  start: function() {
-    if (this._listener) {
-      return;
-    }
-
-    RemoteDebugger.initServer();
-
-    try {
-      dump("Starting WiFi debugger");
-      const AuthenticatorType = DebuggerServer.Authenticators.get("OOB_CERT");
-      const authenticator = new AuthenticatorType.Server();
-      authenticator.allowConnection = RemoteDebugger.allowConnection;
-      authenticator.receiveOOB = RemoteDebugger.receiveOOB;
-      const socketOptions = {
-        authenticator,
-        discoverable: true,
-        encryption: true,
-        portOrPath: -1,
-      };
-      this._listener = new SocketListener(DebuggerServer, socketOptions);
-      this._listener.open();
-      let port = this._listener.port;
-      dump("Started WiFi debugger on " + port);
-    } catch (e) {
-      dump("Unable to start WiFi debugger server: " + e);
-    }
-  },
-
-  stop: function() {
-    if (!this._listener) {
-      return;
-    }
-
-    try {
-      this._listener.close();
-      this._listener = null;
-    } catch (e) {
-      dump("Unable to stop WiFi debugger server: " + e);
-    }
-  },
-};
deleted file mode 100644
--- a/mobile/android/chrome/content/about.js
+++ /dev/null
@@ -1,147 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const {EventDispatcher} = ChromeUtils.import("resource://gre/modules/Messaging.jsm");
-const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-function init() {
-  // Include the build date and a warning about Telemetry
-  // if this is an "a#" (nightly or aurora) build
-#expand const version = "__MOZ_APP_VERSION_DISPLAY__";
-  if (/a\d+$/.test(version)) {
-    let buildID = Services.appinfo.appBuildID;
-    let buildDate = buildID.slice(0, 4) + "-" + buildID.slice(4, 6) + "-" + buildID.slice(6, 8);
-    let br = document.createElement("br");
-    let versionPara = document.getElementById("version");
-    versionPara.appendChild(br);
-    let date = document.createTextNode("(" + buildDate + ")");
-    versionPara.appendChild(date);
-    document.getElementById("telemetry").hidden = false;
-  }
-
-  // Include the Distribution information if available
-  try {
-    let distroId = Services.prefs.getCharPref("distribution.id");
-    if (distroId) {
-      let distroVersion = Services.prefs.getCharPref("distribution.version");
-      let distroIdField = document.getElementById("distributionID");
-      distroIdField.textContent = distroId + " - " + distroVersion;
-      distroIdField.hidden = false;
-
-      let distroAbout = Services.prefs.getStringPref("distribution.about");
-      let distroField = document.getElementById("distributionAbout");
-      distroField.textContent = distroAbout;
-      distroField.hidden = false;
-    }
-  } catch (e) {
-    // Pref is unset
-  }
-
-  // get URLs from prefs
-  try {
-    let formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter);
-
-    let links = [
-      {id: "releaseNotesURL", pref: "app.releaseNotesURL"},
-      {id: "supportURL",      pref: "app.supportURL"},
-      {id: "faqURL",          pref: "app.faqURL"},
-      {id: "privacyURL",      pref: "app.privacyURL"},
-      {id: "creditsURL",      pref: "app.creditsURL"},
-    ];
-
-    links.forEach(function(link) {
-      let url = formatter.formatURLPref(link.pref);
-      let element = document.getElementById(link.id);
-      if (element) {
-        element.setAttribute("href", url);
-      }
-    });
-  } catch (ex) {}
-
-#ifdef MOZ_UPDATER
-  function expectUpdateResult() {
-    EventDispatcher.instance.registerListener(function listener(event, data, callback) {
-      EventDispatcher.instance.unregisterListener(listener, event);
-      showUpdateMessage(data.result);
-    }, "Update:CheckResult");
-  }
-
-  function checkForUpdates() {
-    showCheckingMessage();
-    expectUpdateResult();
-
-    EventDispatcher.instance.sendRequest({ type: "Update:Check" });
-  }
-
-  function downloadUpdate() {
-    expectUpdateResult();
-
-    EventDispatcher.instance.sendRequest({ type: "Update:Download" });
-  }
-
-  function installUpdate() {
-    showCheckAction();
-
-    EventDispatcher.instance.sendRequest({ type: "Update:Install" });
-  }
-
-  let updateLink = document.getElementById("updateLink");
-  let checkingSpan = document.getElementById("update-message-checking");
-  let noneSpan = document.getElementById("update-message-none");
-  let foundSpan = document.getElementById("update-message-found");
-  let downloadingSpan = document.getElementById("update-message-downloading");
-  let downloadedSpan = document.getElementById("update-message-downloaded");
-
-  updateLink.onclick = checkForUpdates;
-  foundSpan.onclick = downloadUpdate;
-  downloadedSpan.onclick = installUpdate;
-
-  function showCheckAction() {
-    checkingSpan.style.display = "none";
-    noneSpan.style.display = "none";
-    foundSpan.style.display = "none";
-    downloadingSpan.style.display = "none";
-    downloadedSpan.style.display = "none";
-    updateLink.style.display = "block";
-  }
-
-  function showCheckingMessage() {
-    updateLink.style.display = "none";
-    noneSpan.style.display = "none";
-    foundSpan.style.display = "none";
-    downloadingSpan.style.display = "none";
-    downloadedSpan.style.display = "none";
-    checkingSpan.style.display = "block";
-  }
-
-  function showUpdateMessage(aResult) {
-    updateLink.style.display = "none";
-    checkingSpan.style.display = "none";
-    noneSpan.style.display = "none";
-    foundSpan.style.display = "none";
-    downloadingSpan.style.display = "none";
-    downloadedSpan.style.display = "none";
-
-    // the aResult values come from mobile/android/base/UpdateServiceHelper.java
-    switch (aResult) {
-      case "NOT_AVAILABLE":
-        noneSpan.style.display = "block";
-        setTimeout(showCheckAction, 2000);
-        break;
-      case "AVAILABLE":
-        foundSpan.style.display = "block";
-        break;
-      case "DOWNLOADING":
-        downloadingSpan.style.display = "block";
-        expectUpdateResult();
-        break;
-      case "DOWNLOADED":
-        downloadedSpan.style.display = "block";
-        break;
-    }
-  }
-#endif
-}
-
-document.addEventListener("DOMContentLoaded", init);
deleted file mode 100644
--- a/mobile/android/chrome/content/about.xhtml
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!DOCTYPE html [
-<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
-%brandDTD;
-<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
-%globalDTD;
-<!ENTITY % fennecDTD SYSTEM "chrome://browser/locale/about.dtd">
-%fennecDTD;
-]>
-
-<!-- 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/. -->
-
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-  <meta name="viewport" content="width=480; initial-scale=.6667; user-scalable=no"/>
-  <title>&aboutPage.title;</title>
-  <link rel="stylesheet" href="chrome://browser/skin/aboutPage.css" type="text/css"/>
-  <link rel="icon" type="image/png" sizes="64x64" href="chrome://branding/content/favicon64.png" />
-</head>
-
-<body dir="&locale.dir;">
-  <div id="header" dir="ltr">
-    <div id="wordmark"></div>
-#expand <p id="version">__MOZ_APP_VERSION_DISPLAY__</p>
-  </div>
-
-  <div id="banner">
-    <div id="logo"/>
-#ifdef MOZ_UPDATER
-    <div id="updateBox">
-      <a id="updateLink" href="">&aboutPage.checkForUpdates.link;</a>
-      <span id="update-message-checking">&aboutPage.checkForUpdates.checking;</span>
-      <span id="update-message-none">&aboutPage.checkForUpdates.none;</span>
-      <span id="update-message-found">&aboutPage.checkForUpdates.available2;</span>
-      <span id="update-message-downloading">&aboutPage.checkForUpdates.downloading;</span>
-      <span id="update-message-downloaded">&aboutPage.checkForUpdates.downloaded2;</span>
-    </div>
-#endif
-
-    <div id="messages">
-      <p id="distributionAbout" hidden="true"/>
-      <p id="distributionID" hidden="true"/>
-      <p id="telemetry" hidden="true">
-        &aboutPage.warningVersion;
-      </p>
-    </div>
-
-  </div>
-
-    <ul id="aboutLinks">
-      <div class="top-border"></div>
-      <li><a id="faqURL">&aboutPage.faq.label;</a></li>
-      <li><a id="supportURL">&aboutPage.support.label;</a></li>
-      <li><a id="privacyURL">&aboutPage.privacyPolicy.label;</a></li>
-      <li><a href="about:rights">&aboutPage.rights.label;</a></li>
-#ifndef NIGHTLY_BUILD
-#ifndef FENNEC_NIGHTLY
-      <li><a id="releaseNotesURL">&aboutPage.relNotes.label;</a></li>
-#endif
-#endif
-      <li><a id="creditsURL">&aboutPage.credits.label;</a></li>
-      <li><a href="about:license">&aboutPage.license.label;</a></li>
-      <div class="bottom-border"></div>
-    </ul>
-
-#ifdef RELEASE_OR_BETA
-#ifndef FENNEC_NIGHTLY
-    <div id="aboutDetails">
-      <p>&aboutPage.logoTrademark;</p>
-    </div>
-#endif
-#endif
-
-    <script type="application/javascript" src="chrome://browser/content/about.js" />
-
-</body>
-</html>
deleted file mode 100644
--- a/mobile/android/chrome/content/aboutAccounts.js
+++ /dev/null
@@ -1,377 +0,0 @@
-// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
-/* 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/. */
-
-/**
- * Wrap a remote fxa-content-server.
- *
- * An about:accounts tab loads and displays an fxa-content-server page,
- * depending on the current Android Account status and an optional 'action'
- * parameter.
- *
- * We show a spinner while the remote iframe is loading.  We expect the
- * WebChannel message listening to the fxa-content-server to send this tab's
- * <browser>'s messageManager a LOADED message when the remote iframe provides
- * the WebChannel LOADED message.  See the messageManager registration and the
- * |loadedDeferred| promise.  This loosely couples the WebChannel implementation
- * and about:accounts!  (We need this coupling in order to distinguish
- * WebChannel LOADED messages produced by multiple about:accounts tabs.)
- *
- * We capture error conditions by accessing the inner nsIWebNavigation of the
- * iframe directly.
- */
-
-"use strict";
-
-const { Accounts } = ChromeUtils.import("resource://gre/modules/Accounts.jsm");
-const { PromiseUtils } = ChromeUtils.import(
-  "resource://gre/modules/PromiseUtils.jsm"
-);
-const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { XPCOMUtils } = ChromeUtils.import(
-  "resource://gre/modules/XPCOMUtils.jsm"
-);
-
-const ACTION_URL_PARAM = "action";
-
-const COMMAND_LOADED = "fxaccounts:loaded";
-
-const log = ChromeUtils.import(
-  "resource://gre/modules/AndroidLog.jsm",
-  {}
-).AndroidLog.bind("FxAccounts");
-
-XPCOMUtils.defineLazyServiceGetter(
-  this,
-  "ParentalControls",
-  "@mozilla.org/parental-controls-service;1",
-  "nsIParentalControlsService"
-);
-
-// Shows the toplevel element with |id| to be shown - all other top-level
-// elements are hidden.
-// If |id| is 'spinner', then 'remote' is also shown, with opacity 0.
-function show(id) {
-  let allTop = document.querySelectorAll(".toplevel");
-  for (let elt of allTop) {
-    if (elt.getAttribute("id") == id) {
-      elt.style.display = "block";
-    } else {
-      elt.style.display = "none";
-    }
-  }
-  if (id == "spinner") {
-    document.getElementById("remote").style.display = "block";
-    document.getElementById("remote").style.opacity = 0;
-  }
-}
-
-// Each time we try to load the remote <iframe>, loadedDeferred is replaced.  It
-// is resolved by a LOADED message, and rejected by a failure to load.
-var loadedDeferred = null;
-
-// We have a new load starting.  Replace the existing promise with a new one,
-// and queue up the transition to remote content.
-function deferTransitionToRemoteAfterLoaded() {
-  log.d("Waiting for LOADED message.");
-
-  loadedDeferred = PromiseUtils.defer();
-  loadedDeferred.promise
-    .then(() => {
-      log.d("Got LOADED message!");
-      document.getElementById("remote").style.opacity = 0;
-      show("remote");
-      document.getElementById("remote").style.opacity = 1;
-    })
-    .catch(e => {
-      log.w("Did not get LOADED message: " + e.toString());
-    });
-}
-
-function handleLoadedMessage(message) {
-  loadedDeferred.resolve();
-}
-
-var wrapper = {
-  iframe: null,
-
-  url: null,
-
-  init: function(url) {
-    this.url = url;
-    deferTransitionToRemoteAfterLoaded();
-
-    let iframe = document.getElementById("remote");
-    this.iframe = iframe;
-    let docShell = this.iframe.frameLoader.docShell;
-    docShell.QueryInterface(Ci.nsIWebProgress);
-    docShell.addProgressListener(
-      this.iframeListener,
-      Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT |
-        Ci.nsIWebProgress.NOTIFY_LOCATION
-    );
-
-    // Set the iframe's location with loadURI/LOAD_FLAGS_BYPASS_HISTORY to
-    // avoid having a new history entry being added.
-    let webNav = iframe.frameLoader.docShell.QueryInterface(
-      Ci.nsIWebNavigation
-    );
-    let loadURIOptions = {
-      triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
-      loadFlags: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY,
-    };
-    webNav.loadURI(url, loadURIOptions);
-  },
-
-  retry: function() {
-    deferTransitionToRemoteAfterLoaded();
-
-    let webNav = this.iframe.frameLoader.docShell.QueryInterface(
-      Ci.nsIWebNavigation
-    );
-    let loadURIOptions = {
-      triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
-      loadFlags: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY,
-    };
-    webNav.loadURI(this.url, loadURIOptions);
-  },
-
-  iframeListener: {
-    QueryInterface: ChromeUtils.generateQI([
-      Ci.nsIWebProgressListener,
-      Ci.nsISupportsWeakReference,
-    ]),
-
-    onStateChange: function(aWebProgress, aRequest, aState, aStatus) {
-      let failure = false;
-
-      // Captive portals sometimes redirect users
-      if (aState & Ci.nsIWebProgressListener.STATE_REDIRECTING) {
-        failure = true;
-      } else if (aState & Ci.nsIWebProgressListener.STATE_STOP) {
-        if (aRequest instanceof Ci.nsIHttpChannel) {
-          try {
-            failure = aRequest.responseStatus != 200;
-          } catch (e) {
-            failure = aStatus != Cr.NS_OK;
-          }
-        }
-      }
-
-      // Calling cancel() will raise some OnStateChange notifications by itself,
-      // so avoid doing that more than once
-      if (failure && aStatus != Cr.NS_BINDING_ABORTED) {
-        aRequest.cancel(Cr.NS_BINDING_ABORTED);
-        // Since after a promise is fulfilled, subsequent fulfillments are
-        // treated as no-ops, we don't care that we might see multiple failures
-        // due to multiple listener callbacks.  (It's not easy to extract this
-        // from the Promises spec, but it is widely quoted.  Start with
-        // http://stackoverflow.com/a/18218542.)
-        loadedDeferred.reject(new Error("Failed in onStateChange!"));
-        show("networkError");
-      }
-    },
-
-    onLocationChange: function(aWebProgress, aRequest, aLocation, aFlags) {
-      if (
-        aRequest &&
-        aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE
-      ) {
-        aRequest.cancel(Cr.NS_BINDING_ABORTED);
-        // As above, we're not concerned by multiple listener callbacks.
-        loadedDeferred.reject(new Error("Failed in onLocationChange!"));
-        show("networkError");
-      }
-    },
-  },
-};
-
-function retry() {
-  log.i("Retrying.");
-  show("spinner");
-  wrapper.retry();
-}
-
-function openPrefs() {
-  log.i("Opening Sync preferences.");
-  // If an Android Account exists, this will open the Status Activity.
-  // Otherwise, it will begin the Get Started flow.  This should only be shown
-  // when an Account actually exists.
-  Accounts.launchSetup();
-}
-
-function getURLForAction(action, urlParams) {
-  let url = Services.urlFormatter.formatURLPref(
-    "identity.fxaccounts.remote.webchannel.uri"
-  );
-  url = url + (url.endsWith("/") ? "" : "/") + action;
-  const CONTEXT = "fx_fennec_v1";
-  // The only service managed by Fennec, to date, is Firefox Sync.
-  const SERVICE = "sync";
-  urlParams = urlParams || new URLSearchParams("");
-  urlParams.set("service", SERVICE);
-  urlParams.set("context", CONTEXT);
-  // Ideally we'd just merge urlParams with new URL(url).searchParams, but our
-  // URLSearchParams implementation doesn't support iteration (bug 1085284).
-  let urlParamStr = urlParams.toString();
-  if (urlParamStr) {
-    url += (url.includes("?") ? "&" : "?") + urlParamStr;
-  }
-  return url;
-}
-
-function updateDisplayedEmail(user) {
-  let emailDiv = document.getElementById("email");
-  if (emailDiv && user) {
-    emailDiv.textContent = user.email;
-  }
-}
-
-function init() {
-  // Test for restrictions before getFirefoxAccount(), since that will fail if
-  // we are restricted.
-  if (!ParentalControls.isAllowed(ParentalControls.MODIFY_ACCOUNTS)) {
-    // It's better to log and show an error message than to invite user
-    // confusion by removing about:accounts entirely.  That is, if the user is
-    // restricted, this way they'll discover as much and may be able to get
-    // out of their restricted profile.  If we remove about:accounts entirely,
-    // it will look like Fennec is buggy, and the user will be very confused.
-    log.e(
-      "This profile cannot connect to Firefox Accounts: showing restricted error."
-    );
-    show("restrictedError");
-    return;
-  }
-
-  Accounts.getFirefoxAccount()
-    .then(user => {
-      // It's possible for the window to start closing before getting the user
-      // completes.  Tests in particular can cause this.
-      if (window.closed) {
-        return;
-      }
-
-      updateDisplayedEmail(user);
-
-      // Ideally we'd use new URL(document.URL).searchParams, but for about: URIs,
-      // searchParams is empty.
-      let urlParams = new URLSearchParams(document.URL.split("?")[1] || "");
-      let action = urlParams.get(ACTION_URL_PARAM);
-      urlParams.delete(ACTION_URL_PARAM);
-
-      switch (action) {
-        case "signup":
-          if (user) {
-            // Asking to sign-up when already signed in just shows prefs.
-            show("prefs");
-          } else {
-            show("spinner");
-            wrapper.init(getURLForAction("signup", urlParams));
-          }
-          break;
-        case "signin":
-          if (user) {
-            // Asking to sign-in when already signed in just shows prefs.
-            show("prefs");
-          } else {
-            show("spinner");
-            wrapper.init(getURLForAction("signin", urlParams));
-          }
-          break;
-        case "force_auth":
-          if (user) {
-            show("spinner");
-            urlParams.set("email", user.email); // In future, pin using the UID.
-            wrapper.init(getURLForAction("force_auth", urlParams));
-          } else {
-            show("spinner");
-            wrapper.init(getURLForAction("signup", urlParams));
-          }
-          break;
-        case "manage":
-          if (user) {
-            show("spinner");
-            urlParams.set("email", user.email); // In future, pin using the UID.
-            wrapper.init(getURLForAction("settings", urlParams));
-          } else {
-            show("spinner");
-            wrapper.init(getURLForAction("signup", urlParams));
-          }
-          break;
-        case "avatar":
-          if (user) {
-            show("spinner");
-            urlParams.set("email", user.email); // In future, pin using the UID.
-            wrapper.init(getURLForAction("settings/avatar/change", urlParams));
-          } else {
-            show("spinner");
-            wrapper.init(getURLForAction("signup", urlParams));
-          }
-          break;
-        default:
-          // Unrecognized or no action specified.
-          if (action) {
-            log.w("Ignoring unrecognized action: " + action);
-          }
-          if (user) {
-            show("prefs");
-          } else {
-            show("spinner");
-            wrapper.init(getURLForAction("signup", urlParams));
-          }
-          break;
-      }
-    })
-    .catch(e => {
-      log.e("Failed to get the signed in user: " + e.toString());
-    });
-}
-
-document.addEventListener(
-  "DOMContentLoaded",
-  function() {
-    init();
-    var buttonRetry = document.getElementById("buttonRetry");
-    buttonRetry.addEventListener("click", retry);
-
-    var buttonOpenPrefs = document.getElementById("buttonOpenPrefs");
-    buttonOpenPrefs.addEventListener("click", openPrefs);
-  },
-  { capture: true, once: true }
-);
-
-// This window is contained in a XUL <browser> element.  Return the
-// messageManager of that <browser> element, or null.
-function getBrowserMessageManager() {
-  let browser = window.docShell.rootTreeItem.domWindow.BrowserApp.getBrowserForDocument(
-    document
-  );
-  if (browser) {
-    return browser.messageManager;
-  }
-  return null;
-}
-
-// Add a single listener for 'loaded' messages from the iframe in this
-// <browser>.  These 'loaded' messages are ferried from the WebChannel to just
-// this <browser>.
-var mm = getBrowserMessageManager();
-if (mm) {
-  mm.addMessageListener(COMMAND_LOADED, handleLoadedMessage);
-} else {
-  log.e("No messageManager, not listening for LOADED message!");
-}
-
-window.addEventListener("unload", function(event) {
-  try {
-    let mm = getBrowserMessageManager();
-    if (mm) {
-      mm.removeMessageListener(COMMAND_LOADED, handleLoadedMessage);
-    }
-  } catch (e) {
-    // This could fail if the page is being torn down, the tab is being
-    // destroyed, etc.
-    log.w("Not removing listener for LOADED message: " + e.toString());
-  }
-});
deleted file mode 100644
--- a/mobile/android/chrome/content/aboutAccounts.xhtml
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - License, v. 2.0. If a copy of the MPL was not distributed with this
-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
-  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" [
-<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
-%brandDTD;
-<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd" >
-%globalDTD;
-<!ENTITY % aboutDTD SYSTEM "chrome://browser/locale/aboutAccounts.dtd">
-%aboutDTD;
-]>
-
-<html xmlns="http://www.w3.org/1999/xhtml" dir="&locale.dir;">
-  <head>
-    <title>Firefox Sync</title>
-    <meta name="viewport" content="width=device-width; user-scalable=0" />
-    <link rel="icon" type="image/png" sizes="64x64" href="chrome://branding/content/favicon64.png" />
-    <link rel="stylesheet" href="chrome://browser/skin/spinner.css" type="text/css"/>
-    <link rel="stylesheet" href="chrome://browser/skin/aboutBase.css" type="text/css"/>
-    <link rel="stylesheet" href="chrome://browser/skin/aboutAccounts.css" type="text/css"/>
-  </head>
-  <body>
-    <div id="spinner" class="toplevel">
-      <div class="container flex-column">
-        <!-- Empty text-container for spacing. -->
-        <div class="text-container flex-column" />
-
-          <div class="mui-refresh-main">
-            <div class="mui-refresh-wrapper">
-              <div class="mui-spinner-wrapper">
-                <div class="mui-spinner-main">
-                  <div class="mui-spinner-left">
-                    <div class="mui-half-circle-left" />
-                  </div>
-                  <div class="mui-spinner-right">
-                    <div class="mui-half-circle-right" />
-                  </div>
-                </div>
-              </div>
-            </div>
-          </div>
-
-      </div>
-    </div>
-
-    <iframe mozframetype="content" id="remote" class="toplevel" />
-
-    <div id="prefs" class="toplevel">
-      <div class="container flex-column">
-        <div class="text-container flex-column">
-          <div class="text">&aboutAccounts.connected.title;</div>
-          <div class="hint">&aboutAccounts.connected.description;</div>
-          <div id="email" class="hint"></div>
-        </div>
-        <a id="buttonOpenPrefs" tabindex="0" href="#">&aboutAccounts.syncPreferences.label;</a>
-      </div>
-    </div>
-
-    <div id="networkError" class="toplevel">
-      <div class="container flex-column">
-        <div class="text-container flex-column">
-          <div class="text">&aboutAccounts.noConnection.title;</div>
-        </div>
-        <div class="button-row">
-          <button id="buttonRetry" class="button" tabindex="1">&aboutAccounts.retry.label;</button>
-        </div>
-      </div>
-    </div>
-
-    <div id="restrictedError" class="toplevel">
-      <div class="container flex-column">
-        <div class="text-container flex-column">
-          <div class="text">&aboutAccounts.restrictedError.title;</div>
-          <div class="hint">&aboutAccounts.restrictedError.description;</div>
-        </div>
-      </div>
-    </div>
-
-    <script type="application/javascript" src="chrome://browser/content/aboutAccounts.js"></script>
-  </body>
-</html>
deleted file mode 100644
--- a/mobile/android/chrome/content/aboutAddons.js
+++ /dev/null
@@ -1,897 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-/* globals gChromeWin */
-
-const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { AddonManager } = ChromeUtils.import(
-  "resource://gre/modules/AddonManager.jsm"
-);
-const { XPCOMUtils } = ChromeUtils.import(
-  "resource://gre/modules/XPCOMUtils.jsm"
-);
-const { EventDispatcher } = ChromeUtils.import(
-  "resource://gre/modules/Messaging.jsm"
-);
-
-const AMO_ICON = "chrome://browser/skin/images/amo-logo.png";
-const UPDATE_INDICATOR = "chrome://browser/skin/images/extension-update.svg";
-
-var gStringBundle = Services.strings.createBundle(
-  "chrome://browser/locale/aboutAddons.properties"
-);
-
-XPCOMUtils.defineLazyGetter(window, "gChromeWin", function() {
-  return window.docShell.rootTreeItem.domWindow;
-});
-ChromeUtils.defineModuleGetter(
-  window,
-  "Preferences",
-  "resource://gre/modules/Preferences.jsm"
-);
-
-var ContextMenus = {
-  target: null,
-
-  init: function() {
-    document.addEventListener("contextmenu", this);
-
-    document
-      .getElementById("contextmenu-enable")
-      .addEventListener("click", ContextMenus.enable.bind(this));
-    document
-      .getElementById("contextmenu-disable")
-      .addEventListener("click", ContextMenus.disable.bind(this));
-    document
-      .getElementById("contextmenu-uninstall")
-      .addEventListener("click", ContextMenus.uninstall.bind(this));
-
-    // XXX - Hack to fix bug 985867 for now
-    document.addEventListener("touchstart", function() {});
-  },
-
-  handleEvent: function(event) {
-    // store the target of context menu events so that we know which app to act on
-    this.target = event.target;
-    while (!this.target.hasAttribute("contextmenu")) {
-      this.target = this.target.parentNode;
-    }
-
-    if (!this.target) {
-      document
-        .getElementById("contextmenu-enable")
-        .setAttribute("hidden", "true");
-      document
-        .getElementById("contextmenu-disable")
-        .setAttribute("hidden", "true");
-      document
-        .getElementById("contextmenu-uninstall")
-        .setAttribute("hidden", "true");
-      return;
-    }
-
-    let addon = this.target.addon;
-    if (addon.scope == AddonManager.SCOPE_APPLICATION) {
-      document
-        .getElementById("contextmenu-uninstall")
-        .setAttribute("hidden", "true");
-    } else {
-      document
-        .getElementById("contextmenu-uninstall")
-        .removeAttribute("hidden");
-    }
-
-    // Hide the enable/disable context menu items if the add-on was disabled by
-    // Firefox (e.g. unsigned or blocklisted add-on).
-    if (addon.appDisabled) {
-      document
-        .getElementById("contextmenu-enable")
-        .setAttribute("hidden", "true");
-      document
-        .getElementById("contextmenu-disable")
-        .setAttribute("hidden", "true");
-      return;
-    }
-
-    let enabled = this.target.getAttribute("isDisabled") != "true";
-    if (enabled) {
-      document
-        .getElementById("contextmenu-enable")
-        .setAttribute("hidden", "true");
-      document.getElementById("contextmenu-disable").removeAttribute("hidden");
-    } else {
-      document.getElementById("contextmenu-enable").removeAttribute("hidden");
-      document
-        .getElementById("contextmenu-disable")
-        .setAttribute("hidden", "true");
-    }
-  },
-
-  enable: function(event) {
-    Addons.setEnabled(true, this.target.addon);
-    this.target = null;
-  },
-
-  disable: function(event) {
-    Addons.setEnabled(false, this.target.addon);
-    this.target = null;
-  },
-
-  uninstall: function(event) {
-    Addons.uninstall(this.target.addon);
-    this.target = null;
-  },
-};
-
-function sendEMPong() {
-  Services.obs.notifyObservers(window, "EM-pong");
-}
-
-async function init() {
-  window.addEventListener("popstate", onPopState);
-
-  AddonManager.addInstallListener(Addons);
-  AddonManager.addAddonListener(Addons);
-
-  await Addons.init();
-  showAddons();
-  ContextMenus.init();
-
-  Services.obs.addObserver(sendEMPong, "EM-ping");
-
-  // The addons list has been loaded and rendered, send a notification
-  // if the openOptionsPage is waiting to be able to select an addon details page.
-  Services.obs.notifyObservers(window, "EM-loaded");
-}
-
-function uninit() {
-  AddonManager.removeInstallListener(Addons);
-  AddonManager.removeAddonListener(Addons);
-
-  Services.obs.removeObserver(sendEMPong, "EM-ping");
-}
-
-function openLink(url) {
-  let BrowserApp = gChromeWin.BrowserApp;
-  BrowserApp.addTab(url, {
-    selected: true,
-    parentId: BrowserApp.selectedTab.id,
-  });
-}
-
-function openOptionsInTab(url) {
-  let BrowserApp = gChromeWin.BrowserApp;
-  BrowserApp.selectOrAddTab(url, {
-    startsWith: true,
-    selected: true,
-    parentId: BrowserApp.selectedTab.id,
-  });
-}
-
-function onPopState(aEvent) {
-  // Called when back/forward is used to change the state of the page
-  if (aEvent.state) {
-    // Show the detail page for an addon
-    const listItem = Addons._getElementForAddon(aEvent.state.id);
-    if (listItem) {
-      Addons.showDetails(listItem);
-    } else {
-      // If the addon doesn't exist anymore, go back in the history.
-      history.back();
-    }
-  } else {
-    // Clear any previous detail addon
-    let detailItem = document.querySelector("#addons-details > .addon-item");
-    detailItem.addon = null;
-
-    showAddons();
-  }
-}
-
-function showAddonDetails(addonId) {
-  const listItem = Addons._getElementForAddon(addonId);
-  if (listItem) {
-    Addons.showDetails(listItem);
-    history.pushState({ id: addonId }, document.title);
-  } else {
-    throw new Error(`Addon not found: ${addonId}`);
-  }
-}
-
-function showAddons() {
-  // Hide the addon options and show the addons list
-  let details = document.querySelector("#addons-details");
-  details.classList.add("hidden");
-  let list = document.querySelector("#addons-list");
-  list.classList.remove("hidden");
-  document.documentElement.removeAttribute("details");
-
-  // Clean the optionsBox content when switching to the add-ons list view.
-  let optionsBox = document.querySelector(
-    "#addons-details > .addon-item .options-box"
-  );
-  optionsBox.innerHTML = "";
-}
-
-function showAddonOptions() {
-  // Hide the addon list and show the addon options
-  let list = document.querySelector("#addons-list");
-  list.classList.add("hidden");
-  let details = document.querySelector("#addons-details");
-  details.classList.remove("hidden");
-  document.documentElement.setAttribute("details", "true");
-}
-
-var Addons = {
-  _restartCount: 0,
-
-  _createItem: function _createItem(aAddon) {
-    let outer = document.createElement("div");
-    outer.setAttribute("addonID", aAddon.id);
-    outer.className = "addon-item list-item";
-    outer.setAttribute("role", "button");
-    outer.setAttribute("contextmenu", "addonmenu");
-    outer.addEventListener(
-      "click",
-      () => {
-        this.showDetails(outer);
-        history.pushState({ id: aAddon.id }, document.title);
-      },
-      true
-    );
-
-    let img = document.createElement("img");
-    img.className = "icon";
-    img.setAttribute("src", aAddon.iconURL || AMO_ICON);
-    outer.appendChild(img);
-
-    let inner = document.createElement("div");
-    inner.className = "inner";
-
-    let details = document.createElement("div");
-    details.className = "details";
-    inner.appendChild(details);
-
-    let titlePart = document.createElement("div");
-    titlePart.textContent = aAddon.name;
-    titlePart.className = "title";
-    details.appendChild(titlePart);
-
-    let versionPart = document.createElement("div");
-    versionPart.textContent = aAddon.version;
-    versionPart.className = "version";
-    details.appendChild(versionPart);
-
-    if ("description" in aAddon) {
-      let descPart = document.createElement("div");
-      descPart.textContent = aAddon.description;
-      descPart.className = "description";
-      inner.appendChild(descPart);
-    }
-
-    outer.appendChild(inner);
-
-    let update = document.createElement("img");
-    update.className = "update-indicator";
-    update.setAttribute("src", UPDATE_INDICATOR);
-    outer.appendChild(update);
-
-    return outer;
-  },
-
-  _createBrowseItem: function _createBrowseItem() {
-    let outer = document.createElement("div");
-    outer.className = "addon-item list-item";
-    outer.setAttribute("role", "button");
-    outer.addEventListener(
-      "click",
-      function(event) {
-        try {
-          openLink(
-            Services.urlFormatter.formatURLPref(
-              "extensions.getAddons.browseAddons"
-            )
-          );
-        } catch (e) {
-          Cu.reportError(e);
-        }
-      },
-      true
-    );
-
-    let img = document.createElement("img");
-    img.className = "icon";
-    img.setAttribute("src", AMO_ICON);
-    outer.appendChild(img);
-
-    let inner = document.createElement("div");
-    inner.className = "inner";
-
-    let title = document.createElement("div");
-    title.id = "browse-title";
-    title.className = "title";
-    title.textContent = this._getAmoTitle();
-    inner.appendChild(title);
-
-    outer.appendChild(inner);
-    return outer;
-  },
-
-  // Ensure we get a localized string by using the previous title as a fallback
-  // if the new one has not yet been translated.
-  _getAmoTitle: function _getAmoTitle() {
-    const initialTitleUS = "Browse all Firefox Add-ons";
-    const updatedTitleUS = "Browse Firefox’s Recommended Extensions";
-    const initialTitleLocalized = gStringBundle.GetStringFromName(
-      "addons.browseAll"
-    );
-    const updatedTitleLocalized = gStringBundle.GetStringFromName(
-      "addons.browseRecommended"
-    );
-    let title = initialTitleLocalized;
-
-    const titleWasLocalized = updatedTitleLocalized !== updatedTitleUS;
-    const localeIsDefaultUS =
-      updatedTitleLocalized === updatedTitleUS &&
-      initialTitleLocalized === initialTitleUS;
-
-    if (titleWasLocalized || localeIsDefaultUS) {
-      title = updatedTitleLocalized;
-    }
-
-    EventDispatcher.instance.dispatch("about:addons", { amoTitle: title });
-    return title;
-  },
-
-  _createItemForAddon: function _createItemForAddon(aAddon) {
-    let opType = this._getOpTypeForOperations(aAddon.pendingOperations);
-    let hasUpdate = this._addonHasUpdate(aAddon);
-
-    let optionsURL = aAddon.optionsURL || "";
-
-    let blocked = "";
-    switch (aAddon.blocklistState) {
-      case Ci.nsIBlocklistService.STATE_BLOCKED:
-        blocked = "blocked";
-        break;
-      case Ci.nsIBlocklistService.STATE_SOFTBLOCKED:
-        blocked = "softBlocked";
-        break;
-      case Ci.nsIBlocklistService.STATE_OUTDATED:
-        blocked = "outdated";
-        break;
-    }
-
-    let item = this._createItem(aAddon);
-    item.setAttribute("isDisabled", !aAddon.isActive);
-    item.setAttribute(
-      "isUnsigned",
-      aAddon.signedState <= AddonManager.SIGNEDSTATE_MISSING
-    );
-    item.setAttribute("opType", opType);
-    if (blocked) {
-      item.setAttribute("blockedStatus", blocked);
-    }
-    item.setAttribute("optionsURL", optionsURL);
-    item.setAttribute("hasUpdate", hasUpdate);
-    item.addon = aAddon;
-
-    return item;
-  },
-
-  _getElementForAddon: function(aKey) {
-    let list = document.getElementById("addons-list");
-    let element = list.querySelector('div[addonID="' + CSS.escape(aKey) + '"]');
-    return element;
-  },
-
-  _addonHasUpdate(addon) {
-    return gChromeWin.ExtensionPermissions.updates.has(addon.id);
-  },
-
-  init: async function init() {
-    const aAddons = await AddonManager.getAllAddons();
-
-    // Clear all content before filling the addons
-    let list = document.getElementById("addons-list");
-    list.innerHTML = "";
-
-    aAddons.sort(function(a, b) {
-      return a.name.localeCompare(b.name);
-    });
-
-    for (let i = 0; i < aAddons.length; i++) {
-      // Don't create item for system add-ons.
-      if (aAddons[i].isSystem) {
-        continue;
-      }
-
-      let item = this._createItemForAddon(aAddons[i]);
-      list.appendChild(item);
-    }
-
-    // Add a "Browse all Firefox Add-ons" item to the bottom of the list.
-    let browseItem = this._createBrowseItem();
-    list.appendChild(browseItem);
-
-    document
-      .getElementById("update-btn")
-      .addEventListener("click", Addons.updateCurrent.bind(this));
-    document
-      .getElementById("uninstall-btn")
-      .addEventListener("click", Addons.uninstallCurrent.bind(this));
-    document
-      .getElementById("cancel-btn")
-      .addEventListener("click", Addons.cancelUninstall.bind(this));
-    document
-      .getElementById("disable-btn")
-      .addEventListener("click", Addons.disable.bind(this));
-    document
-      .getElementById("enable-btn")
-      .addEventListener("click", Addons.enable.bind(this));
-
-    document
-      .getElementById("unsigned-learn-more")
-      .addEventListener("click", function() {
-        openLink(
-          Services.urlFormatter.formatURLPref("app.support.baseURL") +
-            "unsigned-addons"
-        );
-      });
-  },
-
-  _getOpTypeForOperations: function _getOpTypeForOperations(aOperations) {
-    if (aOperations & AddonManager.PENDING_UNINSTALL) {
-      return "needs-uninstall";
-    }
-    if (aOperations & AddonManager.PENDING_ENABLE) {
-      return "needs-enable";
-    }
-    if (aOperations & AddonManager.PENDING_DISABLE) {
-      return "needs-disable";
-    }
-    return "";
-  },
-
-  showDetails: function showDetails(aListItem) {
-    let detailItem = document.querySelector("#addons-details > .addon-item");
-    detailItem.setAttribute("isDisabled", aListItem.getAttribute("isDisabled"));
-    detailItem.setAttribute("isUnsigned", aListItem.getAttribute("isUnsigned"));
-    detailItem.setAttribute("opType", aListItem.getAttribute("opType"));
-    detailItem.setAttribute("optionsURL", aListItem.getAttribute("optionsURL"));
-    let addon = (detailItem.addon = aListItem.addon);
-
-    let favicon = document.querySelector("#addons-details > .addon-item .icon");
-    favicon.setAttribute("src", addon.iconURL || AMO_ICON);
-
-    detailItem.querySelector(".title").textContent = addon.name;
-    detailItem.querySelector(".version").textContent = addon.version;
-    detailItem.querySelector(".description-full").textContent =
-      addon.description;
-    detailItem.querySelector(
-      ".status-uninstalled"
-    ).textContent = gStringBundle.formatStringFromName(
-      "addonStatus.uninstalled",
-      [addon.name]
-    );
-
-    let updateBtn = document.getElementById("update-btn");
-    if (this._addonHasUpdate(addon)) {
-      updateBtn.removeAttribute("hidden");
-    } else {
-      updateBtn.setAttribute("hidden", true);
-    }
-
-    let enableBtn = document.getElementById("enable-btn");
-    if (addon.appDisabled) {
-      enableBtn.setAttribute("disabled", "true");
-    } else {
-      enableBtn.removeAttribute("disabled");
-    }
-
-    let uninstallBtn = document.getElementById("uninstall-btn");
-    if (addon.scope == AddonManager.SCOPE_APPLICATION) {
-      uninstallBtn.setAttribute("disabled", "true");
-    } else {
-      uninstallBtn.removeAttribute("disabled");
-    }
-
-    let addonItem = document.querySelector("#addons-details > .addon-item");
-    let optionsBox = addonItem.querySelector(".options-box");
-    let optionsURL = aListItem.getAttribute("optionsURL");
-
-    // Always clean the options content before rendering the options of the
-    // newly selected extension.
-    optionsBox.innerHTML = "";
-
-    switch (parseInt(addon.optionsType)) {
-      case AddonManager.OPTIONS_TYPE_INLINE_BROWSER:
-        // Allow the options to use all the available width space.
-        optionsBox.classList.remove("inner");
-
-        this.createWebExtensionOptions(optionsBox, addon, addonItem);
-        break;
-      case AddonManager.OPTIONS_TYPE_TAB:
-        // Keep the usual layout for any options related the legacy (or system) add-ons
-        // when the options are opened in a new tab from a single button in the addon
-        // details page.
-        optionsBox.classList.add("inner");
-
-        this.createOptionsInTabButton(optionsBox, addon, addonItem);
-        break;
-    }
-
-    showAddonOptions();
-  },
-
-  createOptionsInTabButton: function(destination, addon, detailItem) {
-    let frame = destination.querySelector("iframe#addon-options");
-    let button = destination.querySelector("button#open-addon-options");
-
-    if (frame) {
-      // Remove any existent options frame (e.g. when the addon updates
-      // contains the open_in_tab options for the first time).
-
-      frame.remove();
-    }
-
-    if (!button) {
-      button = document.createElement("button");
-      button.setAttribute("id", "open-addon-options");
-      button.textContent = gStringBundle.GetStringFromName("addon.options");
-      destination.appendChild(button);
-    }
-
-    button.onclick = async () => {
-      if (addon.isWebExtension) {
-        // WebExtensions are loaded asynchronously and the optionsURL
-        // may not be available until the addon has been started.
-        await addon.startupPromise;
-      }
-
-      const { optionsURL } = addon;
-      openOptionsInTab(optionsURL);
-    };
-
-    // Ensure that the Addon Options are visible (the options box will be hidden if the optionsURL
-    // attribute is an empty string, which happens when a WebExtensions is still loading).
-    detailItem.removeAttribute("optionsURL");
-  },
-
-  createWebExtensionOptions: async function(destination, addon, detailItem) {
-    // WebExtensions are loaded asynchronously and the optionsURL
-    // may not be available until the addon has been started.
-    await addon.startupPromise;
-
-    const { optionsURL, optionsBrowserStyle } = addon;
-    let frame = destination.querySelector("iframe#addon-options");
-
-    if (!frame) {
-      let originalHeight;
-      frame = document.createElement("iframe");
-      frame.setAttribute("id", "addon-options");
-      frame.setAttribute("mozbrowser", "true");
-      frame.setAttribute("style", "width: 100%; overflow: hidden;");
-
-      // Adjust iframe height to the iframe content (also between navigation of multiple options
-      // files).
-      frame.onload = evt => {
-        if (evt.target !== frame) {
-          return;
-        }
-
-        const { document } = frame.contentWindow;
-        const bodyScrollHeight = document.body && document.body.scrollHeight;
-        const documentScrollHeight = document.documentElement.scrollHeight;
-
-        // Set the iframe height to the maximum between the body and the document
-        // scrollHeight values.
-        frame.style.height =
-          Math.max(bodyScrollHeight, documentScrollHeight) + "px";
-
-        // Restore the original iframe height between option page loads,
-        // so that we don't force the new document to have the same size
-        // of the previosuly loaded option page.
-        frame.contentWindow.addEventListener(
-          "unload",
-          () => {
-            frame.style.height = originalHeight + "px";
-          },
-          { once: true }
-        );
-      };
-
-      destination.appendChild(frame);
-      originalHeight = frame.getBoundingClientRect().height;
-    }
-
-    // Loading the URL this way prevents the native back
-    // button from applying to the iframe.
-    frame.contentWindow.location.replace(optionsURL);
-
-    // Ensure that the Addon Options are visible (the options box will be hidden if the optionsURL
-    // attribute is an empty string, which happens when a WebExtensions is still loading).
-    detailItem.removeAttribute("optionsURL");
-  },
-
-  setEnabled: function setEnabled(aValue, aAddon) {
-    let detailItem = document.querySelector("#addons-details > .addon-item");
-    let addon = aAddon || detailItem.addon;
-    if (!addon) {
-      return;
-    }
-
-    let listItem = this._getElementForAddon(addon.id);
-
-    function setDisabled(addon, value) {
-      if (value) {
-        return addon.disable();
-      }
-      return addon.enable();
-    }
-
-    function updateOtherThemeStateInUI(item) {
-      if (aValue) {
-        // Mark the previously enabled theme as disabled.
-        if (item.addon.isActive) {
-          item.setAttribute("isDisabled", true);
-          return true;
-        }
-        // The current theme is being disabled - enable the default theme.
-      } else if (item.addon.id == "default-theme@mozilla.org") {
-        item.removeAttribute("isDisabled");
-        return true;
-      }
-      return false;
-    }
-
-    let opType;
-    if (addon.type == "theme") {
-      // Themes take care of themselves to make sure only one is active at the
-      // same time, but we need to fix up the state of other themes in the UI.
-      let list = document.getElementById("addons-list");
-      let item = list.firstElementChild;
-      while (item) {
-        if (
-          item.addon &&
-          item.addon.type == "theme" &&
-          updateOtherThemeStateInUI(item)
-        ) {
-          break;
-        }
-        item = item.nextSibling;
-      }
-      setDisabled(addon, !aValue);
-    } else if (addon.type == "locale") {
-      setDisabled(addon, !aValue);
-    } else {
-      setDisabled(addon, !aValue);
-      opType = this._getOpTypeForOperations(addon.pendingOperations);
-
-      if (
-        addon.pendingOperations & AddonManager.PENDING_ENABLE ||
-        addon.pendingOperations & AddonManager.PENDING_DISABLE
-      ) {
-        this.showRestart();
-      } else if (
-        listItem &&
-        /needs-(enable|disable)/.test(listItem.getAttribute("opType"))
-      ) {
-        this.hideRestart();
-      }
-    }
-
-    if (addon == detailItem.addon) {
-      detailItem.setAttribute("isDisabled", !aValue);
-      if (opType) {
-        detailItem.setAttribute("opType", opType);
-      } else {
-        detailItem.removeAttribute("opType");
-      }
-
-      // Remove any addon options iframe if the currently selected addon has been disabled.
-      if (!aValue) {
-        const addonOptionsIframe = document.querySelector("#addon-options");
-        if (addonOptionsIframe) {
-          addonOptionsIframe.remove();
-        }
-      }
-    }
-
-    // Sync to the list item
-    if (listItem) {
-      listItem.setAttribute("isDisabled", !aValue);
-      if (opType) {
-        listItem.setAttribute("opType", opType);
-      } else {
-        listItem.removeAttribute("opType");
-      }
-    }
-  },
-
-  enable: function enable() {
-    this.setEnabled(true);
-  },
-
-  disable: function disable() {
-    this.setEnabled(false);
-  },
-
-  updateCurrent() {
-    let detailItem = document.querySelector("#addons-details > .addon-item");
-
-    let addon = detailItem.addon;
-    if (!addon) {
-      return;
-    }
-
-    gChromeWin.ExtensionPermissions.applyUpdate(addon.id);
-  },
-
-  uninstallCurrent: function uninstallCurrent() {
-    let detailItem = document.querySelector("#addons-details > .addon-item");
-
-    let addon = detailItem.addon;
-    if (!addon) {
-      return;
-    }
-
-    this.uninstall(addon);
-  },
-
-  uninstall: function uninstall(aAddon) {
-    if (!aAddon) {
-      return;
-    }
-
-    let listItem = this._getElementForAddon(aAddon.id);
-    aAddon.uninstall();
-
-    if (aAddon.pendingOperations & AddonManager.PENDING_UNINSTALL) {
-      this.showRestart();
-
-      // A disabled addon doesn't need a restart so it has no pending ops and
-      // can't be cancelled
-      let opType = this._getOpTypeForOperations(aAddon.pendingOperations);
-      if (!aAddon.isActive && opType == "") {
-        opType = "needs-uninstall";
-      }
-
-      detailItem.setAttribute("opType", opType);
-      listItem.setAttribute("opType", opType);
-    }
-  },
-
-  cancelUninstall: function ev_cancelUninstall() {
-    let detailItem = document.querySelector("#addons-details > .addon-item");
-    let addon = detailItem.addon;
-    if (!addon) {
-      return;
-    }
-
-    addon.cancelUninstall();
-    this.hideRestart();
-
-    let opType = this._getOpTypeForOperations(addon.pendingOperations);
-    detailItem.setAttribute("opType", opType);
-
-    let listItem = this._getElementForAddon(addon.id);
-    listItem.setAttribute("opType", opType);
-  },
-
-  showRestart: function showRestart() {
-    this._restartCount++;
-    gChromeWin.XPInstallObserver.showRestartPrompt();
-  },
-
-  hideRestart: function hideRestart() {
-    this._restartCount--;
-    if (this._restartCount == 0) {
-      gChromeWin.XPInstallObserver.hideRestartPrompt();
-    }
-  },
-
-  onEnabled: function(aAddon) {
-    let listItem = this._getElementForAddon(aAddon.id);
-    if (!listItem) {
-      return;
-    }
-
-    // Reload the details to pick up any options now that it's enabled.
-    listItem.setAttribute("optionsURL", aAddon.optionsURL || "");
-    let detailItem = document.querySelector("#addons-details > .addon-item");
-    if (aAddon == detailItem.addon) {
-      this.showDetails(listItem);
-    }
-  },
-
-  onInstallEnded: function(aInstall, aAddon) {
-    let needsRestart = false;
-    if (
-      aInstall.existingAddon &&
-      aInstall.existingAddon.pendingOperations & AddonManager.PENDING_UPGRADE
-    ) {
-      needsRestart = true;
-    } else if (aAddon.pendingOperations & AddonManager.PENDING_INSTALL) {
-      needsRestart = true;
-    }
-
-    let list = document.getElementById("addons-list");
-    let element = this._getElementForAddon(aAddon.id);
-    if (!element) {
-      element = this._createItemForAddon(aAddon);
-      list.insertBefore(element, list.firstElementChild);
-    }
-
-    if (needsRestart) {
-      element.setAttribute("opType", "needs-restart");
-    }
-  },
-
-  onInstalled: function(aAddon) {
-    let list = document.getElementById("addons-list");
-    let element = this._getElementForAddon(aAddon.id);
-    if (element) {
-      // Upgrade of an existing addon, update version and description in
-      // list item and detail view, plus indicators about a pending update.
-      element.querySelector(".version").textContent = aAddon.version;
-
-      let desc = element.querySelector(".description");
-      if (desc) {
-        desc.textContent = aAddon.description;
-      }
-
-      element.setAttribute("hasUpdate", false);
-      document.getElementById("update-btn").setAttribute("hidden", true);
-
-      element = document.querySelector("#addons-details > .addon-item");
-      if (element.addon && element.addon.id == aAddon.id) {
-        element.querySelector(".version").textContent = aAddon.version;
-        element.querySelector(".description-full").textContent =
-          aAddon.description;
-      }
-    } else {
-      element = this._createItemForAddon(aAddon);
-
-      // Themes aren't considered active on install, so set existing as disabled, and new one enabled.
-      if (aAddon.type == "theme") {
-        let item = list.firstElementChild;
-        while (item) {
-          if (item.addon && item.addon.type == "theme") {
-            item.setAttribute("isDisabled", true);
-          }
-          item = item.nextSibling;
-        }
-        element.setAttribute("isDisabled", false);
-      }
-
-      list.insertBefore(element, list.firstElementChild);
-    }
-  },
-
-  onUninstalled: function(aAddon) {
-    let list = document.getElementById("addons-list");
-    let element = this._getElementForAddon(aAddon.id);
-    list.removeChild(element);
-
-    // Go back if we're in the detail view of the add-on that was uninstalled.
-    let detailItem = document.querySelector("#addons-details > .addon-item");
-    if (detailItem.addon.id == aAddon.id) {
-      history.back();
-    }
-  },
-
-  onInstallFailed: function(aInstall) {},
-
-  onDownloadProgress: function xpidm_onDownloadProgress(aInstall) {},
-
-  onDownloadFailed: function(aInstall) {},
-
-  onDownloadCancelled: function(aInstall) {},
-};
-
-window.addEventListener("load", init);
-window.addEventListener("unload", uninit);
deleted file mode 100644
--- a/mobile/android/chrome/content/aboutAddons.xhtml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
-  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" [
-<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
-%brandDTD;
-<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd" >
-%globalDTD;
-<!ENTITY % aboutDTD SYSTEM "chrome://browser/locale/aboutAddons.dtd" >
-%aboutDTD;
-]>
-
-<!-- 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/. -->
-
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-  <title>&aboutAddons.title2;</title>
-  <meta name="viewport" content="width=device-width; user-scalable=0" />
-  <link rel="icon" type="image/png" sizes="64x64" href="chrome://branding/content/favicon64.png" />
-  <link rel="stylesheet" href="chrome://browser/skin/aboutBase.css" type="text/css"/>
-  <link rel="stylesheet" href="chrome://browser/skin/aboutAddons.css" type="text/css"/>
-</head>
-
-<body dir="&locale.dir;">
-  <menu type="context" id="addonmenu">
-    <menuitem id="contextmenu-enable" label="&addonAction.enable;"></menuitem>
-    <menuitem id="contextmenu-disable" label="&addonAction.disable;" ></menuitem>
-    <menuitem id="contextmenu-uninstall" label="&addonAction.uninstall;" ></menuitem>
-  </menu>
-
-  <div id="addons-header" class="header">
-    <div>&aboutAddons.header2;</div>
-  </div>
-  <div id="addons-list" class="list hidden">
-  </div>
-
-  <div id="addons-details" class="list hidden">
-    <div class="addon-item list-item">
-      <img class="icon"/>
-      <div class="inner">
-        <div class="details">
-          <div class="title"></div><div class="version"></div>
-        </div>
-        <div class="description-full"></div>
-      </div>
-      <div class="warn-unsigned">&addonUnsigned.message; <a id="unsigned-learn-more">&addonUnsigned.learnMore;</a></div>
-      <div class="options-box"></div>
-      <div class="status status-uninstalled show-on-uninstall"></div>
-      <div class="buttons">
-        <button id="update-btn" class="show-on-update">&addonAction.update;</button>
-        <button id="enable-btn" class="show-on-disable hide-on-enable hide-on-uninstall" >&addonAction.enable;</button>
-        <button id="disable-btn" class="show-on-enable hide-on-disable hide-on-uninstall" >&addonAction.disable;</button>
-        <button id="uninstall-btn" class="hide-on-uninstall" >&addonAction.uninstall;</button>
-        <button id="cancel-btn" class="show-on-uninstall" >&addonAction.undo;</button>
-      </div>
-    </div>
-  </div>
-
-  <script type="application/javascript" src="chrome://browser/content/aboutAddons.js"></script>
-</body>
-</html>
deleted file mode 100644
--- a/mobile/android/chrome/content/aboutCertError.xhtml
+++ /dev/null
@@ -1,152 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!DOCTYPE html [
-  <!ENTITY % htmlDTD
-    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "DTD/xhtml1-strict.dtd">
-  %htmlDTD;
-  <!ENTITY % globalDTD
-    SYSTEM "chrome://global/locale/global.dtd">
-  %globalDTD;
-  <!ENTITY % certerrorDTD
-    SYSTEM "chrome://browser/locale/aboutCertError.dtd">
-  %certerrorDTD;
-]>
-
-<!-- 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/. -->
-<html xmlns="http://www.w3.org/1999/xhtml">
-  <head>
-    <title>&certerror.pagetitle;</title>
-    <meta name="viewport" content="width=device-width; user-scalable=false" />
-    <link rel="stylesheet" href="chrome://browser/skin/netError.css" media="all" />
-    <!-- This page currently uses the same favicon as neterror.xhtml.
-         If the location of the favicon is changed for both pages, the
-         FAVICON_ERRORPAGE_URL symbol in toolkit/components/places/src/nsFaviconService.h
-         should be updated. If this page starts using a different favicon
-         than neterrorm nsFaviconService->SetAndLoadFaviconForPage
-         should be updated to ignore this one as well. -->
-    <link rel="icon" type="image/png" id="favicon" sizes="64x64" href="chrome://browser/skin/images/certerror-warning.png"/>
-
-    <script type="application/javascript"><![CDATA[
-      // Error url MUST be formatted like this:
-      //   about:certerror?e=error&u=url&d=desc
-
-      // Note that this file uses document.documentURI to get
-      // the URL (with the format from above). This is because
-      // document.location.href gets the current URI off the docshell,
-      // which is the URL displayed in the location bar, i.e.
-      // the URI that the user attempted to load.
-
-      function getCSSClass() {
-        var url = document.documentURI;
-        var matches = url.match(/s\=([^&]+)\&/);
-        // s is optional, if no match just return nothing
-        if (!matches || matches.length < 2)
-          return "";
-
-        // parenthetical match is the second entry
-        return decodeURIComponent(matches[1]);
-      }
-
-      function initPage() {
-        // Replace the "#1" string in the intro with the hostname.  Trickier
-        // than it might seem since we want to preserve the <b> tags, but
-        // not allow for any injection by just using innerHTML.  Instead,
-        // just find the right target text node.
-        var intro = document.getElementById("introContentP1");
-        function replaceWithHost(node) {
-          if (node.textContent == "#1")
-            node.textContent = location.host;
-          else
-            for (var i = 0; i < node.childNodes.length; i++)
-              replaceWithHost(node.childNodes[i]);
-        }
-        replaceWithHost(intro);
-
-        if (getCSSClass() == "expertBadCert") {
-          toggle("technicalContent");
-          toggle("expertContent");
-        }
-
-        // Disallow overrides if this is a Strict-Transport-Security
-        // host and the cert is bad (STS Spec section 7.3) or if the
-        // certerror is in a frame (bug 633691).
-        if (getCSSClass() == "badStsCert" || window != top)
-          document.getElementById("expertContent").setAttribute("hidden", "true");
-
-        var event = new CustomEvent("AboutCertErrorLoad", {bubbles: true});
-        document.dispatchEvent(event);
-      }
-
-      function createLink(el, id, text) {
-        var anchorEl = document.createElement("a");
-        anchorEl.setAttribute("id", id);
-        anchorEl.setAttribute("title", text);
-        anchorEl.appendChild(document.createTextNode(text));
-        el.appendChild(anchorEl);
-      }
-
-      function toggle(id) {
-        var el = document.getElementById(id);
-        if (el.hasAttribute("collapsed"))
-          el.removeAttribute("collapsed");
-        else
-          el.setAttribute("collapsed", true);
-      }
-    ]]></script>
-  </head>
-
-  <body id="errorPage" class="certerror" dir="&locale.dir;">
-
-    <!-- PAGE CONTAINER (for styling purposes only) -->
-    <div id="errorPageContainer">
-
-      <!-- Error Title -->
-      <div id="errorTitle">
-        <h1 class="errorTitleText">&certerror.longpagetitle;</h1>
-      </div>
-
-      <!-- LONG CONTENT (the section most likely to require scrolling) -->
-      <div id="errorLongContent">
-        <div id="introContent">
-          <p id="introContentP1">&certerror.introPara1;</p>
-        </div>
-
-        <div id="whatShouldIDoContent">
-          <h2>&certerror.whatShouldIDo.heading;</h2>
-          <div>
-            <p id="whatShouldIDoContentText">&certerror.whatShouldIDo.content;</p>
-            <button id="getMeOutOfHereButton">&certerror.getMeOutOfHere.label;</button>
-          </div>
-        </div>
-
-        <!-- The following sections can be unhidden by default by setting the
-             "browser.xul.error_pages.expert_bad_cert" pref to true -->
-        <div id="technicalContent" collapsed="true">
-          <h2 class="expander" onclick="toggle('technicalContent');" id="technicalContentHeading">&certerror.technical.heading;</h2>
-          <p id="technicalContentText"/>
-        </div>
-
-        <div id="expertContent" collapsed="true">
-          <h2 class="expander" onclick="toggle('expertContent');" id="expertContentHeading">&certerror.expert.heading;</h2>
-          <div>
-            <p>&certerror.expert.content;</p>
-            <p>&certerror.expert.contentPara2;</p>
-            <button id="temporaryExceptionButton">&certerror.addTemporaryException.label;</button>
-            <button id="permanentExceptionButton">&certerror.addPermanentException.label;</button>
-          </div>
-        </div>
-      </div>
-    </div>
-
-    <!--
-    - Note: It is important to run the script this way, instead of using
-    - an onload handler. This is because error pages are loaded as
-    - LOAD_BACKGROUND, which means that onload handlers will not be executed.
-    -->
-    <script type="application/javascript">initPage();</script>
-
-  </body>
-</html>
deleted file mode 100644
--- a/mobile/android/chrome/content/aboutDownloads.js
+++ /dev/null
@@ -1,427 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "Downloads",
-  "resource://gre/modules/Downloads.jsm"
-);
-ChromeUtils.defineModuleGetter(
-  this,
-  "DownloadUtils",
-  "resource://gre/modules/DownloadUtils.jsm"
-);
-ChromeUtils.defineModuleGetter(
-  this,
-  "EventDispatcher",
-  "resource://gre/modules/Messaging.jsm"
-);
-ChromeUtils.defineModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
-ChromeUtils.defineModuleGetter(
-  this,
-  "PluralForm",
-  "resource://gre/modules/PluralForm.jsm"
-);
-ChromeUtils.defineModuleGetter(
-  this,
-  "Services",
-  "resource://gre/modules/Services.jsm"
-);
-
-var gStrings = Services.strings.createBundle(
-  "chrome://browser/locale/aboutDownloads.properties"
-);
-XPCOMUtils.defineLazyGetter(this, "strings", () =>
-  Services.strings.createBundle(
-    "chrome://browser/locale/aboutDownloads.properties"
-  )
-);
-
-function deleteDownload(download) {
-  download.finalize(true).catch(Cu.reportError);
-  OS.File.remove(download.target.path).catch(ex => {
-    if (!(ex instanceof OS.File.Error && ex.becauseNoSuchFile)) {
-      Cu.reportError(ex);
-    }
-  });
-}
-
-var contextMenu = {
-  _items: [],
-  _targetDownload: null,
-
-  init: function() {
-    let element = document.getElementById("downloadmenu");
-    element.addEventListener(
-      "click",
-      event => (event.download = this._targetDownload),
-      true
-    );
-    this._items = [
-      new ContextMenuItem(
-        "open",
-        download => download.succeeded,
-        download => download.launch().catch(Cu.reportError)
-      ),
-      new ContextMenuItem(
-        "retry",
-        download =>
-          download.error || (download.canceled && !download.hasPartialData),
-        download => download.start().catch(Cu.reportError)
-      ),
-      new ContextMenuItem(
-        "remove",
-        download => download.stopped,
-        download => {
-          Downloads.getList(Downloads.ALL)
-            .then(list => list.remove(download))
-            .catch(Cu.reportError);
-          deleteDownload(download);
-        }
-      ),
-      new ContextMenuItem(
-        "pause",
-        download => !download.stopped && download.hasPartialData,
-        download => download.cancel().catch(Cu.reportError)
-      ),
-      new ContextMenuItem(
-        "resume",
-        download => download.canceled && download.hasPartialData,
-        download => download.start().catch(Cu.reportError)
-      ),
-      new ContextMenuItem(
-        "cancel",
-        download =>
-          !download.stopped || (download.canceled && download.hasPartialData),
-        download => {
-          download.cancel().catch(Cu.reportError);
-          download.removePartialData().catch(Cu.reportError);
-        }
-      ),
-      // following menu item is a global action
-      new ContextMenuItem(
-        "removeall",
-        () => downloadLists.finished.length > 0,
-        () => downloadLists.removeFinished()
-      ),
-    ];
-  },
-
-  addContextMenuEventListener: function(element) {
-    element.addEventListener("contextmenu", this.onContextMenu.bind(this));
-  },
-
-  onContextMenu: function(event) {
-    let target = event.target;
-    while (target && !target.download) {
-      target = target.parentNode;
-    }
-    if (!target) {
-      Cu.reportError("No download found for context menu target");
-      event.preventDefault();
-      return;
-    }
-
-    // capture the target download for menu items to use in a click event
-    this._targetDownload = target.download;
-    for (let item of this._items) {
-      item.updateVisibility(target.download);
-    }
-  },
-};
-
-function ContextMenuItem(name, isVisible, action) {
-  this.element = document.getElementById("contextmenu-" + name);
-  this.isVisible = isVisible;
-
-  this.element.addEventListener("click", event => action(event.download));
-}
-
-ContextMenuItem.prototype = {
-  updateVisibility: function(download) {
-    this.element.hidden = !this.isVisible(download);
-  },
-};
-
-function DownloadListView(type, listElementId) {
-  this.listElement = document.getElementById(listElementId);
-  contextMenu.addContextMenuEventListener(this.listElement);
-
-  this.items = new Map();
-
-  Downloads.getList(type)
-    .then(list => list.addView(this))
-    .catch(Cu.reportError);
-
-  window.addEventListener("unload", event => {
-    Downloads.getList(type)
-      .then(list => list.removeView(this))
-      .catch(Cu.reportError);
-  });
-}
-
-DownloadListView.prototype = {
-  get finished() {
-    let finished = [];
-    for (let download of this.items.keys()) {
-      if (download.stopped && (!download.hasPartialData || download.error)) {
-        finished.push(download);
-      }
-    }
-
-    return finished;
-  },
-
-  insertOrMoveItem: function(item) {
-    var compare = (a, b) => {
-      // active downloads always before stopped downloads
-      if (a.stopped != b.stopped) {
-        return b.stopped ? -1 : 1;
-      }
-      // most recent downloads first
-      return b.startTime - a.startTime;
-    };
-
-    let insertLocation = this.listElement.firstChild;
-    while (
-      insertLocation &&
-      compare(item.download, insertLocation.download) > 0
-    ) {
-      insertLocation = insertLocation.nextElementSibling;
-    }
-    this.listElement.insertBefore(item.element, insertLocation);
-  },
-
-  onDownloadAdded: function(download) {
-    let item = new DownloadItem(download);
-    this.items.set(download, item);
-    this.insertOrMoveItem(item);
-  },
-
-  onDownloadChanged: function(download) {
-    let item = this.items.get(download);
-    if (!item) {
-      Cu.reportError("No DownloadItem found for download");
-      return;
-    }
-
-    if (item.stateChanged) {
-      this.insertOrMoveItem(item);
-    }
-
-    item.onDownloadChanged();
-  },
-
-  onDownloadRemoved: function(download) {
-    let item = this.items.get(download);
-    if (!item) {
-      Cu.reportError("No DownloadItem found for download");
-      return;
-    }
-
-    this.items.delete(download);
-    this.listElement.removeChild(item.element);
-
-    EventDispatcher.instance.sendRequest({
-      type: "Download:Remove",
-      path: download.target.path,
-    });
-  },
-};
-
-var downloadLists = {
-  init: function() {
-    this.publicDownloads = new DownloadListView(
-      Downloads.PUBLIC,
-      "public-downloads-list"
-    );
-    this.privateDownloads = new DownloadListView(
-      Downloads.PRIVATE,
-      "private-downloads-list"
-    );
-  },
-
-  get finished() {
-    return this.publicDownloads.finished.concat(this.privateDownloads.finished);
-  },
-
-  removeFinished: function() {
-    let finished = this.finished;
-    if (finished.length == 0) {
-      return;
-    }
-
-    let title = strings.GetStringFromName("downloadAction.deleteAll");
-    let messageForm = strings.GetStringFromName("downloadMessage.deleteAll");
-    let message = PluralForm.get(finished.length, messageForm).replace(
-      "#1",
-      finished.length
-    );
-
-    if (Services.prompt.confirm(null, title, message)) {
-      Downloads.getList(Downloads.ALL).then(list => {
-        for (let download of finished) {
-          list.remove(download).catch(Cu.reportError);
-          deleteDownload(download);
-        }
-      }, Cu.reportError);
-    }
-  },
-};
-
-function DownloadItem(download) {
-  this._download = download;
-  this._updateFromDownload();
-
-  this._domain = DownloadUtils.getURIHost(download.source.url)[0];
-  this._fileName = this._htmlEscape(OS.Path.basename(download.target.path));
-  this._iconUrl = "moz-icon://" + this._fileName + "?size=64";
-  this._startDate = this._htmlEscape(
-    DownloadUtils.getReadableDates(download.startTime)[0]
-  );
-
-  this._element = this.createElement();
-}
-
-const kDownloadStatePropertyNames = [
-  "stopped",
-  "succeeded",
-  "canceled",
-  "error",
-  "startTime",
-];
-
-DownloadItem.prototype = {
-  _htmlEscape: function(s) {
-    s = s.replace(/&/g, "&amp;");
-    s = s.replace(/>/g, "&gt;");
-    s = s.replace(/</g, "&lt;");
-    s = s.replace(/"/g, "&quot;");
-    s = s.replace(/'/g, "&apos;");
-    return s;
-  },
-
-  _updateFromDownload: function() {
-    this._state = {};
-    kDownloadStatePropertyNames.forEach(
-      name => (this._state[name] = this._download[name]),
-      this
-    );
-  },
-
-  get stateChanged() {
-    return kDownloadStatePropertyNames.some(
-      name => this._state[name] != this._download[name],
-      this
-    );
-  },
-
-  get download() {
-    return this._download;
-  },
-  get element() {
-    return this._element;
-  },
-
-  createElement: function() {
-    let template = document.getElementById("download-item");
-    // TODO: use this once <template> is working
-    // let element = document.importNode(template.content, true);
-
-    // simulate a <template> node...
-    let element = template.cloneNode(true);
-    element.removeAttribute("id");
-    element.removeAttribute("style");
-
-    // launch the download if clicked
-    element.addEventListener("click", this.onClick.bind(this));
-
-    // set download as an expando property for the context menu
-    element.download = this.download;
-
-    // fill in template placeholders
-    this.updateElement(element);
-
-    return element;
-  },
-
-  updateElement: function(element) {
-    element.querySelector(".date").textContent = this.startDate;
-    element.querySelector(".domain").textContent = this.domain;
-    element.querySelector(".icon").src = this.iconUrl;
-    element.querySelector(".size").textContent = this.size;
-    element.querySelector(".state").textContent = this.stateDescription;
-    element.querySelector(".title").setAttribute("value", this.fileName);
-  },
-
-  onClick: function(event) {
-    if (this.download.succeeded) {
-      this.download.launch().catch(Cu.reportError);
-    }
-  },
-
-  onDownloadChanged: function() {
-    this._updateFromDownload();
-    this.updateElement(this.element);
-  },
-
-  // template properties below
-  get domain() {
-    return this._domain;
-  },
-  get fileName() {
-    return this._fileName;
-  },
-  get id() {
-    return this._id;
-  },
-  get iconUrl() {
-    return this._iconUrl;
-  },
-
-  get size() {
-    if (this.download.succeeded && this.download.target.exists) {
-      return DownloadUtils.convertByteUnits(this.download.target.size).join("");
-    } else if (this.download.hasProgress) {
-      return DownloadUtils.convertByteUnits(this.download.totalBytes).join("");
-    }
-    return strings.GetStringFromName("downloadState.unknownSize");
-  },
-
-  get startDate() {
-    return this._startDate;
-  },
-
-  get stateDescription() {
-    let name;
-    if (this.download.error) {
-      name = "downloadState.failed";
-    } else if (this.download.canceled) {
-      if (this.download.hasPartialData) {
-        name = "downloadState.paused";
-      } else {
-        name = "downloadState.canceled";
-      }
-    } else if (!this.download.stopped) {
-      if (this.download.currentBytes > 0) {
-        name = "downloadState.downloading";
-      } else {
-        name = "downloadState.starting";
-      }
-    }
-
-    if (name) {
-      return strings.GetStringFromName(name);
-    }
-    return "";
-  },
-};
-
-window.addEventListener("DOMContentLoaded", event => {
-  contextMenu.init();
-  downloadLists.init();
-});
deleted file mode 100644
--- a/mobile/android/chrome/content/aboutDownloads.xhtml
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
-  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" [
-<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
-%brandDTD;
-<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd" >
-%globalDTD;
-<!ENTITY % downloadsDTD SYSTEM "chrome://browser/locale/aboutDownloads.dtd" >
-%downloadsDTD;
-]>
-
-<!-- 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/.  -->
-
-<html xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-<head>
-  <title>&aboutDownloads.title;</title>
-  <meta name="viewport" content="width=device-width; user-scalable=0" />
-  <link rel="icon" type="image/png" sizes="64x64" href="chrome://branding/content/favicon64.png" />
-  <link rel="stylesheet" href="chrome://browser/skin/aboutBase.css" type="text/css"/>
-  <link rel="stylesheet" href="chrome://browser/skin/aboutDownloads.css" type="text/css"/>
-</head>
-
-<body dir="&locale.dir;">
-  <menu type="context" id="downloadmenu">
-    <menuitem id="contextmenu-open" label="&aboutDownloads.open;"></menuitem>
-    <menuitem id="contextmenu-retry" label="&aboutDownloads.retry;"></menuitem>
-    <menuitem id="contextmenu-remove" label="&aboutDownloads.remove;"></menuitem>
-    <menuitem id="contextmenu-pause" label="&aboutDownloads.pause;"></menuitem>
-    <menuitem id="contextmenu-resume" label="&aboutDownloads.resume;"></menuitem>
-    <menuitem id="contextmenu-cancel" label="&aboutDownloads.cancel;"></menuitem>
-    <menuitem id="contextmenu-removeall" label="&aboutDownloads.removeAll;"></menuitem>
-  </menu>
-
-  <!--template id="download-item"-->
-    <li id="download-item" class="list-item" role="button" contextmenu="downloadmenu" style="display: none">
-      <img class="icon" src=""/>
-      <div class="details">
-        <div class="row">
-          <!-- This is a hack so that we can crop this label in its center -->
-          <xul:label class="title" crop="center" value=""/>
-          <div class="date"></div>
-        </div>
-        <div class="size"></div>
-        <div class="domain"></div>
-        <div class="state"></div>
-      </div>
-    </li>
-  <!--/template-->
-
-  <div class="header">
-    <div>&aboutDownloads.header;</div>
-  </div>
-  <ul id="private-downloads-list" class="list"></ul>
-  <ul id="public-downloads-list" class="list"></ul>
-  <span id="no-downloads-indicator">&aboutDownloads.empty;</span>
-  <script type="application/javascript" src="chrome://browser/content/aboutDownloads.js"/>
-</body>
-</html>
deleted file mode 100644
--- a/mobile/android/chrome/content/aboutExperiments.js
+++ /dev/null
@@ -1,127 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { XPCOMUtils } = ChromeUtils.import(
-  "resource://gre/modules/XPCOMUtils.jsm"
-);
-
-XPCOMUtils.defineLazyModuleGetters(this, {
-  AndroidLog: "resource://gre/modules/AndroidLog.jsm",
-  EventDispatcher: "resource://gre/modules/Messaging.jsm",
-});
-
-const LOGTAG = "Experiments";
-const EXPERIMENTS_CONFIGURATION =
-  "https://firefox.settings.services.mozilla.com/v1/buckets/fennec/collections/experiments/records";
-const Experiments = Services.wm.getMostRecentWindow("navigator:browser")
-  .Experiments;
-
-document.addEventListener("DOMContentLoaded", initList);
-
-function log(msg) {
-  AndroidLog.d(LOGTAG, msg);
-}
-
-function initList() {
-  const list = document.getElementById("list");
-  list.addEventListener("click", toggleOverride);
-
-  Promise.all([
-    promiseEnabledExperiments(),
-    promiseExperimentsConfiguration(),
-  ]).then(values => {
-    const enabledExperiments = values[0];
-    const serverConfiguration = values[1];
-
-    serverConfiguration.data.forEach(function(experiment) {
-      try {
-        let item = document.createElement("li");
-        item.textContent = experiment.name;
-        item.setAttribute("name", experiment.name);
-        item.setAttribute(
-          "isEnabled",
-          enabledExperiments.includes(experiment.name)
-        );
-        list.appendChild(item);
-      } catch (e) {
-        log(`Error while setting experiments list: ${e.error}`);
-      }
-    });
-  });
-}
-
-function toggleOverride(experiment) {
-  const item = experiment.originalTarget;
-  const name = item.getAttribute("name");
-  const isEnabled = item.getAttribute("isEnabled") === "true";
-
-  log(`toggleOverride: ${name}`);
-
-  Experiments.setOverride(name, !isEnabled);
-  item.setAttribute("isEnabled", !isEnabled);
-}
-
-/**
- * Get the list of locally enabled experiments.
- */
-function promiseEnabledExperiments() {
-  log("Getting the locally enabled experiments");
-
-  return EventDispatcher.instance
-    .sendRequestForResult({
-      type: "Experiments:GetActive",
-    })
-    .then(experiments => {
-      log("List of locally enabled experiments ready");
-      return experiments;
-    });
-}
-
-/**
- * Fetch the list of experiments from server configuration.
- */
-function promiseExperimentsConfiguration() {
-  log("Fetching server experiments");
-
-  return new Promise((resolve, reject) => {
-    const xhr = new XMLHttpRequest();
-
-    try {
-      xhr.open("GET", EXPERIMENTS_CONFIGURATION, true);
-    } catch (e) {
-      reject(`Error opening request: ${e}`);
-      return;
-    }
-
-    xhr.onerror = function(e) {
-      reject(`Error making request: ${e.error}`);
-    };
-
-    xhr.onload = function(event) {
-      if (xhr.readyState === 4) {
-        if (xhr.status === 200) {
-          try {
-            resolve(JSON.parse(xhr.responseText));
-          } catch (e) {
-            const errorMessage = `Error while parsing request: ${e}`;
-            log(errorMessage);
-            reject(errorMessage);
-          }
-        } else {
-          const errorMessage = `Request to ${url} returned status ${
-            xhr.status
-          }`;
-          log(errorMessage);
-          reject(errorMessage);
-        }
-      }
-      log("Finished fetching server experiments");
-    };
-
-    xhr.send(null);
-  });
-}
deleted file mode 100644
--- a/mobile/android/chrome/content/aboutExperiments.xhtml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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/. -->
-
-<html xmlns="http://www.w3.org/1999/xhtml">
-  <head>
-    <title>Switchboard Experiments</title>
-    <meta name="viewport" content="width=device-width; user-scalable=0" />
-    <link rel="stylesheet" href="chrome://browser/skin/aboutBase.css" type="text/css"/>
-    <link rel="stylesheet" href="chrome://browser/skin/aboutExperiments.css" type="text/css"/>
-    <script type="application/javascript" src="chrome://browser/content/aboutExperiments.js"></script>
-  </head>
-
-  <body>
-    <ul id="list"/>
-  </body>
-</html>
deleted file mode 100644
--- a/mobile/android/chrome/content/aboutHome.xhtml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!DOCTYPE html [
-  <!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
-  %htmlDTD;
-  <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
-  %brandDTD;
-  <!ENTITY % abouthomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd">
-  %abouthomeDTD;
-]>
-
-<!-- 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/. -->
-
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-  <title>&abouthome.title;</title>
-</head>
-<body>
-</body>
-</html>
deleted file mode 100644
--- a/mobile/android/chrome/content/aboutLogins.js
+++ /dev/null
@@ -1,628 +0,0 @@
-/* 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/. */
-
-ChromeUtils.import(
-  "resource://services-common/utils.js"
-); /* global: CommonUtils */
-const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { XPCOMUtils } = ChromeUtils.import(
-  "resource://gre/modules/XPCOMUtils.jsm"
-);
-const { Accounts } = ChromeUtils.import("resource://gre/modules/Accounts.jsm");
-
-XPCOMUtils.defineLazyGetter(
-  window,
-  "gChromeWin",
-  () => window.docShell.rootTreeItem.domWindow
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "EventDispatcher",
-  "resource://gre/modules/Messaging.jsm"
-);
-ChromeUtils.defineModuleGetter(
-  this,
-  "Snackbars",
-  "resource://gre/modules/Snackbars.jsm"
-);
-ChromeUtils.defineModuleGetter(
-  this,
-  "Prompt",
-  "resource://gre/modules/Prompt.jsm"
-);
-
-var debug = ChromeUtils.import(
-  "resource://gre/modules/AndroidLog.jsm",
-  {}
-).AndroidLog.d.bind(null, "AboutLogins");
-
-var gStringBundle = Services.strings.createBundle(
-  "chrome://browser/locale/aboutLogins.properties"
-);
-
-function copyStringShowSnackbar(string, notifyString) {
-  try {
-    let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(
-      Ci.nsIClipboardHelper
-    );
-    clipboard.copyString(string);
-    Snackbars.show(notifyString, Snackbars.LENGTH_LONG);
-  } catch (e) {
-    debug("Error copying from about:logins");
-    Snackbars.show(
-      gStringBundle.GetStringFromName("loginsDetails.copyFailed"),
-      Snackbars.LENGTH_LONG
-    );
-  }
-}
-
-// Delay filtering while typing in MS
-const FILTER_DELAY = 500;
-
-var Logins = {
-  _logins: [],
-  _filterTimer: null,
-  _selectedLogin: null,
-
-  // Load the logins list, displaying interstitial UI (see
-  // #logins-list-loading-body) while loading.  There are careful
-  // jank-avoiding measures taken in this function; be careful when
-  // modifying it!
-  //
-  // Returns a Promise that resolves to the list of logins, ordered by
-  // origin.
-  _promiseLogins: function() {
-    let contentBody = document.getElementById("content-body");
-    let emptyBody = document.getElementById("empty-body");
-    let filterIcon = document.getElementById("filter-button");
-
-    let showSpinner = () => {
-      this._toggleListBody(true);
-      emptyBody.classList.add("hidden");
-    };
-
-    let getAllLogins = () => {
-      let logins = [];
-      try {
-        logins = Services.logins.getAllLogins();
-      } catch (e) {
-        // It's likely that the Master Password was not entered; give
-        // a hint to the next person.
-        throw new Error(
-          "Possible Master Password permissions error: " + e.toString()
-        );
-      }
-
-      logins.sort((a, b) => a.origin.localeCompare(b.origin));
-
-      return logins;
-    };
-
-    let hideSpinner = logins => {
-      this._toggleListBody(false);
-
-      if (!logins.length) {
-        contentBody.classList.add("hidden");
-        filterIcon.classList.add("hidden");
-        emptyBody.classList.remove("hidden");
-      } else {
-        contentBody.classList.remove("hidden");
-        emptyBody.classList.add("hidden");
-      }
-
-      return logins;
-    };
-
-    // Return a promise that is resolved after a paint.
-    let waitForPaint = () => {
-      // We're changing 'display'.  We need to wait for the new value to take
-      // effect; otherwise, we'll block and never paint a change.  Since
-      // requestAnimationFrame callback is generally triggered *before* any
-      // style flush and layout, we wait for two animation frames.  This
-      // approach was cribbed from
-      // https://dxr.mozilla.org/mozilla-central/rev/5abe3c4deab94270440422c850bbeaf512b1f38d/browser/base/content/browser-fullScreen.js?offset=0#469.
-      return new Promise(function(resolve, reject) {
-        requestAnimationFrame(() => {
-          requestAnimationFrame(() => {
-            resolve();
-          });
-        });
-      });
-    };
-
-    // getAllLogins janks the main-thread.  We need to paint before that jank;
-    // by throwing the janky load onto the next tick, we paint the spinner; the
-    // spinner is CSS animated off-main-thread.
-    return Promise.resolve()
-      .then(showSpinner)
-      .then(waitForPaint)
-      .then(getAllLogins)
-      .then(hideSpinner);
-  },
-
-  // Reload the logins list, displaying interstitial UI while loading.
-  // Update the stored and displayed list upon completion.
-  _reloadList: function() {
-    this._promiseLogins()
-      .then(logins => {
-        this._logins = logins;
-        this._loadList(logins);
-      })
-      .catch(e => {
-        // There's no way to recover from errors, sadly.  Log and make
-        // it obvious that something is up.
-        this._logins = [];
-        debug("Failed to _reloadList!");
-        Cu.reportError(e);
-      });
-  },
-
-  _toggleListBody: function(isLoading) {
-    let contentBody = document.getElementById("content-body");
-    let loadingBody = document.getElementById("logins-list-loading-body");
-
-    if (isLoading) {
-      contentBody.classList.add("hidden");
-      loadingBody.classList.remove("hidden");
-    } else {
-      loadingBody.classList.add("hidden");
-      contentBody.classList.remove("hidden");
-    }
-  },
-
-  init: function() {
-    window.addEventListener("popstate", this);
-
-    Services.obs.addObserver(this, "passwordmgr-storage-changed");
-    document
-      .getElementById("update-btn")
-      .addEventListener("click", this._onSaveEditLogin.bind(this));
-    document
-      .getElementById("password-btn")
-      .addEventListener("click", this._onPasswordBtn.bind(this));
-
-    let filterInput = document.getElementById("filter-input");
-    let filterContainer = document.getElementById("filter-input-container");
-
-    filterInput.addEventListener("input", event => {
-      // Stop any in-progress filter timer
-      if (this._filterTimer) {
-        clearTimeout(this._filterTimer);
-        this._filterTimer = null;
-      }
-
-      // Start a new timer
-      this._filterTimer = setTimeout(() => {
-        this._filter(event);
-      }, FILTER_DELAY);
-    });
-
-    filterInput.addEventListener("blur", event => {
-      filterContainer.setAttribute("hidden", true);
-    });
-
-    document
-      .getElementById("filter-button")
-      .addEventListener("click", event => {
-        filterContainer.removeAttribute("hidden");
-        filterInput.focus();
-      });
-
-    document.getElementById("filter-clear").addEventListener("click", event => {
-      // Stop any in-progress filter timer
-      if (this._filterTimer) {
-        clearTimeout(this._filterTimer);
-        this._filterTimer = null;
-      }
-
-      filterInput.blur();
-      filterInput.value = "";
-      this._loadList(this._logins);
-    });
-
-    this._showList();
-
-    this._updatePasswordBtn(true);
-
-    this._reloadList();
-  },
-
-  uninit: function() {
-    Services.obs.removeObserver(this, "passwordmgr-storage-changed");
-    window.removeEventListener("popstate", this);
-  },
-
-  _loadList: function(logins) {
-    let list = document.getElementById("logins-list");
-    let newList = list.cloneNode(false);
-
-    logins.forEach(login => {
-      let item = this._createItemForLogin(login);
-      newList.appendChild(item);
-    });
-
-    list.parentNode.replaceChild(newList, list);
-  },
-
-  _showList: function() {
-    let loginsListPage = document.getElementById("logins-list-page");
-    loginsListPage.classList.remove("hidden");
-
-    let editLoginPage = document.getElementById("edit-login-page");
-    editLoginPage.classList.add("hidden");
-
-    // If the Show/Hide password button has been flipped, reset it
-    if (this._isPasswordBtnInHideMode()) {
-      this._updatePasswordBtn(true);
-    }
-  },
-
-  _onPopState: function(event) {
-    // Called when back/forward is used to change the state of the page
-    if (event.state) {
-      this._showEditLoginDialog(event.state.id);
-    } else {
-      this._selectedLogin = null;
-      this._showList();
-    }
-  },
-  _showEditLoginDialog: function(login) {
-    let listPage = document.getElementById("logins-list-page");
-    listPage.classList.add("hidden");
-
-    let editLoginPage = document.getElementById("edit-login-page");
-    editLoginPage.classList.remove("hidden");
-
-    let usernameField = document.getElementById("username");
-    usernameField.value = login.username;
-    let passwordField = document.getElementById("password");
-    passwordField.value = login.password;
-    let domainField = document.getElementById("origin");
-    domainField.value = login.origin;
-
-    let img = document.getElementById("favicon");
-    this._loadFavicon(img, login.origin);
-
-    let headerText = document.getElementById("edit-login-header-text");
-    if (login.origin && login.origin != "") {
-      headerText.textContent = login.origin;
-    } else {
-      headerText.textContent = gStringBundle.GetStringFromName(
-        "editLogin.fallbackTitle"
-      );
-    }
-
-    passwordField.addEventListener("input", event => {
-      let newPassword = passwordField.value;
-      let updateBtn = document.getElementById("update-btn");
-
-      if (newPassword === "") {
-        updateBtn.disabled = true;
-        updateBtn.classList.add("disabled-btn");
-      } else if (newPassword !== "" && updateBtn.disabled === true) {
-        updateBtn.disabled = false;
-        updateBtn.classList.remove("disabled-btn");
-      }
-    });
-  },
-
-  _onSaveEditLogin: function() {
-    let newUsername = document.getElementById("username").value;
-    let newPassword = document.getElementById("password").value;
-    let origUsername = this._selectedLogin.username;
-    let origPassword = this._selectedLogin.password;
-
-    try {
-      if (newUsername === origUsername && newPassword === origPassword) {
-        Snackbars.show(
-          gStringBundle.GetStringFromName("editLogin.saved1"),
-          Snackbars.LENGTH_LONG
-        );
-        this._showList();
-        return;
-      }
-
-      let logins = Services.logins.findLogins(
-        this._selectedLogin.origin,
-        this._selectedLogin.formActionOrigin,
-        this._selectedLogin.httpRealm
-      );
-
-      for (let i = 0; i < logins.length; i++) {
-        if (logins[i].username == origUsername) {
-          let propBag = Cc["@mozilla.org/hash-property-bag;1"].createInstance(
-            Ci.nsIWritablePropertyBag
-          );
-          if (newUsername !== origUsername) {
-            propBag.setProperty("username", newUsername);
-          }
-          if (newPassword !== origPassword) {
-            propBag.setProperty("password", newPassword);
-          }
-          // Sync relies on timePasswordChanged to decide whether
-          // or not to sync a login, so touch it.
-          propBag.setProperty("timePasswordChanged", Date.now());
-          Services.logins.modifyLogin(logins[i], propBag);
-          break;
-        }
-      }
-    } catch (e) {
-      Snackbars.show(
-        gStringBundle.GetStringFromName("editLogin.couldNotSave"),
-        Snackbars.LENGTH_LONG
-      );
-      return;
-    }
-    Snackbars.show(
-      gStringBundle.GetStringFromName("editLogin.saved1"),
-      Snackbars.LENGTH_LONG
-    );
-    this._showList();
-  },
-
-  _onPasswordBtn: function() {
-    this._updatePasswordBtn(this._isPasswordBtnInHideMode());
-  },
-
-  _updatePasswordBtn: function(aShouldShow) {
-    let passwordField = document.getElementById("password");
-    let button = document.getElementById("password-btn");
-    let show = gStringBundle.GetStringFromName("password-btn.show");
-    let hide = gStringBundle.GetStringFromName("password-btn.hide");
-    if (aShouldShow) {
-      passwordField.type = "password";
-      button.textContent = show;
-      button.classList.remove("password-btn-hide");
-    } else {
-      passwordField.type = "text";
-      button.textContent = hide;
-      button.classList.add("password-btn-hide");
-    }
-  },
-
-  _isPasswordBtnInHideMode: function() {
-    let button = document.getElementById("password-btn");
-    return button.classList.contains("password-btn-hide");
-  },
-
-  _showPassword: function(password) {
-    let passwordPrompt = new Prompt({
-      window: window,
-      message: password,
-      buttons: [
-        gStringBundle.GetStringFromName("loginsDialog.copy"),
-        gStringBundle.GetStringFromName("loginsDialog.cancel"),
-      ],
-    }).show(data => {
-      switch (data.button) {
-        case 0:
-          // Corresponds to "Copy password" button.
-          copyStringShowSnackbar(
-            password,
-            gStringBundle.GetStringFromName("loginsDetails.passwordCopied")
-          );
-      }
-    });
-  },
-
-  _onLoginClick: function(event) {
-    let loginItem = event.currentTarget;
-    let login = loginItem.login;
-    if (!login) {
-      debug("No login!");
-      return;
-    }
-
-    let prompt = new Prompt({
-      window: window,
-    });
-    let menuItems = [
-      { label: gStringBundle.GetStringFromName("loginsMenu.showPassword") },
-      { label: gStringBundle.GetStringFromName("loginsMenu.copyPassword") },
-      { label: gStringBundle.GetStringFromName("loginsMenu.copyUsername") },
-      { label: gStringBundle.GetStringFromName("loginsMenu.editLogin") },
-      { label: gStringBundle.GetStringFromName("loginsMenu.delete") },
-      { label: gStringBundle.GetStringFromName("loginsMenu.deleteAll") },
-    ];
-
-    prompt.setSingleChoiceItems(menuItems);
-    prompt.show(data => {
-      // Switch on indices of buttons, as they were added when creating login item.
-      switch (data.button) {
-        case 0:
-          this._showPassword(login.password);
-          break;
-        case 1:
-          copyStringShowSnackbar(
-            login.password,
-            gStringBundle.GetStringFromName("loginsDetails.passwordCopied")
-          );
-          break;
-        case 2:
-          copyStringShowSnackbar(
-            login.username,
-            gStringBundle.GetStringFromName("loginsDetails.usernameCopied")
-          );
-          break;
-        case 3:
-          this._selectedLogin = login;
-          this._showEditLoginDialog(login);
-          history.pushState({ id: login.guid }, document.title);
-          break;
-        case 4:
-          Accounts.getFirefoxAccount().then(user => {
-            const promptMessage = user
-              ? gStringBundle.GetStringFromName(
-                  "loginsDialog.confirmDeleteForFxaUser"
-                )
-              : gStringBundle.GetStringFromName("loginsDialog.confirmDelete");
-            const confirmationMessage = gStringBundle.GetStringFromName(
-              "loginsDetails.deleted"
-            );
-
-            this._showConfirmationPrompt(
-              promptMessage,
-              confirmationMessage,
-              () => Services.logins.removeLogin(login)
-            );
-          });
-          break;
-        case 5:
-          Accounts.getFirefoxAccount().then(user => {
-            const promptMessage = user
-              ? gStringBundle.GetStringFromName(
-                  "loginsDialog.confirmDeleteAllForFxaUser"
-                )
-              : gStringBundle.GetStringFromName(
-                  "loginsDialog.confirmDeleteAll"
-                );
-            const confirmationMessage = gStringBundle.GetStringFromName(
-              "loginsDetails.deletedAll"
-            );
-
-            this._showConfirmationPrompt(
-              promptMessage,
-              confirmationMessage,
-              () => Services.logins.removeAllLogins()
-            );
-          });
-          break;
-      }
-    });
-  },
-
-  _showConfirmationPrompt: function(
-    promptMessage,
-    confirmationMessage,
-    actionToPerform
-  ) {
-    new Prompt({
-      window: window,
-      message: promptMessage,
-      buttons: [
-        // Use default, generic values
-        gStringBundle.GetStringFromName("loginsDialog.confirm"),
-        gStringBundle.GetStringFromName("loginsDialog.cancel"),
-      ],
-    }).show(data => {
-      switch (data.button) {
-        case 0:
-          // Corresponds to "confirm" button.
-
-          actionToPerform();
-
-          Snackbars.show(confirmationMessage, Snackbars.LENGTH_LONG);
-      }
-    });
-  },
-
-  _loadFavicon: function(aImg, aOrigin) {
-    // Load favicon from cache.
-    EventDispatcher.instance
-      .sendRequestForResult({
-        type: "Favicon:Request",
-        url: aOrigin,
-        skipNetwork: true,
-      })
-      .then(
-        function(faviconUrl) {
-          aImg.style.backgroundImage = "url('" + faviconUrl + "')";
-          aImg.style.visibility = "visible";
-        },
-        function(data) {
-          debug("Favicon cache failure : " + data);
-          aImg.style.visibility = "visible";
-        }
-      );
-  },
-
-  _createItemForLogin: function(login) {
-    let loginItem = document.createElement("div");
-
-    loginItem.setAttribute("loginID", login.guid);
-    loginItem.className = "login-item list-item";
-
-    loginItem.addEventListener("click", this, true);
-    loginItem.addEventListener("contextmenu", this, true);
-
-    // Create item icon.
-    let img = document.createElement("div");
-    img.className = "icon";
-
-    this._loadFavicon(img, login.origin);
-    loginItem.appendChild(img);
-
-    // Create item details.
-    let inner = document.createElement("div");
-    inner.className = "inner";
-
-    let details = document.createElement("div");
-    details.className = "details";
-    inner.appendChild(details);
-
-    let titlePart = document.createElement("div");
-    titlePart.className = "origin";
-    titlePart.textContent = login.origin;
-    details.appendChild(titlePart);
-
-    let versionPart = document.createElement("div");
-    versionPart.textContent = login.httpRealm;
-    versionPart.className = "realm";
-    details.appendChild(versionPart);
-
-    let descPart = document.createElement("div");
-    descPart.textContent = login.username;
-    descPart.className = "username";
-    inner.appendChild(descPart);
-
-    loginItem.appendChild(inner);
-    loginItem.login = login;
-    return loginItem;
-  },
-
-  handleEvent: function(event) {
-    switch (event.type) {
-      case "popstate": {
-        this._onPopState(event);
-        break;
-      }
-      case "contextmenu":
-      case "click": {
-        this._onLoginClick(event);
-        break;
-      }
-    }
-  },
-
-  observe: function(subject, topic, data) {
-    switch (topic) {
-      case "passwordmgr-storage-changed": {
-        this._reloadList();
-        break;
-      }
-    }
-  },
-
-  _filter: function(event) {
-    let value = event.target.value.toLowerCase();
-    let logins = this._logins.filter(login => {
-      if (login.origin.toLowerCase().includes(value)) {
-        return true;
-      }
-      if (login.username && login.username.toLowerCase().includes(value)) {
-        return true;
-      }
-      if (login.httpRealm && login.httpRealm.toLowerCase().includes(value)) {
-        return true;
-      }
-      return false;
-    });
-
-    this._loadList(logins);
-  },
-};
-
-window.addEventListener("load", Logins.init.bind(Logins));
-window.addEventListener("unload", Logins.uninit.bind(Logins));
deleted file mode 100644
--- a/mobile/android/chrome/content/aboutLogins.xhtml
+++ /dev/null
@@ -1,90 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
-"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" [
-<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd" >
-%globalDTD;
-<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
-%brandDTD;
-<!ENTITY % aboutDTD SYSTEM "chrome://browser/locale/aboutLogins.dtd" >
-%aboutDTD;
-]>
-<!-- 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/. -->
-<html xmlns="http://www.w3.org/1999/xhtml">
-  <head>
-    <title>&aboutLogins.title;</title>
-    <meta name="viewport" content="width=device-width; user-scalable=0" />
-    <link rel="icon" type="image/png" sizes="64x64" href="chrome://branding/content/favicon64.png" />
-    <link rel="stylesheet" href="chrome://browser/skin/spinner.css" type="text/css"/>
-    <link rel="stylesheet" href="chrome://browser/skin/aboutBase.css" type="text/css"/>
-    <link rel="stylesheet" href="chrome://browser/skin/aboutLogins.css" type="text/css"/>
-    <script type="application/javascript" src="chrome://browser/content/aboutLogins.js"></script>
-  </head>
-  <body dir="&locale.dir;">
-
-    <div id="logins-list-page">
-      <div id="logins-header" class="header">
-        <div>&aboutLogins.title;</div>
-        <ul class="toolbar-buttons">
-          <li id="filter-button"></li>
-        </ul>
-      </div>
-      <div id="content-body">
-        <div id="logins-list" class="list"/>
-        <div id="filter-input-container" hidden="true">
-          <input id="filter-input" type="search"/>
-          <div id="filter-clear"/>
-        </div>
-      </div>
-      <div id="logins-list-loading-body" class="hidden">
-        <div id="loading-img-container">
-
-          <div id="spinner" class="mui-refresh-main">
-            <div class="mui-refresh-wrapper">
-              <div class="mui-spinner-wrapper">
-                <div class="mui-spinner-main">
-                  <div class="mui-spinner-left">
-                    <div class="mui-half-circle-left" />
-                  </div>
-                  <div class="mui-spinner-right">
-                    <div class="mui-half-circle-right" />
-                  </div>
-                </div>
-              </div>
-            </div>
-          </div>
-
-        </div>
-      </div>
-      <div id="empty-body" class="hidden">
-        <div id="empty-obj-text-container">
-          <object type="image/svg+xml" id="empty-icon" data="chrome://browser/skin/images/icon_key_emptypage.svg"/>
-          <div class="empty-text">&aboutLogins.emptyLoginText;</div>
-          <div class="empty-hint">&aboutLogins.emptyLoginHint;</div>
-        </div>
-      </div>
-    </div>
-
-    <div id="edit-login-page" class="hidden">
-      <div id="edit-login-header" class="header">
-        <div id="edit-login-header-text"/>
-      </div>
-      <div class="edit-login-div">
-        <div id="favicon" class="edit-login-icon"/>
-          <input type="text" name="origin" id="origin" class="edit-login-input" disabled="disabled"/>
-      </div>
-      <div class="edit-login-div">
-        <input type="text" name="username" id="username" class="edit-login-input" autocomplete="off"/>
-      </div>
-      <div class="edit-login-div">
-        <input type="password" id="password" name="password" value="password" class="edit-login-input" />
-        <button id="password-btn"></button>
-      </div>
-      <div class="edit-login-div">
-        <button id="update-btn" class="update-button">&aboutLogins.update;</button>
-      </div>
-    </div>
-
-  </body>
-</html>
deleted file mode 100644
--- a/mobile/android/chrome/content/aboutPrivateBrowsing.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const { XPCOMUtils } = ChromeUtils.import(
-  "resource://gre/modules/XPCOMUtils.jsm"
-);
-ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { PrivateBrowsingUtils } = ChromeUtils.import(
-  "resource://gre/modules/PrivateBrowsingUtils.jsm"
-);
-
-XPCOMUtils.defineLazyGetter(
-  window,
-  "gChromeWin",
-  () => window.docShell.rootTreeItem.domWindow
-);
-
-document.addEventListener("DOMContentLoaded", function() {
-  let BrowserApp = window.gChromeWin.BrowserApp;
-
-  if (!PrivateBrowsingUtils.isContentWindowPrivate(window)) {
-    document.body.setAttribute("class", "normal");
-    document
-      .getElementById("newPrivateTabLink")
-      .addEventListener("click", function() {
-        BrowserApp.addTab("about:privatebrowsing", {
-          selected: true,
-          parentId: BrowserApp.selectedTab.id,
-          isPrivate: true,
-        });
-      });
-  }
-});
deleted file mode 100644
--- a/mobile/android/chrome/content/aboutPrivateBrowsing.xhtml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
--->
-<!DOCTYPE html [
-  <!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
-  %htmlDTD;
-  <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
-  %brandDTD;
-  <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
-  %globalDTD;
-  <!ENTITY % privatebrowsingpageDTD SYSTEM "chrome://browser/locale/aboutPrivateBrowsing.dtd">
-  %privatebrowsingpageDTD;
-]>
-
-<html xmlns="http://www.w3.org/1999/xhtml">
-  <head>
-    <title>&privatebrowsingpage.title;</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1; user-scalable=no"/>
-    <link rel="stylesheet" href="chrome://browser/skin/aboutPrivateBrowsing.css" type="text/css" media="all"/>
-    <link rel="icon" type="image/png" href="chrome://branding/content/favicon32.png" />
-    <script type="application/javascript" src="chrome://browser/content/aboutPrivateBrowsing.js"></script>
-  </head>
-
-  <body class="private" dir="&locale.dir;">
-    <img class="showPrivate masq" src="chrome://browser/skin/images/privatebrowsing-mask-and-shield.svg" />
-    <img class="showNormal masq" src="chrome://browser/skin/images/privatebrowsing-mask.png" />
-
-    <h1 class="showPrivate">&privatebrowsingpage.title;<br />&privatebrowsingpage.title.private;</h1>
-    <h1 class="showNormal">&privatebrowsingpage.title.normal1;</h1>
-
-    <div class="contentSection">
-      <p class="showPrivate">&privatebrowsingpage.description.trackingProtection;<br /><br />&privatebrowsingpage.description.privateDetails;</p>
-      <p class="showNormal">&privatebrowsingpage.description.normal2;</p>
-
-      <p class="showPrivate"><a href="https://support.mozilla.org/kb/private-browsing-firefox-android">&privatebrowsingpage.link.private;</a></p>
-      <p class="showNormal"><a href="#" id="newPrivateTabLink">&privatebrowsingpage.link.normal;</a></p>
-    </div>
-
-  </body>
-</html>
deleted file mode 100644
--- a/mobile/android/chrome/content/aboutRights.xhtml
+++ /dev/null
@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html [
-    <!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
-    %htmlDTD;
-    ]>
-
-<!-- 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/. -->
-
-<html xmlns="http://www.w3.org/1999/xhtml">
-
-<head>
-  <title data-l10n-id="rights-title"></title>
-  <link rel="stylesheet" href="chrome://global/skin/in-content/info-pages.css" type="text/css"/>
-  <link rel="localization" href="branding/brand.ftl"/>
-  <link rel="localization" href="toolkit/about/aboutRights.ftl"/>
-</head>
-
-<body id="your-rights">
-<div class="container">
-  <h1 data-l10n-id="rights-title"></h1>
-
-  <p data-l10n-id="rights-intro"></p>
-
-  <ul>
-    <li data-l10n-id="rights-intro-point-1"><a href="http://www.mozilla.org/MPL/" data-l10n-name="mozilla-public-license-link"></a></li>
-  <!-- Point 2 discusses Mozilla trademarks, and isn't needed when the build is unbranded.
-    - Point 4 discusses privacy policy, unbranded builds get a placeholder (for the vendor to replace)
-    - Point 5 discusses web service terms, unbranded builds gets a placeholder (for the vendor to replace) -->
-    <li data-l10n-id="rights-intro-point-2"><a href="http://www.mozilla.org/foundation/trademarks/policy.html" data-l10n-name="mozilla-trademarks-link"></a></li>
-    <li data-l10n-id="rights-intro-point-3"></li>
-    <li data-l10n-id="rights-intro-point-4"><a href="https://www.mozilla.org/legal/privacy/firefox.html" data-l10n-name="mozilla-privacy-policy-link"></a></li>
-    <li data-l10n-id="rights-intro-point-5"><a href="about:rights#webservices" onclick="showServices();" data-l10n-name="mozilla-service-terms-link"></a></li>
-    <li data-l10n-id="rights-intro-point-6"></li>
-  </ul>
-
-  <div id="webservices-container">
-    <a name="webservices"/>
-    <h3 data-l10n-id="rights-webservices-header"></h3>
-
-    <p data-l10n-id="rights-webservices"><a href="about:rights#disabling-webservices" onclick="showDisablingServices();" id="showDisablingWebServices" data-l10n-name="mozilla-disable-service-link"></a></p>
-
-    <div id="disabling-webservices-container" style="margin-left:40px;">
-      <a name="disabling-webservices"/>
-      <!-- Safe Browsing cannot be disabled in Firefox Mobile; these instructions show how to do it on desktop
-      <p><strong>&rights.safebrowsing-a;</strong>&rights.safebrowsing-b;</p>
-      <ul>
-        <li>&rights.safebrowsing-term1;</li>
-        <li>&rights.safebrowsing-term2;</li>
-        <li>&rights2.safebrowsing-term3;</li>
-        <li>&rights.safebrowsing-term4;</li>
-      </ul>
-      -->
-
-      <p data-l10n-id="rights-locationawarebrowsing"></p>
-      <ul>
-        <li data-l10n-id="rights-locationawarebrowsing-term-1"></li>
-        <li data-l10n-id="rights-locationawarebrowsing-term-2"></li>
-        <li data-l10n-id="rights-locationawarebrowsing-term-3"></li>
-        <li data-l10n-id="rights-locationawarebrowsing-term-4"></li>
-      </ul>
-    </div>
-
-    <ol>
-      <!-- Terms only apply to official builds, unbranded builds get a placeholder. -->
-      <li data-l10n-id="rights-webservices-term-1"></li>
-      <li data-l10n-id="rights-webservices-term-2"></li>
-      <li data-l10n-id="rights-webservices-term-3"></li>
-      <li data-l10n-id="rights-webservices-term-4"></li>
-      <li data-l10n-id="rights-webservices-term-5"></li>
-      <li data-l10n-id="rights-webservices-term-6"></li>
-      <li data-l10n-id="rights-webservices-term-7"></li>
-    </ol>
-  </div>
-</div>
-
-<script type="application/javascript"><![CDATA[
-  var servicesDiv = document.getElementById("webservices-container");
-  servicesDiv.style.display = "none";
-
-  function showServices() {
-    servicesDiv.style.display = "";
-  }
-
-  var disablingServicesDiv = document.getElementById("disabling-webservices-container");
-  disablingServicesDiv.style.display = "none";
-
-  function showDisablingServices() {
-    disablingServicesDiv.style.display = "";
-  }
-]]></script>
-
-</body>
-</html>
deleted file mode 100644
--- a/mobile/android/chrome/content/blockedSite.xhtml
+++ /dev/null
@@ -1,211 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!DOCTYPE html [
-  <!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
-  %htmlDTD;
-  <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
-  %globalDTD;
-  <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
-  %brandDTD;
-  <!ENTITY % blockedSiteDTD SYSTEM "chrome://browser/locale/phishing.dtd">
-  %blockedSiteDTD;
-]>
-
-<!-- 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/. -->
-
-<html xmlns="http://www.w3.org/1999/xhtml">
-  <head>
-    <meta name="viewport" content="width=device-width; user-scalable=false" />
-    <link rel="stylesheet" href="chrome://browser/skin/netError.css" media="all" />
-    <link rel="icon" type="image/png" id="favicon" sizes="64x64" href="chrome://browser/skin/images/blocked-warning.png"/>
-
-    <script type="application/javascript"><![CDATA[
-      // Error url MUST be formatted like this:
-      //   about:blocked?e=error_code&u=url(&o=1)?
-      //     (o=1 when user overrides are allowed)
-
-      // Note that this file uses document.documentURI to get
-      // the URL (with the format from above). This is because
-      // document.location.href gets the current URI off the docshell,
-      // which is the URL displayed in the location bar, i.e.
-      // the URI that the user attempted to load.
-
-      function getErrorCode() {
-        var url = document.documentURI;
-        var error = url.search(/e\=/);
-        var duffUrl = url.search(/\&u\=/);
-        return decodeURIComponent(url.slice(error + 2, duffUrl));
-      }
-
-      function getURL() {
-        var url = document.documentURI;
-        var match = url.match(/&u=([^&]+)&/);
-
-        // match == null if not found; if so, return an empty string
-        // instead of what would turn out to be portions of the URI
-        if (!match)
-          return "";
-
-        url = decodeURIComponent(match[1]);
-
-        // If this is a view-source page, then get then real URI of the page
-        if (/^view-source\:/.test(url))
-          url = url.slice(12);
-        return url;
-      }
-
-      /**
-       * Check whether this warning page should be overridable or whether
-       * the "ignore warning" button should be hidden.
-       */
-      function getOverride() {
-        var url = document.documentURI;
-        var match = url.match(/&o=1&/);
-        return !!match;
-      }
-
-      /**
-       * Attempt to get the hostname via document.location.  Fail back
-       * to getURL so that we always return something meaningful.
-       */
-      function getHostString() {
-        try {
-          return document.location.hostname;
-        } catch (e) {
-          return getURL();
-        }
-      }
-
-      function initPage() {
-        var error = "";
-        switch (getErrorCode()) {
-          case "malwareBlocked" :
-            error = "malware";
-            break;
-          case "deceptiveBlocked" :
-            error = "phishing";
-            break;
-          case "unwantedBlocked" :
-            error = "unwanted";
-            break;
-          case "harmfulBlocked" :
-            error = "harmful";
-            break;
-          default:
-            return;
-        }
-
-        var el;
-
-        if (error !== "malware") {
-          el = document.getElementById("errorTitleText_malware");
-          el.remove();
-          el = document.getElementById("errorShortDescText_malware");
-          el.remove();
-          el = document.getElementById("errorLongDescText_malware");
-          el.remove();
-        }
-
-        if (error !== "phishing") {
-          el = document.getElementById("errorTitleText_phishing");
-          el.remove();
-          el = document.getElementById("errorShortDescText_phishing");
-          el.remove();
-          el = document.getElementById("errorLongDescText_phishing");
-          el.remove();
-        }
-
-        if (error !== "unwanted") {
-          el = document.getElementById("errorTitleText_unwanted");
-          el.remove();
-          el = document.getElementById("errorShortDescText_unwanted");
-          el.remove();
-          el = document.getElementById("errorLongDescText_unwanted");
-          el.remove();
-        }
-
-        if (error !== "harmful") {
-          el = document.getElementById("errorTitleText_harmful");
-          el.remove();
-          el = document.getElementById("errorShortDescText_harmful");
-          el.remove();
-        }
-
-        if (!getOverride()) {
-          var btn = document.getElementById("ignoreWarningButton");
-          if (btn) {
-            btn.remove();
-          }
-        }
-
-        // Set sitename
-        let siteElem = document.getElementById(error + "_sitename");
-        if (siteElem) {
-          siteElem.textContent = getHostString();
-        }
-
-        document.title = document.getElementById("errorTitleText_" + error)
-                                 .innerHTML;
-
-        // Inform the test harness that we're done loading the page
-        var event = new CustomEvent("AboutBlockedLoaded", { bubbles: true });
-        document.dispatchEvent(event);
-      }
-    ]]></script>
-  </head>
-
-  <body id="errorPage" class="blockedsite" dir="&locale.dir;">
-
-    <div id="errorPageContainer">
-
-      <!-- Error Title -->
-      <div id="errorTitle">
-        <h1 id="errorTitleText_phishing" class="errorTitleText">&safeb.blocked.phishingPage.title3;</h1>
-        <h1 id="errorTitleText_malware" class="errorTitleText">&safeb.blocked.malwarePage.title;</h1>
-        <h1 id="errorTitleText_unwanted" class="errorTitleText">&safeb.blocked.unwantedPage.title;</h1>
-        <h1 id="errorTitleText_harmful" class="errorTitleText">&safeb.blocked.harmfulPage.title;</h1>
-      </div>
-
-      <div id="errorLongContent">
-
-        <!-- Short Description -->
-        <div id="errorShortDesc">
-          <p id="errorShortDescText_phishing">&safeb.blocked.phishingPage.shortDesc3;</p>
-          <p id="errorShortDescText_malware">&safeb.blocked.malwarePage.shortDesc;</p>
-          <p id="errorShortDescText_unwanted">&safeb.blocked.unwantedPage.shortDesc;</p>
-          <p id="errorShortDescText_harmful">&safeb.blocked.harmfulPage.shortDesc;</p>
-        </div>
-
-        <!-- Long Description -->
-        <div id="errorLongDesc">
-          <p id="errorLongDescText_phishing">&safeb.blocked.phishingPage.longDesc3;</p>
-          <p id="errorLongDescText_malware">&safeb.blocked.malwarePage.longDesc;</p>
-          <p id="errorLongDescText_unwanted">&safeb.blocked.unwantedPage.longDesc;</p>
-        </div>
-
-        <!-- Advisory -->
-        <div id="advisoryDesc">
-          <p id="advisoryDescText">&safeb.palm.advisory.desc;</p>
-        </div>
-
-        <!-- Action buttons -->
-        <div id="buttons">
-          <!-- Commands handled in browser.js -->
-          <button id="getMeOutButton">&safeb.palm.accept.label;</button>
-          <button id="reportButton">&safeb.palm.reportPage.label;</button>
-        </div>
-      </div>
-      <div id="ignoreWarning">
-        <button id="ignoreWarningButton">&safeb.palm.decline.label;</button>
-      </div>
-    </div>
-    <!--
-    - Note: It is important to run the script this way, instead of using
-    - an onload handler. This is because error pages are loaded as
-    - LOAD_BACKGROUND, which means that onload handlers will not be executed.
-    -->
-    <script type="application/javascript">initPage();</script>
-  </body>
-</html>
deleted file mode 100644
--- a/mobile/android/chrome/content/browser.css
+++ /dev/null
@@ -1,4 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
deleted file mode 100644
--- a/mobile/android/chrome/content/browser.js
+++ /dev/null
@@ -1,8150 +0,0 @@
-// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
-/* 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 { AddonManager } = ChromeUtils.import(
-  "resource://gre/modules/AddonManager.jsm"
-);
-var { AppConstants } = ChromeUtils.import(
-  "resource://gre/modules/AppConstants.jsm"
-);
-var { DelayedInit } = ChromeUtils.import(
-  "resource://gre/modules/DelayedInit.jsm"
-);
-var { EventDispatcher } = ChromeUtils.import(
-  "resource://gre/modules/Messaging.jsm"
-);
-var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-var { XPCOMUtils } = ChromeUtils.import(
-  "resource://gre/modules/XPCOMUtils.jsm"
-);
-var { TelemetryController } = ChromeUtils.import(
-  "resource://gre/modules/TelemetryController.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "AsyncPrefs",
-  "resource://gre/modules/AsyncPrefs.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "Manifests",
-  "resource://gre/modules/Manifest.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "FileUtils",
-  "resource://gre/modules/FileUtils.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "UITelemetry",
-  "resource://gre/modules/UITelemetry.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "PluralForm",
-  "resource://gre/modules/PluralForm.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "Downloads",
-  "resource://gre/modules/Downloads.jsm"
-);
-
-ChromeUtils.defineModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "SafeBrowsing",
-  "resource://gre/modules/SafeBrowsing.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "BrowserUtils",
-  "resource://gre/modules/BrowserUtils.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "PrivateBrowsingUtils",
-  "resource://gre/modules/PrivateBrowsingUtils.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "Sanitizer",
-  "resource://gre/modules/Sanitizer.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "Prompt",
-  "resource://gre/modules/Prompt.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "HelperApps",
-  "resource://gre/modules/HelperApps.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "FormHistory",
-  "resource://gre/modules/FormHistory.jsm"
-);
-
-XPCOMUtils.defineLazyServiceGetter(
-  this,
-  "uuidgen",
-  "@mozilla.org/uuid-generator;1",
-  "nsIUUIDGenerator"
-);
-
-XPCOMUtils.defineLazyGetter(this, "DEFAULT_UA", function() {
-  return Cc["@mozilla.org/network/protocol;1?name=http"].getService(
-    Ci.nsIHttpProtocolHandler
-  ).userAgent;
-});
-
-XPCOMUtils.defineLazyGetter(this, "DESKTOP_UA", function() {
-  return DEFAULT_UA.replace(
-    /Android \d.+?; [a-zA-Z]+/,
-    "X11; Linux x86_64"
-  ).replace(/Gecko\/[0-9\.]+/, "Gecko/20100101");
-});
-
-if (AppConstants.MOZ_ENABLE_PROFILER_SPS) {
-  XPCOMUtils.defineLazyServiceGetter(
-    this,
-    "Profiler",
-    "@mozilla.org/tools/profiler;1",
-    "nsIProfiler"
-  );
-}
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "SimpleServiceDiscovery",
-  "resource://gre/modules/SimpleServiceDiscovery.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "CharsetMenu",
-  "resource://gre/modules/CharsetMenu.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "NetErrorHelper",
-  "resource://gre/modules/NetErrorHelper.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "PermissionsUtils",
-  "resource://gre/modules/PermissionsUtils.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "Preferences",
-  "resource://gre/modules/Preferences.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "SharedPreferences",
-  "resource://gre/modules/SharedPreferences.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "Notifications",
-  "resource://gre/modules/Notifications.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "ReaderMode",
-  "resource://gre/modules/ReaderMode.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "Snackbars",
-  "resource://gre/modules/Snackbars.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "RuntimePermissions",
-  "resource://gre/modules/RuntimePermissions.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "WebsiteMetadata",
-  "resource://gre/modules/WebsiteMetadata.jsm"
-);
-
-XPCOMUtils.defineLazyServiceGetter(
-  this,
-  "FontEnumerator",
-  "@mozilla.org/gfx/fontenumerator;1",
-  "nsIFontEnumerator"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "E10SUtils",
-  "resource://gre/modules/E10SUtils.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "FormLikeFactory",
-  "resource://gre/modules/FormLikeFactory.jsm"
-);
-ChromeUtils.defineModuleGetter(
-  this,
-  "GeckoViewAutofill",
-  "resource://gre/modules/GeckoViewAutofill.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "ContentBlockingAllowList",
-  "resource://gre/modules/ContentBlockingAllowList.jsm"
-);
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "GMPInstallManager",
-  "resource://gre/modules/GMPInstallManager.jsm"
-);
-
-var GlobalEventDispatcher = EventDispatcher.instance;
-var WindowEventDispatcher = EventDispatcher.for(window);
-
-var lazilyLoadedBrowserScripts = [
-  ["MasterPassword", "chrome://browser/content/MasterPassword.js"],
-  ["OfflineApps", "chrome://browser/content/OfflineApps.js"],
-  ["Linkifier", "chrome://browser/content/Linkify.js"],
-  ["CastingApps", "chrome://browser/content/CastingApps.js"],
-  ["RemoteDebugger", "chrome://browser/content/RemoteDebugger.js"],
-  ["gViewSourceUtils", "chrome://global/content/viewSourceUtils.js"],
-];
-
-lazilyLoadedBrowserScripts.forEach(function(aScript) {
-  let [name, script] = aScript;
-  XPCOMUtils.defineLazyGetter(window, name, function() {
-    let sandbox = {};
-    Services.scriptloader.loadSubScript(script, sandbox);
-    return sandbox[name];
-  });
-});
-
-var lazilyLoadedObserverScripts = [
-  [
-    "MemoryObserver",
-    ["memory-pressure", "memory-pressure-stop", "Memory:Dump"],
-    "chrome://browser/content/MemoryObserver.js",
-  ],
-  [
-    "ConsoleAPI",
-    ["console-api-log-event"],
-    "chrome://browser/content/ConsoleAPI.js",
-  ],
-  [
-    "ExtensionPermissions",
-    [
-      "webextension-permission-prompt",
-      "webextension-update-permissions",
-      "webextension-optional-permission-prompt",
-    ],
-    "chrome://browser/content/ExtensionPermissions.js",
-  ],
-];
-
-lazilyLoadedObserverScripts.forEach(function(aScript) {
-  let [name, notifications, script] = aScript;
-  XPCOMUtils.defineLazyGetter(window, name, function() {
-    let sandbox = {};
-    Services.scriptloader.loadSubScript(script, sandbox);
-    return sandbox[name];
-  });
-  let observer = (s, t, d) => {
-    Services.obs.removeObserver(observer, t);
-    Services.obs.addObserver(window[name], t);
-    window[name].observe(s, t, d); // Explicitly notify new observer
-  };
-  notifications.forEach(notification => {
-    Services.obs.addObserver(observer, notification);
-  });
-});
-
-// Lazily-loaded browser scripts that use message listeners.
-[
-  [
-    "Reader",
-    [
-      ["Reader:AddToCache", false],
-      ["Reader:RemoveFromCache", false],
-      ["Reader:ArticleGet", false],
-      ["Reader:DropdownClosed", true], // 'true' allows us to survive mid-air cycle-collection.
-      ["Reader:DropdownOpened", false],
-      ["Reader:FaviconRequest", false],
-      ["Reader:ToolbarHidden", false],
-      ["Reader:SystemUIVisibility", false],
-      ["Reader:UpdateReaderButton", false],
-    ],
-    "chrome://browser/content/Reader.js",
-  ],
-].forEach(aScript => {
-  let [name, messages, script] = aScript;
-  XPCOMUtils.defineLazyGetter(window, name, function() {
-    let sandbox = {};
-    Services.scriptloader.loadSubScript(script, sandbox);
-    return sandbox[name];
-  });
-
-  let mm = window.getGroupMessageManager("browsers");
-  let listener = message => {
-    mm.removeMessageListener(message.name, listener);
-    let listenAfterClose = false;
-    for (let [name, laClose] of messages) {
-      if (message.name === name) {
-        listenAfterClose = laClose;
-        break;
-      }
-    }
-
-    mm.addMessageListener(message.name, window[name], listenAfterClose);
-    window[name].receiveMessage(message);
-  };
-
-  messages.forEach(message => {
-    let [name, listenAfterClose] = message;
-    mm.addMessageListener(name, listener, listenAfterClose);
-  });
-});
-
-// Lazily-loaded JS subscripts and modules that use global/window EventDispatcher.
-[
-  [
-    "EmbedRT",
-    WindowEventDispatcher,
-    ["GeckoView:ImportScript"],
-    "chrome://browser/content/EmbedRT.js",
-  ],
-  [
-    "Feedback",
-    GlobalEventDispatcher,
-    ["Feedback:Show"],
-    "chrome://browser/content/Feedback.js",
-  ],
-  [
-    "FeedHandler",
-    GlobalEventDispatcher,
-    ["Feeds:Subscribe"],
-    "chrome://browser/content/FeedHandler.js",
-  ],
-  [
-    "FindHelper",
-    GlobalEventDispatcher,
-    ["FindInPage:Opened", "FindInPage:Closed"],
-    "chrome://browser/content/FindHelper.js",
-  ],
-  [
-    "Home",
-    GlobalEventDispatcher,
-    [
-      "HomeBanner:Get",
-      "HomePanels:Get",
-      "HomePanels:Authenticate",
-      "HomePanels:RefreshView",
-      "HomePanels:Installed",
-      "HomePanels:Uninstalled",
-    ],
-    "resource://gre/modules/Home.jsm",
-  ],
-  [
-    "PermissionsHelper",
-    GlobalEventDispatcher,
-    ["Permissions:Check", "Permissions:Get", "Permissions:Clear"],
-    "chrome://browser/content/PermissionsHelper.js",
-  ],
-  [
-    "PrintHelper",
-    GlobalEventDispatcher,
-    ["Print:PDF"],
-    "chrome://browser/content/PrintHelper.js",
-  ],
-  [
-    "Reader",
-    GlobalEventDispatcher,
-    ["Reader:AddToCache", "Reader:RemoveFromCache"],
-    "chrome://browser/content/Reader.js",
-  ],
-].forEach(module => {
-  let [name, dispatcher, events, script] = module;
-  XPCOMUtils.defineLazyGetter(window, name, function() {
-    let sandbox = {};
-    if (script.endsWith(".jsm")) {
-      ChromeUtils.import(script, sandbox);
-    } else {
-      Services.scriptloader.loadSubScript(script, sandbox);
-    }
-    return sandbox[name];
-  });
-  let listener = (event, message, callback) => {
-    dispatcher.unregisterListener(listener, event);
-    dispatcher.registerListener(window[name], event);
-    window[name].onEvent(event, message, callback); // Explicitly notify new listener
-  };
-  dispatcher.registerListener(listener, events);
-});
-
-XPCOMUtils.defineLazyServiceGetter(
-  this,
-  "Haptic",
-  "@mozilla.org/widget/hapticfeedback;1",
-  "nsIHapticFeedback"
-);
-
-XPCOMUtils.defineLazyServiceGetter(
-  this,
-  "ParentalControls",
-  "@mozilla.org/parental-controls-service;1",
-  "nsIParentalControlsService"
-);
-
-XPCOMUtils.defineLazyModuleGetter(
-  this,
-  "Log",
-  "resource://gre/modules/AndroidLog.jsm",
-  "AndroidLog"
-);
-
-// Define the "dump" function as a binding of the Log.d function so it specifies
-// the "debug" priority and a log tag.
-function dump(msg) {
-  Log.d("Browser", msg);
-}
-
-const kStateActive = 0x00000001; // :active pseudoclass for elements
-
-const kXLinkNamespace = "http://www.w3.org/1999/xlink";
-
-function fuzzyEquals(a, b) {
-  return Math.abs(a - b) < 1e-6;
-}
-
-XPCOMUtils.defineLazyGetter(this, "ContentAreaUtils", function() {
-  let ContentAreaUtils = {};
-  Services.scriptloader.loadSubScript(
-    "chrome://global/content/contentAreaUtils.js",
-    ContentAreaUtils
-  );
-  return ContentAreaUtils;
-});
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "Rect",
-  "resource://gre/modules/Geometry.jsm"
-);
-ChromeUtils.defineModuleGetter(
-  this,
-  "Point",
-  "resource://gre/modules/Geometry.jsm"
-);
-
-function resolveGeckoURI(aURI) {
-  if (!aURI) {
-    throw new Error("Can't resolve an empty uri");
-  }
-
-  if (aURI.startsWith("chrome://")) {
-    let registry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(
-      Ci.nsIChromeRegistry
-    );
-    return registry.convertChromeURL(Services.io.newURI(aURI)).spec;
-  } else if (aURI.startsWith("resource://")) {
-    let handler = Services.io
-      .getProtocolHandler("resource")
-      .QueryInterface(Ci.nsIResProtocolHandler);
-    return handler.resolveURI(Services.io.newURI(aURI));
-  }
-  return aURI;
-}
-
-XPCOMUtils.defineLazyGetter(this, "ReferrerInfo", () =>
-  Components.Constructor(
-    "@mozilla.org/referrer-info;1",
-    "nsIReferrerInfo",
-    "init"
-  )
-);
-
-function createReferrerInfo(aReferrer) {
-  let referrerUri;
-  try {
-    referrerUri = Services.io.newURI(aReferrer);
-  } catch (ignored) {}
-
-  return new ReferrerInfo(Ci.nsIReferrerInfo.EMPTY, true, referrerUri);
-}
-
-/**
- * Cache of commonly used string bundles.
- */
-var Strings = {
-  init: function() {
-    XPCOMUtils.defineLazyGetter(Strings, "brand", () =>
-      Services.strings.createBundle("chrome://branding/locale/brand.properties")
-    );
-    XPCOMUtils.defineLazyGetter(Strings, "browser", () =>
-      Services.strings.createBundle(
-        "chrome://browser/locale/browser.properties"
-      )
-    );
-    XPCOMUtils.defineLazyGetter(Strings, "reader", () =>
-      Services.strings.createBundle(
-        "chrome://global/locale/aboutReader.properties"
-      )
-    );
-  },
-
-  flush: function() {
-    Services.strings.flushBundles();
-    this.init();
-  },
-};
-
-Strings.init();
-
-const kFormHelperModeDisabled = 0;
-const kFormHelperModeEnabled = 1;
-const kFormHelperModeDynamic = 2; // disabled on tablets
-const kMaxHistoryListSize = 50;
-
-function InitLater(fn, object, name) {
-  return DelayedInit.schedule(fn, object, name, 15000 /* 15s max wait */);
-}
-
-var BrowserApp = {
-  _tabs: [],
-  _selectedTab: null,
-
-  get isTablet() {
-    let sysInfo = Cc["@mozilla.org/system-info;1"].getService(
-      Ci.nsIPropertyBag2
-    );
-    delete this.isTablet;
-    return (this.isTablet = sysInfo.get("tablet"));
-  },
-
-  get isOnLowMemoryPlatform() {
-    let memory = Cc["@mozilla.org/xpcom/memory-service;1"].getService(
-      Ci.nsIMemory
-    );
-    delete this.isOnLowMemoryPlatform;
-    return (this.isOnLowMemoryPlatform = memory.isLowMemoryPlatform());
-  },
-
-  // Note that the deck list order does not necessarily reflect the user visible tab order (see
-  // bug 1331154 for the reason), so deck.selectedIndex should not be used (though
-  // deck.selectedPanel is still valid) - use selectedTabIndex instead.
-  deck: null,
-
-  startup: function startup() {
-    window.browserDOMWindow = new nsBrowserAccess();
-    Services.obs.notifyObservers(this.browser, "BrowserChrome:Ready");
-
-    this.deck = document.getElementById("browsers");
-
-    BrowserEventHandler.init();
-
-    Services.androidBridge.browserApp = this;
-
-    WindowEventDispatcher.registerListener(this, [
-      "GeckoView:ZoomToInput",
-      "Session:Restore",
-      "Tab:Load",
-      "Tab:Selected",
-      "Tab:Closed",
-      "Tab:Move",
-      "Tab:OpenUri",
-      "Tab:ViewSource",
-    ]);
-
-    GlobalEventDispatcher.registerListener(this, [
-      "Browser:LoadManifest",
-      "Browser:Quit",
-      "DesktopMode:Change",
-      "Fonts:Reload",
-      "FormHistory:Init",
-      "FullScreen:Exit",
-      "Locale:OS",
-      "Locale:Changed",
-      "Passwords:Init",
-      "Sanitize:ClearData",
-      "SaveAs:PDF",
-      "Session:Back",
-      "Session:Forward",
-      "Session:GetHistory",
-      "Session:Navigate",
-      "Session:Reload",
-      "Session:Stop",
-      "Telemetry:CustomTabsPing",
-    ]);
-
-    // Provide compatibility for add-ons like QuitNow that send "Browser:Quit"
-    // as an observer notification.
-    Services.obs.addObserver(
-      (subject, topic, data) => this.quit(data ? JSON.parse(data) : undefined),
-      "Browser:Quit"
-    );
-
-    Services.obs.addObserver(this, "android-get-pref");
-    Services.obs.addObserver(this, "android-set-pref");
-    Services.obs.addObserver(this, "gather-telemetry");
-    Services.obs.addObserver(this, "keyword-search");
-    Services.obs.addObserver(this, "Vibration:Request");
-
-    window.addEventListener("fullscreen", function() {
-      WindowEventDispatcher.sendRequest({
-        type: window.fullScreen ? "ToggleChrome:Hide" : "ToggleChrome:Show",
-      });
-    });
-
-    window.addEventListener("fullscreenchange", e => {
-      WindowEventDispatcher.sendRequest({
-        type: document.fullscreenElement
-          ? "DOMFullScreen:Start"
-          : "DOMFullScreen:Stop",
-      });
-
-      if (this.fullscreenTransitionTab) {
-        // Tab selection has changed during a fullscreen transition, handle it now.
-        let tab = this.fullscreenTransitionTab;
-        this.fullscreenTransitionTab = null;
-        this.selectTab(tab);
-      }
-    });
-
-    NativeWindow.init();
-    IndexedDB.init();
-    XPInstallObserver.init();
-    CharacterEncoding.init();
-    ActivityObserver.init();
-    RemoteDebugger.init(window);
-    Distribution.init();
-    Tabs.init();
-    SearchEngines.init();
-    Experiments.init();
-
-    // XXX maybe we don't do this if the launch was kicked off from external
-    Services.io.offline = false;
-
-    // Broadcast a UIReady message so add-ons know we are finished with startup
-    let event = document.createEvent("Events");
-    event.initEvent("UIReady", true, false);
-    window.dispatchEvent(event);
-
-    if (this._startupStatus) {
-      this.onAppUpdated();
-    }
-
-    if (!ParentalControls.isAllowed(ParentalControls.INSTALL_EXTENSION)) {
-      // Disable extension installs
-      Services.prefs.setIntPref("extensions.enabledScopes", 5);
-      Services.prefs.setIntPref("extensions.autoDisableScopes", 1);
-      Services.prefs.setBoolPref("xpinstall.enabled", false);
-    } else if (ParentalControls.parentalControlsEnabled) {
-      Services.prefs.clearUserPref("extensions.enabledScopes");
-      Services.prefs.clearUserPref("extensions.autoDisableScopes");
-      Services.prefs.setBoolPref("xpinstall.enabled", true);
-    }
-
-    this.hideH264AddonIfNeeded();
-
-    if (ParentalControls.parentalControlsEnabled) {
-      let isBlockListEnabled = ParentalControls.isAllowed(
-        ParentalControls.BLOCK_LIST
-      );
-      Services.prefs.setBoolPref(
-        "browser.safebrowsing.allowOverride",
-        !isBlockListEnabled
-      );
-
-      let isTelemetryEnabled = ParentalControls.isAllowed(
-        ParentalControls.TELEMETRY
-      );
-      Services.prefs.setBoolPref(
-        "toolkit.telemetry.enabled",
-        isTelemetryEnabled
-      );
-
-      let isHealthReportEnabled = ParentalControls.isAllowed(
-        ParentalControls.HEALTH_REPORT
-      );
-      SharedPreferences.forApp().setBoolPref(
-        "android.not_a_preference.healthreport.uploadEnabled",
-        isHealthReportEnabled
-      );
-    }
-
-    InitLater(
-      () => {
-        // The order that context menu items are added is important
-        // Make sure the "Open in App" context menu item appears at the bottom of the list
-        this.initContextMenu();
-        ExternalApps.init();
-      },
-      NativeWindow,
-      "contextmenus"
-    );
-
-    InitLater(() => {
-      (async () => {
-        let downloadsDir = await Downloads.getPreferredDownloadsDirectory();
-        let logsDir = OS.Path.join(downloadsDir, "memory-reports");
-        await OS.File.removeDir(logsDir);
-      })();
-    });
-
-    // Don't delay loading content.js because when we restore reader mode tabs,
-    // we require the reader mode scripts in content.js right away.
-    let mm = window.getGroupMessageManager("browsers");
-    mm.loadFrameScript("chrome://browser/content/content.js", true, true);
-
-    // Listen to manifest messages
-    mm.loadFrameScript(
-      "chrome://global/content/manifestMessages.js",
-      true,
-      true
-    );
-
-    // We can't delay registering WebChannel listeners: if the first page is
-    // about:accounts, which can happen when starting the Firefox Account flow
-    // from the first run experience, or via the Firefox Account Status
-    // Activity, we can and do miss messages from the fxa-content-server.
-    // However, we never allow suitably restricted profiles from listening to
-    // fxa-content-server messages.
-    if (ParentalControls.isAllowed(ParentalControls.MODIFY_ACCOUNTS)) {
-      var { EnsureFxAccountsWebChannel } = ChromeUtils.import(
-        "resource://gre/modules/FxAccountsWebChannel.jsm"
-      );
-      EnsureFxAccountsWebChannel();
-    } else {
-      console.log(
-        "browser.js: not loading Firefox Accounts WebChannel; this profile cannot connect to Firefox Accounts."
-      );
-    }
-
-    // Notify Java that Gecko has loaded.
-    GlobalEventDispatcher.sendRequest({ type: "Gecko:Ready" });
-
-    this.deck.addEventListener(
-      "DOMContentLoaded",
-      function() {
-        ChromeUtils.import("resource://gre/modules/NotificationDB.jsm");
-
-        InitLater(() =>
-          Services.obs.notifyObservers(
-            window,
-            "browser-delayed-startup-finished"
-          )
-        );
-        InitLater(() =>
-          GlobalEventDispatcher.sendRequest({ type: "Gecko:DelayedStartup" })
-        );
-
-        // AsyncPrefs is needed for reader mode.
-        InitLater(() => AsyncPrefs.init());
-
-        // Collect telemetry data.
-        // We do this at startup because we want to move away from "gather-telemetry" (bug 1127907)
-        InitLater(() => {
-          Telemetry.addData(
-            "FENNEC_TRACKING_PROTECTION_STATE",
-            parseInt(BrowserApp.getTrackingProtectionState())
-          );
-        });
-
-        InitLater(() => LightWeightThemeStuff.init());
-        InitLater(() => CastingApps.init(), window, "CastingApps");
-
-        // Bug 778855 - Perf regression if we do this here. To be addressed in bug 779008.
-        InitLater(() => SafeBrowsing.init(), window, "SafeBrowsing");
-
-        // Start Marionette after all startup scripts have been run.
-        InitLater(() => {
-          Services.obs.notifyObservers(window, "marionette-startup-requested");
-        });
-
-        // This should always go last, since the idle tasks (except for the ones with
-        // timeouts) should execute in order. Note that this observer notification is
-        // not guaranteed to fire, since the window could close before we get here.
-        InitLater(() => {
-          Services.obs.notifyObservers(
-            window,
-            "browser-idle-startup-tasks-finished"
-          );
-        });
-      },
-      { once: true }
-    );
-  },
-
-  get _startupStatus() {
-    delete this._startupStatus;
-
-    let savedMilestone = Services.prefs.getCharPref(
-      "browser.startup.homepage_override.mstone",
-      ""
-    );
-    let ourMilestone = AppConstants.MOZ_APP_VERSION;
-    this._startupStatus = "";
-    if (ourMilestone != savedMilestone) {
-      Services.prefs.setCharPref(
-        "browser.startup.homepage_override.mstone",
-        ourMilestone
-      );
-      this._startupStatus = savedMilestone ? "upgrade" : "new";
-    }
-
-    return this._startupStatus;
-  },
-
-  /**
-   * Pass this a locale string, such as "fr" or "es_ES".
-   */
-  setLocale: function(locale) {
-    WindowEventDispatcher.sendRequest({ type: "Locale:Set", locale: locale });
-  },
-
-  hideH264AddonIfNeeded: function() {
-    let installManager = new GMPInstallManager();
-    installManager.checkForAddons().then(
-      ({ usedFallback, gmpAddons }) => {
-        gmpAddons.forEach(addon => {
-          if (addon && addon.id === "gmp-gmpopenh264" && !addon.isInstalled) {
-            Services.prefs.setBoolPref("media.gmp-gmpopenh264.visible", false);
-            Services.prefs.setBoolPref("media.gmp-gmpopenh264.enabled", false);
-          }
-        });
-      },
-      err => {
-        console.log(`Checking for addons failed with:${err}`);
-      }
-    );
-  },
-
-  initContextMenu: function() {
-    // We pass a thunk in place of a raw label string. This allows the
-    // context menu to automatically accommodate locale changes without
-    // having to be rebuilt.
-    let stringGetter = name => () => Strings.browser.GetStringFromName(name);
-
-    function videoClassifier(aTarget) {
-      if (aTarget.readyState == aTarget.HAVE_NOTHING) {
-        // We don't know if the height/width of the video,
-        // show a generic string.
-        return "Media";
-      } else if (aTarget.videoWidth == 0 || aTarget.videoHeight == 0) {
-        // If a video element is zero width or height, it's essentially
-        // an HTMLAudioElement.
-        return "Audio";
-      }
-      return "Video";
-    }
-
-    // TODO: These should eventually move into more appropriate classes
-    NativeWindow.contextmenus.add(
-      stringGetter("contextmenu.openInNewTab"),
-      NativeWindow.contextmenus.linkOpenableNonPrivateContext,
-      function(aTarget) {
-        UITelemetry.addEvent(
-          "action.1",
-          "contextmenu",
-          null,
-          "web_open_new_tab"
-        );
-        UITelemetry.addEvent("loadurl.1", "contextmenu", null);
-
-        let url = NativeWindow.contextmenus._getLinkURL(aTarget);
-        ContentAreaUtils.urlSecurityCheck(
-          url,
-          aTarget.ownerDocument.nodePrincipal
-        );
-        let tab = BrowserApp.addTab(url, {
-          selected: false,
-          parentId: BrowserApp.selectedTab.id,
-        });
-
-        let newtabStrings = Strings.browser.GetStringFromName(
-          "newtabpopup.opened"
-        );
-        let label = PluralForm.get(1, newtabStrings).replace("#1", 1);
-        let buttonLabel = Strings.browser.GetStringFromName(
-          "newtabpopup.switch"
-        );
-
-        Snackbars.show(label, Snackbars.LENGTH_LONG, {
-          action: {
-            label: buttonLabel,
-            callback: () => {
-              BrowserApp.selectTab(tab);
-            },
-          },
-        });
-      }
-    );
-
-    let showOpenInPrivateTab = true;
-    if ("@mozilla.org/parental-controls-service;1" in Cc) {
-      let pc = Cc["@mozilla.org/parental-controls-service;1"].createInstance(
-        Ci.nsIParentalControlsService
-      );
-      showOpenInPrivateTab = pc.isAllowed(
-        Ci.nsIParentalControlsService.PRIVATE_BROWSING
-      );
-    }
-
-    if (showOpenInPrivateTab) {
-      NativeWindow.contextmenus.add(
-        stringGetter("contextmenu.openInPrivateTab"),
-        NativeWindow.contextmenus.linkOpenableContext,
-        function(aTarget) {
-          UITelemetry.addEvent(
-            "action.1",
-            "contextmenu",
-            null,
-            "web_open_new_tab"
-          );
-          UITelemetry.addEvent("loadurl.1", "contextmenu", null);
-
-          let url = NativeWindow.contextmenus._getLinkURL(aTarget);
-          ContentAreaUtils.urlSecurityCheck(
-            url,
-            aTarget.ownerDocument.nodePrincipal
-          );
-          let tab = BrowserApp.addTab(url, {
-            selected: false,
-            parentId: BrowserApp.selectedTab.id,
-            isPrivate: true,
-          });
-
-          let newtabStrings = Strings.browser.GetStringFromName(
-            "newprivatetabpopup.opened"
-          );
-          let label = PluralForm.get(1, newtabStrings).replace("#1", 1);
-          let buttonLabel = Strings.browser.GetStringFromName(
-            "newtabpopup.switch"
-          );
-          Snackbars.show(label, Snackbars.LENGTH_LONG, {
-            action: {
-              label: buttonLabel,
-              callback: () => {
-                BrowserApp.selectTab(tab);
-              },
-            },
-          });
-        }
-      );
-    }
-
-    NativeWindow.contextmenus.add(
-      stringGetter("contextmenu.copyLink"),
-      NativeWindow.contextmenus.linkCopyableContext,
-      function(aTarget) {
-        UITelemetry.addEvent("action.1", "contextmenu", null, "web_copy_link");
-
-        let url = NativeWindow.contextmenus._getLinkURL(aTarget);
-        url = NativeWindow.contextmenus._stripViewSource(url);
-        NativeWindow.contextmenus._copyStringToDefaultClipboard(url);
-      }
-    );
-
-    NativeWindow.contextmenus.add(
-      stringGetter("contextmenu.copyEmailAddress"),
-      NativeWindow.contextmenus.emailLinkContext,
-      function(aTarget) {
-        UITelemetry.addEvent("action.1", "contextmenu", null, "web_copy_email");
-
-        let url = NativeWindow.contextmenus._getLinkURL(aTarget);
-        let emailAddr = NativeWindow.contextmenus._stripScheme(url);
-        NativeWindow.contextmenus._copyStringToDefaultClipboard(emailAddr);
-      }
-    );
-
-    NativeWindow.contextmenus.add(
-      stringGetter("contextmenu.copyPhoneNumber"),
-      NativeWindow.contextmenus.phoneNumberLinkContext,
-      function(aTarget) {
-        UITelemetry.addEvent("action.1", "contextmenu", null, "web_copy_phone");
-
-        let url = NativeWindow.contextmenus._getLinkURL(aTarget);
-        let phoneNumber = NativeWindow.contextmenus._stripScheme(url);
-        NativeWindow.contextmenus._copyStringToDefaultClipboard(phoneNumber);
-      }
-    );
-
-    NativeWindow.contextmenus.add({
-      label: stringGetter("contextmenu.shareLink"),
-      order: NativeWindow.contextmenus.DEFAULT_HTML5_ORDER - 1, // Show above HTML5 menu items
-      selector: NativeWindow.contextmenus._disableRestricted(
-        "SHARE",
-        NativeWindow.contextmenus.linkShareableContext
-      ),
-      showAsActions: function(aElement) {
-        let uri = NativeWindow.contextmenus._getLinkURL(aElement);
-        uri = NativeWindow.contextmenus._stripViewSource(uri);
-        return {
-          title: aElement.textContent.trim() || aElement.title.trim(),
-          uri,
-        };
-      },
-      icon: "drawable://ic_menu_share",
-      callback: function(aTarget) {
-        // share.1 telemetry is handled in Java via PromptList
-        UITelemetry.addEvent("action.1", "contextmenu", null, "web_share_link");
-      },
-    });
-
-    NativeWindow.contextmenus.add({
-      label: stringGetter("contextmenu.shareEmailAddress"),
-      order: NativeWindow.contextmenus.DEFAULT_HTML5_ORDER - 1,
-      selector: NativeWindow.contextmenus._disableRestricted(
-        "SHARE",
-        NativeWindow.contextmenus.emailLinkContext
-      ),
-      showAsActions: function(aElement) {
-        let url = NativeWindow.contextmenus._getLinkURL(aElement);
-        let emailAddr = NativeWindow.contextmenus._stripScheme(url);
-        let title = aElement.textContent || aElement.title;
-        return {
-          title: title,
-          uri: emailAddr,
-        };
-      },
-      icon: "drawable://ic_menu_share",
-      callback: function(aTarget) {
-        // share.1 telemetry is handled in Java via PromptList
-        UITelemetry.addEvent(
-          "action.1",
-          "contextmenu",
-          null,
-          "web_share_email"
-        );
-      },
-    });
-
-    NativeWindow.contextmenus.add({
-      label: stringGetter("contextmenu.sharePhoneNumber"),
-      order: NativeWindow.contextmenus.DEFAULT_HTML5_ORDER - 1,
-      selector: NativeWindow.contextmenus._disableRestricted(
-        "SHARE",
-        NativeWindow.contextmenus.phoneNumberLinkContext
-      ),
-      showAsActions: function(aElement) {
-        let url = NativeWindow.contextmenus._getLinkURL(aElement);
-        let phoneNumber = NativeWindow.contextmenus._stripScheme(url);
-        let title = aElement.textContent || aElement.title;
-        return {
-          title: title,
-          uri: phoneNumber,
-        };
-      },
-      icon: "drawable://ic_menu_share",
-      callback: function(aTarget) {
-        // share.1 telemetry is handled in Java via PromptList
-        UITelemetry.addEvent(
-          "action.1",
-          "contextmenu",
-          null,
-          "web_share_phone"
-        );
-      },
-    });
-
-    NativeWindow.contextmenus.add(
-      stringGetter("contextmenu.addToContacts"),
-      NativeWindow.contextmenus._disableRestricted(
-        "ADD_CONTACT",
-        NativeWindow.contextmenus.emailLinkContext
-      ),
-      function(aTarget) {
-        UITelemetry.addEvent(
-          "action.1",
-          "contextmenu",
-          null,
-          "web_contact_email"
-        );
-
-        let url = NativeWindow.contextmenus._getLinkURL(aTarget);
-        WindowEventDispatcher.sendRequest({
-          type: "Contact:Add",
-          email: url,
-        });
-      }
-    );
-
-    NativeWindow.contextmenus.add(
-      stringGetter("contextmenu.addToContacts"),
-      NativeWindow.contextmenus._disableRestricted(
-        "ADD_CONTACT",
-        NativeWindow.contextmenus.phoneNumberLinkContext
-      ),
-      function(aTarget) {
-        UITelemetry.addEvent(
-          "action.1",
-          "contextmenu",
-          null,
-          "web_contact_phone"
-        );
-
-        let url = NativeWindow.contextmenus._getLinkURL(aTarget);
-        WindowEventDispatcher.sendRequest({
-          type: "Contact:Add",
-          phone: url,
-        });
-      }
-    );
-
-    NativeWindow.contextmenus.add(
-      stringGetter("contextmenu.bookmarkLink"),
-      NativeWindow.contextmenus._disableRestricted(
-        "BOOKMARK",
-        NativeWindow.contextmenus.linkBookmarkableContext
-      ),
-      function(aTarget) {
-        UITelemetry.addEvent("action.1", "contextmenu", null, "web_bookmark");
-        UITelemetry.addEvent("save.1", "contextmenu", null, "bookmark");
-
-        let url = NativeWindow.contextmenus._getLinkURL(aTarget);
-        let title = aTarget.textContent || aTarget.title || url;
-        GlobalEventDispatcher.sendRequest({
-          type: "Bookmark:Insert",
-          url: url,
-          title: title,
-        });
-      }
-    );
-
-    NativeWindow.contextmenus.add(
-      stringGetter("contextmenu.playMedia"),
-      NativeWindow.contextmenus.mediaContext("media-paused"),
-      function(aTarget) {
-        UITelemetry.addEvent("action.1", "contextmenu", null, "web_play");
-        aTarget.play();
-      }
-    );
-
-    NativeWindow.contextmenus.add(
-      stringGetter("contextmenu.pauseMedia"),
-      NativeWindow.contextmenus.mediaContext("media-playing"),
-      function(aTarget) {
-        UITelemetry.addEvent("action.1", "contextmenu", null, "web_pause");
-        aTarget.pause();
-      }
-    );
-
-    NativeWindow.contextmenus.add(
-      stringGetter("contextmenu.showControls2"),
-      NativeWindow.contextmenus.mediaContext("media-hidingcontrols"),
-      function(aTarget) {
-        UITelemetry.addEvent(
-          "action.1",
-          "contextmenu",
-          null,
-          "web_controls_media"
-        );
-        aTarget.setAttribute("controls", true);
-      }
-    );
-
-    NativeWindow.contextmenus.add({
-      label: function(aTarget) {
-        return Strings.browser.GetStringFromName(
-          `contextmenu.share${videoClassifier(aTarget)}2`
-        );
-      },
-      order: NativeWindow.contextmenus.DEFAULT_HTML5_ORDER - 1,
-      selector: NativeWindow.contextmenus._disableRestricted(
-        "SHARE",
-        NativeWindow.contextmenus.videoContext()
-      ),
-      showAsActions: function(aElement) {
-        let url = aElement.currentSrc || aElement.src;
-        let title = aElement.textContent || aElement.title;
-        return {
-          title: title,
-          uri: url,
-          type: videoClassifier(aElement) === "Audio" ? "audio/*" : "video/*",
-        };
-      },
-      icon: "drawable://ic_menu_share",
-      callback: function(aTarget) {
-        // share.1 telemetry is handled in Java via PromptList
-        UITelemetry.addEvent(
-          "action.1",
-          "contextmenu",
-          null,
-          "web_share_media"
-        );
-      },
-    });
-
-    NativeWindow.contextmenus.add(
-      stringGetter("contextmenu.fullScreen"),
-      NativeWindow.contextmenus.videoContext("not-fullscreen"),
-      function(aTarget) {
-        UITelemetry.addEvent("action.1", "contextmenu", null, "web_fullscreen");
-        aTarget.requestFullscreen();
-      }
-    );
-
-    NativeWindow.contextmenus.add(
-      stringGetter("contextmenu.mute"),
-      NativeWindow.contextmenus.mediaContext("media-unmuted"),
-      function(aTarget) {
-        UITelemetry.addEvent("action.1", "contextmenu", null, "web_mute");
-        aTarget.muted = true;
-      }
-    );
-
-    NativeWindow.contextmenus.add(
-      stringGetter("contextmenu.unmute"),
-      NativeWindow.contextmenus.mediaContext("media-muted"),
-      function(aTarget) {
-        UITelemetry.addEvent("action.1", "contextmenu", null, "web_unmute");
-        aTarget.muted = false;
-      }
-    );
-
-    NativeWindow.contextmenus.add(
-      stringGetter("contextmenu.viewImage"),
-      NativeWindow.contextmenus.imageLocationCopyableContext,
-      function(aTarget) {
-        let url = aTarget.currentSrc || aTarget.src;
-        ContentAreaUtils.urlSecurityCheck(
-          url,
-          aTarget.ownerDocument.nodePrincipal,
-          Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT
-        );
-
-        UITelemetry.addEvent("action.1", "contextmenu", null, "web_view_image");
-        UITelemetry.addEvent("loadurl.1", "contextmenu", null);
-        BrowserApp.selectedBrowser.loadURI(url);
-      }
-    );
-
-    NativeWindow.contextmenus.add(
-      stringGetter("contextmenu.copyImageLocation"),
-      NativeWindow.contextmenus.imageLocationCopyableContext,
-      function(aTarget) {
-        UITelemetry.addEvent("action.1", "contextmenu", null, "web_copy_image");
-
-        let url = aTarget.currentSrc || aTarget.src;
-        url = NativeWindow.contextmenus._stripViewSource(url);
-        NativeWindow.contextmenus._copyStringToDefaultClipboard(url);
-      }
-    );
-
-    NativeWindow.contextmenus.add({
-      label: stringGetter("contextmenu.shareImage"),
-      selector: NativeWindow.contextmenus._disableRestricted(
-        "SHARE",
-        NativeWindow.contextmenus.imageShareableContext
-      ),
-      order: NativeWindow.contextmenus.DEFAULT_HTML5_ORDER - 1, // Show above HTML5 menu items
-      showAsActions: function(aTarget) {
-        let src = aTarget.currentSrc || aTarget.src;
-        src = NativeWindow.contextmenus._stripViewSource(src);
-        return {
-          title: src,
-          uri: src,
-          type: "image/*",
-        };
-      },
-      icon: "drawable://ic_menu_share",
-      menu: true,
-      callback: function(aTarget) {
-        UITelemetry.addEvent(
-          "action.1",
-          "contextmenu",
-          null,
-          "web_share_image"
-        );
-      },
-    });
-
-    NativeWindow.contextmenus.add(
-      stringGetter("contextmenu.saveImage"),
-      NativeWindow.contextmenus.imageSaveableContext,
-      function(aTarget) {
-        UITelemetry.addEvent("action.1", "contextmenu", null, "web_save_image");
-        UITelemetry.addEvent("save.1", "contextmenu", null, "image");
-        WindowEventDispatcher.sendRequest({
-          type: "Mma:web_save_image",
-        });
-
-        RuntimePermissions.waitForPermissions(
-          RuntimePermissions.WRITE_EXTERNAL_STORAGE
-        ).then(function(permissionGranted) {
-          if (!permissionGranted) {
-            return;
-          }
-
-          let referrerInfo = Cc["@mozilla.org/referrer-info;1"].createInstance(
-            Ci.nsIReferrerInfo
-          );
-          referrerInfo.initWithDocument(aTarget.ownerDocument);
-          let uri = aTarget.currentRequestFinalURI || aTarget.currentURI;
-          ContentAreaUtils.saveImageURL(
-            uri.spec,
-            null,
-            "SaveImageTitle",
-            false,
-            true,
-            referrerInfo,
-            aTarget.ownerDocument
-          );
-        });
-      }
-    );
-
-    NativeWindow.contextmenus.add(
-      stringGetter("contextmenu.setImageAs"),
-      NativeWindow.contextmenus._disableRestricted(
-        "SET_IMAGE",
-        NativeWindow.contextmenus.imageSaveableContext
-      ),
-      function(aTarget) {
-        UITelemetry.addEvent(
-          "action.1",
-          "contextmenu",
-          null,
-          "web_background_image"
-        );
-
-        let src = aTarget.currentSrc || aTarget.src;
-        GlobalEventDispatcher.sendRequest({
-          type: "Image:SetAs",
-          url: src,
-        });
-      }
-    );
-
-    NativeWindow.contextmenus.add(
-      function(aTarget) {
-        if (aTarget instanceof HTMLVideoElement) {
-          return Strings.browser.GetStringFromName(
-            `contextmenu.save${videoClassifier(aTarget)}`
-          );
-        } else if (aTarget instanceof HTMLAudioElement) {
-          return Strings.browser.GetStringFromName("contextmenu.saveAudio");
-        }
-        return Strings.browser.GetStringFromName("contextmenu.saveVideo");
-      },
-      NativeWindow.contextmenus.mediaSaveableContext,
-      function(aTarget) {
-        UITelemetry.addEvent("action.1", "contextmenu", null, "web_save_media");
-        UITelemetry.addEvent("save.1", "contextmenu", null, "media");
-        WindowEventDispatcher.sendRequest({
-          type: "Mma:web_save_media",
-        });
-
-        let url = aTarget.currentSrc || aTarget.src;
-
-        let filePickerTitleKey;
-        if (aTarget instanceof HTMLVideoElement) {
-          filePickerTitleKey = `Save${videoClassifier(aTarget)}Title`;
-        } else {
-          filePickerTitleKey = "SaveAudioTitle";
-        }
-
-        // Skipped trying to pull MIME type out of cache for now
-        let referrerInfo = Cc["@mozilla.org/referrer-info;1"].createInstance(
-          Ci.nsIReferrerInfo
-        );
-        referrerInfo.initWithDocument(aTarget.ownerDocument);
-        ContentAreaUtils.internalSave(
-          url,
-          null,
-          null,
-          null,
-          null,
-          false,
-          filePickerTitleKey,
-          null,
-          referrerInfo,
-          aTarget.ownerDocument,
-          true,
-          null
-        );
-      }
-    );
-
-    NativeWindow.contextmenus.add(
-      stringGetter("contextmenu.showImage"),
-      NativeWindow.contextmenus.imageBlockingPolicyContext,
-      function(aTarget) {
-        UITelemetry.addEvent("action.1", "contextmenu", null, "web_show_image");
-        aTarget.setAttribute("data-ctv-show", "true");
-        aTarget.setAttribute("src", aTarget.getAttribute("data-ctv-src"));
-
-        // Shows a snackbar to unblock all images if browser.image_blocking.enabled is enabled.
-        let blockedImgs = aTarget.ownerDocument.querySelectorAll(
-          "[data-ctv-src]"
-        );
-        if (blockedImgs.length == 0) {
-          return;
-        }
-        let message = Strings.browser.GetStringFromName(
-          "imageblocking.downloadedImage"
-        );
-        Snackbars.show(message, Snackbars.LENGTH_LONG, {
-          action: {
-            label: Strings.browser.GetStringFromName(
-              "imageblocking.showAllImages"
-            ),
-            callback: () => {
-              UITelemetry.addEvent(
-                "action.1",
-                "toast",
-                null,
-                "web_show_all_image"
-              );
-              for (let i = 0; i < blockedImgs.length; ++i) {
-                blockedImgs[i].setAttribute("data-ctv-show", "true");
-                blockedImgs[i].setAttribute(
-                  "src",
-                  blockedImgs[i].getAttribute("data-ctv-src")
-                );
-              }
-            },
-          },
-        });
-      }
-    );
-  },
-
-  onAppUpdated: function() {
-    // initialize the form history and passwords databases on upgrades
-    GlobalEventDispatcher.dispatch("FormHistory:Init", null);
-    GlobalEventDispatcher.dispatch("Passwords:Init", null);
-
-    if (this._startupStatus === "upgrade") {
-      this._migrateUI();
-    }
-  },
-
-  _migrateUI: function() {
-    const UI_VERSION = 4;
-    let currentUIVersion = Services.prefs.getIntPref(
-      "browser.migration.version",
-      0
-    );
-    if (currentUIVersion >= UI_VERSION) {
-      return;
-    }
-
-    if (currentUIVersion < 1) {
-      // Migrate the "privacy.donottrackheader.value" pref. See bug 1042135.
-      if (Services.prefs.prefHasUserValue("privacy.donottrackheader.value")) {
-        // Make sure the doNotTrack value conforms to the conversion from
-        // three-state to two-state. (This reverts a setting of "please track me"
-        // to the default "don't say anything").
-        if (
-          Services.prefs.getBoolPref("privacy.donottrackheader.enabled") &&
-          Services.prefs.getIntPref("privacy.donottrackheader.value") != 1
-        ) {
-          Services.prefs.clearUserPref("privacy.donottrackheader.enabled");
-        }
-
-        // This pref has been removed, so always clear it.
-        Services.prefs.clearUserPref("privacy.donottrackheader.value");
-      }
-
-      // Set the search activity default pref on app upgrade if it has not been set already.
-      if (!Services.prefs.prefHasUserValue("searchActivity.default.migrated")) {
-        Services.prefs.setBoolPref("searchActivity.default.migrated", true);
-        SearchEngines.migrateSearchActivityDefaultPref();
-      }
-
-      Reader.migrateCache().catch(e =>
-        Cu.reportError("Error migrating Reader cache: " + e)
-      );
-
-      // We removed this pref from user visible settings, so we should reset it.
-      // Power users can go into about:config to re-enable this if they choose.
-      if (Services.prefs.prefHasUserValue("nglayout.debug.paint_flashing")) {
-        Services.prefs.clearUserPref("nglayout.debug.paint_flashing");
-      }
-    }
-
-    if (currentUIVersion < 2) {
-      let name;
-      if (Services.prefs.prefHasUserValue("browser.search.defaultenginename")) {
-        name = Services.prefs.getCharPref("browser.search.defaultenginename");
-      }
-      if (
-        !name &&
-        Services.prefs.prefHasUserValue("browser.search.defaultenginename.US")
-      ) {
-        name = Services.prefs.getCharPref(
-          "browser.search.defaultenginename.US"
-        );
-      }
-      if (name) {
-        Services.search.init().then(() => {
-          let engine = Services.search.getEngineByName(name);
-          if (engine) {
-            Services.search.defaultEngine = engine;
-            Services.obs.notifyObservers(
-              null,
-              "default-search-engine-migrated"
-            );
-          }
-        });
-      }
-    }
-
-    if (currentUIVersion < 3) {
-      const kOldSafeBrowsingPref = "browser.safebrowsing.enabled";
-      // Default value is set to true, a user pref means that the pref was
-      // set to false.
-      if (
-        Services.prefs.prefHasUserValue(kOldSafeBrowsingPref) &&
-        !Services.prefs.getBoolPref(kOldSafeBrowsingPref)
-      ) {
-        Services.prefs.setBoolPref(
-          "browser.safebrowsing.phishing.enabled",
-          false
-        );
-        // Should just remove support for the pref entirely, even if it's
-        // only in about:config
-        Services.prefs.clearUserPref(kOldSafeBrowsingPref);
-      }
-    }
-
-    if (currentUIVersion < 4) {
-      // The handler app service will read this. We need to wait with migrating
-      // until the handler service has started up, so just set a pref here.
-      Services.prefs.setCharPref("browser.handlers.migrations", "30boxes");
-    }
-
-    // Update the migration version.
-    Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
-  },
-
-  // This function returns false during periods where the browser displayed document is
-  // different from the browser content document, so user actions and some kinds of viewport
-  // updates should be ignored. This period starts when we start loading a new page or
-  // switch tabs, and ends when the new browser content document has been drawn and handed
-  // off to the compositor.
-  isBrowserContentDocumentDisplayed: function() {
-    try {
-      if (!Services.androidBridge.isContentDocumentDisplayed(window)) {
-        return false;
-      }
-    } catch (e) {
-      return false;
-    }
-
-    let tab = this.selectedTab;
-    if (!tab) {
-      return false;
-    }
-    return tab.contentDocumentIsDisplayed;
-  },
-
-  contentDocumentChanged: function() {
-    window.top.windowUtils.isFirstPaint = true;
-    Services.androidBridge.contentDocumentChanged(window);
-  },
-
-  get tabs() {
-    return this._tabs;
-  },
-
-  set selectedTab(aTab) {
-    if (this._selectedTab == aTab) {
-      return;
-    }
-
-    if (this._selectedTab) {
-      this._selectedTab.setActive(false);
-    }
-
-    this._selectedTab = aTab;
-    if (!aTab) {
-      return;
-    }
-
-    aTab.setActive(true);
-    this.contentDocumentChanged();
-    this.deck.selectedPanel = aTab.browser;
-    // Focus the browser so that things like selection will be styled correctly.
-    aTab.browser.focus();
-  },
-
-  get selectedBrowser() {
-    if (this._selectedTab) {
-      return this._selectedTab.browser;
-    }
-    return null;
-  },
-
-  getTabForId: function getTabForId(aId) {
-    let tabs = this._tabs;
-    for (let i = 0; i < tabs.length; i++) {
-      if (tabs[i].id == aId) {
-        return tabs[i];
-      }
-    }
-    return null;
-  },
-
-  getTabForBrowser: function getTabForBrowser(aBrowser) {
-    let tabs = this._tabs;
-    for (let i = 0; i < tabs.length; i++) {
-      if (tabs[i].browser == aBrowser) {
-        return tabs[i];
-      }
-    }
-    return null;
-  },
-
-  getTabForWindow: function getTabForWindow(aWindow) {
-    let tabs = this._tabs;
-    for (let i = 0; i < tabs.length; i++) {
-      if (tabs[i].browser.contentWindow == aWindow) {
-        return tabs[i];
-      }
-    }
-    return null;
-  },
-
-  getBrowserForWindow: function getBrowserForWindow(aWindow) {
-    let tabs = this._tabs;
-    for (let i = 0; i < tabs.length; i++) {
-      if (tabs[i].browser.contentWindow == aWindow) {
-        return tabs[i].browser;
-      }
-    }
-    return null;
-  },
-
-  getBrowserForDocument: function getBrowserForDocument(aDocument) {
-    let tabs = this._tabs;
-    for (let i = 0; i < tabs.length; i++) {
-      if (tabs[i].browser.contentDocument == aDocument) {
-        return tabs[i].browser;
-      }
-    }
-    return null;
-  },
-
-  // Use this instead of deck.selectedIndex (which is invalid for this purpose).
-  get selectedTabIndex() {
-    return this._tabs.indexOf(this._selectedTab);
-  },
-
-  loadURI: function loadURI(aURI, aBrowser, aParams) {
-    aBrowser = aBrowser || this.selectedBrowser;
-    if (!aBrowser) {
-      return;
-    }
-
-    aParams = aParams || {};
-
-    let flags =
-      "flags" in aParams ? aParams.flags : Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
-    let postData =
-      "postData" in aParams && aParams.postData ? aParams.postData : null;
-    let referrerInfo =
-      "referrerURI" in aParams ? createReferrerInfo(aParams.referrerURI) : null;
-    let charset = "charset" in aParams ? aParams.charset : null;
-
-    let tab = this.getTabForBrowser(aBrowser);
-    if (tab) {
-      if ("userRequested" in aParams) {
-        tab.userRequested = aParams.userRequested;
-      }
-      tab.isSearch = "isSearch" in aParams ? aParams.isSearch : false;
-    }
-    // Don't fall back to System here Bug 1474619
-    let triggeringPrincipal =
-      "triggeringPrincipal" in aParams
-        ? aParams.triggeringPrincipal
-        : Services.scriptSecurityManager.getSystemPrincipal();
-
-    try {
-      aBrowser.loadURI(aURI, {
-        flags,
-        referrerInfo,
-        charset,
-        postData,
-        triggeringPrincipal,
-      });
-    } catch (e) {
-      if (tab) {
-        let message = {
-          type: "Content:LoadError",
-          tabID: tab.id,
-        };
-        GlobalEventDispatcher.sendRequest(message);
-        dump("Handled load error: " + e);
-      }
-    }
-  },
-
-  addTab: function addTab(aURI, aParams) {
-    aParams = aParams || {};
-
-    let fullscreenState;
-    if (this.selectedBrowser) {
-      fullscreenState = this.selectedBrowser.contentDocument.fullscreenElement;
-      if (fullscreenState) {
-        aParams.selected = false;
-      }
-    }
-
-    let newTab = new Tab(aURI, aParams);
-
-    if (fullscreenState) {
-      this.fullscreenTransitionTab = newTab;
-      this.selectedBrowser.contentDocument.exitFullscreen();
-    }
-
-    if (typeof aParams.tabIndex == "number") {
-      this._tabs.splice(aParams.tabIndex, 0, newTab);
-    } else {
-      this._tabs.push(newTab);
-    }
-
-    let selected = "selected" in aParams ? aParams.selected : true;
-    if (selected) {
-      this.selectedTab = newTab;
-    }
-
-    let evt = document.createEvent("UIEvents");
-    evt.initUIEvent("TabOpen", true, false, window, null);
-    newTab.browser.dispatchEvent(evt);
-
-    return newTab;
-  },
-
-  // Use this method to close a tab from JS. This method sends a message
-  // to Java to close the tab in the Java UI (we'll get a Tab:Closed message
-  // back from Java when that happens).
-  closeTab: function closeTab(aTab) {
-    if (!aTab) {
-      Cu.reportError("Error trying to close tab (tab doesn't exist)");
-      return;
-    }
-
-    let message = {
-      type: "Tab:Close",
-      tabID: aTab.id,
-    };
-    GlobalEventDispatcher.sendRequest(message);
-  },
-
-  // Calling this will update the state in BrowserApp after a tab has been
-  // closed in the Java UI.
-  _handleTabClosed: function _handleTabClosed(aTab, aShowUndoSnackbar) {
-    if (aTab == this.selectedTab) {
-      this.selectedTab = null;
-    }
-
-    let tabIndex = this._tabs.indexOf(aTab);
-
-    let evt = document.createEvent("UIEvents");
-    evt.initUIEvent("TabClose", true, false, window, tabIndex);
-    aTab.browser.dispatchEvent(evt);
-
-    let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(
-      Ci.nsISessionStore
-    );
-    if (aShowUndoSnackbar && ss.canUndoLastCloseTab) {
-      // Get a title for the undo close snackbar. Fall back to the URL if there is no title.
-      let closedTabData = ss.getClosedTabs(window)[0];
-
-      if (closedTabData) {
-        let message;
-        let title = closedTabData.entries[closedTabData.index - 1].title;
-        let isPrivate = PrivateBrowsingUtils.isBrowserPrivate(aTab.browser);
-
-        if (isPrivate) {
-          message = Strings.browser.GetStringFromName(
-            "privateClosedMessage.message"
-          );
-        } else if (title) {
-          message = Strings.browser.formatStringFromName(
-            "undoCloseToast.message",
-            [title]
-          );
-        } else {
-          message = Strings.browser.GetStringFromName(
-            "undoCloseToast.messageDefault"
-          );
-        }
-
-        Snackbars.show(message, Snackbars.LENGTH_LONG, {
-          action: {
-            label: Strings.browser.GetStringFromName("undoCloseToast.action2"),
-            callback: function() {
-              UITelemetry.addEvent("undo.1", "toast", null, "closetab");
-              ss.undoCloseTab(window, closedTabData);
-            },
-          },
-        });
-      }
-    }
-
-    // Retrieve updated tabIndex again for the removal because the index could
-    // be changed if a new tab is added by the event listener.
-    tabIndex = this._tabs.indexOf(aTab);
-    aTab.destroy();
-    this._tabs.splice(tabIndex, 1);
-  },
-
-  _handleTabMove(fromTabId, fromPosition, toTabId, toPosition) {
-    let movedTab = this._tabs[fromPosition];
-    if (movedTab.id != fromTabId || this._tabs[toPosition].id != toTabId) {
-      // The gecko and/or java Tabs tabs lists changed sometime between when the Tabs list was
-      // updated and when news of the update arrived here.
-      throw new Error(
-        "Moved tab mismatch: (" +
-          fromTabId +
-          ", " +
-          movedTab.id +
-          "), " +
-          "(" +
-          toTabId +
-          ", " +
-          this._tabs[toPosition].id +
-          ")"
-      );
-    }
-
-    let step = fromPosition < toPosition ? 1 : -1;
-    for (let i = fromPosition; i != toPosition; i += step) {
-      this._tabs[i] = this._tabs[i + step];
-    }
-    this._tabs[toPosition] = movedTab;
-
-    let evt = new UIEvent("TabMove", {
-      bubbles: true,
-      cancelable: false,
-      view: window,
-      detail: fromPosition,
-    });
-    this.tabs[toPosition].browser.dispatchEvent(evt);
-  },
-
-  // Use this method to select a tab from JS. This method sends a message
-  // to Java to select the tab in the Java UI (we'll get a Tab:Selected message
-  // back from Java when that happens).
-  selectTab: function selectTab(aTab) {
-    if (!aTab) {
-      Cu.reportError("Error trying to select tab (tab doesn't exist)");
-      return;
-    }
-
-    // There's nothing to do if the tab is already selected
-    if (aTab == this.selectedTab) {
-      return;
-    }
-
-    let doc = this.selectedBrowser.contentDocument;
-    if (doc.fullscreenElement) {
-      // We'll finish the tab selection once the fullscreen transition has ended,
-      // remember the new tab for this.
-      this.fullscreenTransitionTab = aTab;
-      doc.exitFullscreen();
-      return;
-    }
-
-    let message = {
-      type: "Tab:Select",
-      tabID: aTab.id,
-    };
-    GlobalEventDispatcher.sendRequest(message);
-  },
-
-  /**
-   * Gets an open tab with the given URL.
-   *
-   * @param  aURL URL to look for
-   * @param  aOptions Options for the search. Currently supports:
-   **  @option startsWith a Boolean indicating whether to search for a tab who's url starts with the
-   *           requested url. Useful if you want to ignore hash codes on the end of a url. For instance
-   *           to have about:downloads match about:downloads#123.
-   * @return the tab with the given URL, or null if no such tab exists
-   */
-  getTabWithURL: function getTabWithURL(aURL, aOptions) {
-    aOptions = aOptions || {};
-    let uri = Services.io.newURI(aURL);
-    for (let i = 0; i < this._tabs.length; ++i) {
-      let tab = this._tabs[i];
-      if (aOptions.startsWith) {
-        if (tab.currentURI.spec.startsWith(uri.spec)) {
-          return tab;
-        }
-      } else if (tab.currentURI.equals(uri)) {
-        return tab;
-      }
-    }
-    return null;
-  },
-
-  /**
-   * If a tab with the given URL already exists, that tab is selected.
-   * Otherwise, a new tab is opened with the given URL.
-   *
-   * @param aURL URL to open
-   * @param aParam Options used if a tab is created
-   * @param aFlags Options for the search. Currently supports:
-   **  @option startsWith a Boolean indicating whether to search for a tab who's url starts with the
-   *           requested url. Useful if you want to ignore hash codes on the end of a url. For instance
-   *           to have about:downloads match about:downloads#123.
-   */
-  selectOrAddTab: function selectOrAddTab(aURL, aParams, aFlags) {
-    let tab = this.getTabWithURL(aURL, aFlags);
-    if (tab == null) {
-      tab = this.addTab(aURL, aParams);
-    } else {
-      this.selectTab(tab);
-    }
-
-    return tab;
-  },
-
-  /**
-   * Open or select a tab with the "about:addons" page and optionally
-   * switch to the details page related to a defined addonId.
-   *
-   * @param {string} addonId
-   */
-  openAddonManager: function openAddonManager({ addonId }) {
-    if (addonId) {
-      let emWindow;
-
-      function receivePong(subject, topic, data) {
-        emWindow = subject;
-      }
-
-      Services.obs.addObserver(receivePong, "EM-pong");
-      Services.obs.notifyObservers(null, "EM-ping");
-      Services.obs.removeObserver(receivePong, "EM-pong");
-
-      if (emWindow) {
-        // "about:addons" has been already loaded in a tab.
-        emWindow.showAddonDetails(addonId);
-      } else {
-        // Wait for "about:addons" to be fully loaded.
-        function waitAboutAddons(subject, topic, data) {
-          Services.obs.removeObserver(waitAboutAddons, "EM-loaded");
-          emWindow = subject;
-
-          emWindow.showAddonDetails(addonId);
-        }
-        Services.obs.addObserver(waitAboutAddons, "EM-loaded");
-      }
-    }
-
-    BrowserApp.selectOrAddTab("about:addons", {
-      selected: true,
-      parentId: BrowserApp.selectedTab.id,
-    });
-  },
-
-  // This method updates the state in BrowserApp after a tab has been selected
-  // in the Java UI.
-  _handleTabSelected: function _handleTabSelected(aTab) {
-    if (this.fullscreenTransitionTab) {
-      // Defer updating to "fullscreenchange" if tab selection happened during
-      // a fullscreen transition.
-      return;
-    }
-    this.selectedTab = aTab;
-
-    let evt = document.createEvent("UIEvents");
-    evt.initUIEvent("TabSelect", true, false, window, null);
-    aTab.browser.dispatchEvent(evt);
-  },
-
-  viewSourceForTab(aTab) {
-    let browser = aTab.browser;
-    let outerWindowID = browser.outerWindowID;
-    let url = browser.currentURI.spec;
-    let args = { browser, outerWindowID, URL: url };
-
-    // `viewSourceInBrowser` will load the source content from the page
-    // descriptor for the tab (when possible) or fallback to the network if
-    // that fails.  Either way, the view source module will manage the tab's
-    // location, so use "about:blank" here to avoid unnecessary redundant
-    // requests.
-    let tab = this.addTab("about:blank", {
-      selected: true,
-      parentId: aTab.id,
-      isPrivate: PrivateBrowsingUtils.isBrowserPrivate(aTab.browser),
-    });
-    args.viewSourceBrowser = tab.browser;
-
-    gViewSourceUtils.viewSourceInBrowser(args);
-  },
-
-  quit: function quit(aClear = { sanitize: {}, dontSaveSession: false }) {
-    // Notify all windows that an application quit has been requested.
-    let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(
-      Ci.nsISupportsPRBool
-    );
-    Services.obs.notifyObservers(cancelQuit, "quit-application-requested");
-
-    // Quit aborted.
-    if (cancelQuit.data) {
-      return;
-    }
-
-    Services.obs.notifyObservers(null, "quit-application-proceeding");
-
-    // Tell session store to forget about this window
-    if (aClear.dontSaveSession) {
-      let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(
-        Ci.nsISessionStore
-      );
-      ss.removeWindow(window);
-    }
-
-    BrowserApp.sanitize(
-      aClear.sanitize,
-      function() {
-        let appStartup = Services.startup;
-        appStartup.quit(Ci.nsIAppStartup.eForceQuit);
-      },
-      true
-    );
-  },
-
-  saveAsPDF: function saveAsPDF(aBrowser) {
-    RuntimePermissions.waitForPermissions(
-      RuntimePermissions.WRITE_EXTERNAL_STORAGE
-    ).then(function(permissionGranted) {
-      if (!permissionGranted) {
-        return;
-      }
-
-      (async () => {
-        let fileName = ContentAreaUtils.getDefaultFileName(
-          aBrowser.contentTitle,
-          aBrowser.currentURI,
-          null,
-          null
-        );
-        fileName = fileName.trim() + ".pdf";
-
-        let downloadsDir = await Downloads.getPreferredDownloadsDirectory();
-        let file = OS.Path.join(downloadsDir, fileName);
-
-        // Force this to have a unique name.
-        let openedFile = await OS.File.openUnique(file, {
-          humanReadable: true,
-        });
-        file = openedFile.path;
-        await openedFile.file.close();
-
-        let download = await Downloads.createDownload({
-          source: aBrowser.contentWindow,
-          target: file,
-          saver: "pdf",<