Bug 1442398 - Convert the TabBrowser class to a plain object and make gBrowser available already before gBrowser.init returns. r?bgrins draft
authorDão Gottwald <dao@mozilla.com>
Wed, 07 Mar 2018 06:49:53 +0100
changeset 764088 40e19ddefc6160cf425f6d987b0bfd3e4ef461d7
parent 763942 bccdc684210431c233622650a91454c09f6af9eb
push id101662
push userdgottwald@mozilla.com
push dateWed, 07 Mar 2018 05:50:23 +0000
reviewersbgrins
bugs1442398
milestone60.0a1
Bug 1442398 - Convert the TabBrowser class to a plain object and make gBrowser available already before gBrowser.init returns. r?bgrins MozReview-Commit-ID: Cmq8IOaoxn5
browser/base/content/browser.js
browser/base/content/tabbrowser.js
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -135,22 +135,33 @@ XPCOMUtils.defineLazyServiceGetters(this
 });
 
 if (AppConstants.MOZ_CRASHREPORTER) {
   XPCOMUtils.defineLazyServiceGetter(this, "gCrashReporter",
                                      "@mozilla.org/xre/app-info;1",
                                      "nsICrashReporter");
 }
 
-XPCOMUtils.defineLazyGetter(this, "gBrowser", function() {
-  // The TabBrowser class only exists in proper browser windows, whereas
-  // browser.js may be loaded in other windows where a non-tabbrowser
-  // browser might try to access the gBrowser property.
-  // eslint-disable-next-line no-undef
-  return (typeof TabBrowser == "function") ? new TabBrowser() : null;
+Object.defineProperty(this, "gBrowser", {
+  configurable: true,
+  enumerable: true,
+  get() {
+    delete window.gBrowser;
+
+    // The tabbed browser only exists in proper browser windows, but on Mac we
+    // load browser.js in other windows and might try to access gBrowser.
+    if (!window._gBrowser) {
+      return window.gBrowser = null;
+    }
+
+    window.gBrowser = window._gBrowser;
+    delete window._gBrowser;
+    gBrowser.init();
+    return gBrowser;
+  },
 });
 
 XPCOMUtils.defineLazyGetter(this, "gBrowserBundle", function() {
   return Services.strings.createBundle("chrome://browser/locale/browser.properties");
 });
 XPCOMUtils.defineLazyGetter(this, "gNavigatorBundle", function() {
   // This is a stringbundle-like interface to gBrowserBundle, formerly a getter for
   // the "bundle_browser" element.
--- a/browser/base/content/tabbrowser.js
+++ b/browser/base/content/tabbrowser.js
@@ -1,17 +1,17 @@
 /* -*- 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/. */
 
 /* eslint-env mozilla/browser-window */
 
-class TabBrowser {
-  constructor() {
+window._gBrowser = {
+  init() {
     this.requiresAddonInterpositions = true;
 
     ChromeUtils.defineModuleGetter(this, "AsyncTabSwitcher",
       "resource:///modules/AsyncTabSwitcher.jsm");
 
     XPCOMUtils.defineLazyServiceGetters(this, {
       _unifiedComplete: ["@mozilla.org/autocomplete/search;1?name=unifiedcomplete", "mozIPlacesAutoComplete"],
       serializationHelper: ["@mozilla.org/network/serialization-helper;1", "nsISerializationHelper"],
@@ -249,231 +249,231 @@ class TabBrowser {
       "browser.tabs.tabMinWidth", this._tabMinWidthLimit,
       (pref, prevValue, newValue) => this.tabMinWidth = newValue,
       newValue => Math.max(newValue, this._tabMinWidthLimit),
     );
 
     this.tabMinWidth = this.tabMinWidthPref;
 
     this._setupEventListeners();
-  }
+  },
 
   get tabContextMenu() {
     return this.tabContainer.contextMenu;
-  }
+  },
 
   get visibleTabs() {
     if (!this._visibleTabs)
       this._visibleTabs = Array.filter(this.tabs,
         tab => !tab.hidden && !tab.closing);
     return this._visibleTabs;
-  }
+  },
 
   get _numPinnedTabs() {
     for (var i = 0; i < this.tabs.length; i++) {
       if (!this.tabs[i].pinned)
         break;
     }
     return i;
-  }
+  },
 
   get popupAnchor() {
     if (this.mCurrentTab._popupAnchor) {
       return this.mCurrentTab._popupAnchor;
     }
     let stack = this.mCurrentBrowser.parentNode;
     // Create an anchor for the popup
     let popupAnchor = document.createElementNS(this._XUL_NS, "hbox");
     popupAnchor.className = "popup-anchor";
     popupAnchor.hidden = true;
     stack.appendChild(popupAnchor);
     return this.mCurrentTab._popupAnchor = popupAnchor;
-  }
+  },
 
   set selectedTab(val) {
     if (gNavToolbox.collapsed && !this._allowTabChange) {
       return this.tabbox.selectedTab;
     }
     // Update the tab
     this.tabbox.selectedTab = val;
     return val;
-  }
+  },
 
   get selectedTab() {
     return this.mCurrentTab;
-  }
+  },
 
   get selectedBrowser() {
     return this.mCurrentBrowser;
-  }
+  },
 
   /**
    * BEGIN FORWARDED BROWSER PROPERTIES.  IF YOU ADD A PROPERTY TO THE BROWSER ELEMENT
    * MAKE SURE TO ADD IT HERE AS WELL.
    */
   get canGoBack() {
     return this.mCurrentBrowser.canGoBack;
-  }
+  },
 
   get canGoForward() {
     return this.mCurrentBrowser.canGoForward;
-  }
+  },
 
   goBack() {
     return this.mCurrentBrowser.goBack();
-  }
+  },
 
   goForward() {
     return this.mCurrentBrowser.goForward();
-  }
+  },
 
   reload() {
     return this.mCurrentBrowser.reload();
-  }
+  },
 
   reloadWithFlags(aFlags) {
     return this.mCurrentBrowser.reloadWithFlags(aFlags);
-  }
+  },
 
   stop() {
     return this.mCurrentBrowser.stop();
-  }
+  },
 
   /**
    * throws exception for unknown schemes
    */
   loadURI(aURI, aReferrerURI, aCharset) {
     return this.mCurrentBrowser.loadURI(aURI, aReferrerURI, aCharset);
-  }
+  },
 
   /**
    * throws exception for unknown schemes
    */
   loadURIWithFlags(aURI, aFlags, aReferrerURI, aCharset, aPostData) {
     // Note - the callee understands both:
     // (a) loadURIWithFlags(aURI, aFlags, ...)
     // (b) loadURIWithFlags(aURI, { flags: aFlags, ... })
     // Forwarding it as (a) here actually supports both (a) and (b),
     // so you can call us either way too.
     return this.mCurrentBrowser.loadURIWithFlags(aURI, aFlags, aReferrerURI, aCharset, aPostData);
-  }
+  },
 
   goHome() {
     return this.mCurrentBrowser.goHome();
-  }
+  },
 
   gotoIndex(aIndex) {
     return this.mCurrentBrowser.gotoIndex(aIndex);
-  }
+  },
 
   set homePage(val) {
     this.mCurrentBrowser.homePage = val;
     return val;
-  }
+  },
 
   get homePage() {
     return this.mCurrentBrowser.homePage;
-  }
+  },
 
   get currentURI() {
     return this.mCurrentBrowser.currentURI;
-  }
+  },
 
   get finder() {
     return this.mCurrentBrowser.finder;
-  }
+  },
 
   get docShell() {
     return this.mCurrentBrowser.docShell;
-  }
+  },
 
   get webNavigation() {
     return this.mCurrentBrowser.webNavigation;
-  }
+  },
 
   get webBrowserFind() {
     return this.mCurrentBrowser.webBrowserFind;
-  }
+  },
 
   get webProgress() {
     return this.mCurrentBrowser.webProgress;
-  }
+  },
 
   get contentWindow() {
     return this.mCurrentBrowser.contentWindow;
-  }
+  },
 
   get contentWindowAsCPOW() {
     return this.mCurrentBrowser.contentWindowAsCPOW;
-  }
+  },
 
   get sessionHistory() {
     return this.mCurrentBrowser.sessionHistory;
-  }
+  },
 
   get markupDocumentViewer() {
     return this.mCurrentBrowser.markupDocumentViewer;
-  }
+  },
 
   get contentDocument() {
     return this.mCurrentBrowser.contentDocument;
-  }
+  },
 
   get contentDocumentAsCPOW() {
     return this.mCurrentBrowser.contentDocumentAsCPOW;
-  }
+  },
 
   get contentTitle() {
     return this.mCurrentBrowser.contentTitle;
-  }
+  },
 
   get contentPrincipal() {
     return this.mCurrentBrowser.contentPrincipal;
-  }
+  },
 
   get securityUI() {
     return this.mCurrentBrowser.securityUI;
-  }
+  },
 
   set fullZoom(val) {
     this.mCurrentBrowser.fullZoom = val;
-  }
+  },
 
   get fullZoom() {
     return this.mCurrentBrowser.fullZoom;
-  }
+  },
 
   set textZoom(val) {
     this.mCurrentBrowser.textZoom = val;
-  }
+  },
 
   get textZoom() {
     return this.mCurrentBrowser.textZoom;
-  }
+  },
 
   get isSyntheticDocument() {
     return this.mCurrentBrowser.isSyntheticDocument;
-  }
+  },
 
   set userTypedValue(val) {
     return this.mCurrentBrowser.userTypedValue = val;
-  }
+  },
 
   get userTypedValue() {
     return this.mCurrentBrowser.userTypedValue;
-  }
+  },
 
   set tabMinWidth(val) {
     this.tabContainer.style.setProperty("--tab-min-width", val + "px");
     return val;
-  }
+  },
 
   isFindBarInitialized(aTab) {
     return (aTab || this.selectedTab)._findBar != undefined;
-  }
+  },
 
   getFindBar(aTab) {
     if (!aTab)
       aTab = this.selectedTab;
 
     if (aTab._findBar)
       return aTab._findBar;
 
@@ -490,35 +490,35 @@ class TabBrowser {
 
     aTab._findBar = findBar;
 
     let event = document.createEvent("Events");
     event.initEvent("TabFindInitialized", true, false);
     aTab.dispatchEvent(event);
 
     return findBar;
-  }
+  },
 
   getStatusPanel() {
     if (!this._statusPanel) {
       this._statusPanel = document.createElementNS(this._XUL_NS, "statuspanel");
       this._statusPanel.setAttribute("inactive", "true");
       this._statusPanel.setAttribute("layer", "true");
       this._appendStatusPanel();
     }
     return this._statusPanel;
-  }
+  },
 
   _appendStatusPanel() {
     if (this._statusPanel) {
       let browser = this.selectedBrowser;
       let browserContainer = this.getBrowserContainer(browser);
       browserContainer.insertBefore(this._statusPanel, browser.parentNode.nextSibling);
     }
-  }
+  },
 
   pinTab(aTab) {
     if (aTab.pinned)
       return;
 
     if (aTab.hidden)
       this.showTab(aTab);
 
@@ -528,17 +528,17 @@ class TabBrowser {
     this.tabContainer._positionPinnedTabs();
     this.tabContainer._updateCloseButtons();
 
     this.getBrowserForTab(aTab).messageManager.sendAsyncMessage("Browser:AppTab", { isAppTab: true });
 
     let event = document.createEvent("Events");
     event.initEvent("TabPinned", true, false);
     aTab.dispatchEvent(event);
-  }
+  },
 
   unpinTab(aTab) {
     if (!aTab.pinned)
       return;
 
     this.moveTabTo(aTab, this._numPinnedTabs - 1);
     aTab.removeAttribute("pinned");
     aTab.style.marginInlineStart = "";
@@ -546,30 +546,30 @@ class TabBrowser {
     this.tabContainer._positionPinnedTabs();
     this.tabContainer._updateCloseButtons();
 
     this.getBrowserForTab(aTab).messageManager.sendAsyncMessage("Browser:AppTab", { isAppTab: false });
 
     let event = document.createEvent("Events");
     event.initEvent("TabUnpinned", true, false);
     aTab.dispatchEvent(event);
-  }
+  },
 
   previewTab(aTab, aCallback) {
     let currentTab = this.selectedTab;
     try {
       // Suppress focus, ownership and selected tab changes
       this._previewMode = true;
       this.selectedTab = aTab;
       aCallback();
     } finally {
       this.selectedTab = currentTab;
       this._previewMode = false;
     }
-  }
+  },
 
   syncThrobberAnimations(aTab) {
     aTab.ownerGlobal.promiseDocumentFlushed(() => {
       if (!aTab.parentNode) {
         return;
       }
 
       const animations =
@@ -602,40 +602,40 @@ class TabBrowser {
           // the playState, since reading the playState of
           // a CSSAnimation object will flush style.
           if (animation.currentTime !== null) {
             animation.startTime = firstStartTime;
           }
         }
       });
     });
