Bug 1331971 - Can't navigate out of style editor content window using keyboard. r?yzen draft
authorNancy Pang <npang@mozilla.com>
Wed, 18 Jan 2017 16:15:42 -0500
changeset 463326 81a7cdc831cb752cc43e9de594f7f399c57104fa
parent 463183 20d71b8cba1558f8b55a3c07e8b4d5ea91b9288b
child 542638 fefffc6acfd65f619e728ff9888d7d79599d7b5f
push id42023
push userbmo:npang@mozilla.com
push dateWed, 18 Jan 2017 21:16:05 +0000
reviewersyzen
bugs1331971
milestone53.0a1
Bug 1331971 - Can't navigate out of style editor content window using keyboard. r?yzen MozReview-Commit-ID: 14mNmuLF35h
devtools/client/sourceeditor/editor.js
devtools/client/styleeditor/test/browser.ini
devtools/client/styleeditor/test/browser_styleeditor_sourceditor_keyboard_navigation.js
--- a/devtools/client/sourceeditor/editor.js
+++ b/devtools/client/sourceeditor/editor.js
@@ -362,16 +362,20 @@ Editor.prototype = {
       } else if (ev.deltaMode == ev.DOM_DELTA_PAGE) {
         deltaX *= cm.getWrapperElement().clientWidth;
         deltaY *= cm.getWrapperElement().clientHeight;
       }
 
       cm.getScrollerElement().scrollBy(deltaX, deltaY);
     });
 
+    // Make code conatiner focusable
+    cm.getWrapperElement().tabIndex = 0;
+    cm.getWrapperElement().addEventListener("keydown", e => this.onKeyDown(e), true);
+
     cm.getWrapperElement().addEventListener("contextmenu", ev => {
       ev.preventDefault();
 
       if (!this.config.contextMenu) {
         return;
       }
 
       let popup = this.config.contextMenu;
@@ -486,16 +490,36 @@ Editor.prototype = {
     // turn it off and back on again so the proper mode can be used.
     if (this.config.autocomplete) {
       this.setOption("autocomplete", false);
       this.setOption("autocomplete", true);
     }
   },
 
   /**
+   * Handles keyboard navigation
+   * - Focuses on editor code container when Escape is pressed
+   * - Focuses on editor code text area when Enter is pressed
+   */
+  onKeyDown: function (e) {
+    let {key, target} = e;
+    let codeWrapper = this.codeMirror.getWrapperElement();
+
+    if (key === "Escape") {
+      e.stopPropagation();
+      e.preventDefault();
+      codeWrapper.focus();
+    } else if (key === "Enter" && target == codeWrapper) {
+      e.preventDefault();
+      // Focus into editor's text area
+      codeWrapper.firstChild.firstChild.focus();
+    }
+  },
+
+  /**
    * Returns text from the text area. If line argument is provided
    * the method returns only that line.
    */
   getText: function (line) {
     let cm = editors.get(this);
 
     if (line == null) {
       return cm.getValue();
--- a/devtools/client/styleeditor/test/browser.ini
+++ b/devtools/client/styleeditor/test/browser.ini
@@ -88,16 +88,17 @@ skip-if = e10s && debug # Bug 1252201 - 
 [browser_styleeditor_opentab.js]
 [browser_styleeditor_pretty.js]
 [browser_styleeditor_private_perwindowpb.js]
 [browser_styleeditor_reload.js]
 [browser_styleeditor_scroll.js]
 [browser_styleeditor_sv_keynav.js]
 [browser_styleeditor_sv_resize.js]
 [browser_styleeditor_selectstylesheet.js]
+[browser_styleeditor_sourceditor_keyboard_navigation.js]
 [browser_styleeditor_sourcemaps.js]
 [browser_styleeditor_sourcemaps_inline.js]
 [browser_styleeditor_sourcemap_large.js]
 [browser_styleeditor_sourcemap_watching.js]
 [browser_styleeditor_sync.js]
 [browser_styleeditor_syncAddProperty.js]
 [browser_styleeditor_syncAddRule.js]
 [browser_styleeditor_syncAlreadyOpen.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/styleeditor/test/browser_styleeditor_sourceditor_keyboard_navigation.js
@@ -0,0 +1,29 @@
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+"use strict";
+
+// Test that tests keyboard navigation out and into style editor
+
+const TESTCASE_URI = TEST_BASE_HTTPS + "simple.html";
+
+const LINE_NO = 0;
+const COL_NO = 0;
+
+add_task(function* () {
+  let { ui } = yield openStyleEditorForURL(TESTCASE_URI);
+  let doc = ui._panelDoc.getElementsByTagName("iframe")[0].contentDocument;
+  let editor = ui.editors[0];
+
+  let codeContainer = doc.querySelector(".CodeMirror");
+  let textArea = doc.querySelector("textarea");
+
+  info("Select the first style sheet");
+  yield ui.selectStyleSheet(editor.styleSheet, LINE_NO, COL_NO);
+
+  EventUtils.synthesizeKey("VK_ESCAPE", {});
+  is(codeContainer, doc.activeElement, "Container is focused");
+
+  EventUtils.synthesizeKey("VK_RETURN", {});
+  is(textArea, doc.activeElement, "Editor is enabled");
+});