diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
index 3fc9b56b7dc1..e0139f9fa819 100644
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -7865,9 +7865,15 @@ var TabContextMenu = {
document.getElementById("context_undoCloseTab").disabled =
SessionStore.getClosedTabCount(window) == 0;
- // Only one of pin/unpin should be visible
- document.getElementById("context_pinTab").hidden = this.contextTab.pinned;
- document.getElementById("context_unpinTab").hidden = !this.contextTab.pinned;
+ // Only one of pin/unpin/multiselect-pin/multiselect-unpin should be visible
+ let contextPinTab = document.getElementById("context_pinTab");
+ contextPinTab.hidden = this.contextTab.pinned || multiselectionContext;
+ let contextUnpinTab = document.getElementById("context_unpinTab");
+ contextUnpinTab.hidden = !this.contextTab.pinned || multiselectionContext;
+ let contextPinSelectedTabs = document.getElementById("context_pinSelectedTabs");
+ contextPinSelectedTabs.hidden = this.contextTab.pinned || !multiselectionContext;
+ let contextUnpinSelectedTabs = document.getElementById("context_unpinSelectedTabs");
+ contextUnpinSelectedTabs.hidden = !this.contextTab.pinned || !multiselectionContext;
// Disable "Close Tabs to the Right" if there are no tabs
// following it.
diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul
index fa3fdf224f14..674511cbbb1d 100644
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -109,6 +109,12 @@
+
+
diff --git a/browser/base/content/tabbrowser.js b/browser/base/content/tabbrowser.js
index 952b4b85247a..58bf4b3d69ef 100644
--- a/browser/base/content/tabbrowser.js
+++ b/browser/base/content/tabbrowser.js
@@ -3735,6 +3735,18 @@ window._gBrowser = {
}
},
+ pinMultiSelectedTabs() {
+ for (let tab of this.selectedTabs) {
+ this.pinTab(tab);
+ }
+ },
+
+ unpinMultiSelectedTabs() {
+ for (let tab of this.selectedTabs) {
+ this.unpinTab(tab);
+ }
+ },
+
activateBrowserForPrintPreview(aBrowser) {
this._printPreviewBrowsers.add(aBrowser);
if (this._switcher) {
diff --git a/browser/base/content/test/tabs/browser.ini b/browser/base/content/test/tabs/browser.ini
index f3003f8680c1..8ece3712fe98 100644
--- a/browser/base/content/test/tabs/browser.ini
+++ b/browser/base/content/test/tabs/browser.ini
@@ -23,6 +23,7 @@ support-files =
[browser_multiselect_tabs_close_using_shortcuts.js]
[browser_multiselect_tabs_close.js]
[browser_multiselect_tabs_mute_unmute.js]
+[browser_multiselect_tabs_pin_unpin.js]
[browser_multiselect_tabs_positional_attrs.js]
[browser_multiselect_tabs_using_Ctrl.js]
[browser_multiselect_tabs_using_Shift.js]
diff --git a/browser/base/content/test/tabs/browser_multiselect_tabs_pin_unpin.js b/browser/base/content/test/tabs/browser_multiselect_tabs_pin_unpin.js
new file mode 100644
index 000000000000..9de8c6ab7cb8
--- /dev/null
+++ b/browser/base/content/test/tabs/browser_multiselect_tabs_pin_unpin.js
@@ -0,0 +1,75 @@
+const PREF_MULTISELECT_TABS = "browser.tabs.multiselect";
+
+add_task(async function setPref() {
+ await SpecialPowers.pushPrefEnv({
+ set: [[PREF_MULTISELECT_TABS, true]]
+ });
+});
+
+add_task(async function test() {
+ let tab1 = await addTab();
+ let tab2 = await addTab();
+ let tab3 = await addTab();
+
+ let menuItemPinTab = document.getElementById("context_pinTab");
+ let menuItemUnpinTab = document.getElementById("context_unpinTab");
+ let menuItemPinSelectedTabs = document.getElementById("context_pinSelectedTabs");
+ let menuItemUnpinSelectedTabs = document.getElementById("context_unpinSelectedTabs");
+
+ is(gBrowser.multiSelectedTabsCount, 0, "Zero multiselected tabs");
+
+ await BrowserTestUtils.switchTab(gBrowser, tab1);
+ await triggerClickOn(tab2, { ctrlKey: true });
+
+ ok(tab1.multiselected, "Tab1 is multiselected");
+ ok(tab2.multiselected, "Tab2 is multiselected");
+ ok(!tab3.multiselected, "Tab3 is not multiselected");
+
+ // Check the context menu with a non-multiselected tab
+ updateTabContextMenu(tab3);
+ ok(!tab3.pinned, "Tab3 is unpinned");
+ is(menuItemPinTab.hidden, false, "Pin Tab is visible");
+ is(menuItemUnpinTab.hidden, true, "Unpin Tab is hidden");
+ is(menuItemPinSelectedTabs.hidden, true, "Pin Selected Tabs is hidden");
+ is(menuItemUnpinSelectedTabs.hidden, true, "Unpin Selected Tabs is hidden");
+
+ // Check the context menu with a multiselected and unpinned tab
+ updateTabContextMenu(tab2);
+ ok(!tab2.pinned, "Tab2 is unpinned");
+ is(menuItemPinTab.hidden, true, "Pin Tab is hidden");
+ is(menuItemUnpinTab.hidden, true, "Unpin Tab is hidden");
+ is(menuItemPinSelectedTabs.hidden, false, "Pin Selected Tabs is visible");
+ is(menuItemUnpinSelectedTabs.hidden, true, "Unpin Selected Tabs is hidden");
+
+ let tab1Pinned = BrowserTestUtils.waitForEvent(tab1, "TabPinned");
+ let tab2Pinned = BrowserTestUtils.waitForEvent(tab2, "TabPinned");
+ menuItemPinSelectedTabs.click();
+ await tab1Pinned;
+ await tab2Pinned;
+
+ ok(tab1.pinned, "Tab1 is pinned");
+ ok(tab2.pinned, "Tab2 is pinned");
+ ok(!tab3.pinned, "Tab3 is unpinned");
+
+ // Check the context menu with a multiselected and pinned tab
+ updateTabContextMenu(tab2);
+ ok(tab2.pinned, "Tab2 is pinned");
+ is(menuItemPinTab.hidden, true, "Pin Tab is hidden");
+ is(menuItemUnpinTab.hidden, true, "Unpin Tab is hidden");
+ is(menuItemPinSelectedTabs.hidden, true, "Pin Selected Tabs is hidden");
+ is(menuItemUnpinSelectedTabs.hidden, false, "Unpin Selected Tabs is visible");
+
+ let tab1Unpinned = BrowserTestUtils.waitForEvent(tab1, "TabUnpinned");
+ let tab2Unpinned = BrowserTestUtils.waitForEvent(tab2, "TabUnpinned");
+ menuItemUnpinSelectedTabs.click();
+ await tab1Unpinned;
+ await tab2Unpinned;
+
+ ok(!tab1.pinned, "Tab1 is unpinned");
+ ok(!tab2.pinned, "Tab2 is unpinned");
+ ok(!tab3.pinned, "Tab3 is unpinned");
+
+ BrowserTestUtils.removeTab(tab1);
+ BrowserTestUtils.removeTab(tab2);
+ BrowserTestUtils.removeTab(tab3);
+});
diff --git a/browser/locales/en-US/chrome/browser/browser.dtd b/browser/locales/en-US/chrome/browser/browser.dtd
index fbc9850a4040..610fc562aefa 100644
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -34,8 +34,17 @@ left instead of right. -->
+
+
+
+
+
+
+