Backed out 2 changesets (bug 1545766, bug 1546633) for causing browser_PanelMultiView_keyboard.js to perma fail CLOSED TREE
authorCiure Andrei <aciure@mozilla.com>
Wed, 01 May 2019 09:02:48 +0300
changeset 472066 47ea779dc66b06fdcc4a247fbe29bf9770cefa8b
parent 472065 041741ce164674137968c39aab0a9c80e84c99db
child 472067 38c57ccca71e24c90e73bfd2a06bd6a1de6b17db
push id84447
push useraciure@mozilla.com
push dateWed, 01 May 2019 06:03:20 +0000
treeherderautoland@47ea779dc66b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1545766, 1546633
milestone68.0a1
backs out041741ce164674137968c39aab0a9c80e84c99db
fbc294a6fe785b56a5ef52b5b1ea61d511bebc52
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
Backed out 2 changesets (bug 1545766, bug 1546633) for causing browser_PanelMultiView_keyboard.js to perma fail CLOSED TREE Backed out changeset 041741ce1646 (bug 1546633) Backed out changeset fbc294a6fe78 (bug 1545766)
browser/components/customizableui/PanelMultiView.jsm
browser/components/customizableui/test/browser_PanelMultiView_keyboard.js
--- a/browser/components/customizableui/PanelMultiView.jsm
+++ b/browser/components/customizableui/PanelMultiView.jsm
@@ -1406,19 +1406,17 @@ var PanelView = class extends Associated
 
   /**
    * Determine whether an element can only be navigated to with tab/shift+tab,
    * not the arrow keys.
    */
   _isNavigableWithTabOnly(element) {
     let tag = element.localName;
     return tag == "menulist" || tag == "textbox" || tag == "input"
-           || tag == "textarea"
-           // Allow tab to reach embedded documents in extension panels.
-           || tag == "browser";
+           || tag == "textarea";
   }
 
   /**
    * Make a TreeWalker for keyboard navigation.
    *
    * @param {Boolean} arrowKey If `true`, elements only navigable with tab are
    *        excluded.
    */
