Bug 1024133 - Switch to tab magic URL not trimmed on key navigation. r=mano, a=sledru
authorMarco Bonardo <mbonardo@mozilla.com>
Fri, 18 Jul 2014 22:04:00 +0200
changeset 208174 a8dd4b54e15b
parent 208173 2bc7c49698cc
child 208175 ecfc5bee1685
push id3753
push userryanvm@gmail.com
push date2014-07-28 14:29 +0000
treeherdermozilla-beta@ecfc5bee1685 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmano, sledru
bugs1024133
milestone32.0
Bug 1024133 - Switch to tab magic URL not trimmed on key navigation. r=mano, a=sledru
browser/base/content/test/general/browser.ini
browser/base/content/test/general/browser_bug1024133-switchtab-override-keynav.js
browser/base/content/urlbarBindings.xml
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -422,8 +422,9 @@ skip-if = (os == "win" && !debug) || e10
 skip-if = e10s # Bug ?????? - test directly manipulates content (content.document.getElementById)
 [browser_zbug569342.js]
 skip-if = e10s # Bug 516755 - SessionStore disabled for e10s
 [browser_registerProtocolHandler_notification.js]
 skip-if = e10s # Bug 940206 - nsIWebContentHandlerRegistrar::registerProtocolHandler doesn't work in e10s
 [browser_no_mcb_on_http_site.js]
 skip-if = e10s # Bug 516755 - SessionStore disabled for e10s
 [browser_bug1003461-switchtab-override.js]
+[browser_bug1024133-switchtab-override-keynav.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/browser_bug1024133-switchtab-override-keynav.js
@@ -0,0 +1,52 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+add_task(function* test_switchtab_override_keynav() {
+  let testURL = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
+
+  info("Opening first tab");
+  let tab = gBrowser.addTab(testURL);
+  let tabLoadDeferred = Promise.defer();
+  whenTabLoaded(tab, tabLoadDeferred.resolve);
+  yield tabLoadDeferred.promise;
+
+  info("Opening and selecting second tab");
+  let secondTab = gBrowser.selectedTab = gBrowser.addTab();
+  registerCleanupFunction(() => {
+    try {
+      gBrowser.removeTab(tab);
+      gBrowser.removeTab(secondTab);
+    } catch(ex) { /* tabs may have already been closed in case of failure */ }
+    return promiseClearHistory();
+  });
+
+  info("Wait for autocomplete")
+  let searchDeferred = Promise.defer();
+  let onSearchComplete = gURLBar.onSearchComplete;
+  registerCleanupFunction(() => {
+    gURLBar.onSearchComplete = onSearchComplete;
+  });
+  gURLBar.onSearchComplete = function () {
+    ok(gURLBar.popupOpen, "The autocomplete popup is correctly open");
+    onSearchComplete.apply(gURLBar);
+    searchDeferred.resolve();
+  }
+
+  gURLBar.focus();
+  gURLBar.value = "dummy_pag";
+  EventUtils.synthesizeKey("e" , {});
+  yield searchDeferred.promise;
+
+  info("Select first autocomplete popup entry");
+  EventUtils.synthesizeKey("VK_DOWN" , {});
+  ok(/moz-action:switchtab/.test(gURLBar.value), "switch to tab entry found");
+
+  info("Shift+left on switch-to-tab entry");
+
+  EventUtils.synthesizeKey("VK_SHIFT" , { type: "keydown" });
+  EventUtils.synthesizeKey("VK_LEFT", { shiftKey: true });
+  EventUtils.synthesizeKey("VK_SHIFT" , { type: "keyup" });
+
+  ok(!/moz-action:switchtab/.test(gURLBar.inputField.value), "switch to tab should be hidden");
+});
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -138,20 +138,23 @@
         It should return the value that the setter should use.
       -->
       <method name="onBeforeValueSet">
         <parameter name="aValue"/>
         <body><![CDATA[
           this._value = aValue;
           var returnValue = aValue;
           var action = this._parseActionUrl(aValue);
-          // Don't put back the action if we are invoked while override actions
-          // is active.
-          if (action && this._numNoActionsKeys <= 0) {
+
+          if (action) {
             returnValue = action.param;
+          }
+
+          // Set the actiontype only if the user is not overriding actions.
+          if (action && this._noActionsKeys.size == 0) {
             this.setAttribute("actiontype", action.type);
           } else {
             this.removeAttribute("actiontype");
           }
           return returnValue;
         ]]></body>
       </method>
 
@@ -683,24 +686,24 @@
             return null;
 
           // url is in the format moz-action:ACTION,PARAM
           let [, action, param] = aUrl.match(/^moz-action:([^,]+),(.*)$/);
           return {type: action, param: param};
         ]]></body>
       </method>
 
-      <field name="_numNoActionsKeys"><![CDATA[
-        0
+      <field name="_noActionsKeys"><![CDATA[
+        new Set();
       ]]></field>
 
       <method name="_clearNoActions">
         <parameter name="aURL"/>
         <body><![CDATA[
-          this._numNoActionsKeys = 0;
+          this._noActionsKeys.clear();
           this.popup.removeAttribute("noactions");
           let action = this._parseActionUrl(this._value);
           if (action)
             this.setAttribute("actiontype", action.type);
         ]]></body>
       </method>
 
       <method name="selectTextRange">
@@ -712,29 +715,32 @@
         ]]></body>
       </method>
     </implementation>
 
     <handlers>
       <handler event="keydown"><![CDATA[
         if ((event.keyCode === KeyEvent.DOM_VK_ALT ||
              event.keyCode === KeyEvent.DOM_VK_SHIFT) &&
-            this.popup.selectedIndex >= 0) {
-          this._numNoActionsKeys++;
-          this.popup.setAttribute("noactions", "true");
-          this.removeAttribute("actiontype");
+            this.popup.selectedIndex >= 0 &&
+            !this._noActionsKeys.has(event.keyCode)) {
+          if (this._noActionsKeys.size == 0) {
+            this.popup.setAttribute("noactions", "true");
+            this.removeAttribute("actiontype");
+          }
+          this._noActionsKeys.add(event.keyCode);
         }
       ]]></handler>
 
       <handler event="keyup"><![CDATA[
         if ((event.keyCode === KeyEvent.DOM_VK_ALT ||
              event.keyCode === KeyEvent.DOM_VK_SHIFT) &&
-            this._numNoActionsKeys > 0) {
-          this._numNoActionsKeys--;
-          if (this._numNoActionsKeys == 0)
+            this._noActionsKeys.has(event.keyCode)) {
+          this._noActionsKeys.delete(event.keyCode);
+          if (this._noActionsKeys.size == 0)
             this._clearNoActions();
         }
       ]]></handler>
 
       <handler event="blur"><![CDATA[
         this._clearNoActions();
         this.formatValue();
       ]]></handler>