-  }
+  },
 
   getBrowserAtIndex(aIndex) {
     return this.browsers[aIndex];
-  }
+  },
 
   getBrowserIndexForDocument(aDocument) {
     var tab = this._getTabForContentWindow(aDocument.defaultView);
     return tab ? tab._tPos : -1;
-  }
+  },
 
   getBrowserForDocument(aDocument) {
     var tab = this._getTabForContentWindow(aDocument.defaultView);
     return tab ? tab.linkedBrowser : null;
-  }
+  },
 
   getBrowserForContentWindow(aWindow) {
     var tab = this._getTabForContentWindow(aWindow);
     return tab ? tab.linkedBrowser : null;
-  }
+  },
 
   getBrowserForOuterWindowID(aID) {
     return this._outerWindowIDBrowserMap.get(aID);
-  }
+  },
 
   _getTabForContentWindow(aWindow) {
     // When not using remote browsers, we can take a fast path by getting
     // directly from the content window to the browser without looping
     // over all browsers.
     if (!gMultiProcessBrowser) {
       let browser = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                            .getInterface(Ci.nsIWebNavigation)
@@ -646,52 +646,52 @@ class TabBrowser {
 
     for (let i = 0; i < this.browsers.length; i++) {
       // NB: We use contentWindowAsCPOW so that this code works both
       // for remote browsers as well. aWindow may be a CPOW.
       if (this.browsers[i].contentWindowAsCPOW == aWindow)
         return this.tabs[i];
     }
     return null;
-  }
+  },
 
   getTabForBrowser(aBrowser) {
     return this._tabForBrowser.get(aBrowser);
-  }
+  },
 
   getNotificationBox(aBrowser) {
     return this.getSidebarContainer(aBrowser).parentNode;
-  }
+  },
 
   getSidebarContainer(aBrowser) {
     return this.getBrowserContainer(aBrowser).parentNode;
-  }
+  },
 
   getBrowserContainer(aBrowser) {
     return (aBrowser || this.mCurrentBrowser).parentNode.parentNode;
-  }
+  },
 
   getTabModalPromptBox(aBrowser) {
     let browser = (aBrowser || this.mCurrentBrowser);
     if (!browser.tabModalPromptBox) {
       browser.tabModalPromptBox = new TabModalPromptBox(browser);
     }
     return browser.tabModalPromptBox;
-  }
+  },
 
   getTabFromAudioEvent(aEvent) {
     if (!Services.prefs.getBoolPref("browser.tabs.showAudioPlayingIcon") ||
       !aEvent.isTrusted) {
       return null;
     }
 
     var browser = aEvent.originalTarget;
     var tab = this.getTabForBrowser(browser);
     return tab;
-  }
+  },
 
   _callProgressListeners(aBrowser, aMethod, aArguments, aCallGlobalListeners, aCallTabsListeners) {
     var rv = true;
 
     function callListeners(listeners, args) {
       for (let p of listeners) {
         if (aMethod in p) {
           try {
@@ -717,17 +717,17 @@ class TabBrowser {
     // eslint-disable-next-line mozilla/no-compare-against-boolean-literals
     if (aCallTabsListeners != false) {
       aArguments.unshift(aBrowser);
 
       callListeners(this.mTabsProgressListeners, aArguments);
     }
 
     return rv;
-  }
+  },
 
   /**
    * Determine if a URI is an about: page pointing to a local resource.
    */
   _isLocalAboutURI(aURI, aResolvedURI) {
     if (!aURI.schemeIs("about")) {
       return false;
     }
@@ -747,28 +747,28 @@ class TabBrowser {
         Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, // securityFlags
         Ci.nsIContentPolicy.TYPE_OTHER // contentPolicyType
       ).URI;
       return resolvedURI.schemeIs("jar") || resolvedURI.schemeIs("file");
     } catch (ex) {
       // aURI might be invalid.
       return false;
     }
-  }
+  },
 
   storeIcon(aBrowser, aURI, aLoadingPrincipal, aRequestContextID) {
     try {
       if (!(aURI instanceof Ci.nsIURI)) {
         aURI = makeURI(aURI);
       }
       PlacesUIUtils.loadFavicon(aBrowser, aLoadingPrincipal, aURI, aRequestContextID);
     } catch (ex) {
       Cu.reportError(ex);
     }
-  }
+  },
 
   setIcon(aTab, aURI, aLoadingPrincipal, aRequestContextID) {
     let browser = this.getBrowserForTab(aTab);
     browser.mIconURL = aURI instanceof Ci.nsIURI ? aURI.spec : aURI;
     let loadingPrincipal = aLoadingPrincipal ||
       Services.scriptSecurityManager.getSystemPrincipal();
     let requestContextID = aRequestContextID || 0;
     let sizedIconUrl = browser.mIconURL || "";
@@ -786,36 +786,36 @@ class TabBrowser {
         aTab.removeAttribute("iconloadingprincipal");
         delete browser.mIconLoadingPrincipal;
         aTab.removeAttribute("image");
       }
       this._tabAttrModified(aTab, ["image"]);
     }
 
     this._callProgressListeners(browser, "onLinkIconAvailable", [browser.mIconURL]);
-  }
+  },
 
   getIcon(aTab) {
     let browser = aTab ? this.getBrowserForTab(aTab) : this.selectedBrowser;
     return browser.mIconURL;
-  }
+  },
 
   setPageInfo(aURL, aDescription, aPreviewImage) {
     if (aURL) {
       let pageInfo = { url: aURL, description: aDescription, previewImageURL: aPreviewImage };
       PlacesUtils.history.update(pageInfo).catch(Cu.reportError);
     }
-  }
+  },
 
   shouldLoadFavIcon(aURI) {
     return (aURI &&
             Services.prefs.getBoolPref("browser.chrome.site_icons") &&
             Services.prefs.getBoolPref("browser.chrome.favicons") &&
             ("schemeIs" in aURI) && (aURI.schemeIs("http") || aURI.schemeIs("https")));
-  }
+  },
 
   useDefaultIcon(aTab) {
     let browser = this.getBrowserForTab(aTab);
     let documentURI = browser.documentURI;
     let requestContextID = browser.contentRequestContextID;
     let loadingPrincipal = browser.contentPrincipal;
     let icon = null;
 
@@ -837,23 +837,23 @@ class TabBrowser {
       let url = documentURI.prePath + "/favicon.ico";
       if (!this.isFailedIcon(url)) {
         icon = url;
         this.storeIcon(browser, icon, loadingPrincipal, requestContextID);
       }
     }
 
     this.setIcon(aTab, icon, loadingPrincipal, requestContextID);
-  }
+  },
 
   isFailedIcon(aURI) {
     if (!(aURI instanceof Ci.nsIURI))
       aURI = makeURI(aURI);
     return PlacesUtils.favicons.isFailedFavicon(aURI);
-  }
+  },
 
   getWindowTitleForBrowser(aBrowser) {
     var newTitle = "";
     var docElement = document.documentElement;
     var sep = docElement.getAttribute("titlemenuseparator");
     let tab = this.getTabForBrowser(aBrowser);
     let docTitle;
 
@@ -886,21 +886,21 @@ class TabBrowser {
         if (uri.scheme == "about")
           newTitle = uri.spec + sep + newTitle;
         else
           newTitle = uri.prePath + sep + newTitle;
       }
     } catch (e) {}
 
     return newTitle;