@@ -1562,48 +1560,43 @@ var PanelView = class extends Associated
    *
    * @param {KeyEvent} event
    */
   keyNavigation(event) {
     if (!this.active) {
       return;
     }
 
-    let focus = this.document.activeElement;
-    // Make sure the focus is actually inside the panel. (It might not be if
-    // the panel was opened with the mouse.) If it isn't, we don't care
-    // about it for our purposes.
-    // We use Node.compareDocumentPosition because Node.contains doesn't
-    // behave as expected for anonymous content; e.g. the input inside a
-    // textbox.
-    if (focus && !(this.node.compareDocumentPosition(focus)
-                   & Node.DOCUMENT_POSITION_CONTAINED_BY)) {
-      focus = null;
-    }
-
-    // Extension panels contain embedded documents. We can't manage
-    // keyboard navigation within those.
-    if (focus && focus.tagName == "browser") {
-      return;
-    }
-
     let stop = () => {
       event.stopPropagation();
       event.preventDefault();
     };
 
     // If the focused element is only navigable with tab, it wants the arrow
     // keys, etc. We shouldn't handle any keys except tab and shift+tab.
     // We make a function for this for performance reasons: we only want to
     // check this for keys we potentially care about, not *all* keys.
     let tabOnly = () => {
       // We use the real focus rather than this.selectedElement because focus
       // might have been moved without keyboard navigation (e.g. mouse click)
       // and this.selectedElement is only updated for keyboard navigation.
-      return focus && this._isNavigableWithTabOnly(focus);
+      let focus = this.document.activeElement;
+      if (!focus) {
+        return false;
+      }
+      // Make sure the focus is actually inside the panel.
+      // (It might not be if the panel was opened with the mouse.)
+      // We use Node.compareDocumentPosition because Node.contains doesn't
+      // behave as expected for anonymous content; e.g. the input inside a
+      // textbox.
+      if (!(this.node.compareDocumentPosition(focus)
+            & Node.DOCUMENT_POSITION_CONTAINED_BY)) {
+        return false;
+      }
+      return this._isNavigableWithTabOnly(focus);
     };
 
     let keyCode = event.code;
     switch (keyCode) {
       case "ArrowDown":
       case "ArrowUp":
         if (tabOnly()) {
           break;
@@ -1659,27 +1652,22 @@ var PanelView = class extends Associated
         let button = this.selectedElement;
         if (!button)
           break;
         stop();
 
         this._doingKeyboardActivation = true;
         // Unfortunately, 'tabindex' doesn't execute the default action, so
         // we explicitly do this here.
-        // We are sending a command event, a mousedown event and then a click
-        // event. This is done in order to mimic a "real" mouse click event.
-        // Normally, the command event executes the action, then the click event
-        // closes the menu. However, in some cases (e.g. the Library button),
-        // there is no command event handler and the mousedown event executes the
-        // action instead.
+        // We are sending a command event and then a click event.
+        // This is done in order to mimic a "real" mouse click event.
+        // The command event executes the action, then the click event closes the menu.
         button.doCommand();
-        let dispEvent = new event.target.ownerGlobal.MouseEvent("mousedown", {"bubbles": true});
-        button.dispatchEvent(dispEvent);
-        dispEvent = new event.target.ownerGlobal.MouseEvent("click", {"bubbles": true});
-        button.dispatchEvent(dispEvent);
+        let clickEvent = new event.target.ownerGlobal.MouseEvent("click", {"bubbles": true});
+        button.dispatchEvent(clickEvent);
         this._doingKeyboardActivation = false;
         break;
       }
     }
   }
 
   /**
    * Focus the last selected element in the view, if any.
--- a/browser/components/customizableui/test/browser_PanelMultiView_keyboard.js
+++ b/browser/components/customizableui/test/browser_PanelMultiView_keyboard.js
@@ -18,35 +18,32 @@ let gMainMenulist;
 let gMainTextbox;
 let gMainButton2;
 let gMainButton3;
 let gMainTabOrder;
 let gMainArrowOrder;
 let gSubView;
 let gSubButton;
 let gSubTextarea;
-let gDocView;
-let gDocBrowser;
 
 async function openPopup() {
   let shown = BrowserTestUtils.waitForEvent(gMainView, "ViewShown");
   PanelMultiView.openPopup(gPanel, gAnchor, "bottomcenter topright");
   await shown;
 }
 
 async function hidePopup() {
   let hidden = BrowserTestUtils.waitForEvent(gPanel, "popuphidden");
   PanelMultiView.hidePopup(gPanel);
   await hidden;
 }
 
-async function showSubView(view = gSubView) {
-  let shown = BrowserTestUtils.waitForEvent(view, "ViewShown");
-  // We must show with an anchor so the Back button is generated.
-  gPanelMultiView.showSubView(view, gMainButton1);
+async function showSubView() {
+  let shown = BrowserTestUtils.waitForEvent(gSubView, "ViewShown");
+  gPanelMultiView.showSubView(gSubView);
   await shown;
 }
 
 async function expectFocusAfterKey(aKey, aFocus) {
   let res = aKey.match(/^(Shift\+)?(.+)$/);
   let shift = Boolean(res[1]);
   let key;
   if (res[2].length == 1) {
@@ -72,18 +69,16 @@ add_task(async function setup() {
   gPanel.appendChild(gPanelMultiView);
 
   gMainView = document.createXULElement("panelview");
   gMainView.id = "testMainView";
   gPanelMultiView.appendChild(gMainView);
   gMainButton1 = document.createXULElement("button");
   gMainButton1.id = "gMainButton1";
   gMainView.appendChild(gMainButton1);
-  // We use this for anchoring subviews, so it must have a label.
-  gMainButton1.setAttribute("label", "gMainButton1");
   gMainMenulist = document.createXULElement("menulist");
   gMainMenulist.id = "gMainMenulist";
   gMainView.appendChild(gMainMenulist);
   let menuPopup = document.createXULElement("menupopup");
   gMainMenulist.appendChild(menuPopup);
   let item = document.createXULElement("menuitem");
   item.setAttribute("value", "1");
   item.setAttribute("selected", "true");
@@ -111,28 +106,16 @@ add_task(async function setup() {
   gSubButton = document.createXULElement("button");
   gSubView.appendChild(gSubButton);
   gSubTextarea = document.createElementNS("http://www.w3.org/1999/xhtml",
                                           "textarea");
   gSubTextarea.id = "gSubTextarea";
   gSubView.appendChild(gSubTextarea);
   gSubTextarea.value = "value";
 
-  gDocView = document.createXULElement("panelview");
-  gDocView.id = "testDocView";
-  gPanelMultiView.appendChild(gDocView);
-  gDocBrowser = document.createXULElement("browser");
-  gDocBrowser.id = "gDocBrowser";
-  gDocBrowser.setAttribute("type", "content");
-  gDocBrowser.setAttribute("src",
-    'data:text/html,<textarea id="docTextarea">value</textarea><button id="docButton"></button>');
-  gDocBrowser.setAttribute("width", 100);
-  gDocBrowser.setAttribute("height", 100);
-  gDocView.appendChild(gDocBrowser);
-
   registerCleanupFunction(() => {
     gAnchor.remove();
     gPanel.remove();
   });
 });
 
 // Test that the tab key focuses all expected controls.
 add_task(async function testTab() {
@@ -282,53 +265,8 @@ add_task(async function testActivation()
   }
   await openPopup();
   await expectFocusAfterKey("ArrowDown", gMainButton1);
   checkActivated(gMainButton1, () => EventUtils.synthesizeKey("KEY_Enter"), "pressing enter");
   checkActivated(gMainButton1, () => EventUtils.synthesizeKey(" "), "pressing space");
   checkActivated(gMainButton1, () => EventUtils.synthesizeKey("KEY_Enter", {code: "NumpadEnter"}), "pressing numpad enter");
   await hidePopup();
 });
-
-// Test that keyboard activation works for buttons responding to mousedown
-// events (instead of command or click). The Library button does this, for
-// example.
-add_task(async function testActivationMousedown() {
-  await openPopup();
-  await expectFocusAfterKey("ArrowDown", gMainButton1);
-  let activated = false;
-  gMainButton1.onmousedown = function() { activated = true; };
-  EventUtils.synthesizeKey(" ");
-  ok(activated, "mousedown activated after space");
-  gMainButton1.onmousedown = null;
-  await hidePopup();
-});
-
-// Test that tab and the arrow keys aren't overridden in embedded documents.
-add_task(async function testTabArrowsBrowser() {
-  await openPopup();
-  await showSubView(gDocView);
-  let backButton = gDocView.querySelector(".subviewbutton-back");
-  backButton.id = "docBack";
-  await expectFocusAfterKey("Tab", backButton);
-  let doc = gDocBrowser.contentDocument;
-  // Documents don't have an id property, but expectFocusAfterKey wants one.
-  doc.id = "doc";
-  await expectFocusAfterKey("Tab", doc);
-  // Make sure tab/arrows aren't overridden within the embedded document.
-  let textarea = doc.getElementById("docTextarea");
-  // Tab should really focus the textarea, but default tab handling seems to
-  // skip everything inside the browser element when run in this test. This
-  // behaves as expected in real panels, though. Force focus to the textarea
-  // and then test from there.
-  textarea.focus();
-  is(doc.activeElement, textarea, "textarea focused");
-  EventUtils.synthesizeKey("KEY_End");
-  is(textarea.selectionStart, 5, "selectionStart 5 after End");
-  EventUtils.synthesizeKey("KEY_ArrowLeft");
-  is(textarea.selectionStart, 4, "selectionStart 4 after ArrowLeft");
-  is(doc.activeElement, textarea, "textarea still focused");
-  let docButton = doc.getElementById("docButton");
-  expectFocusAfterKey("Tab", docButton);
-  // Make sure tab leaves the document and reaches the Back button.
-  expectFocusAfterKey("Tab", backButton);
-  await hidePopup();
-});