Loading browser/base/content/test/tabs/browser_tab_manager_close.js +41 −4 Original line number Diff line number Diff line Loading @@ -9,14 +9,16 @@ const URL3 = "data:text/plain,tab3"; const URL4 = "data:text/plain,tab4"; const URL5 = "data:text/plain,tab5"; /** * Tests that middle-clicking on a tab in the Tab Manager will close it. */ add_task(async function test_tab_manager_close() { add_setup(async function () { await SpecialPowers.pushPrefEnv({ set: [["browser.tabs.tabmanager.enabled", true]], }); }); /** * Tests that middle-clicking on a tab in the Tab Manager will close it. */ add_task(async function test_tab_manager_close_middle_click() { let win = await BrowserTestUtils.openNewWindowWithFlushedCacheForMozSupports(); win.gTabsPanel.init(); Loading Loading @@ -45,3 +47,38 @@ add_task(async function test_tab_manager_close() { } await BrowserTestUtils.closeWindow(win); }); /** * Tests that clicking the close button next to a tab manager item * will close it. */ add_task(async function test_tab_manager_close_button() { let win = await BrowserTestUtils.openNewWindowWithFlushedCacheForMozSupports(); win.gTabsPanel.init(); await addTabTo(win.gBrowser, URL1); await addTabTo(win.gBrowser, URL2); await addTabTo(win.gBrowser, URL3); await addTabTo(win.gBrowser, URL4); await addTabTo(win.gBrowser, URL5); let button = win.document.getElementById("alltabs-button"); let allTabsView = win.document.getElementById("allTabsMenu-allTabsView"); let allTabsPopupShownPromise = BrowserTestUtils.waitForEvent( allTabsView, "ViewShown" ); button.click(); await allTabsPopupShownPromise; let list = win.document.getElementById("allTabsMenu-allTabsView-tabs"); while (win.gBrowser.tabs.length > 1) { let row = list.lastElementChild; let tabClosing = BrowserTestUtils.waitForTabClosing(row.tab); let closeButton = row.lastElementChild; EventUtils.synthesizeMouseAtCenter(closeButton, { button: 1 }, win); await tabClosing; Assert.ok(true, "Closed a tab with the close button."); } await BrowserTestUtils.closeWindow(win); }); browser/modules/TabsList.jsm +26 −12 Original line number Diff line number Diff line Loading @@ -258,10 +258,14 @@ class TabsPanel extends TabsListBase { } break; case "command": if (event.target.hasAttribute("toggle-mute")) { if (event.target.classList.contains("all-tabs-mute-button")) { event.target.tab.toggleMuteAudio(); break; } if (event.target.classList.contains("all-tabs-close-button")) { this.gBrowser.removeTab(event.target.tab); break; } // fall through default: super.handleEvent(event); Loading Loading @@ -317,15 +321,26 @@ class TabsPanel extends TabsListBase { row.appendChild(button); let secondaryButton = doc.createXULElement("toolbarbutton"); secondaryButton.setAttribute( "class", "all-tabs-secondary-button subviewbutton subviewbutton-iconic" let muteButton = doc.createXULElement("toolbarbutton"); muteButton.classList.add( "all-tabs-mute-button", "all-tabs-secondary-button", "subviewbutton", "subviewbutton-iconic" ); muteButton.setAttribute("closemenu", "none"); muteButton.tab = tab; row.appendChild(muteButton); let closeButton = doc.createXULElement("toolbarbutton"); closeButton.classList.add( "all-tabs-close-button", "all-tabs-secondary-button", "subviewbutton" ); secondaryButton.setAttribute("closemenu", "none"); secondaryButton.setAttribute("toggle-mute", "true"); secondaryButton.tab = tab; row.appendChild(secondaryButton); closeButton.setAttribute("closemenu", "none"); closeButton.tab = tab; row.appendChild(closeButton); this._setRowAttributes(row, tab); Loading @@ -346,11 +361,10 @@ class TabsPanel extends TabsListBase { this._setImageAttributes(row, tab); let secondaryButton = row.querySelector(".all-tabs-secondary-button"); setAttributes(secondaryButton, { let muteButton = row.querySelector(".all-tabs-mute-button"); setAttributes(muteButton, { muted: tab.muted, soundplaying: tab.soundPlaying, pictureinpicture: tab.pictureinpicture, hidden: !(tab.muted || tab.soundPlaying), }); } Loading browser/themes/shared/tabs.css +23 −16 Original line number Diff line number Diff line Loading @@ -752,22 +752,20 @@ toolbar:not(#TabsToolbar) #firefox-view-button:-moz-locale-dir(rtl) { border-radius: var(--arrowpanel-menuitem-border-radius); } .all-tabs-item:hover { background-color: var(--panel-item-hover-bgcolor); } .all-tabs-item:hover:active { background-color: var(--panel-item-active-bgcolor); } .all-tabs-item[selected] { font-weight: bold; } .all-tabs-item > toolbarbutton { margin: 0; /* Since the background is set on the item, don't set it on the children. */ background-color: transparent !important; } .all-tabs-item > toolbarbutton:hover { background-color: var(--panel-item-hover-bgcolor); } .all-tabs-item > toolbarbutton:hover:active { background-color: var(--panel-item-active-bgcolor); } .all-tabs-button { Loading @@ -780,18 +778,27 @@ toolbar:not(#TabsToolbar) #firefox-view-button:-moz-locale-dir(rtl) { fill: currentColor; } .all-tabs-secondary-button[soundplaying] { .all-tabs-secondary-button > label { display: none !important; /* override panelUI-shared.css */ } .all-tabs-secondary-button:hover { opacity: 1; } .all-tabs-mute-button[soundplaying] { list-style-image: url(chrome://global/skin/media/audio.svg); } .all-tabs-secondary-button[muted] { .all-tabs-mute-button[muted] { list-style-image: url(chrome://global/skin/media/audio-muted.svg); } .all-tabs-secondary-button:hover { opacity: 1; .all-tabs-close-button { list-style-image: url(chrome://global/skin/icons/close-12.svg); } .all-tabs-secondary-button > label { display: none !important; /* override panelUI-shared.css */ .all-tabs-close-button > .toolbarbutton-icon { width: 12px; margin-inline: 2px !important; /* override panelUI-shared.css */ } Loading
browser/base/content/test/tabs/browser_tab_manager_close.js +41 −4 Original line number Diff line number Diff line Loading @@ -9,14 +9,16 @@ const URL3 = "data:text/plain,tab3"; const URL4 = "data:text/plain,tab4"; const URL5 = "data:text/plain,tab5"; /** * Tests that middle-clicking on a tab in the Tab Manager will close it. */ add_task(async function test_tab_manager_close() { add_setup(async function () { await SpecialPowers.pushPrefEnv({ set: [["browser.tabs.tabmanager.enabled", true]], }); }); /** * Tests that middle-clicking on a tab in the Tab Manager will close it. */ add_task(async function test_tab_manager_close_middle_click() { let win = await BrowserTestUtils.openNewWindowWithFlushedCacheForMozSupports(); win.gTabsPanel.init(); Loading Loading @@ -45,3 +47,38 @@ add_task(async function test_tab_manager_close() { } await BrowserTestUtils.closeWindow(win); }); /** * Tests that clicking the close button next to a tab manager item * will close it. */ add_task(async function test_tab_manager_close_button() { let win = await BrowserTestUtils.openNewWindowWithFlushedCacheForMozSupports(); win.gTabsPanel.init(); await addTabTo(win.gBrowser, URL1); await addTabTo(win.gBrowser, URL2); await addTabTo(win.gBrowser, URL3); await addTabTo(win.gBrowser, URL4); await addTabTo(win.gBrowser, URL5); let button = win.document.getElementById("alltabs-button"); let allTabsView = win.document.getElementById("allTabsMenu-allTabsView"); let allTabsPopupShownPromise = BrowserTestUtils.waitForEvent( allTabsView, "ViewShown" ); button.click(); await allTabsPopupShownPromise; let list = win.document.getElementById("allTabsMenu-allTabsView-tabs"); while (win.gBrowser.tabs.length > 1) { let row = list.lastElementChild; let tabClosing = BrowserTestUtils.waitForTabClosing(row.tab); let closeButton = row.lastElementChild; EventUtils.synthesizeMouseAtCenter(closeButton, { button: 1 }, win); await tabClosing; Assert.ok(true, "Closed a tab with the close button."); } await BrowserTestUtils.closeWindow(win); });
browser/modules/TabsList.jsm +26 −12 Original line number Diff line number Diff line Loading @@ -258,10 +258,14 @@ class TabsPanel extends TabsListBase { } break; case "command": if (event.target.hasAttribute("toggle-mute")) { if (event.target.classList.contains("all-tabs-mute-button")) { event.target.tab.toggleMuteAudio(); break; } if (event.target.classList.contains("all-tabs-close-button")) { this.gBrowser.removeTab(event.target.tab); break; } // fall through default: super.handleEvent(event); Loading Loading @@ -317,15 +321,26 @@ class TabsPanel extends TabsListBase { row.appendChild(button); let secondaryButton = doc.createXULElement("toolbarbutton"); secondaryButton.setAttribute( "class", "all-tabs-secondary-button subviewbutton subviewbutton-iconic" let muteButton = doc.createXULElement("toolbarbutton"); muteButton.classList.add( "all-tabs-mute-button", "all-tabs-secondary-button", "subviewbutton", "subviewbutton-iconic" ); muteButton.setAttribute("closemenu", "none"); muteButton.tab = tab; row.appendChild(muteButton); let closeButton = doc.createXULElement("toolbarbutton"); closeButton.classList.add( "all-tabs-close-button", "all-tabs-secondary-button", "subviewbutton" ); secondaryButton.setAttribute("closemenu", "none"); secondaryButton.setAttribute("toggle-mute", "true"); secondaryButton.tab = tab; row.appendChild(secondaryButton); closeButton.setAttribute("closemenu", "none"); closeButton.tab = tab; row.appendChild(closeButton); this._setRowAttributes(row, tab); Loading @@ -346,11 +361,10 @@ class TabsPanel extends TabsListBase { this._setImageAttributes(row, tab); let secondaryButton = row.querySelector(".all-tabs-secondary-button"); setAttributes(secondaryButton, { let muteButton = row.querySelector(".all-tabs-mute-button"); setAttributes(muteButton, { muted: tab.muted, soundplaying: tab.soundPlaying, pictureinpicture: tab.pictureinpicture, hidden: !(tab.muted || tab.soundPlaying), }); } Loading
browser/themes/shared/tabs.css +23 −16 Original line number Diff line number Diff line Loading @@ -752,22 +752,20 @@ toolbar:not(#TabsToolbar) #firefox-view-button:-moz-locale-dir(rtl) { border-radius: var(--arrowpanel-menuitem-border-radius); } .all-tabs-item:hover { background-color: var(--panel-item-hover-bgcolor); } .all-tabs-item:hover:active { background-color: var(--panel-item-active-bgcolor); } .all-tabs-item[selected] { font-weight: bold; } .all-tabs-item > toolbarbutton { margin: 0; /* Since the background is set on the item, don't set it on the children. */ background-color: transparent !important; } .all-tabs-item > toolbarbutton:hover { background-color: var(--panel-item-hover-bgcolor); } .all-tabs-item > toolbarbutton:hover:active { background-color: var(--panel-item-active-bgcolor); } .all-tabs-button { Loading @@ -780,18 +778,27 @@ toolbar:not(#TabsToolbar) #firefox-view-button:-moz-locale-dir(rtl) { fill: currentColor; } .all-tabs-secondary-button[soundplaying] { .all-tabs-secondary-button > label { display: none !important; /* override panelUI-shared.css */ } .all-tabs-secondary-button:hover { opacity: 1; } .all-tabs-mute-button[soundplaying] { list-style-image: url(chrome://global/skin/media/audio.svg); } .all-tabs-secondary-button[muted] { .all-tabs-mute-button[muted] { list-style-image: url(chrome://global/skin/media/audio-muted.svg); } .all-tabs-secondary-button:hover { opacity: 1; .all-tabs-close-button { list-style-image: url(chrome://global/skin/icons/close-12.svg); } .all-tabs-secondary-button > label { display: none !important; /* override panelUI-shared.css */ .all-tabs-close-button > .toolbarbutton-icon { width: 12px; margin-inline: 2px !important; /* override panelUI-shared.css */ }