-  }
+  },
 
   updateTitlebar() {
     document.title = this.getWindowTitleForBrowser(this.mCurrentBrowser);
-  }
+  },
 
   updateCurrentBrowser(aForceUpdate) {
     var newBrowser = this.getBrowserAtIndex(this.tabContainer.selectedIndex);
     if (this.mCurrentBrowser == newBrowser && !aForceUpdate)
       return;
 
     if (!aForceUpdate) {
       document.commandDispatcher.lock();
@@ -1115,17 +1115,17 @@ class TabBrowser {
         bubbles: true,
         cancelable: true
       });
       this.dispatchEvent(event);
     }
 
     if (!aForceUpdate)
       TelemetryStopwatch.finish("FX_TAB_SWITCH_UPDATE_MS");
-  }
+  },
 
   _adjustFocusBeforeTabSwitch(oldTab, newTab) {
     if (this._previewMode) {
       return;
     }
 
     let oldBrowser = oldTab.linkedBrowser;
     let newBrowser = newTab.linkedBrowser;
@@ -1151,17 +1151,17 @@ class TabBrowser {
         gURLBar &&
         gURLBar.focused;
       if (!keepFocusOnUrlBar) {
         // Clear focus so that _adjustFocusAfterTabSwitch can detect if
         // some element has been focused and respect that.
         document.activeElement.blur();
       }
     }
-  }
+  },
 
   _adjustFocusAfterTabSwitch(newTab) {
     // Don't steal focus from the tab bar.
     if (document.activeElement == newTab)
       return;
 
     let newBrowser = this.getBrowserForTab(newTab);
 
@@ -1218,31 +1218,31 @@ class TabBrowser {
       // last clicked when switching back to that tab
       if (newFocusedElement &&
           (newFocusedElement instanceof HTMLAnchorElement ||
             newFocusedElement.getAttributeNS("http://www.w3.org/1999/xlink", "type") == "simple"))
         focusFlags |= fm.FLAG_SHOWRING;
     }
 
     fm.setFocus(newBrowser, focusFlags);
-  }
+  },
 
   _tabAttrModified(aTab, aChanged) {
     if (aTab.closing)
       return;
 
     let event = new CustomEvent("TabAttrModified", {
       bubbles: true,
       cancelable: false,
       detail: {
         changed: aChanged,
       }
     });
     aTab.dispatchEvent(event);
-  }
+  },
 
   setBrowserSharing(aBrowser, aState) {
     let tab = this.getTabForBrowser(aBrowser);
     if (!tab)
       return;
 
     if (aState.sharing) {
       tab._sharingState = aState;
@@ -1254,37 +1254,37 @@ class TabBrowser {
     } else {
       tab._sharingState = null;
       tab.removeAttribute("sharing");
     }
     this._tabAttrModified(tab, ["sharing"]);
 
     if (aBrowser == this.mCurrentBrowser)
       gIdentityHandler.updateSharingIndicator();
-  }
+  },
 
   getTabSharingState(aTab) {
     // Normalize the state object for consumers (ie.extensions).
     let state = Object.assign({}, aTab._sharingState);
     return {
       camera: !!state.camera,
       microphone: !!state.microphone,
       screen: state.screen && state.screen.replace("Paused", ""),
     };
-  }
+  },
 
   setInitialTabTitle(aTab, aTitle, aOptions) {
     if (aTitle) {
       if (!aTab.getAttribute("label")) {
         aTab._labelIsInitialTitle = true;
       }
 
       this._setTabLabel(aTab, aTitle, aOptions);
     }
-  }
+  },
 
   setTabTitle(aTab) {
     var browser = this.getBrowserForTab(aTab);
     var title = browser.contentTitle;
 
     // Don't replace an initially set label with the URL while the tab
     // is loading.
     if (aTab._labelIsInitialTitle) {
@@ -1332,17 +1332,17 @@ class TabBrowser {
         } catch (ex) { /* Do nothing. */ }
       } else {
         // Still no title? Fall back to our untitled string.
         title = gTabBrowserBundle.GetStringFromName("tabs.emptyTabTitle");
       }
     }
 
     return this._setTabLabel(aTab, title, { isContentTitle });
