From baf97fe23aaaba3c72e92d59175db5f0b87fc7d8 Mon Sep 17 00:00:00 2001 From: Erica Wright Date: Thu, 12 May 2016 15:59:32 -0400 Subject: [PATCH] lint for spaces --- .eslintrc.json | 12 +- bootstrap.js | 1 - groups.jsm | 2 +- tabdatastore.jsm | 221 +++++++------- utils.js | 6 +- vertical-tabbrowser.xml | 84 +++--- verticaltabs.jsm | 644 ++++++++++++++++++++-------------------- 7 files changed, 480 insertions(+), 490 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index ea7fd7be..8066a312 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -4,12 +4,6 @@ "es6": true }, "extends": "eslint:recommended", - "installedESLint": true, - "parserOptions": { - "ecmaFeatures": { - "experimentalObjectRestSpread": true - } - }, "plugins": [ "mozilla" ], @@ -18,8 +12,6 @@ "Services": false, "Cc": false, "Ci": false, - "VTTabDataStore": false, - "VerticalTabs": false, "TAB_DROP_TYPE": false, "TabsInTitlebar": false }, @@ -30,6 +22,7 @@ "comma-dangle": 0, "comma-spacing": 2, "computed-property-spacing": [2, "never"], + "curly": 2, "default-case": 0, "eqeqeq": [2, "smart"], "func-names": 0, @@ -39,6 +32,7 @@ "id-blacklist": 0, "id-length": 0, "id-match": 0, + "indent": [2, 2], "init-declarations": 0, "max-len": 0, "max-params": 0, @@ -49,6 +43,7 @@ "no-inline-comments": 0, "no-invalid-this": 0, "no-magic-numbers": 0, + "no-mixed-spaces-and-tabs": [2, "smart-tabs"], "no-negated-condition": 0, "no-shadow": 0, "no-trailing-spaces": [2, {"skipBlankLines": false}], @@ -56,7 +51,6 @@ "no-unused-vars": [2, {"vars": "local", "args": "none"}], "no-warning-comments": 0, "object-curly-spacing": [2, "never"], - "curly": 2, "no-var": 2, "prefer-const": 0, "prefer-reflect": 0, diff --git a/bootstrap.js b/bootstrap.js index b250b827..e154e3a9 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -57,7 +57,6 @@ function include(src) { } function setDefaultPrefs() { - // let branch = Services.prefs.getDefaultBranch(''); for (let [name, value] in Iterator(DEFAULT_PREFS)) { switch (typeof value) { case 'boolean': diff --git a/groups.jsm b/groups.jsm index 1ef1384d..613a5e82 100644 --- a/groups.jsm +++ b/groups.jsm @@ -49,7 +49,7 @@ * - But we have to make sure that groups don't behave like tabs at * all. */ - +/*eslint-disable */ /*exported EXPORTED_SYMBOLS*/ const EXPORTED_SYMBOLS = ['VTGroups']; Components.utils.import('resource://tabcenter/tabdatastore.jsm'); diff --git a/tabdatastore.jsm b/tabdatastore.jsm index e0a824df..1a56cfb1 100644 --- a/tabdatastore.jsm +++ b/tabdatastore.jsm @@ -49,131 +49,128 @@ const EXPORTED_SYMBOLS = ['VTTabDataStore', 'VTTabIDs']; Components.utils.import('resource://gre/modules/XPCOMUtils.jsm'); let VTTabDataStore = { + getTabValue: function(aTab, aKey) { + let value = null; + try { + value = this.sessionStore.getTabValue(aTab, aKey); + } catch(ex) { + // Ignore + } + return value; + }, + + setTabValue: function(aTab, aKey, aValue) { + if (!aValue) { + this.deleteTabValue(aTab, aKey); + } - getTabValue: function(aTab, aKey) { - let value = null; - try { - value = this.sessionStore.getTabValue(aTab, aKey); - } catch(ex) { - // Ignore - } - return value; - }, - - setTabValue: function(aTab, aKey, aValue) { - if (!aValue) { - this.deleteTabValue(aTab, aKey); - } - - aTab.setAttribute(aKey, aValue); - try { - this.checkCachedSessionDataExpiration(aTab); - this.sessionStore.setTabValue(aTab, aKey, aValue); - } catch(ex) { - // Ignore - } - }, - - deleteTabValue: function(aTab, aKey) { - aTab.removeAttribute(aKey); - try { - this.checkCachedSessionDataExpiration(aTab); - this.sessionStore.setTabValue(aTab, aKey, ''); - this.sessionStore.deleteTabValue(aTab, aKey); - } catch(ex) { - // Ignore - } - }, - - // workaround for http://piro.sakura.ne.jp/latest/blosxom/mozilla/extension/treestyletab/2009-09-29_debug.htm - checkCachedSessionDataExpiration: function(aTab) { - let data = aTab.linkedBrowser.__SS_data; - if (data && - data._tabStillLoading && - aTab.getAttribute('busy') !== 'true') - data._tabStillLoading = false; + aTab.setAttribute(aKey, aValue); + try { + this.checkCachedSessionDataExpiration(aTab); + this.sessionStore.setTabValue(aTab, aKey, aValue); + } catch(ex) { + // Ignore } + }, + + deleteTabValue: function(aTab, aKey) { + aTab.removeAttribute(aKey); + try { + this.checkCachedSessionDataExpiration(aTab); + this.sessionStore.setTabValue(aTab, aKey, ''); + this.sessionStore.deleteTabValue(aTab, aKey); + } catch(ex) { + // Ignore + } + }, + + // workaround for http://piro.sakura.ne.jp/latest/blosxom/mozilla/extension/treestyletab/2009-09-29_debug.htm + checkCachedSessionDataExpiration: function(aTab) { + let data = aTab.linkedBrowser.__SS_data; + if (data && + data._tabStillLoading && + aTab.getAttribute('busy') !== 'true') { + data._tabStillLoading = false; + } + } }; -XPCOMUtils.defineLazyServiceGetter(VTTabDataStore, 'sessionStore', - '@mozilla.org/browser/sessionstore;1', - 'nsISessionStore'); +XPCOMUtils.defineLazyServiceGetter(VTTabDataStore, 'sessionStore', '@mozilla.org/browser/sessionstore;1', 'nsISessionStore'); /* - * Assign tabs a persistent unique identifier. - * - * Necessary until https://bugzilla.mozilla.org/show_bug.cgi?id=529477 - * is implemented. - */ +* Assign tabs a persistent unique identifier. +* +* Necessary until https://bugzilla.mozilla.org/show_bug.cgi?id=529477 +* is implemented. +*/ function VTTabIDs(tabs) { - this.tabs = tabs; - this.init(); + this.tabs = tabs; + this.init(); } VTTabIDs.prototype = { - init: function() { - const tabs = this.tabs; - tabs.VTTabIDs = this; - tabs.addEventListener('TabOpen', this, true); - tabs.addEventListener('SSTabRestoring', this, true); - for (let i = 0; i < tabs.childNodes.length; i++) { - this.initTab(tabs.childNodes[i]); - } - }, - - unload: function unload() { - const tabs = this.tabs; - delete tabs.VTTabIDs; - tabs.removeEventListener('TabOpen', this, true); - tabs.removeEventListener('SSTabRestoring', this, true); - }, - - kId: 'verticaltabs-id', - - id: function(aTab) { - return aTab.getAttribute(this.kId); - }, - - get: function(aID) { - let elements = this.tabs.getElementsByAttribute(this.kId, aID); - return elements.length ? elements[0] : undefined; - }, - - /*** Event handlers ***/ - - handleEvent: function(aEvent) { - switch (aEvent.type) { - case 'TabOpen': - this.initTab(aEvent.originalTarget); - return; - case 'SSTabRestoring': - this.restoreTab(aEvent.originalTarget); - return; - } - }, - - makeNewId: function() { - return this.uuidGen.generateUUID().toString(); - }, - - initTab: function(aTab) { - if (aTab.hasAttribute(this.kId)) { - return; - } - // Assign an ID. This may be temporary if the tab is being restored. - let id = VTTabDataStore.getTabValue(aTab, this.kId) || this.makeNewId(); - VTTabDataStore.setTabValue(aTab, this.kId, id); - }, - - restoreTab: function(aTab) { - // Restore the original ID - let newId = VTTabDataStore.getTabValue(aTab, this.kId); - if (newId) { - aTab.setAttribute(this.kId, newId); - } + init: function() { + const tabs = this.tabs; + tabs.VTTabIDs = this; + tabs.addEventListener('TabOpen', this, true); + tabs.addEventListener('SSTabRestoring', this, true); + for (let i = 0; i < tabs.childNodes.length; i++) { + this.initTab(tabs.childNodes[i]); + } + }, + + unload: function unload() { + const tabs = this.tabs; + delete tabs.VTTabIDs; + tabs.removeEventListener('TabOpen', this, true); + tabs.removeEventListener('SSTabRestoring', this, true); + }, + + kId: 'verticaltabs-id', + + id: function(aTab) { + return aTab.getAttribute(this.kId); + }, + + get: function(aID) { + let elements = this.tabs.getElementsByAttribute(this.kId, aID); + return elements.length ? elements[0] : undefined; + }, + + /*** Event handlers ***/ + + handleEvent: function(aEvent) { + switch (aEvent.type) { + case 'TabOpen': + this.initTab(aEvent.originalTarget); + return; + case 'SSTabRestoring': + this.restoreTab(aEvent.originalTarget); + return; } + }, + + makeNewId: function() { + return this.uuidGen.generateUUID().toString(); + }, + initTab: function(aTab) { + if (aTab.hasAttribute(this.kId)) { + return; + } + // Assign an ID. This may be temporary if the tab is being restored. + let id = VTTabDataStore.getTabValue(aTab, this.kId) || this.makeNewId(); + VTTabDataStore.setTabValue(aTab, this.kId, id); + }, + + restoreTab: function(aTab) { + // Restore the original ID + let newId = VTTabDataStore.getTabValue(aTab, this.kId); + if (newId) { + aTab.setAttribute(this.kId, newId); + } + } }; XPCOMUtils.defineLazyServiceGetter(VTTabIDs.prototype, 'uuidGen', '@mozilla.org/uuid-generator;1', diff --git a/utils.js b/utils.js index 0cb92f2b..b2608720 100644 --- a/utils.js +++ b/utils.js @@ -57,7 +57,7 @@ function unload(callback, container) { // Initialize the array of unloaders on the first usage let unloaders = unload.unloaders; - if (unloaders == null){ + if (unloaders == null) { unloaders = unload.unloaders = []; } // Calling with no arguments runs all the unloader callbacks @@ -139,7 +139,7 @@ function watchWindows(callback) { if (window.document.readyState === 'complete'){ watcher(window); // Wait for the window to load before continuing - }else { + } else { runOnLoad(window); } } @@ -211,8 +211,6 @@ function sendPing() { }); payload = newPayload(); // Send metrics to the main Test Pilot add-on. - // let console = (Components.utils.import('resource://gre/modules/devtools/Console.jsm', {})).console; - // console.log('Sending ping', ping); observerService.notifyObservers(subject, 'testpilot::send-metric', ping); // Clear out the metrics for next time… } diff --git a/vertical-tabbrowser.xml b/vertical-tabbrowser.xml index f2b95ea0..30432695 100644 --- a/vertical-tabbrowser.xml +++ b/vertical-tabbrowser.xml @@ -16,7 +16,7 @@ - + @@ -241,45 +241,45 @@ @@ -343,12 +343,12 @@ if (this.getAttribute('overflow') === 'true') { let targetAnonid = event.originalTarget.getAttribute('anonid'); switch (targetAnonid) { - case 'scrollbutton-up': - pixelsToScroll = tabStrip.scrollIncrement * -1; - break; - case 'scrollbutton-down': - pixelsToScroll = tabStrip.scrollIncrement; - break; + case 'scrollbutton-up': + pixelsToScroll = tabStrip.scrollIncrement * -1; + break; + case 'scrollbutton-down': + pixelsToScroll = tabStrip.scrollIncrement; + break; } if (pixelsToScroll) { tabStrip.scrollByPixels((ltr ? 1 : -1) * pixelsToScroll); @@ -516,8 +516,8 @@ window.focus(); } else { this.tabbrowser.replaceTabWithWindow(draggedTab, {screenX: left, - screenY: top, - }); + screenY: top, + }); } event.stopPropagation(); ]]> diff --git a/verticaltabs.jsm b/verticaltabs.jsm index 9e1b2a69..82c8732d 100644 --- a/verticaltabs.jsm +++ b/verticaltabs.jsm @@ -91,345 +91,347 @@ function vtInit() { * Main entry point of this add-on. */ function VerticalTabs(window, {newPayload, addPingStats}) { - this.window = window; - this.document = window.document; - this.unloaders = []; - this.addPingStats = addPingStats; - this.newPayload = newPayload; - this.stats = this.newPayload(); - this.init(); + this.window = window; + this.document = window.document; + this.unloaders = []; + this.addPingStats = addPingStats; + this.newPayload = newPayload; + this.stats = this.newPayload(); + this.init(); } VerticalTabs.prototype = { - init: function() { - this.window.VerticalTabs = this; - this.unloaders.push(function() { - delete this.window.VerticalTabs; - }); - this.window.onunload = () => { - this.sendStats(); - }; + init: function() { + this.window.VerticalTabs = this; + this.unloaders.push(function() { + delete this.window.VerticalTabs; + }); + this.window.onunload = () => { + this.sendStats(); + }; - this.rearrangeXUL(); - this.initContextMenu(); + this.rearrangeXUL(); + this.initContextMenu(); - let tabs = this.document.getElementById('tabbrowser-tabs'); - let results = this.document.getElementById('PopupAutoCompleteRichResult'); + let tabs = this.document.getElementById('tabbrowser-tabs'); + let results = this.document.getElementById('PopupAutoCompleteRichResult'); - if (results) { - results.removeAttribute('width'); - } - this.tabIDs = new VTTabIDs(tabs); - this.tabObserver = new this.document.defaultView.MutationObserver((mutations) => { - this.tabObserver.disconnect(); - mutations.forEach((mutation) => { - if (mutation.type === 'attributes' && - mutation.target.localName === 'tab') { - let tab = mutation.target; - if (mutation.attributeName === 'crop' && !tabs.expanded) { - tab.removeAttribute('crop'); - } else if (mutation.attributeName === 'progress' && - !tab.getAttribute('progress')) { - if (tab.linkedBrowser.contentDocument.URL === 'about:newtab') { - this.window.gBrowser.moveTabTo(tab, 0); - } - } - } else if (mutation.type === 'attributes' && - mutation.target.id === 'PopupAutoCompleteRichResult' && - mutation.attributeName === 'width') { - results.removeAttribute('width'); - } else if (mutation.type === 'childList' && - !tabs.expanded) { - for (let node of mutation.addedNodes) { - node.removeAttribute('crop'); - } + if (results) { + results.removeAttribute('width'); + } + this.tabIDs = new VTTabIDs(tabs); + this.tabObserver = new this.document.defaultView.MutationObserver((mutations) => { + this.tabObserver.disconnect(); + mutations.forEach((mutation) => { + if (mutation.type === 'attributes' && + mutation.target.localName === 'tab') { + let tab = mutation.target; + if (mutation.attributeName === 'crop' && !tabs.expanded) { + tab.removeAttribute('crop'); + } else if (mutation.attributeName === 'progress' && + !tab.getAttribute('progress')) { + if (tab.linkedBrowser.contentDocument.URL === 'about:newtab') { + this.window.gBrowser.moveTabTo(tab, 0); } - }); - this.tabObserver.observe(tabs, {childList: true, attributes: true, subtree: true}); - if (results) { - this.tabObserver.observe(results, {attributes: true}); } - }); - this.tabObserver.observe(tabs, {childList: true, attributes: true, subtree: true}); - if (results) { - this.tabObserver.observe(results, {attributes: true}); + } else if (mutation.type === 'attributes' && + mutation.target.id === 'PopupAutoCompleteRichResult' && + mutation.attributeName === 'width') { + results.removeAttribute('width'); + } else if (mutation.type === 'childList' && + !tabs.expanded) { + for (let node of mutation.addedNodes) { + node.removeAttribute('crop'); + } } + }); + this.tabObserver.observe(tabs, {childList: true, attributes: true, subtree: true}); + if (results) { + this.tabObserver.observe(results, {attributes: true}); + } + }); + this.tabObserver.observe(tabs, {childList: true, attributes: true, subtree: true}); + if (results) { + this.tabObserver.observe(results, {attributes: true}); + } - this.unloaders.push(function() { - this.tabIDs.unload(); - this.tabObserver.disconnect(); - }); - }, - - createElement: function(label, attrs) { - let rv = this.document.createElementNS(NS_XUL, label); - if (attrs) { - for ( let attr in attrs) { - rv.setAttribute(attr, attrs[attr]); + this.unloaders.push(function() { + this.tabIDs.unload(); + this.tabObserver.disconnect(); + }); + }, + + createElement: function(label, attrs) { + let rv = this.document.createElementNS(NS_XUL, label); + if (attrs) { + for (let attr in attrs) { + rv.setAttribute(attr, attrs[attr]); + } + } + return rv; + }, + + rearrangeXUL: function() { + const window = this.window; + const document = this.document; + + // Move the bottom stuff (findbar, addonbar, etc.) in with the + // tabbrowser. That way it will share the same (horizontal) + // space as the brower. In other words, the bottom stuff no + // longer extends across the whole bottom of the window. + let mainWindow = document.getElementById('main-window'); + let contentbox = document.getElementById('appcontent'); + let bottom = document.getElementById('browser-bottombox'); + contentbox.appendChild(bottom); + let top = document.getElementById('navigator-toolbox'); + + // save the label of the first tab, and the toolbox palette for later… + let tabs = document.getElementById('tabbrowser-tabs'); + let label = tabs.firstChild.label; + let palette = top.palette; + + contentbox.insertBefore(top, contentbox.firstChild); + + // Create a box next to the app content. It will hold the tab + // bar and the tab toolbar. + let browserbox = document.getElementById('browser'); + let leftbox = this.createElement('vbox', {'id': 'verticaltabs-box'}); + browserbox.insertBefore(leftbox, contentbox); + mainWindow.setAttribute('persist', + mainWindow.getAttribute('persist') + ' tabspinned'); + + // Move the tabs next to the app content, make them vertical, + // and restore their width from previous session + tabs.setAttribute('vertical', true); + leftbox.insertBefore(tabs, leftbox.firstChild); + tabs.orient = 'vertical'; + tabs.mTabstrip.orient = 'vertical'; + tabs.tabbox.orient = 'horizontal'; // probably not necessary + + // And restore the label and palette here. + tabs.firstChild.label = label; + top.palette = palette; + + // Move the tabs toolbar into the tab strip + let toolbar = document.getElementById('TabsToolbar'); + toolbar.setAttribute('collapsed', 'false'); // no more vanishing new tab toolbar + toolbar._toolbox = null; // reset value set by constructor + toolbar.setAttribute('toolboxid', 'navigator-toolbox'); + let spacer = this.createElement('spacer', {'id': 'new-tab-spacer'}); + toolbar.appendChild(spacer); + let pin_button = this.createElement('toolbarbutton', { + 'id': 'pin-button', + 'tooltiptext': 'Keep sidebar open', + 'onclick': `let box = document.getElementById('main-window'); + let newstate = box.getAttribute('tabspinned') == 'true' ? 'false' : 'true'; + box.setAttribute('tabspinned', newstate); + if (newstate == 'true') { + window.VerticalTabs.stats.tab_center_pinned++; + } else { + window.VerticalTabs.stats.tab_center_unpinned++; } + ` + }); + toolbar.appendChild(pin_button); + leftbox.insertBefore(toolbar, leftbox.firstChild); + + let enter = (event) => { + if (event.type === 'mouseenter' && !tabs.expanded) { + this.stats.tab_center_expanded++; } - return rv; - }, - - rearrangeXUL: function() { - const window = this.window; - const document = this.document; - - // Move the bottom stuff (findbar, addonbar, etc.) in with the - // tabbrowser. That way it will share the same (horizontal) - // space as the brower. In other words, the bottom stuff no - // longer extends across the whole bottom of the window. - let mainWindow = document.getElementById('main-window'); - let contentbox = document.getElementById('appcontent'); - let bottom = document.getElementById('browser-bottombox'); - contentbox.appendChild(bottom); - let top = document.getElementById('navigator-toolbox'); - - // save the label of the first tab, and the toolbox palette for later… - let tabs = document.getElementById('tabbrowser-tabs'); - let label = tabs.firstChild.label; - let palette = top.palette; - - contentbox.insertBefore(top, contentbox.firstChild); - - // Create a box next to the app content. It will hold the tab - // bar and the tab toolbar. - let browserbox = document.getElementById('browser'); - let leftbox = this.createElement('vbox', {'id': 'verticaltabs-box'}); - browserbox.insertBefore(leftbox, contentbox); - mainWindow.setAttribute('persist', - mainWindow.getAttribute('persist') + ' tabspinned'); - - // Move the tabs next to the app content, make them vertical, - // and restore their width from previous session - tabs.setAttribute('vertical', true); - leftbox.insertBefore(tabs, leftbox.firstChild); - tabs.orient = 'vertical'; - tabs.mTabstrip.orient = 'vertical'; - tabs.tabbox.orient = 'horizontal'; // probably not necessary - - // And restore the label and palette here. - tabs.firstChild.label = label; - top.palette = palette; - - // Move the tabs toolbar into the tab strip - let toolbar = document.getElementById('TabsToolbar'); - toolbar.setAttribute('collapsed', 'false'); // no more vanishing new tab toolbar - toolbar._toolbox = null; // reset value set by constructor - toolbar.setAttribute('toolboxid', 'navigator-toolbox'); - let spacer = this.createElement('spacer', {'id': 'new-tab-spacer'}); - toolbar.appendChild(spacer); - let pin_button = this.createElement('toolbarbutton', { - 'id': 'pin-button', - 'tooltiptext': 'Keep sidebar open', - 'onclick': `let box = document.getElementById('main-window'); - let newstate = box.getAttribute('tabspinned') == 'true' ? 'false' : 'true'; - box.setAttribute('tabspinned', newstate); - if (newstate == 'true') { - window.VerticalTabs.stats.tab_center_pinned++; - } else { - window.VerticalTabs.stats.tab_center_unpinned++; - } - ` - }); - toolbar.appendChild(pin_button); - leftbox.insertBefore(toolbar, leftbox.firstChild); - - let enter = (event) => { - if (event.type === 'mouseenter' && !tabs.expanded) { - this.stats.tab_center_expanded++; - } - tabs.expanded = true; - if (event.pageX <= 4) { - leftbox.style.transition = 'box-shadow 150ms ease-out, width 150ms ease-out'; - window.setTimeout(() => { - leftbox.style.transition = ''; - }, 300); - } - window.setTimeout(() => { - for (let i = 0; i < tabs.childNodes.length; i++) { - tabs.childNodes[i].setAttribute('crop', 'end'); - } - }, 300); - }; - leftbox.addEventListener('mouseenter', enter); - leftbox.addEventListener('mousemove', enter); - leftbox.addEventListener('mouseleave', () => { - if (mainWindow.getAttribute('tabspinned') !== 'true') { - tabs.expanded = false; - let tabsPopup = document.getElementById('alltabs-popup'); - if (tabsPopup.state === 'open') { - tabsPopup.hidePopup(); - } - } - }); - - tabs.addEventListener('TabOpen', this, false); - tabs.addEventListener('TabSelect', this, false); - tabs.addEventListener('TabClose', this, false); - tabs.addEventListener('TabPinned', this, false); - tabs.addEventListener('TabUnpinned', this, false); + tabs.expanded = true; + if (event.pageX <= 4) { + leftbox.style.transition = 'box-shadow 150ms ease-out, width 150ms ease-out'; window.setTimeout(() => { - if (mainWindow.getAttribute('tabspinned') === 'true') { - tabs.expanded = true; - } - for (let i = 0; i < tabs.childNodes.length; i++) { - this.initTab(tabs.childNodes[i]); - } - }, 150); - - this.unloaders.push(function() { - // Move the tabs toolbar back to where it was - toolbar._toolbox = null; // reset value set by constructor - toolbar.removeAttribute('toolboxid'); - toolbar.removeAttribute('collapsed'); - toolbar.removeChild(spacer); - toolbar.removeChild(pin_button); - let toolbox = document.getElementById('navigator-toolbox'); - let navbar = document.getElementById('nav-bar'); - let browserPanel = document.getElementById('browser-panel'); - let new_tab_button = document.getElementById('new-tab-button'); - - // Put the tabs back up top - tabs.orient = 'horizontal'; - tabs.mTabstrip.orient = 'horizontal'; - tabs.tabbox.orient = 'vertical'; // probably not necessary - tabs.removeAttribute('width'); - tabs.removeEventListener('TabOpen', this, false); - tabs.removeEventListener('TabSelect', this, false); - tabs.removeEventListener('TabClose', this, false); - tabs.removeEventListener('TabPinned', this, false); - tabs.removeEventListener('TabUnpinned', this, false); - tabs.removeAttribute('vertical'); - - // Restore all individual tabs. - for (let i = 0; i < tabs.childNodes.length; i++) { - let tab = tabs.childNodes[i]; - tab.setAttribute('crop', 'end'); - tab.removeAttribute('verticaltabs-id'); - } - - // Remove all the crap we added. - browserbox.removeChild(leftbox); - browserbox.removeAttribute('dir'); - mainWindow.removeAttribute('tabspinned'); - mainWindow.setAttribute('persist', - mainWindow.getAttribute('persist').replace(' tabspinnned', '')); - leftbox = null; - - // Restore the tab strip. - toolbar.insertBefore(tabs, new_tab_button); - toolbox.insertBefore(toolbar, navbar); - browserPanel.insertBefore(toolbox, browserPanel.firstChild); - browserPanel.insertBefore(bottom, document.getElementById('fullscreen-warning').nextSibling); - this.window.TabsInTitlebar.updateAppearance(true); - }); - }, - - initContextMenu: function() { - const document = this.document; - const tabs = document.getElementById('tabbrowser-tabs'); - - let closeMultiple = null; - if (this.multiSelect) { - closeMultiple = this.createElement('menuitem', { - 'id': 'context_verticalTabsCloseMultiple', - 'label': 'Close Selected Tabs', - 'tbattr': 'tabbrowser-multiple', - 'oncommand': 'gBrowser.tabContainer.VTMultiSelect.closeSelected();' - }); - tabs.contextMenu.appendChild(closeMultiple); + leftbox.style.transition = ''; + }, 300); + } + window.setTimeout(() => { + for (let i = 0; i < tabs.childNodes.length; i++) { + tabs.childNodes[i].setAttribute('crop', 'end'); + } + }, 300); + }; + leftbox.addEventListener('mouseenter', enter); + leftbox.addEventListener('mousemove', enter); + leftbox.addEventListener('mouseleave', () => { + if (mainWindow.getAttribute('tabspinned') !== 'true') { + tabs.expanded = false; + let tabsPopup = document.getElementById('alltabs-popup'); + if (tabsPopup.state === 'open') { + tabsPopup.hidePopup(); } + } + }); + + tabs.addEventListener('TabOpen', this, false); + tabs.addEventListener('TabSelect', this, false); + tabs.addEventListener('TabClose', this, false); + tabs.addEventListener('TabPinned', this, false); + tabs.addEventListener('TabUnpinned', this, false); + window.setTimeout(() => { + if (mainWindow.getAttribute('tabspinned') === 'true') { + tabs.expanded = true; + } + for (let i = 0; i < tabs.childNodes.length; i++) { + this.initTab(tabs.childNodes[i]); + } + }, 150); + + this.unloaders.push(function() { + // Move the tabs toolbar back to where it was + toolbar._toolbox = null; // reset value set by constructor + toolbar.removeAttribute('toolboxid'); + toolbar.removeAttribute('collapsed'); + toolbar.removeChild(spacer); + toolbar.removeChild(pin_button); + let toolbox = document.getElementById('navigator-toolbox'); + let navbar = document.getElementById('nav-bar'); + let browserPanel = document.getElementById('browser-panel'); + let new_tab_button = document.getElementById('new-tab-button'); + + // Put the tabs back up top + tabs.orient = 'horizontal'; + tabs.mTabstrip.orient = 'horizontal'; + tabs.tabbox.orient = 'vertical'; // probably not necessary + tabs.removeAttribute('width'); + tabs.removeEventListener('TabOpen', this, false); + tabs.removeEventListener('TabSelect', this, false); + tabs.removeEventListener('TabClose', this, false); + tabs.removeEventListener('TabPinned', this, false); + tabs.removeEventListener('TabUnpinned', this, false); + tabs.removeAttribute('vertical'); + + // Restore all individual tabs. + for (let i = 0; i < tabs.childNodes.length; i++) { + let tab = tabs.childNodes[i]; + tab.setAttribute('crop', 'end'); + tab.removeAttribute('verticaltabs-id'); + } - tabs.contextMenu.addEventListener('popupshowing', this, false); + // Remove all the crap we added. + browserbox.removeChild(leftbox); + browserbox.removeAttribute('dir'); + mainWindow.removeAttribute('tabspinned'); + mainWindow.setAttribute('persist', + mainWindow.getAttribute('persist').replace(' tabspinnned', '')); + leftbox = null; + + // Restore the tab strip. + toolbar.insertBefore(tabs, new_tab_button); + toolbox.insertBefore(toolbar, navbar); + browserPanel.insertBefore(toolbox, browserPanel.firstChild); + browserPanel.insertBefore(bottom, document.getElementById('fullscreen-warning').nextSibling); + this.window.TabsInTitlebar.updateAppearance(true); + }); + }, + + initContextMenu: function() { + const document = this.document; + const tabs = document.getElementById('tabbrowser-tabs'); + + let closeMultiple = null; + if (this.multiSelect) { + closeMultiple = this.createElement('menuitem', { + 'id': 'context_verticalTabsCloseMultiple', + 'label': 'Close Selected Tabs', + 'tbattr': 'tabbrowser-multiple', + 'oncommand': 'gBrowser.tabContainer.VTMultiSelect.closeSelected();' + }); + tabs.contextMenu.appendChild(closeMultiple); + } - this.unloaders.push(function() { - if (closeMultiple) - tabs.contextMenu.removeChild(closeMultiple); - tabs.contextMenu.removeEventListener('popupshowing', this, false); - }); - }, + tabs.contextMenu.addEventListener('popupshowing', this, false); - initTab: function(aTab) { - if (this.document.getElementById('main-window').getAttribute('tabspinned') !== 'true') { - aTab.removeAttribute('crop'); - } else { - aTab.setAttribute('crop', 'end'); + this.unloaders.push(function() { + if (closeMultiple) { + tabs.contextMenu.removeChild(closeMultiple); } - }, - - unload: function() { - this.unloaders.forEach(function(func) { - func.call(this); - }, this); - }, - - /*** Event handlers ***/ - - handleEvent: function(aEvent) { - switch (aEvent.type) { - case 'DOMContentLoaded': - this.init(); - return; - case 'TabOpen': - this.onTabOpen(aEvent); - return; - case 'TabClose': - this.onTabClose(aEvent); - return; - case 'TabPinned': - this.onTabPinned(aEvent); - return; - case 'TabUnpinned': - this.onTabUnpinned(aEvent); - return; - case 'mouseup': - this.onMouseUp(aEvent); - return; - case 'popupshowing': - this.onPopupShowing(aEvent); - return; - case 'TabSelect': - this.onTabSelect(aEvent); - return; - } - }, - - onTabSelect: function(aEvent) { - let tab = aEvent.target; - tab.scrollIntoView(); - }, - - onTabOpen: function(aEvent) { - let tab = aEvent.target; - this.stats.tabs_created++; - this.initTab(tab); - }, - - onTabClose: function(aEvent) { - this.stats.tabs_destroyed++; - }, - - onTabPinned: function(aEvent) { - this.stats.tabs_pinned++; - }, - - onTabUnpinned: function(aEvent) { - this.stats.tabs_unpinned++; - }, - - onPopupShowing: function(aEvent) { - if (!this.multiSelect) - return; - - let closeTabs = this.document.getElementById('context_verticalTabsCloseMultiple'); - let tabs = this.multiSelect.getSelected(); - if (tabs.length > 1) { - closeTabs.disabled = false; - } else { - closeTabs.disabled = true; - } - }, + tabs.contextMenu.removeEventListener('popupshowing', this, false); + }); + }, + + initTab: function(aTab) { + if (this.document.getElementById('main-window').getAttribute('tabspinned') !== 'true') { + aTab.removeAttribute('crop'); + } else { + aTab.setAttribute('crop', 'end'); + } + }, + + unload: function() { + this.unloaders.forEach(function(func) { + func.call(this); + }, this); + }, + + /*** Event handlers ***/ + + handleEvent: function(aEvent) { + switch (aEvent.type) { + case 'DOMContentLoaded': + this.init(); + return; + case 'TabOpen': + this.onTabOpen(aEvent); + return; + case 'TabClose': + this.onTabClose(aEvent); + return; + case 'TabPinned': + this.onTabPinned(aEvent); + return; + case 'TabUnpinned': + this.onTabUnpinned(aEvent); + return; + case 'mouseup': + this.onMouseUp(aEvent); + return; + case 'popupshowing': + this.onPopupShowing(aEvent); + return; + case 'TabSelect': + this.onTabSelect(aEvent); + return; + } + }, + + onTabSelect: function(aEvent) { + let tab = aEvent.target; + tab.scrollIntoView(); + }, + + onTabOpen: function(aEvent) { + let tab = aEvent.target; + this.stats.tabs_created++; + this.initTab(tab); + }, + + onTabClose: function(aEvent) { + this.stats.tabs_destroyed++; + }, + + onTabPinned: function(aEvent) { + this.stats.tabs_pinned++; + }, + + onTabUnpinned: function(aEvent) { + this.stats.tabs_unpinned++; + }, + + onPopupShowing: function(aEvent) { + if (!this.multiSelect) { + return; + } + + let closeTabs = this.document.getElementById('context_verticalTabsCloseMultiple'); + let tabs = this.multiSelect.getSelected(); + if (tabs.length > 1) { + closeTabs.disabled = false; + } else { + closeTabs.disabled = true; + } + }, sendStats: function(payload) { this.addPingStats(this.stats);