Bug 1458061 - Implement ability to reload a selection of tabs. r=Gijs
MozReview-Commit-ID: CyJLk7pxGRr
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -7859,16 +7859,20 @@ var TabContextMenu = {
menuItems = aPopupMenu.getElementsByAttribute("tbattr", "tabbrowser-multiple-visible");
for (let menuItem of menuItems)
menuItem.disabled = disabled;
// Session store
document.getElementById("context_undoCloseTab").disabled =
SessionStore.getClosedTabCount(window) == 0;
+ // Only one of Reload_Tab/Reload_Selected_Tabs should be visible.
+ document.getElementById("context_reloadTab").hidden = multiselectionContext;
+ document.getElementById("context_reloadSelectedTabs").hidden = !multiselectionContext;
+
// 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");
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -94,16 +94,19 @@
#undef FULL_BROWSER_WINDOW
<popupset id="mainPopupSet">
<menupopup id="tabContextMenu"
onpopupshowing="if (event.target == this) TabContextMenu.updateContextMenu(this);"
onpopuphidden="if (event.target == this) TabContextMenu.contextTab = null;">
<menuitem id="context_reloadTab" label="&reloadTab.label;" accesskey="&reloadTab.accesskey;"
oncommand="gBrowser.reloadTab(TabContextMenu.contextTab);"/>
+ <menuitem id="context_reloadSelectedTabs" label="&reloadSelectedTabs.label;" hidden="true"
+ accesskey="&reloadSelectedTabs.accesskey;"
+ oncommand="gBrowser.reloadMultiSelectedTabs();"/>
<menuitem id="context_toggleMuteTab" oncommand="TabContextMenu.contextTab.toggleMuteAudio();"/>
<menuitem id="context_toggleMuteSelectedTabs" hidden="true"
oncommand="gBrowser.toggleMuteAudioOnMultiSelectedTabs(TabContextMenu.contextTab);"/>
<menuseparator/>
<menuitem id="context_pinTab" label="&pinTab.label;"
accesskey="&pinTab.accesskey;"
oncommand="gBrowser.pinTab(TabContextMenu.contextTab);"/>
<menuitem id="context_unpinTab" label="&unpinTab.label;" hidden="true"
--- a/browser/base/content/tabbrowser.js
+++ b/browser/base/content/tabbrowser.js
@@ -3254,21 +3254,27 @@ window._gBrowser = {
delete aOtherBrowser.registeredOpenURI;
}
if (tmp) {
aOtherBrowser.registeredOpenURI = tmp;
}
},
reloadAllTabs() {
- let tabs = this.visibleTabs;
- let l = tabs.length;
- for (var i = 0; i < l; i++) {
+ this.reloadTabs(this.visibleTabs);
+ },
+
+ reloadMultiSelectedTabs() {
+ this.reloadTabs(this.selectedTabs);
+ },
+
+ reloadTabs(tabs) {
+ for (let tab of tabs) {
try {
- this.getBrowserForTab(tabs[i]).reload();
+ this.getBrowserForTab(tab).reload();
} catch (e) {
// ignore failure to reload so others will be reloaded
}
}
},
reloadTab(aTab) {
let browser = this.getBrowserForTab(aTab);
--- a/browser/base/content/test/tabs/browser.ini
+++ b/browser/base/content/test/tabs/browser.ini
@@ -20,16 +20,17 @@ support-files =
test_bug1358314.html
[browser_isLocalAboutURI.js]
[browser_multiselect_tabs_active_tab_selected_by_default.js]
[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_reload.js]
[browser_multiselect_tabs_using_Ctrl.js]
[browser_multiselect_tabs_using_Shift.js]
[browser_navigatePinnedTab.js]
[browser_new_file_whitelisted_http_tab.js]
skip-if = !e10s # Test only relevant for e10s.
[browser_new_tab_insert_position.js]
skip-if = (debug && os == 'linux' && bits == 32) #Bug 1455882, disabled on Linux32 for almost permafailing
support-files = file_new_tab_page.html
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/tabs/browser_multiselect_tabs_reload.js
@@ -0,0 +1,50 @@
+const PREF_MULTISELECT_TABS = "browser.tabs.multiselect";
+
+async function tabLoaded(tab) {
+ const browser = gBrowser.getBrowserForTab(tab);
+ await BrowserTestUtils.browserLoaded(browser);
+ return true;
+}
+
+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 menuItemReloadTab = document.getElementById("context_reloadTab");
+ let menuItemReloadSelectedTabs = document.getElementById("context_reloadSelectedTabs");
+
+ await BrowserTestUtils.switchTab(gBrowser, tab1);
+ await triggerClickOn(tab2, { ctrlKey: true });
+
+ ok(tab1.multiselected, "Tab1 is multi-selected");
+ ok(tab2.multiselected, "Tab2 is multi-selected");
+ ok(!tab3.multiselected, "Tab3 is not multi-selected");
+
+ updateTabContextMenu(tab3);
+ is(menuItemReloadTab.hidden, false, "Reload Tab is visible");
+ is(menuItemReloadSelectedTabs.hidden, true, "Reload Selected Tabs is hidden");
+
+ updateTabContextMenu(tab2);
+ is(menuItemReloadTab.hidden, true, "Reload Tab is hidden");
+ is(menuItemReloadSelectedTabs.hidden, false, "Reload Selected Tabs is visible");
+
+ let tab1Loaded = tabLoaded(tab1);
+ let tab2Loaded = tabLoaded(tab2);
+ menuItemReloadSelectedTabs.click();
+ await tab1Loaded;
+ await tab2Loaded;
+
+ // We got here because tab1 and tab2 are reloaded. Otherwise the test would have timed out and failed.
+ ok(true, "Tab1 and Tab2 are reloaded");
+
+ BrowserTestUtils.removeTab(tab1);
+ BrowserTestUtils.removeTab(tab2);
+ BrowserTestUtils.removeTab(tab3);
+});
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -40,16 +40,20 @@ left instead of right. -->
<!ENTITY pinSelectedTabs.label "Pin Tabs">
<!-- Pin Tab and Pin Selected Tabs have the same accesskey
but will never be visible at the same time. -->
<!ENTITY pinSelectedTabs.accesskey "P">
<!ENTITY unpinSelectedTabs.label "Unpin Tabs">
<!-- Unpin Tab and Unpin Selected Tabs have the same accesskey
but will never be visible at the same time. -->
<!ENTITY unpinSelectedTabs.accesskey "b">
+<!-- Reload Tab and Reload Selected Tabs have the same accesskey
+but will never be visible at the same time. -->
+<!ENTITY reloadSelectedTabs.label "Reload Selected Tabs">
+<!ENTITY reloadSelectedTabs.accesskey "R">
<!-- LOCALIZATION NOTE (pinTab.label, unpinTab.label): "Pin" is being
used as a metaphor for expressing the fact that these tabs are "pinned" to the
left edge of the tabstrip. Really we just want the string to express the idea
that this is a lightweight and reversible action that keeps your tab where you
can reach it easily. -->
<!ENTITY pinTab.label "Pin Tab">
<!ENTITY pinTab.accesskey "P">