-  }
+  },
 
   _setTabLabel(aTab, aLabel, aOptions) {
     if (!aLabel) {
       return false;
     }
 
     aTab._fullLabel = aLabel;
 
@@ -1374,17 +1374,17 @@ class TabBrowser {
       this._tabAttrModified(aTab, ["label"]);
     }
 
     if (aTab.selected) {
       this.updateTitlebar();
     }
 
     return true;
-  }
+  },
 
   loadOneTab(aURI, aReferrerURI, aCharset, aPostData, aLoadInBackground, aAllowThirdPartyFixup) {
     var aTriggeringPrincipal;
     var aReferrerPolicy;
     var aFromExternal;
     var aRelatedToCurrent;
     var aAllowMixedContent;
     var aSkipAnimation;
@@ -1457,17 +1457,17 @@ class TabBrowser {
       nextTabParentId: aNextTabParentId,
       focusUrlBar: aFocusUrlBar,
       name: aName
     });
     if (!bgLoad)
       this.selectedTab = tab;
 
     return tab;
-  }
+  },
 
   loadTabs(aURIs, aLoadInBackground, aReplace) {
     let aTriggeringPrincipal;
     let aAllowThirdPartyFixup;
     let aTargetTab;
     let aNewIndex = -1;
     let aPostDatas = [];
     let aUserContextId;
@@ -1554,17 +1554,17 @@ class TabBrowser {
       });
       if (targetTabIndex !== -1)
         this.moveTabTo(tab, ++tabNum);
     }
 
     if (firstTabAdded && !aLoadInBackground) {
       this.selectedTab = firstTabAdded;
     }
