Bug 1628288. r=adw
authorMarco Bonardo <mbonardo@mozilla.com>
Fri, 17 Apr 2020 09:59:23 +0000
changeset 524579 e187ef437b760862a1dcc5285570cf3e5ae38adc
parent 524578 063fb58eb4c2fe6e7680e08a8d9300ee2772e9a7
child 524580 a4bba077f98ec70d9e2cbd05a14d6981ad75c442
push id37323
push userdluca@mozilla.com
push dateFri, 17 Apr 2020 16:25:55 +0000
treeherdermozilla-central@b4b1d6f91ef0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersadw
bugs1628288
milestone77.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 1628288. r=adw Differential Revision: https://phabricator.services.mozilla.com/D71191
browser/components/urlbar/UrlbarInput.jsm
browser/components/urlbar/tests/browser/browser_top_sites.js
--- a/browser/components/urlbar/UrlbarInput.jsm
+++ b/browser/components/urlbar/UrlbarInput.jsm
@@ -772,16 +772,21 @@ class UrlbarInput {
    *   The result that was selected or picked, null if no result was selected.
    * @param {Event} [event] The event that picked the result.
    * @returns {boolean}
    *   Whether the value has been canonized
    */
   setValueFromResult(result = null, event = null) {
     let canonizedUrl;
 
+    // Usually this is set by a previous input event, but in certain cases, like
+    // when opening Top Sites on a loaded page, it wouldn't happen. To avoid
+    // confusing the user, we always enforce it when a result changes our value.
+    this.setPageProxyState("invalid", true);
+
     if (!result) {
       // This usually happens when there's no selected results (the user cycles
       // through results and there was no heuristic), and we reset the input
       // value to the previous text value.
       this.value = this._valueOnLastSearch;
     } else {
       // For autofilled results, the value that should be canonized is not the
       // autofilled value but the value that the user typed.
--- a/browser/components/urlbar/tests/browser/browser_top_sites.js
+++ b/browser/components/urlbar/tests/browser/browser_top_sites.js
@@ -37,16 +37,19 @@ add_task(async function init() {
 add_task(async function topSitesShown() {
   let sites = AboutNewTab.getTopSites();
   Assert.equal(
     sites.length,
     6,
     "The test suite browser should have 6 Top Sites."
   );
   await UrlbarTestUtils.promisePopupOpen(window, () => {
+    if (gURLBar.getAttribute("pageproxystate") == "invalid") {
+      gURLBar.handleRevert();
+    }
     EventUtils.synthesizeMouseAtCenter(window.gURLBar.inputField, {});
   });
   Assert.ok(window.gURLBar.view.isOpen, "UrlbarView should be open.");
   await UrlbarTestUtils.promiseSearchComplete(window);
   Assert.equal(
     UrlbarTestUtils.getResultCount(window),
     sites.length,
     "The number of results should be the same as the number of Top Sites (6)."
@@ -81,16 +84,19 @@ add_task(async function topSitesShown() 
 });
 
 add_task(async function selectSearchTopSite() {
   await updateTopSites(
     sites => sites && sites[0] && sites[0].searchTopSite,
     true
   );
   await UrlbarTestUtils.promisePopupOpen(window, () => {
+    if (gURLBar.getAttribute("pageproxystate") == "invalid") {
+      gURLBar.handleRevert();
+    }
     EventUtils.synthesizeMouseAtCenter(window.gURLBar.inputField, {});
   });
   await UrlbarTestUtils.promiseSearchComplete(window);
 
   let amazonSearch = await UrlbarTestUtils.waitForAutocompleteResultAt(
     window,
     0
   );
@@ -144,16 +150,19 @@ add_task(async function topSitesBookmark
   let sites = AboutNewTab.getTopSites();
   Assert.equal(
     sites.length,
     7,
     "The test suite browser should have 7 Top Sites."
   );
 
   await UrlbarTestUtils.promisePopupOpen(window, () => {
+    if (gURLBar.getAttribute("pageproxystate") == "invalid") {
+      gURLBar.handleRevert();
+    }
     EventUtils.synthesizeMouseAtCenter(window.gURLBar.inputField, {});
   });
   Assert.ok(window.gURLBar.view.isOpen, "UrlbarView should be open.");
   await UrlbarTestUtils.promiseSearchComplete(window);
 
   Assert.equal(
     UrlbarTestUtils.getResultCount(window),
     7,
@@ -183,32 +192,83 @@ add_task(async function topSitesBookmark
     UrlbarUtils.RESULT_SOURCE.BOOKMARKS,
     "The YouTube Top Site should appear in the view as a bookmark result."
   );
   await UrlbarTestUtils.promisePopupClose(window, () => {
     window.gURLBar.blur();
   });
 });
 
+add_task(async function topSitesKeywordNavigationPageproxystate() {
+  Assert.equal(
+    gURLBar.getAttribute("pageproxystate"),
+    "valid",
+    "Sanity check initial state"
+  );
+
+  await UrlbarTestUtils.promisePopupOpen(window, () => {
+    if (gURLBar.getAttribute("pageproxystate") == "invalid") {
+      gURLBar.handleRevert();
+    }
+    EventUtils.synthesizeMouseAtCenter(window.gURLBar.inputField, {});
+  });
+  Assert.ok(window.gURLBar.view.isOpen, "UrlbarView should be open.");
+  await UrlbarTestUtils.promiseSearchComplete(window);
+
+  let count = UrlbarTestUtils.getResultCount(window);
+  Assert.equal(count, 7, "The number of results should be the expected one.");
+
+  for (let i = 0; i < count; ++i) {
+    EventUtils.synthesizeKey("KEY_ArrowDown");
+    Assert.equal(
+      gURLBar.getAttribute("pageproxystate"),
+      "invalid",
+      "Moving through results"
+    );
+  }
+  for (let i = 0; i < count; ++i) {
+    EventUtils.synthesizeKey("KEY_ArrowUp");
+    Assert.equal(
+      gURLBar.getAttribute("pageproxystate"),
+      "invalid",
+      "Moving through results"
+    );
+  }
+
+  // Double ESC should restore state.
+  await UrlbarTestUtils.promisePopupClose(window, () => {
+    EventUtils.synthesizeKey("KEY_Escape");
+  });
+  EventUtils.synthesizeKey("KEY_Escape");
+  Assert.equal(
+    gURLBar.getAttribute("pageproxystate"),
+    "valid",
+    "Double ESC should restore state"
+  );
+});
+
 add_task(async function topSitesDisabled() {
   // Disable top sites.
   await SpecialPowers.pushPrefEnv({
     set: [["browser.newtabpage.activity-stream.feeds.topsites", false]],
   });
 
   // Add some visits.
   await PlacesUtils.bookmarks.eraseEverything();
   await PlacesUtils.history.clear();
   let urlCount = 5;
   for (let i = 0; i < urlCount; i++) {
     await PlacesTestUtils.addVisits(`http://example.com/${i}`);
   }
 
   // Open the view.
   await UrlbarTestUtils.promisePopupOpen(window, () => {
+    if (gURLBar.getAttribute("pageproxystate") == "invalid") {
+      gURLBar.handleRevert();
+    }
     EventUtils.synthesizeMouseAtCenter(window.gURLBar.inputField, {});
   });
   Assert.ok(window.gURLBar.view.isOpen, "UrlbarView should be open.");
   await UrlbarTestUtils.promiseSearchComplete(window);
 
   // Check the results.  We should show the most frecent sites from history via
   // the UnifiedComplete provider.
   Assert.equal(