Bug 1442398 - Convert the TabBrowser class to a plain object and make gBrowser available already before gBrowser.init returns. r=bgrins
authorDão Gottwald <dao@mozilla.com>
Wed, 07 Mar 2018 06:49:53 +0100
changeset 461888 f27d7eca013d66027d9579a619899fdda5fa4dbc
parent 461887 d93c5f3b88c5ae767e67370e336eb4b8b26b9d9a
child 461889 5f8f9db9e66db97bd5250357ce33e7a507bdf613
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgrins
bugs1442398
milestone60.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 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