-  }
+  },
 
   updateBrowserRemoteness(aBrowser, aShouldBeRemote, aOptions) {
     aOptions = aOptions || {};
     let isRemote = aBrowser.getAttribute("remote") == "true";
 
     if (!gMultiProcessBrowser && aShouldBeRemote) {
       throw new Error("Cannot switch to remote browser in a window " +
         "without the remote tabs load context.");
@@ -1710,17 +1710,17 @@ class TabBrowser {
       this.getFindBar(tab).browser = aBrowser;
     }
 
     evt = document.createEvent("Events");
     evt.initEvent("TabRemotenessChange", true, false);
     tab.dispatchEvent(evt);
 
     return true;
-  }
+  },
 
   updateBrowserRemotenessByURL(aBrowser, aURL, aOptions) {
     aOptions = aOptions || {};
 
     if (!gMultiProcessBrowser)
       return this.updateBrowserRemoteness(aBrowser, false);
 
     let currentRemoteType = aBrowser.getAttribute("remoteType") || null;
@@ -1735,29 +1735,29 @@ class TabBrowser {
     // correct type.
     if (currentRemoteType != aOptions.remoteType ||
       aOptions.newFrameloader) {
       let remote = aOptions.remoteType != E10SUtils.NOT_REMOTE;
       return this.updateBrowserRemoteness(aBrowser, remote, aOptions);
     }
 
     return false;
-  }
+  },
 
   removePreloadedBrowser() {
     if (!this._isPreloadingEnabled()) {
       return;
     }
 
     let browser = this._getPreloadedBrowser();
 
     if (browser) {
       browser.remove();
     }
-  }
+  },
 
   _getPreloadedBrowser() {
     if (!this._isPreloadingEnabled()) {
       return null;
     }
 
     // The preloaded browser might be null.
     let browser = this._preloadedBrowser;
@@ -1772,25 +1772,25 @@ class TabBrowser {
     // in the case that the browser is remote, as remote browsers take
     // care of that themselves.
     if (browser) {
       browser.setAttribute("preloadedState", "consumed");
       browser.setAttribute("autocompletepopup", "PopupAutoComplete");
     }
 
     return browser;
-  }
+  },
 
   _isPreloadingEnabled() {
     // Preloading for the newtab page is enabled when the pref is true
     // and the URL is "about:newtab". We do not support preloading for
     // custom newtab URLs.
     return Services.prefs.getBoolPref("browser.newtab.preload") &&
       !aboutNewTabService.overridden;
-  }
+  },
 
   _createPreloadBrowser() {
     // Do nothing if we have a preloaded browser already
     // or preloading of newtab pages is disabled.
     if (this._preloadedBrowser || !this._isPreloadingEnabled()) {
       return;
     }
 
@@ -1811,17 +1811,17 @@ class TabBrowser {
     }
 
     browser.loadURI(BROWSER_NEW_TAB_URL);
     browser.docShellIsActive = false;
 
     // Make sure the preloaded browser is loaded with desired zoom level
     let tabURI = Services.io.newURI(BROWSER_NEW_TAB_URL);
     FullZoom.onLocationChange(tabURI, false, browser);
-  }
+  },
 
   _createBrowser(aParams) {
     // Supported parameters:
     // userContextId, remote, remoteType, isPreloadBrowser,
     // uriIsAboutBlank, sameProcessAsFrameLoader
 
     let b = document.createElementNS(this._XUL_NS, "browser");
     b.permanentKey = {};
@@ -1927,17 +1927,17 @@ class TabBrowser {
 
     // Prevent the superfluous initial load of a blank document
     // if we're going to load something other than about:blank.
     if (!aParams.uriIsAboutBlank) {
       b.setAttribute("nodefaultsrc", "true");
     }
 
     return b;
-  }
+  },
 
   _createLazyBrowser(aTab) {
     let browser = aTab.linkedBrowser;
 
     let names = this._browserBindingProperties;
 
     for (let i = 0; i < names.length; i++) {
       let name = names[i];
@@ -2021,17 +2021,17 @@ class TabBrowser {
       }
       Object.defineProperty(browser, name, {
         get: getter,
         set: setter,
         configurable: true,
         enumerable: true
       });
     }
-  }
+  },
 
   _insertBrowser(aTab, aInsertedOnTabCreation) {
     "use strict";
 
     // If browser is already inserted or window is closed don't do anything.
     if (aTab.linkedPanel || window.closed) {
       return;
     }
@@ -2085,17 +2085,17 @@ class TabBrowser {
     // into the DOM. We thus have to register the new outerWindowID
     // for non-remote browsers after we have called browser.loadURI().
     if (remoteType == E10SUtils.NOT_REMOTE) {
       this._outerWindowIDBrowserMap.set(browser.outerWindowID, browser);
     }
 
     var evt = new CustomEvent("TabBrowserInserted", { bubbles: true, detail: { insertedOnTabCreation: aInsertedOnTabCreation } });
     aTab.dispatchEvent(evt);
-  }
+  },
 
   discardBrowser(aBrowser, aForceDiscard) {
     "use strict";
 
     let tab = this.getTabForBrowser(aBrowser);
 
     let permitUnloadFlags = aForceDiscard ? aBrowser.dontPromptAndUnload : aBrowser.dontPromptAndDontUnload;
 
@@ -2144,17 +2144,17 @@ class TabBrowser {
     let notificationbox = this.getNotificationBox(aBrowser);
     this.mPanelContainer.removeChild(notificationbox);
     tab.removeAttribute("linkedpanel");
 
     this._createLazyBrowser(tab);
 
     let evt = new CustomEvent("TabBrowserDiscarded", { bubbles: true });
     tab.dispatchEvent(evt);
-  }
+  },
 
   // eslint-disable-next-line complexity
   addTab(aURI, aReferrerURI, aCharset, aPostData, aOwner, aAllowThirdPartyFixup) {
     "use strict";
 
     var aTriggeringPrincipal;
     var aReferrerPolicy;
     var aFromExternal;
@@ -2481,17 +2481,17 @@ class TabBrowser {
     if (animate) {
       requestAnimationFrame(function() {
         // kick the animation off
         t.setAttribute("fadein", "true");
       });
     }
 
     return t;
-  }
+  },
 
   warnAboutClosingTabs(aCloseTabs, aTab) {
     var tabsToClose;
     switch (aCloseTabs) {
       case this.closingTabsEnum.ALL:
         tabsToClose = this.tabs.length - this._removingTabs.length -
           gBrowser._numPinnedTabs;
         break;
@@ -2544,29 +2544,29 @@ class TabBrowser {
         warnOnClose);
     var reallyClose = (buttonPressed == 0);
 
     // don't set the pref unless they press OK and it's false
     if (aCloseTabs == this.closingTabsEnum.ALL && reallyClose && !warnOnClose.value)
       Services.prefs.setBoolPref(pref, false);
 
     return reallyClose;
-  }
+  },
 
   getTabsToTheEndFrom(aTab) {
     let tabsToEnd = [];
     let tabs = this.visibleTabs;
     for (let i = tabs.length - 1; i >= 0; --i) {
       if (tabs[i] == aTab || tabs[i].pinned) {
         break;
       }
       tabsToEnd.push(tabs[i]);
     }
     return tabsToEnd;
-  }
+  },
 
   removeTabsToTheEndFrom(aTab, aParams) {
     if (!this.warnAboutClosingTabs(this.closingTabsEnum.TO_END, aTab))
       return;
 
     let removeTab = tab => {
       // Avoid changing the selected browser several times.
       if (tab.selected)
@@ -2580,17 +2580,17 @@ class TabBrowser {
     for (let i = tabs.length - 1; i >= 0; --i) {
       let tab = tabs[i];
       if (this._hasBeforeUnload(tab))
         tabsWithBeforeUnload.push(tab);
       else
         removeTab(tab);
     }
     tabsWithBeforeUnload.forEach(removeTab);
-  }
+  },
 
   removeAllTabsBut(aTab) {
     if (!this.warnAboutClosingTabs(this.closingTabsEnum.OTHER)) {
       return;
     }
 
     let tabs = this.visibleTabs.reverse();
     this.selectedTab = aTab;
@@ -2603,21 +2603,21 @@ class TabBrowser {
           tabsWithBeforeUnload.push(tab);
         else
           this.removeTab(tab, { animate: true });
       }
     }
     for (let tab of tabsWithBeforeUnload) {
       this.removeTab(tab, { animate: true });
     }
-  }
+  },
 
   removeCurrentTab(aParams) {
     this.removeTab(this.mCurrentTab, aParams);
-  }
+  },
 
   removeTab(aTab, aParams) {
     if (aParams) {
       var animate = aParams.animate;
       var byMouse = aParams.byMouse;
       var skipPermitUnload = aParams.skipPermitUnload;
     }
 
@@ -2676,24 +2676,24 @@ class TabBrowser {
 
     setTimeout(function(tab, tabbrowser) {
       if (tab.parentNode &&
           window.getComputedStyle(tab).maxWidth == "0.1px") {
         NS_ASSERT(false, "Giving up waiting for the tab closing animation to finish (bug 608589)");
         tabbrowser._endRemoveTab(tab);
       }
     }, 3000, aTab, this);
-  }
+  },
 
   _hasBeforeUnload(aTab) {
     let browser = aTab.linkedBrowser;
     return browser.isRemoteBrowser && browser.frameLoader &&
            browser.frameLoader.tabParent &&
            browser.frameLoader.tabParent.hasBeforeUnload;
-  }
+  },
 
   _beginRemoveTab(aTab, aAdoptedByTab, aCloseWindowWithLastTab, aCloseWindowFastpath, aSkipPermitUnload) {
     if (aTab.closing ||
       this._windowIsClosing)
       return false;
 
     var browser = this.getBrowserForTab(aTab);
     if (!aSkipPermitUnload && !aAdoptedByTab &&
@@ -2823,17 +2823,17 @@ class TabBrowser {
     // Remove this tab as the owner of any other tabs, since it's going away.
     for (let tab of this.tabs) {
       if ("owner" in tab && tab.owner == aTab)
         // |tab| is a child of the tab we're removing, make it an orphan
         tab.owner = null;
     }
 
     return true;
-  }
+  },
 
   _endRemoveTab(aTab) {
     if (!aTab || !aTab._endRemoveArgs)
       return;
 
     var [aCloseWindow, aNewTab] = aTab._endRemoveArgs;
     aTab._endRemoveArgs = null;
 
@@ -2943,17 +2943,17 @@ class TabBrowser {
     // stopwatches here instead.
     TelemetryStopwatch.finish("FX_TAB_CLOSE_TIME_ANIM_MS", aTab,
       true /* aCanceledOkay */ );
     TelemetryStopwatch.finish("FX_TAB_CLOSE_TIME_NO_ANIM_MS", aTab,
       true /* aCanceledOkay */ );
 
     if (aCloseWindow)
       this._windowIsClosing = closeWindow(true, window.warnAboutClosingWindow);
-  }
+  },
 
   _findTabToBlurTo(aTab) {
     if (!aTab.selected) {
       return null;
     }
 
     if (aTab.owner &&
         !aTab.owner.hidden &&
@@ -2981,21 +2981,21 @@ class TabBrowser {
       tab = aTab;
 
       do {
         tab = tab.previousSibling;
       } while (tab && !remainingTabs.includes(tab));
     }
 
     return tab;
-  }
+  },
 
   _blurTab(aTab) {
     this.selectedTab = this._findTabToBlurTo(aTab);
-  }
+  },
 
   swapBrowsersAndCloseOther(aOurTab, aOtherTab) {
     // Do not allow transfering a private tab to a non-private window
     // and vice versa.
     if (PrivateBrowsingUtils.isWindowPrivate(window) !=
       PrivateBrowsingUtils.isWindowPrivate(aOtherTab.ownerGlobal))
       return;
 
@@ -3128,17 +3128,17 @@ class TabBrowser {
     // If the tab was already selected (this happpens in the scenario
     // of replaceTabWithWindow), notify onLocationChange, etc.
     if (aOurTab.selected)
       this.updateCurrentBrowser(true);
 
     if (modifiedAttrs.length) {
       this._tabAttrModified(aOurTab, modifiedAttrs);
     }
-  }
+  },
 
   swapBrowsers(aOurTab, aOtherTab, aFlags) {
     let otherBrowser = aOtherTab.linkedBrowser;
     let otherTabBrowser = otherBrowser.getTabBrowser();
 
     // We aren't closing the other tab so, we also need to swap its tablisteners.
     let filter = otherTabBrowser._tabFilters.get(aOtherTab);
     let tabListener = otherTabBrowser._tabListeners.get(aOtherTab);
@@ -3150,17 +3150,17 @@ class TabBrowser {
 
     // Restore the listeners for the swapped in tab.
     tabListener = new otherTabBrowser.ownerGlobal.TabProgressListener(aOtherTab, otherBrowser, false, false);
     otherTabBrowser._tabListeners.set(aOtherTab, tabListener);
 
     const notifyAll = Ci.nsIWebProgress.NOTIFY_ALL;
     filter.addProgressListener(tabListener, notifyAll);
     otherBrowser.webProgress.addProgressListener(filter, notifyAll);
-  }
+  },
 
   _swapBrowserDocShells(aOurTab, aOtherBrowser, aFlags, aStateFlags) {
     // aOurTab's browser needs to be inserted now if it hasn't already.
     this._insertBrowser(aOurTab);
 
     // Unhook our progress listener
     const filter = this._tabFilters.get(aOurTab);
     let tabListener = this._tabListeners.get(aOurTab);
@@ -3216,106 +3216,106 @@ class TabBrowser {
 
     // Restore the progress listener
     tabListener = new TabProgressListener(aOurTab, ourBrowser, false, false, aStateFlags);
     this._tabListeners.set(aOurTab, tabListener);
 
     const notifyAll = Ci.nsIWebProgress.NOTIFY_ALL;
     filter.addProgressListener(tabListener, notifyAll);
     ourBrowser.webProgress.addProgressListener(filter, notifyAll);
-  }
+  },
 
   _swapRegisteredOpenURIs(aOurBrowser, aOtherBrowser) {
     // Swap the registeredOpenURI properties of the two browsers
     let tmp = aOurBrowser.registeredOpenURI;
     delete aOurBrowser.registeredOpenURI;
     if (aOtherBrowser.registeredOpenURI) {
       aOurBrowser.registeredOpenURI = aOtherBrowser.registeredOpenURI;
       delete aOtherBrowser.registeredOpenURI;
     }
     if (tmp) {
       aOtherBrowser.registeredOpenURI = tmp;
     }
-  }
+  },
 
   reloadAllTabs() {
     let tabs = this.visibleTabs;
     let l = tabs.length;
     for (var i = 0; i < l; i++) {
       try {
         this.getBrowserForTab(tabs[i]).reload();
       } catch (e) {
         // ignore failure to reload so others will be reloaded
       }
     }
-  }
+  },
 
   reloadTab(aTab) {
     let browser = this.getBrowserForTab(aTab);
     // Reset temporary permissions on the current tab. This is done here
     // because we only want to reset permissions on user reload.
     SitePermissions.clearTemporaryPermissions(browser);
     browser.reload();
-  }
+  },
 
   addProgressListener(aListener) {
     if (arguments.length != 1) {
       Cu.reportError("gBrowser.addProgressListener was " +
         "called with a second argument, " +
         "which is not supported. See bug " +
         "608628. Call stack: " + new Error().stack);
     }
 
     this.mProgressListeners.push(aListener);
-  }
+  },
 
   removeProgressListener(aListener) {
     this.mProgressListeners =
       this.mProgressListeners.filter(l => l != aListener);
-  }
+  },
 
   addTabsProgressListener(aListener) {
     this.mTabsProgressListeners.push(aListener);
-  }
+  },
 
   removeTabsProgressListener(aListener) {
     this.mTabsProgressListeners =
       this.mTabsProgressListeners.filter(l => l != aListener);
-  }
+  },
 
   getBrowserForTab(aTab) {
     return aTab.linkedBrowser;
-  }
+  },
 
   showOnlyTheseTabs(aTabs) {
     for (let tab of this.tabs) {
       if (!aTabs.includes(tab))
         this.hideTab(tab);
       else
         this.showTab(tab);
     }
 
     this.tabContainer._handleTabSelect(true);
-  }
+  },
 
   showTab(aTab) {
     if (aTab.hidden) {
       aTab.removeAttribute("hidden");
       this._visibleTabs = null; // invalidate cache
 
       this.tabContainer._updateCloseButtons();
 
       this.tabContainer._setPositionalAttributes();
 
       let event = document.createEvent("Events");
       event.initEvent("TabShow", true, false);
       aTab.dispatchEvent(event);
       SessionStore.deleteTabValue(aTab, "hiddenBy");
     }
-  }
+  },
 
   hideTab(aTab, aSource) {
     if (!aTab.hidden && !aTab.pinned && !aTab.selected &&
         !aTab.closing && !aTab._sharingState) {
       aTab.setAttribute("hidden", "true");
       this._visibleTabs = null; // invalidate cache
 
       this.tabContainer._updateCloseButtons();
@@ -3324,17 +3324,17 @@ class TabBrowser {
 
       let event = document.createEvent("Events");
       event.initEvent("TabHide", true, false);
       aTab.dispatchEvent(event);
       if (aSource) {
         SessionStore.setTabValue(aTab, "hiddenBy", aSource);
       }
     }
-  }
+  },
 
   selectTabAtIndex(aIndex, aEvent) {
     let tabs = this.visibleTabs;
 
     // count backwards for aIndex < 0
     if (aIndex < 0) {
       aIndex += tabs.length;
       // clamp at index 0 if still negative.
@@ -3346,17 +3346,17 @@ class TabBrowser {
     }
 
     this.selectedTab = tabs[aIndex];
 
     if (aEvent) {
       aEvent.preventDefault();
       aEvent.stopPropagation();
     }
-  }
+  },
 
   /**
    * Moves a tab to a new browser window, unless it's already the only tab
    * in the current window, in which case this will do nothing.
    */
   replaceTabWithWindow(aTab, aOptions) {
     if (this.tabs.length == 1)
       return null;
@@ -3370,17 +3370,17 @@ class TabBrowser {
     // content area when the docshells are swapped.
     if (this.animationsEnabled) {
       aTab.style.maxWidth = ""; // ensure that fade-out transition happens
       aTab.removeAttribute("fadein");
     }
 
     // tell a new window to take the "dropped" tab
     return window.openDialog(getBrowserURL(), "_blank", options, aTab);
-  }
+  },
 
   moveTabTo(aTab, aIndex, aKeepRelatedTabs) {
     var oldPosition = aTab._tPos;
     if (oldPosition == aIndex)
       return;
 
     // Don't allow mixing pinned and unpinned tabs.
     if (aTab.pinned)
@@ -3435,28 +3435,28 @@ class TabBrowser {
     if (aTab.pinned)
       this.tabContainer._positionPinnedTabs();
 
     this.tabContainer._setPositionalAttributes();
 
     var evt = document.createEvent("UIEvents");
     evt.initUIEvent("TabMove", true, false, window, oldPosition);
     aTab.dispatchEvent(evt);
-  }
+  },
 
   moveTabForward() {
     let nextTab = this.mCurrentTab.nextSibling;
     while (nextTab && nextTab.hidden)
       nextTab = nextTab.nextSibling;
 
     if (nextTab)
       this.moveTabTo(this.mCurrentTab, nextTab._tPos);
     else if (this.arrowKeysShouldWrap)
       this.moveTabToStart();
-  }
+  },
 
   /**
    * Adopts a tab from another browser window, and inserts it at aIndex
    */
   adoptTab(aTab, aIndex, aSelectTab) {
     // Swap the dropped tab with a new one we create and then close
     // it in the other window (making it seem to have moved between
     // windows). We also ensure that the tab we create to swap into has
@@ -3502,102 +3502,102 @@ class TabBrowser {
 
     if (aSelectTab) {
       // Call updateCurrentBrowser to make sure the URL bar is up to date
       // for our new tab after we've done swapBrowsersAndCloseOther.
       this.updateCurrentBrowser(true);
     }
 
     return newTab;
-  }
+  },
 
   moveTabBackward() {
     let previousTab = this.mCurrentTab.previousSibling;
     while (previousTab && previousTab.hidden)
       previousTab = previousTab.previousSibling;
 
     if (previousTab)
       this.moveTabTo(this.mCurrentTab, previousTab._tPos);
     else if (this.arrowKeysShouldWrap)
       this.moveTabToEnd();
-  }
+  },
 
   moveTabToStart() {
     var tabPos = this.mCurrentTab._tPos;
     if (tabPos > 0)
       this.moveTabTo(this.mCurrentTab, 0);
-  }
+  },
 
   moveTabToEnd() {
     var tabPos = this.mCurrentTab._tPos;
     if (tabPos < this.browsers.length - 1)
       this.moveTabTo(this.mCurrentTab, this.browsers.length - 1);
-  }
+  },
 
   moveTabOver(aEvent) {
     let direction = window.getComputedStyle(document.documentElement).direction;
     if ((direction == "ltr" && aEvent.keyCode == KeyEvent.DOM_VK_RIGHT) ||
         (direction == "rtl" && aEvent.keyCode == KeyEvent.DOM_VK_LEFT)) {
       this.moveTabForward();
     } else {
       this.moveTabBackward();
     }
-  }
+  },
 
   /**
    * @param   aTab
    *          Can be from a different window as well
    * @param   aRestoreTabImmediately
    *          Can defer loading of the tab contents
    */
   duplicateTab(aTab, aRestoreTabImmediately) {
     return SessionStore.duplicateTab(window, aTab, 0, aRestoreTabImmediately);
-  }
+  },
 
   activateBrowserForPrintPreview(aBrowser) {
     this._printPreviewBrowsers.add(aBrowser);
     if (this._switcher) {
       this._switcher.activateBrowserForPrintPreview(aBrowser);
     }
     aBrowser.docShellIsActive = true;
-  }
+  },
 
   deactivatePrintPreviewBrowsers() {
     let browsers = this._printPreviewBrowsers;
     this._printPreviewBrowsers = new Set();
     for (let browser of browsers) {
       browser.docShellIsActive = this.shouldActivateDocShell(browser);
     }
-  }
+  },
 
   /**
    * Returns true if a given browser's docshell should be active.
    */
   shouldActivateDocShell(aBrowser) {
     if (this._switcher) {
       return this._switcher.shouldActivateDocShell(aBrowser);
     }
     return (aBrowser == this.selectedBrowser &&
             window.windowState != window.STATE_MINIMIZED &&
             !window.isFullyOccluded) ||
             this._printPreviewBrowsers.has(aBrowser);
-  }
+  },
 
   _getSwitcher() {
     if (!this._switcher) {
       this._switcher = new this.AsyncTabSwitcher(this);
     }
     return this._switcher;
-  }
+  },
 
   warmupTab(aTab) {
     if (gMultiProcessBrowser) {
       this._getSwitcher().warmupTab(aTab);
     }
-  }
+  },
 
   _handleKeyDownEvent(aEvent) {
     if (!aEvent.isTrusted) {
       // Don't let untrusted events mess with tabs.
       return;
     }
 
     if (aEvent.altKey)
@@ -3622,17 +3622,17 @@ class TabBrowser {
     if (AppConstants.platform != "macosx") {
       if (aEvent.ctrlKey && !aEvent.shiftKey && !aEvent.metaKey &&
           aEvent.keyCode == KeyEvent.DOM_VK_F4 &&
           !this.mCurrentTab.pinned) {
         this.removeCurrentTab({ animate: true });
         aEvent.preventDefault();
       }
     }
-  }
+  },
 
   _handleKeyPressEventMac(aEvent) {
     if (!aEvent.isTrusted) {
       // Don't let untrusted events mess with tabs.
       return;
     }
 
     if (aEvent.altKey)
@@ -3648,17 +3648,17 @@ class TabBrowser {
           offset = -1;
         case "{".charCodeAt(0):
           if (window.getComputedStyle(document.documentElement).direction == "ltr")
             offset *= -1;
           this.tabContainer.advanceSelectedTab(offset, true);
           aEvent.preventDefault();
       }
     }
