Bug 1313568 - Handle captive portal notification bar per-window. r=MattN draft
authorNihanth Subramanya <nhnt11@gmail.com>
Mon, 05 Dec 2016 21:22:01 -1000
changeset 447572 2886154e6ba8442d446bf9775226635f6d41e053
parent 446842 b49684127ce464141b0a989cd621cb4794b6a85f
child 539053 a73c6b96dccd81c8a25fd17fc2c5421f1445e2fd
push id38083
push usernhnt11@gmail.com
push dateTue, 06 Dec 2016 07:24:34 +0000
reviewersMattN
bugs1313568
milestone53.0a1
Bug 1313568 - Handle captive portal notification bar per-window. r=MattN MozReview-Commit-ID: 8txJCCRSYFe
browser/base/content/browser-captivePortal.js
browser/base/content/browser.js
browser/base/content/global-scripts.inc
browser/base/jar.mn
browser/components/nsBrowserGlue.js
browser/modules/CaptivePortalWatcher.jsm
browser/modules/moz.build
new file mode 100644
--- /dev/null
+++ b/browser/base/content/browser-captivePortal.js
@@ -0,0 +1,253 @@
+/* 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";
+
+XPCOMUtils.defineLazyServiceGetter(this, "cps",
+                                   "@mozilla.org/network/captive-portal-service;1",
+                                   "nsICaptivePortalService");
+
+var CaptivePortalWatcher = {
+  /**
+   * This constant is chosen to be large enough for a portal recheck to complete,
+   * and small enough that the delay in opening a tab isn't too noticeable.
+   * Please see comments for _delayedCaptivePortalDetected for more details.
+   */
+  PORTAL_RECHECK_DELAY_MS: 150,
+
+  // This is the value used to identify the captive portal notification.
+  PORTAL_NOTIFICATION_VALUE: "captive-portal-detected",
+
+  // This holds a weak reference to the captive portal tab so that we
+  // don't leak it if the user closes it.
+  _captivePortalTab: null,
+
+  _initialized: false,
+
+  /**
+   * If a portal is detected when we don't have focus, we first wait for focus
+   * and then add the tab if, after a recheck, the portal is still active. This
+   * is set to true while we wait so that in the unlikely event that we receive
+   * another notification while waiting, we don't do things twice.
+   */
+  _delayedCaptivePortalDetectedInProgress: false,
+
+  // In the situation above, this is set to true while we wait for the recheck.
+  // This flag exists so that tests can appropriately simulate a recheck.
+  _waitingForRecheck: false,
+
+  get canonicalURL() {
+    return Services.prefs.getCharPref("captivedetect.canonicalURL");
+  },
+
+  init() {
+    Services.obs.addObserver(this, "captive-portal-login", false);
+    Services.obs.addObserver(this, "captive-portal-login-abort", false);
+    Services.obs.addObserver(this, "captive-portal-login-success", false);
+    this._initialized = true;
+
+    if (cps.state == cps.LOCKED_PORTAL) {
+      // A captive portal has already been detected.
+      this._captivePortalDetected();
+      return;
+    }
+
+    cps.recheckCaptivePortal();
+  },
+
+  uninit() {
+    if (!this._initialized) {
+      return;
+    }
+    Services.obs.removeObserver(this, "captive-portal-login");
+    Services.obs.removeObserver(this, "captive-portal-login-abort");
+    Services.obs.removeObserver(this, "captive-portal-login-success");
+  },
+
+  observe(subject, topic, data) {
+    switch (topic) {
+      case "captive-portal-login":
+        this._captivePortalDetected();
+        break;
+      case "captive-portal-login-abort":
+      case "captive-portal-login-success":
+        this._captivePortalGone();
+        break;
+      case "xul-window-visible":
+        this._delayedCaptivePortalDetected();
+        break;
+    }
+  },
+
+  _captivePortalDetected() {
+    if (this._delayedCaptivePortalDetectedInProgress) {
+      return;
+    }
+
+    this._showNotification();
+
+    let win = RecentWindow.getMostRecentBrowserWindow();
+    // If there's no browser window or none have focus, open and show the
+    // tab when we regain focus. This is so that if a different application was
+    // focused, when the user (re-)focuses a browser window, we open the tab
+    // immediately in that window so they can login before continuing to browse.
+    if (!win || win != Services.ww.activeWindow) {
+      this._delayedCaptivePortalDetectedInProgress = true;
+      Services.obs.addObserver(this, "xul-window-visible", false);
+      return;
+    }
+  },
+
+  _ensureCaptivePortalTab() {
+    let tab;
+    if (this._captivePortalTab) {
+      tab = this._captivePortalTab.get();
+    }
+
+    // If the tab is gone or going, we need to open a new one.
+    if (!tab || tab.closing || !tab.parentNode) {
+      tab = gBrowser.addTab(this.canonicalURL,
+                            { ownerTab: gBrowser.selectedTab });
+      this._captivePortalTab = Cu.getWeakReference(tab);
+    }
+
+    gBrowser.selectedTab = tab;
+  },
+
+  /**
+   * Called after we regain focus if we detect a portal while a browser window
+   * doesn't have focus. Triggers a portal recheck to reaffirm state, and adds
+   * the tab if needed after a short delay to allow the recheck to complete.
+   */
+  _delayedCaptivePortalDetected() {
+    if (!this._delayedCaptivePortalDetectedInProgress) {
+      return;
+    }
+
+    let win = RecentWindow.getMostRecentBrowserWindow();
+    if (win != Services.ww.activeWindow) {
+      // The window that got focused was not a browser window.
+      return;
+    }
+    Services.obs.removeObserver(this, "xul-window-visible");
+
+    if (win != window) {
+      // Another browser window got focus, we can stop worrying.
+      return;
+    }
+
+    // Trigger a portal recheck. The user may have logged into the portal via
+    // another client, or changed networks.
+    cps.recheckCaptivePortal();
+    this._waitingForRecheck = true;
+    let requestTime = Date.now();
+
+    let self = this;
+    Services.obs.addObserver(function observer() {
+      let time = Date.now() - requestTime;
+      Services.obs.removeObserver(observer, "captive-portal-check-complete");
+      self._waitingForRecheck = false;
+      self._delayedCaptivePortalDetectedInProgress = false;
+      if (cps.state != cps.LOCKED_PORTAL) {
+        // We're free of the portal!
+        return;
+      }
+
+      self._showNotification(win);
+      if (time <= self.PORTAL_RECHECK_DELAY_MS) {
+        // The amount of time elapsed since we requested a recheck (i.e. since
+        // the browser window was focused) was small enough that we can add and
+        // focus a tab with the login page with no noticeable delay.
+        self._ensureCaptivePortalTab(win);
+      }
+    }, "captive-portal-check-complete", false);
+  },
+
+  _captivePortalGone() {
+    if (this._delayedCaptivePortalDetectedInProgress) {
+      Services.obs.removeObserver(this, "xul-window-visible");
+      this._delayedCaptivePortalDetectedInProgress = false;
+    }
+
+    this._removeNotification();
+
+    let tab = this._captivePortalTab.get();
+    this._captivePortalTab = null;
+
+    let canonicalURI = makeURI(this.canonicalURL);
+    if (!tab || tab.closing || !tab.parentNode || !tab.linkedBrowser ||
+        !tab.linkedBrowser.currentURI.equalsExceptRef(canonicalURI)) {
+      return;
+    }
+    gBrowser.removeTab(tab);
+  },
+
+  get _browserBundle() {
+    delete this._browserBundle;
+    return this._browserBundle =
+      Services.strings.createBundle("chrome://browser/locale/browser.properties");
+  },
+
+  handleEvent(aEvent) {
+    if (aEvent.type != "TabSelect" || !this._captivePortalTab) {
+      return;
+    }
+
+    let tab = this._captivePortalTab.get();
+    let n = this.captivePortalNotification;
+    if (!tab || !n) {
+      return;
+    }
+
+    let button = n.querySelector("button.notification-button");
+    if (gBrowser.selectedTab == tab) {
+      button.style.visibility = "hidden";
+    } else {
+      button.style.visibility = "visible";
+    }
+  },
+
+  get captivePortalNotification() {
+    let nb = document.getElementById("high-priority-global-notificationbox");
+    return nb.getNotificationWithValue(this.PORTAL_NOTIFICATION_VALUE);
+  },
+
+  _showNotification() {
+    let buttons = [
+      {
+        label: this._browserBundle.GetStringFromName("captivePortal.showLoginPage"),
+        callback: () => {
+          this._ensureCaptivePortalTab();
+
+          // Returning true prevents the notification from closing.
+          return true;
+        },
+        isDefault: true,
+      },
+    ];
+
+    let message = this._browserBundle.GetStringFromName("captivePortal.infoMessage2");
+
+    let closeHandler = (aEventName) => {
+      if (aEventName != "removed") {
+        return;
+      }
+      gBrowser.tabContainer.removeEventListener("TabSelect", this);
+    };
+
+    let nb = document.getElementById("high-priority-global-notificationbox");
+    nb.appendNotification(message, this.PORTAL_NOTIFICATION_VALUE, "",
+                          nb.PRIORITY_INFO_MEDIUM, buttons, closeHandler);
+
+    gBrowser.tabContainer.addEventListener("TabSelect", this);
+  },
+
+  _removeNotification() {
+    let n = this.captivePortalNotification;
+    if (!n || !n.parentNode) {
+      return;
+    }
+    n.close();
+  },
+};
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -974,16 +974,17 @@ var gBrowserInit = {
     gPageStyleMenu.init();
     LanguageDetectionListener.init();
     BrowserOnClick.init();
     FeedHandler.init();
     DevEdition.init();
     AboutPrivateBrowsingListener.init();
     TrackingProtection.init();
     RefreshBlocker.init();
+    CaptivePortalWatcher.init();
 
     let mm = window.getGroupMessageManager("browsers");
     mm.loadFrameScript("chrome://browser/content/tab-content.js", true);
     mm.loadFrameScript("chrome://browser/content/content.js", true);
     mm.loadFrameScript("chrome://browser/content/content-UITour.js", true);
     mm.loadFrameScript("chrome://global/content/manifestMessages.js", true);
 
     // initialize observers and listeners
@@ -1503,16 +1504,18 @@ var gBrowserInit = {
     TrackingProtection.uninit();
 
     RefreshBlocker.uninit();
 
     gMenuButtonUpdateBadge.uninit();
 
     gMenuButtonBadgeManager.uninit();
 
+    CaptivePortalWatcher.uninit();
+
     SidebarUI.uninit();
 
     // Now either cancel delayedStartup, or clean up the services initialized from
     // it.
     if (this._boundDelayedStartup) {
       this._cancelDelayedStartup();
     } else {
       if (Win7Features)
--- a/browser/base/content/global-scripts.inc
+++ b/browser/base/content/global-scripts.inc
@@ -6,16 +6,17 @@
 <script type="application/javascript" src="chrome://global/content/printUtils.js"/>
 <script type="application/javascript" src="chrome://global/content/viewZoomOverlay.js"/>
 <script type="application/javascript" src="chrome://browser/content/places/browserPlacesViews.js"/>
 <script type="application/javascript" src="chrome://browser/content/browser.js"/>
 <script type="application/javascript" src="chrome://browser/content/customizableui/panelUI.js"/>
 <script type="application/javascript" src="chrome://global/content/viewSourceUtils.js"/>
 
 <script type="application/javascript" src="chrome://browser/content/browser-addons.js"/>
+<script type="application/javascript" src="chrome://browser/content/browser-captivePortal.js"/>
 <script type="application/javascript" src="chrome://browser/content/browser-ctrlTab.js"/>
 <script type="application/javascript" src="chrome://browser/content/browser-customization.js"/>
 <script type="application/javascript" src="chrome://browser/content/browser-devedition.js"/>
 <script type="application/javascript" src="chrome://browser/content/browser-feeds.js"/>
 <script type="application/javascript" src="chrome://browser/content/browser-fullScreenAndPointerLock.js"/>
 <script type="application/javascript" src="chrome://browser/content/browser-fullZoom.js"/>
 <script type="application/javascript" src="chrome://browser/content/browser-gestureSupport.js"/>
 <script type="application/javascript" src="chrome://browser/content/browser-media.js"/>
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -67,16 +67,17 @@ browser.jar:
         content/browser/aboutProviderDirectory.xhtml  (content/aboutProviderDirectory.xhtml)
         content/browser/aboutTabCrashed.css           (content/aboutTabCrashed.css)
         content/browser/aboutTabCrashed.js            (content/aboutTabCrashed.js)
         content/browser/aboutTabCrashed.xhtml         (content/aboutTabCrashed.xhtml)
 *       content/browser/browser.css                   (content/browser.css)
         content/browser/browser.js                    (content/browser.js)
 *       content/browser/browser.xul                   (content/browser.xul)
         content/browser/browser-addons.js             (content/browser-addons.js)
+        content/browser/browser-captivePortal.js      (content/browser-captivePortal.js)
         content/browser/browser-ctrlTab.js            (content/browser-ctrlTab.js)
         content/browser/browser-customization.js      (content/browser-customization.js)
         content/browser/browser-data-submission-info-bar.js (content/browser-data-submission-info-bar.js)
         content/browser/browser-devedition.js         (content/browser-devedition.js)
         content/browser/browser-feeds.js              (content/browser-feeds.js)
         content/browser/browser-fullScreenAndPointerLock.js  (content/browser-fullScreenAndPointerLock.js)
         content/browser/browser-fullZoom.js           (content/browser-fullZoom.js)
         content/browser/browser-fxaccounts.js         (content/browser-fxaccounts.js)
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -24,17 +24,16 @@ XPCOMUtils.defineLazyServiceGetter(this,
   ["AddonManager", "resource://gre/modules/AddonManager.jsm"],
   ["AddonWatcher", "resource://gre/modules/AddonWatcher.jsm"],
   ["AsyncShutdown", "resource://gre/modules/AsyncShutdown.jsm"],
   ["AutoCompletePopup", "resource://gre/modules/AutoCompletePopup.jsm"],
   ["BookmarkHTMLUtils", "resource://gre/modules/BookmarkHTMLUtils.jsm"],
   ["BookmarkJSONUtils", "resource://gre/modules/BookmarkJSONUtils.jsm"],
   ["BrowserUITelemetry", "resource:///modules/BrowserUITelemetry.jsm"],
   ["BrowserUsageTelemetry", "resource:///modules/BrowserUsageTelemetry.jsm"],
-  ["CaptivePortalWatcher", "resource:///modules/CaptivePortalWatcher.jsm"],
   ["ContentClick", "resource:///modules/ContentClick.jsm"],
   ["ContentPrefServiceParent", "resource://gre/modules/ContentPrefServiceParent.jsm"],
   ["ContentSearch", "resource:///modules/ContentSearch.jsm"],
   ["DateTimePickerHelper", "resource://gre/modules/DateTimePickerHelper.jsm"],
   ["DirectoryLinksProvider", "resource:///modules/DirectoryLinksProvider.jsm"],
   ["Feeds", "resource:///modules/Feeds.jsm"],
   ["FileUtils", "resource://gre/modules/FileUtils.jsm"],
   ["FormValidationHandler", "resource:///modules/FormValidationHandler.jsm"],
@@ -1003,18 +1002,16 @@ BrowserGlue.prototype = {
         if (removalSuccessful && uninstalledValue == "True") {
           this._resetProfileNotification("uninstall");
         }
       }
     }
 
     this._checkForOldBuildUpdates();
 
-    CaptivePortalWatcher.init();
-
     AutoCompletePopup.init();
     DateTimePickerHelper.init();
 
     this._firstWindowTelemetry(aWindow);
     this._firstWindowLoaded();
   },
 
   /**
@@ -1033,17 +1030,16 @@ BrowserGlue.prototype = {
       appStartup.trackStartupCrashEnd();
     } catch (e) {
       Cu.reportError("Could not end startup crash tracking in quit-application-granted: " + e);
     }
 
     BrowserUsageTelemetry.uninit();
     SelfSupportBackend.uninit();
     NewTabMessages.uninit();
-    CaptivePortalWatcher.uninit();
     AboutNewTab.uninit();
     webrtcUI.uninit();
     FormValidationHandler.uninit();
     AutoCompletePopup.uninit();
     DateTimePickerHelper.uninit();
     if (AppConstants.NIGHTLY_BUILD) {
       AddonWatcher.uninit();
     }
deleted file mode 100644
--- a/browser/modules/CaptivePortalWatcher.jsm
+++ /dev/null
@@ -1,278 +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 { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-
-this.EXPORTED_SYMBOLS = [ "CaptivePortalWatcher" ];
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Timer.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource:///modules/RecentWindow.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "cps",
-                                   "@mozilla.org/network/captive-portal-service;1",
-                                   "nsICaptivePortalService");
-
-this.CaptivePortalWatcher = {
-  /**
-   * This constant is chosen to be large enough for a portal recheck to complete,
-   * and small enough that the delay in opening a tab isn't too noticeable.
-   * Please see comments for _delayedCaptivePortalDetected for more details.
-   */
-  PORTAL_RECHECK_DELAY_MS: 150,
-
-  // This is the value used to identify the captive portal notification.
-  PORTAL_NOTIFICATION_VALUE: "captive-portal-detected",
-
-  // This holds a weak reference to the captive portal tab so that we
-  // don't leak it if the user closes it.
-  _captivePortalTab: null,
-
-  // This holds a weak reference to the captive portal notification.
-  _captivePortalNotification: null,
-
-  _initialized: false,
-
-  /**
-   * If a portal is detected when we don't have focus, we first wait for focus
-   * and then add the tab if, after a recheck, the portal is still active. This
-   * is set to true while we wait so that in the unlikely event that we receive
-   * another notification while waiting, we don't do things twice.
-   */
-  _delayedCaptivePortalDetectedInProgress: false,
-
-  // In the situation above, this is set to true while we wait for the recheck.
-  // This flag exists so that tests can appropriately simulate a recheck.
-  _waitingForRecheck: false,
-
-  get canonicalURL() {
-    return Services.prefs.getCharPref("captivedetect.canonicalURL");
-  },
-
-  init() {
-    Services.obs.addObserver(this, "captive-portal-login", false);
-    Services.obs.addObserver(this, "captive-portal-login-abort", false);
-    Services.obs.addObserver(this, "captive-portal-login-success", false);
-    this._initialized = true;
-
-    if (cps.state == cps.LOCKED_PORTAL) {
-      // A captive portal has already been detected.
-      this._captivePortalDetected();
-      return;
-    }
-
-    cps.recheckCaptivePortal();
-  },
-
-  uninit() {
-    if (!this._initialized) {
-      return;
-    }
-    Services.obs.removeObserver(this, "captive-portal-login");
-    Services.obs.removeObserver(this, "captive-portal-login-abort");
-    Services.obs.removeObserver(this, "captive-portal-login-success");
-  },
-
-  observe(subject, topic, data) {
-    switch (topic) {
-      case "captive-portal-login":
-        this._captivePortalDetected();
-        break;
-      case "captive-portal-login-abort":
-      case "captive-portal-login-success":
-        this._captivePortalGone();
-        break;
-      case "xul-window-visible":
-        this._delayedCaptivePortalDetected();
-        break;
-    }
-  },
-
-  _captivePortalDetected() {
-    if (this._delayedCaptivePortalDetectedInProgress) {
-      return;
-    }
-
-    let win = RecentWindow.getMostRecentBrowserWindow();
-    // If there's no browser window or none have focus, open and show the
-    // tab when we regain focus. This is so that if a different application was
-    // focused, when the user (re-)focuses a browser window, we open the tab
-    // immediately in that window so they can login before continuing to browse.
-    if (!win || win != Services.ww.activeWindow) {
-      this._delayedCaptivePortalDetectedInProgress = true;
-      Services.obs.addObserver(this, "xul-window-visible", false);
-      return;
-    }
-
-    this._showNotification(win);
-  },
-
-  _ensureCaptivePortalTab(win) {
-    let tab;
-    if (this._captivePortalTab) {
-      tab = this._captivePortalTab.get();
-    }
-
-    // If the tab is gone or going, we need to open a new one.
-    if (!tab || tab.closing || !tab.parentNode) {
-      tab = win.gBrowser.addTab(this.canonicalURL,
-                                { ownerTab: win.gBrowser.selectedTab });
-      this._captivePortalTab = Cu.getWeakReference(tab);
-    }
-
-    win.gBrowser.selectedTab = tab;
-  },
-
-  /**
-   * Called after we regain focus if we detect a portal while a browser window
-   * doesn't have focus. Triggers a portal recheck to reaffirm state, and adds
-   * the tab if needed after a short delay to allow the recheck to complete.
-   */
-  _delayedCaptivePortalDetected() {
-    if (!this._delayedCaptivePortalDetectedInProgress) {
-      return;
-    }
-
-    let win = RecentWindow.getMostRecentBrowserWindow();
-    if (win != Services.ww.activeWindow) {
-      // The window that got focused was not a browser window.
-      return;
-    }
-    Services.obs.removeObserver(this, "xul-window-visible");
-
-    // Trigger a portal recheck. The user may have logged into the portal via
-    // another client, or changed networks.
-    cps.recheckCaptivePortal();
-    this._waitingForRecheck = true;
-    let requestTime = Date.now();
-
-    let self = this;
-    Services.obs.addObserver(function observer() {
-      let time = Date.now() - requestTime;
-      Services.obs.removeObserver(observer, "captive-portal-check-complete");
-      self._waitingForRecheck = false;
-      self._delayedCaptivePortalDetectedInProgress = false;
-      if (cps.state != cps.LOCKED_PORTAL) {
-        // We're free of the portal!
-        return;
-      }
-
-      self._showNotification(win);
-      if (time <= self.PORTAL_RECHECK_DELAY_MS) {
-        // The amount of time elapsed since we requested a recheck (i.e. since
-        // the browser window was focused) was small enough that we can add and
-        // focus a tab with the login page with no noticeable delay.
-        self._ensureCaptivePortalTab(win);
-      }
-    }, "captive-portal-check-complete", false);
-  },
-
-  _captivePortalGone() {
-    if (this._delayedCaptivePortalDetectedInProgress) {
-      Services.obs.removeObserver(this, "xul-window-visible");
-      this._delayedCaptivePortalDetectedInProgress = false;
-    }
-
-    this._removeNotification();
-
-    if (!this._captivePortalTab) {
-      return;
-    }
-
-    let tab = this._captivePortalTab.get();
-    // In all the cases below, we want to stop treating the tab as a
-    // captive portal tab.
-    this._captivePortalTab = null;
-
-    // Check parentNode in case the object hasn't been gc'd yet.
-    if (!tab || tab.closing || !tab.parentNode) {
-      // User has closed the tab already.
-      return;
-    }
-
-    let tabbrowser = tab.ownerGlobal.gBrowser;
-
-    // If after the login, the captive portal has redirected to some other page,
-    // leave it open if the tab has focus.
-    if (tab.linkedBrowser.currentURI.spec != this.canonicalURL &&
-        tabbrowser.selectedTab == tab) {
-      return;
-    }
-
-    // Remove the tab.
-    tabbrowser.removeTab(tab);
-  },
-
-  get _browserBundle() {
-    delete this._browserBundle;
-    return this._browserBundle =
-      Services.strings.createBundle("chrome://browser/locale/browser.properties");
-  },
-
-  handleEvent(aEvent) {
-    if (aEvent.type != "TabSelect" || !this._captivePortalTab || !this._captivePortalNotification) {
-      return;
-    }
-
-    let tab = this._captivePortalTab.get();
-    let n = this._captivePortalNotification.get();
-    if (!tab || !n) {
-      return;
-    }
-
-    let doc = tab.ownerDocument;
-    let button = n.querySelector("button.notification-button");
-    if (doc.defaultView.gBrowser.selectedTab == tab) {
-      button.style.visibility = "hidden";
-    } else {
-      button.style.visibility = "visible";
-    }
-  },
-
-  _showNotification(win) {
-    let buttons = [
-      {
-        label: this._browserBundle.GetStringFromName("captivePortal.showLoginPage"),
-        callback: () => {
-          this._ensureCaptivePortalTab(win);
-
-          // Returning true prevents the notification from closing.
-          return true;
-        },
-        isDefault: true,
-      },
-    ];
-
-    let message = this._browserBundle.GetStringFromName("captivePortal.infoMessage2");
-
-    let closeHandler = (aEventName) => {
-      if (aEventName != "removed") {
-        return;
-      }
-      win.gBrowser.tabContainer.removeEventListener("TabSelect", this);
-    };
-
-    let nb = win.document.getElementById("high-priority-global-notificationbox");
-    let n = nb.appendNotification(message, this.PORTAL_NOTIFICATION_VALUE, "",
-                                  nb.PRIORITY_INFO_MEDIUM, buttons, closeHandler);
-
-    this._captivePortalNotification = Cu.getWeakReference(n);
-
-    win.gBrowser.tabContainer.addEventListener("TabSelect", this);
-  },
-
-  _removeNotification() {
-    if (!this._captivePortalNotification)
-      return;
-    let n = this._captivePortalNotification.get();
-    this._captivePortalNotification = null;
-    if (!n || !n.parentNode) {
-      return;
-    }
-    n.close();
-  },
-};
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -11,17 +11,16 @@ XPCSHELL_TESTS_MANIFESTS += [
 ]
 
 EXTRA_JS_MODULES += [
     'AboutHome.jsm',
     'AboutNewTab.jsm',
     'AttributionCode.jsm',
     'BrowserUITelemetry.jsm',
     'BrowserUsageTelemetry.jsm',
-    'CaptivePortalWatcher.jsm',
     'CastingApps.jsm',
     'ContentClick.jsm',
     'ContentCrashHandlers.jsm',
     'ContentLinkHandler.jsm',
     'ContentObservers.jsm',
     'ContentSearch.jsm',
     'ContentWebRTC.jsm',
     'DirectoryLinksProvider.jsm',