Bug 1495299 - Add support for reload tab operation using keyboard shortcuts in a multi-select context. r=jaws
authorAbdoulaye O. Ly <ablayelyfondou@gmail.com>
Mon, 08 Oct 2018 18:32:55 +0000
changeset 495746 7de7e0e7ed1ac3feeb34544a3fd5c891ee47c137
parent 495724 e3d243f3ff07fa45ae97858db2e0ccf07822918f
child 495747 7355fb2908e5087eddab422ac838697284c25d82
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjaws
bugs1495299
milestone64.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 1495299 - Add support for reload tab operation using keyboard shortcuts in a multi-select context. r=jaws Differential Revision: https://phabricator.services.mozilla.com/D7956
browser/base/content/browser.js
browser/base/content/test/tabs/browser_multiselect_tabs_reload.js
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3275,46 +3275,87 @@ function BrowserFullScreen() {
   window.fullScreen = !window.fullScreen;
 }
 
 function getWebNavigation() {
   return gBrowser.webNavigation;
 }
 
 function BrowserReloadWithFlags(reloadFlags) {
-  let url = gBrowser.currentURI.spec;
-  if (gBrowser.updateBrowserRemotenessByURL(gBrowser.selectedBrowser, url)) {
-    // If the remoteness has changed, the new browser doesn't have any
-    // information of what was loaded before, so we need to load the previous
-    // URL again.
-    gBrowser.loadURI(url, {
-      flags: reloadFlags,
-      triggeringPrincipal: gBrowser.selectedBrowser.contentPrincipal,
-    });
+  let unchangedRemoteness = [];
+
+  for (let tab of gBrowser.selectedTabs) {
+    let browser = tab.linkedBrowser;
+    let url = browser.currentURI.spec;
+    if (gBrowser.updateBrowserRemotenessByURL(browser, url)) {
+      // If the remoteness has changed, the new browser doesn't have any
+      // information of what was loaded before, so we need to load the previous
+      // URL again.
+      if (tab.linkedPanel) {
+        loadBrowserURI(browser, url);
+      } else {
+        // Shift to fully loaded browser and make
+        // sure load handler is instantiated.
+        tab.addEventListener("SSTabRestoring",
+                             () => loadBrowserURI(browser, url),
+                             { once: true });
+        gBrowser._insertBrowser(tab);
+      }
+    } else {
+      unchangedRemoteness.push(tab);
+    }
+  }
+
+  if (unchangedRemoteness.length == 0) {
     return;
   }
 
   // Do this after the above case where we might flip remoteness.
   // Unfortunately, we'll count the remoteness flip case as a
   // "newURL" load, since we're using loadURI, but hopefully
   // that's rare enough to not matter.
-  maybeRecordAbandonmentTelemetry(gBrowser.selectedTab, "reload");
-
-  // Reset temporary permissions on the current tab. This is done here
-  // because we only want to reset permissions on user reload.
-  SitePermissions.clearTemporaryPermissions(gBrowser.selectedBrowser);
+  for (let tab of unchangedRemoteness) {
+    maybeRecordAbandonmentTelemetry(tab, "reload");
+  }
+
+  // Reset temporary permissions on the remaining tabs to reload.
+  // This is done here because we only want to reset
+  // permissions on user reload.
+  for (let tab of unchangedRemoteness) {
+    SitePermissions.clearTemporaryPermissions(tab.linkedBrowser);
+  }
   PanelMultiView.hidePopup(gIdentityHandler._identityPopup);
 
 
   let handlingUserInput = window.windowUtils.isHandlingUserInput;
 
-  gBrowser.selectedBrowser
-          .messageManager
-          .sendAsyncMessage("Browser:Reload",
-                            { flags: reloadFlags, handlingUserInput });
+  for (let tab of unchangedRemoteness) {
+    if (tab.linkedPanel) {
+      sendReloadMessage(tab);
+    } else {
+      // Shift to fully loaded browser and make
+      // sure load handler is instantiated.
+      tab.addEventListener("SSTabRestoring", () => sendReloadMessage(tab), { once: true });
+      gBrowser._insertBrowser(tab);
+    }
+  }
+
+  function loadBrowserURI(browser, url) {
+    browser.loadURI(url, {
+      flags: reloadFlags,
+      triggeringPrincipal: browser.contentPrincipal,
+    });
+  }
+
+  function sendReloadMessage(tab) {
+    tab.linkedBrowser
+         .messageManager
+         .sendAsyncMessage("Browser:Reload",
+                           { flags: reloadFlags, handlingUserInput });
+  }
 }
 
 function getSecurityInfo(securityInfoAsString) {
   if (!securityInfoAsString)
     return null;
 
   const serhelper = Cc["@mozilla.org/network/serialization-helper;1"]
                        .getService(Ci.nsISerializationHelper);
--- a/browser/base/content/test/tabs/browser_multiselect_tabs_reload.js
+++ b/browser/base/content/test/tabs/browser_multiselect_tabs_reload.js
@@ -1,50 +1,89 @@
 const PREF_MULTISELECT_TABS = "browser.tabs.multiselect";
 
 async function tabLoaded(tab) {
-    const browser = gBrowser.getBrowserForTab(tab);
-    await BrowserTestUtils.browserLoaded(browser);
-    return true;
+  const browser = gBrowser.getBrowserForTab(tab);
+  await BrowserTestUtils.browserLoaded(browser);
+  return true;
 }
 
 add_task(async function setPref() {
-    await SpecialPowers.pushPrefEnv({
-        set: [[PREF_MULTISELECT_TABS, true]],
-    });
+  await SpecialPowers.pushPrefEnv({
+    set: [[PREF_MULTISELECT_TABS, true]],
+  });
 });
 
-add_task(async function test() {
+add_task(async function test_usingTabContextMenu() {
+  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 Tabs is hidden");
+
+  updateTabContextMenu(tab2);
+  is(menuItemReloadTab.hidden, true, "Reload Tab is hidden");
+  is(menuItemReloadSelectedTabs.hidden, false, "Reload 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);
+});
+
+add_task(async function test_usingKeyboardShortcuts() {
+  let keys = [
+    ["R", { accelKey: true }],
+    ["R", { accelKey: true, shift: true }],
+    ["VK_F5", {}],
+  ];
+
+  if (AppConstants.platform != "macosx") {
+    keys.push(["VK_F5", { accelKey: true }]);
+  }
+
+  for (let key of keys) {
+
     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();
+    EventUtils.synthesizeKey(key[0], key[1]);
     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);
+  }
 });