-  }
+  },
 
   createTooltip(event) {
     event.stopPropagation();
     var tab = document.tooltipNode;
     if (tab.localName != "tab") {
       event.preventDefault();
       return;
     }
@@ -3701,17 +3701,17 @@ class TabBrowser {
         label += " (pid " + tab.linkedBrowser.frameLoader.tabParent.osPid + ")";
       }
       if (tab.userContextId) {
         label = gTabBrowserBundle.formatStringFromName("tabs.containers.tooltip", [label, ContextualIdentityService.getUserContextLabel(tab.userContextId)], 2);
       }
     }
 
     event.target.setAttribute("label", label);
-  }
+  },
 
   handleEvent(aEvent) {
     switch (aEvent.type) {
       case "keydown":
         this._handleKeyDownEvent(aEvent);
         break;
       case "keypress":
         this._handleKeyPressEventMac(aEvent);
@@ -3720,17 +3720,17 @@ class TabBrowser {
       case "occlusionstatechange":
         if (aEvent.target == window && !this._switcher) {
           this.mCurrentBrowser.preserveLayers(
             window.windowState == window.STATE_MINIMIZED || window.isFullyOccluded);
           this.mCurrentBrowser.docShellIsActive = this.shouldActivateDocShell(this.mCurrentBrowser);
         }
         break;
     }
-  }
+  },
 
   receiveMessage(aMessage) {
     let data = aMessage.data;
     let browser = aMessage.target;
 
     switch (aMessage.name) {
       case "DOMTitleChanged":
       {
@@ -3872,17 +3872,17 @@ class TabBrowser {
             "chrome://browser/skin/notification-icons/popup.svg",
             notificationBox.PRIORITY_INFO_MEDIUM,
             buttons);
         }
         break;
       }
     }
     return undefined;
-  }
+  },
 
   observe(aSubject, aTopic, aData) {
     switch (aTopic) {
       case "contextual-identity-updated":
       {
         for (let tab of this.tabs) {
           if (tab.getAttribute("usercontextid") == aData) {
             ContextualIdentityService.setTabStyle(tab);
@@ -3892,17 +3892,17 @@ class TabBrowser {
       }
       case "nsPref:changed":
       {
         // This is the only pref observed.
         this._findAsYouType = Services.prefs.getBoolPref("accessibility.typeaheadfind");
         break;
       }
     }
-  }
+  },
 
   _updateNewTabVisibility() {
     // Helper functions to help deal with customize mode wrapping some items
     let wrap = n => n.parentNode.localName == "toolbarpaletteitem" ? n.parentNode : n;
     let unwrap = n => n && n.localName == "toolbarpaletteitem" ? n.firstElementChild : n;
 
     let sib = this.tabContainer;
     do {
@@ -3910,50 +3910,50 @@ class TabBrowser {
     } while (sib && sib.hidden);
 
     const kAttr = "hasadjacentnewtabbutton";
     if (sib && sib.id == "new-tab-button") {
       this.tabContainer.setAttribute(kAttr, "true");
     } else {
       this.tabContainer.removeAttribute(kAttr);
     }
-  }
+  },
 
   onWidgetAfterDOMChange(aNode, aNextNode, aContainer) {
     if (aContainer.ownerDocument == document &&
         aContainer.id == "TabsToolbar") {
       this._updateNewTabVisibility();
     }
-  }
+  },
 
   onAreaNodeRegistered(aArea, aContainer) {
     if (aContainer.ownerDocument == document &&
         aArea == "TabsToolbar") {
       this._updateNewTabVisibility();
     }
-  }
+  },
 
   onAreaReset(aArea, aContainer) {
     this.onAreaNodeRegistered(aArea, aContainer);
-  }
+  },
 
   _generateUniquePanelID() {
     if (!this._uniquePanelIDCounter) {
       this._uniquePanelIDCounter = 0;
     }
 
     let outerID = window.QueryInterface(Ci.nsIInterfaceRequestor)
                         .getInterface(Ci.nsIDOMWindowUtils)
                         .outerWindowID;
 
     // We want panel IDs to be globally unique, that's why we include the
     // window ID. We switched to a monotonic counter as Date.now() lead
     // to random failures because of colliding IDs.
     return "panel-" + outerID + "-" + (++this._uniquePanelIDCounter);
-  }
+  },
 
   destroy() {
     Services.obs.removeObserver(this, "contextual-identity-updated");
 
     CustomizableUI.removeListener(this);
 
     for (let tab of this.tabs) {
       let browser = tab.linkedBrowser;
@@ -3994,17 +3994,17 @@ class TabBrowser {
       window.messageManager.removeMessageListener("contextmenu", this);
 
       if (this._switcher) {
         this._switcher.destroy();
       }
     }
 
     Services.prefs.removeObserver("accessibility.typeaheadfind", this);
-  }
+  },
 
   _setupEventListeners() {
     this.addEventListener("DOMWindowClose", (event) => {
       if (!event.isTrusted)
         return;
 
       if (this.tabs.length == 1) {
         // We already did PermitUnload in nsGlobalWindow::Close
@@ -4202,18 +4202,18 @@ class TabBrowser {
       if (tab.hasAttribute("activemedia-blocked")) {
         tab.removeAttribute("activemedia-blocked");
         this._tabAttrModified(tab, ["activemedia-blocked"]);
         let hist = Services.telemetry.getHistogramById("TAB_AUDIO_INDICATOR_USED");
         hist.add(2 /* unblockByVisitingTab */ );
         tab.finishMediaBlockTimer();
       }
     });
-  }
-}
+  },
+};
 
 /**
  * A web progress listener object definition for a given tab.
  */
 class TabProgressListener {
   constructor(aTab, aBrowser, aStartsBlank, aWasPreloadedBrowser, aOrigStateFlags) {
     let stateFlags = aOrigStateFlags || 0;
     // Initialize mStateFlags to non-zero e.g. when creating a progress