diff --git a/devtools/client/animationinspector/animation-panel.js b/devtools/client/animationinspector/animation-panel.js index 5113393c32cd..4182d5fecfa1 100644 --- a/devtools/client/animationinspector/animation-panel.js +++ b/devtools/client/animationinspector/animation-panel.js @@ -12,6 +12,7 @@ const {AnimationsTimeline} = require("devtools/client/animationinspector/components/animation-timeline"); const {RateSelector} = require("devtools/client/animationinspector/components/rate-selector"); const {formatStopwatchTime} = require("devtools/client/animationinspector/utils"); +const {KeyCodes} = require("devtools/client/shared/keycodes"); var $ = (selector, target = document) => target.querySelector(selector); @@ -162,12 +163,10 @@ var AnimationsPanel = { }, onKeyDown: function (event) { - let keyEvent = Ci.nsIDOMKeyEvent; - // If the space key is pressed, it should toggle the play state of // the animations displayed in the panel, or of all the animations on // the page if the selected node does not have any animation on it. - if (event.keyCode === keyEvent.DOM_VK_SPACE) { + if (event.keyCode === KeyCodes.DOM_VK_SPACE) { if (AnimationsController.animationPlayers.length > 0) { this.playPauseTimeline().catch(ex => console.error(ex)); } else { diff --git a/devtools/client/debugger/content/views/sources-view.js b/devtools/client/debugger/content/views/sources-view.js index 7fa2f6d8072e..81610b560d3e 100644 --- a/devtools/client/debugger/content/views/sources-view.js +++ b/devtools/client/debugger/content/views/sources-view.js @@ -28,6 +28,7 @@ const { const { Task } = require("devtools/shared/task"); const { SideMenuWidget } = require("resource://devtools/client/shared/widgets/SideMenuWidget.jsm"); const { gDevTools } = require("devtools/client/framework/devtools"); +const {KeyCodes} = require("devtools/client/shared/keycodes"); const NEW_SOURCE_DISPLAY_DELAY = 200; // ms const FUNCTION_SEARCH_POPUP_POSITION = "topcenter bottomleft"; @@ -1206,7 +1207,7 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, { * The keypress listener for the breakpoints conditional expression textbox. */ _onConditionalTextboxKeyPress: function (e) { - if (e.keyCode == e.DOM_VK_RETURN) { + if (e.keyCode == KeyCodes.DOM_VK_RETURN) { this._hideConditionalPopup(); } }, diff --git a/devtools/client/debugger/views/filter-view.js b/devtools/client/debugger/views/filter-view.js index a1ebc70ab1fa..460b1201cdaa 100644 --- a/devtools/client/debugger/views/filter-view.js +++ b/devtools/client/debugger/views/filter-view.js @@ -9,7 +9,6 @@ /* globals document, window */ "use strict"; - /** * Functions handling the filtering UI. */ @@ -321,15 +320,15 @@ FilterView.prototype = { // Return, enter, down and up keys focus next or previous matches, while // the escape key switches focus from the search container. else switch (e.keyCode) { - case e.DOM_VK_RETURN: + case KeyCodes.DOM_VK_RETURN: var isReturnKey = true; // If the shift key is pressed, focus on the previous result actionToPerform = e.shiftKey ? "selectPrev" : "selectNext"; break; - case e.DOM_VK_DOWN: + case KeyCodes.DOM_VK_DOWN: actionToPerform = "selectNext"; break; - case e.DOM_VK_UP: + case KeyCodes.DOM_VK_UP: actionToPerform = "selectPrev"; break; } diff --git a/devtools/client/debugger/views/watch-expressions-view.js b/devtools/client/debugger/views/watch-expressions-view.js index 277921144bcf..59d3ad5a0645 100644 --- a/devtools/client/debugger/views/watch-expressions-view.js +++ b/devtools/client/debugger/views/watch-expressions-view.js @@ -9,6 +9,8 @@ /* globals document */ "use strict"; +const {KeyCodes} = require("devtools/client/shared/keycodes"); + /** * Functions handling the watch expressions UI. */ @@ -289,8 +291,8 @@ WatchExpressionsView.prototype = Heritage.extend(WidgetMethods, { */ _onKeyPress: function (e) { switch (e.keyCode) { - case e.DOM_VK_RETURN: - case e.DOM_VK_ESCAPE: + case KeyCodes.DOM_VK_RETURN: + case KeyCodes.DOM_VK_ESCAPE: e.stopPropagation(); this.DebuggerView.editor.focus(); } diff --git a/devtools/client/framework/toolbox.js b/devtools/client/framework/toolbox.js index b055b97eb1a3..21b84af140e6 100644 --- a/devtools/client/framework/toolbox.js +++ b/devtools/client/framework/toolbox.js @@ -27,6 +27,7 @@ var { attachThread, detachThread } = require("./attach-thread"); var Menu = require("devtools/client/framework/menu"); var MenuItem = require("devtools/client/framework/menu-item"); var { DOMHelpers } = require("resource://devtools/client/shared/DOMHelpers.jsm"); +const { KeyCodes } = require("devtools/client/shared/keycodes"); const { BrowserLoader } = Cu.import("resource://devtools/client/shared/browser-loader.js", {}); @@ -549,7 +550,7 @@ Toolbox.prototype = { }, _splitConsoleOnKeypress: function (e) { - if (e.keyCode === e.DOM_VK_ESCAPE) { + if (e.keyCode === KeyCodes.DOM_VK_ESCAPE) { this.toggleSplitConsole(); // If the debugger is paused, don't let the ESC key stop any pending // navigation. diff --git a/devtools/client/inspector/inspector-search.js b/devtools/client/inspector/inspector-search.js index da400b8d128c..460465197612 100644 --- a/devtools/client/inspector/inspector-search.js +++ b/devtools/client/inspector/inspector-search.js @@ -6,6 +6,7 @@ const promise = require("promise"); const {Task} = require("devtools/shared/task"); +const {KeyCodes} = require("devtools/client/shared/keycodes"); const system = require("devtools/shared/system"); const EventEmitter = require("devtools/shared/event-emitter"); @@ -119,13 +120,13 @@ InspectorSearch.prototype = { this.searchClearButton.hidden = false; this.searchBox.setAttribute("filled", true); } - if (event.keyCode === event.DOM_VK_RETURN) { + if (event.keyCode === KeyCodes.DOM_VK_RETURN) { this._onSearch(event.shiftKey); } const modifierKey = system.constants.platform === "macosx" ? event.metaKey : event.ctrlKey; - if (event.keyCode === event.DOM_VK_G && modifierKey) { + if (event.keyCode === KeyCodes.DOM_VK_G && modifierKey) { this._onSearch(event.shiftKey); event.preventDefault(); } @@ -329,8 +330,8 @@ SelectorAutocompleter.prototype = { let popup = this.searchPopup; switch (event.keyCode) { - case event.DOM_VK_RETURN: - case event.DOM_VK_TAB: + case KeyCodes.DOM_VK_RETURN: + case KeyCodes.DOM_VK_TAB: if (popup.isOpen) { if (popup.selectedItem) { this.searchBox.value = popup.selectedItem.label; @@ -345,7 +346,7 @@ SelectorAutocompleter.prototype = { } break; - case event.DOM_VK_UP: + case KeyCodes.DOM_VK_UP: if (popup.isOpen && popup.itemCount > 0) { if (popup.selectedIndex === 0) { popup.selectedIndex = popup.itemCount - 1; @@ -356,7 +357,7 @@ SelectorAutocompleter.prototype = { } break; - case event.DOM_VK_DOWN: + case KeyCodes.DOM_VK_DOWN: if (popup.isOpen && popup.itemCount > 0) { if (popup.selectedIndex === popup.itemCount - 1) { popup.selectedIndex = 0; @@ -367,7 +368,7 @@ SelectorAutocompleter.prototype = { } break; - case event.DOM_VK_ESCAPE: + case KeyCodes.DOM_VK_ESCAPE: if (popup.isOpen) { this.hidePopup(); } diff --git a/devtools/client/inspector/markup/markup.js b/devtools/client/inspector/markup/markup.js index 34416da97fb6..e9114f406008 100644 --- a/devtools/client/inspector/markup/markup.js +++ b/devtools/client/inspector/markup/markup.js @@ -60,6 +60,7 @@ const nodeFilterConstants = require("devtools/shared/dom-node-filter-constants") const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm"); /* eslint-enable mozilla/reject-some-requires */ const {getCssProperties} = require("devtools/shared/fronts/css-properties"); +const {KeyCodes} = require("devtools/client/shared/keycodes"); const {AutocompletePopup} = require("devtools/client/shared/autocomplete-popup"); @@ -2273,12 +2274,12 @@ MarkupContainer.prototype = { // Ignore all keystrokes that originated in editors except for when 'Tab' is // pressed. - if (isInput && keyCode !== event.DOM_VK_TAB) { + if (isInput && keyCode !== KeyCodes.DOM_VK_TAB) { return; } switch (keyCode) { - case event.DOM_VK_TAB: + case KeyCodes.DOM_VK_TAB: // Only handle 'Tab' if tabbable element is on the edge (first or last). if (isInput) { // Corresponding tabbable element is editor's next sibling. @@ -2299,7 +2300,7 @@ MarkupContainer.prototype = { } } break; - case event.DOM_VK_ESCAPE: + case KeyCodes.DOM_VK_ESCAPE: this.clearFocus(); this.markup.getContainer(this.markup._rootNode).elt.focus(); if (this.isDragging) { diff --git a/devtools/client/inspector/shared/utils.js b/devtools/client/inspector/shared/utils.js index b4c4e626bb2d..01064153cbff 100644 --- a/devtools/client/inspector/shared/utils.js +++ b/devtools/client/inspector/shared/utils.js @@ -6,12 +6,10 @@ "use strict"; -/* eslint-disable mozilla/reject-some-requires */ -const {Ci} = require("chrome"); -/* eslint-enable mozilla/reject-some-requires */ const {parseDeclarations} = require("devtools/shared/css-parsing-utils"); const promise = require("promise"); const {getCSSLexer} = require("devtools/shared/css-lexer"); +const {KeyCodes} = require("devtools/client/shared/keycodes"); const HTML_NS = "http://www.w3.org/1999/xhtml"; @@ -75,7 +73,7 @@ exports.appendText = appendText; */ function advanceValidate(keyCode, value, insertionPoint) { // Only ";" has special handling here. - if (keyCode !== Ci.nsIDOMKeyEvent.DOM_VK_SEMICOLON) { + if (keyCode !== KeyCodes.DOM_VK_SEMICOLON) { return false; } diff --git a/devtools/client/shared/SplitView.jsm b/devtools/client/shared/SplitView.jsm index b882995aff09..f72aad2ac90e 100644 --- a/devtools/client/shared/SplitView.jsm +++ b/devtools/client/shared/SplitView.jsm @@ -5,6 +5,10 @@ "use strict"; +const Cu = Components.utils; +const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); +const {KeyCodes} = require("devtools/client/shared/keycodes"); + this.EXPORTED_SYMBOLS = ["SplitView"]; /* this must be kept in sync with CSS (ie. splitview.css) */ @@ -56,16 +60,16 @@ this.SplitView = function SplitView(aRoot) // handle keyboard navigation within the items list let newFocusOrdinal; - if (aEvent.keyCode == aEvent.DOM_VK_PAGE_UP || - aEvent.keyCode == aEvent.DOM_VK_HOME) { + if (aEvent.keyCode == KeyCodes.DOM_VK_PAGE_UP || + aEvent.keyCode == KeyCodes.DOM_VK_HOME) { newFocusOrdinal = 0; - } else if (aEvent.keyCode == aEvent.DOM_VK_PAGE_DOWN || - aEvent.keyCode == aEvent.DOM_VK_END) { + } else if (aEvent.keyCode == KeyCodes.DOM_VK_PAGE_DOWN || + aEvent.keyCode == KeyCodes.DOM_VK_END) { newFocusOrdinal = this._nav.childNodes.length - 1; - } else if (aEvent.keyCode == aEvent.DOM_VK_UP) { + } else if (aEvent.keyCode == KeyCodes.DOM_VK_UP) { newFocusOrdinal = getFocusedItemWithin(this._nav).getAttribute("data-ordinal"); newFocusOrdinal--; - } else if (aEvent.keyCode == aEvent.DOM_VK_DOWN) { + } else if (aEvent.keyCode == KeyCodes.DOM_VK_DOWN) { newFocusOrdinal = getFocusedItemWithin(this._nav).getAttribute("data-ordinal"); newFocusOrdinal++; } diff --git a/devtools/client/shared/inplace-editor.js b/devtools/client/shared/inplace-editor.js index adf9abce4cac..0be14ab1f3ac 100644 --- a/devtools/client/shared/inplace-editor.js +++ b/devtools/client/shared/inplace-editor.js @@ -26,6 +26,7 @@ const {Ci, Cc} = require("chrome"); const Services = require("Services"); const focusManager = Services.focus; +const {KeyCodes} = require("devtools/client/shared/keycodes"); const HTML_NS = "http://www.w3.org/1999/xhtml"; const CONTENT_TYPES = { @@ -48,7 +49,7 @@ const { findMostRelevantCssPropertyIndex } = require("./suggestion-picker"); /** * Helper to check if the provided key matches one of the expected keys. - * Keys will be prefixed with DOM_VK_ and should match a key in nsIDOMKeyEvent. + * Keys will be prefixed with DOM_VK_ and should match a key in KeyCodes. * * @param {String} key * the key to check (can be a keyCode). @@ -58,7 +59,7 @@ const { findMostRelevantCssPropertyIndex } = require("./suggestion-picker"); */ function isKeyIn(key, ...keys) { return keys.some(expectedKey => { - return key === Ci.nsIDOMKeyEvent["DOM_VK_" + expectedKey]; + return key === KeyCodes["DOM_VK_" + expectedKey]; }); } diff --git a/devtools/client/shared/key-shortcuts.js b/devtools/client/shared/key-shortcuts.js index a6a457462dd8..f1bc9bf809f4 100644 --- a/devtools/client/shared/key-shortcuts.js +++ b/devtools/client/shared/key-shortcuts.js @@ -7,6 +7,7 @@ const Services = require("Services"); const EventEmitter = require("devtools/shared/event-emitter"); const isOSX = Services.appinfo.OS === "Darwin"; +const {KeyCodes} = require("devtools/client/shared/keycodes"); // List of electron keys mapped to DOM API (DOM_VK_*) key code const ElectronKeysMapping = { @@ -139,7 +140,7 @@ KeyShortcuts.parseElectronKey = function (window, str) { } else if (key in ElectronKeysMapping) { // Maps the others manually to DOM API DOM_VK_* key = ElectronKeysMapping[key]; - shortcut.keyCode = window.KeyboardEvent[key]; + shortcut.keyCode = KeyCodes[key]; // Used only to stringify the shortcut shortcut.keyCodeString = key; } else { diff --git a/devtools/client/shared/keycodes.js b/devtools/client/shared/keycodes.js new file mode 100644 index 000000000000..fe4764dbe26a --- /dev/null +++ b/devtools/client/shared/keycodes.js @@ -0,0 +1,146 @@ +/* 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/. */ + +"use strict"; + +// This was copied (and slightly modified) from +// devtools/shared/gcli/source/lib/gcli/util/util.js, which in turn +// says: + +/** + * Keyboard handling is a mess. http://unixpapa.com/js/key.html + * It would be good to use DOM L3 Keyboard events, + * http://www.w3.org/TR/2010/WD-DOM-Level-3-Events-20100907/#events-keyboardevents + * however only Webkit supports them, and there isn't a shim on Modernizr: + * https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills + * and when the code that uses this KeyEvent was written, nothing was clear, + * so instead, we're using this unmodern shim: + * http://stackoverflow.com/questions/5681146/chrome-10-keyevent-or-something-similar-to-firefoxs-keyevent + * See BUG 664991: GCLI's keyboard handling should be updated to use DOM-L3 + * https://bugzilla.mozilla.org/show_bug.cgi?id=664991 + */ + +exports.KeyCodes = { + DOM_VK_CANCEL: 3, + DOM_VK_HELP: 6, + DOM_VK_BACK_SPACE: 8, + DOM_VK_TAB: 9, + DOM_VK_CLEAR: 12, + DOM_VK_RETURN: 13, + DOM_VK_SHIFT: 16, + DOM_VK_CONTROL: 17, + DOM_VK_ALT: 18, + DOM_VK_PAUSE: 19, + DOM_VK_CAPS_LOCK: 20, + DOM_VK_ESCAPE: 27, + DOM_VK_SPACE: 32, + DOM_VK_PAGE_UP: 33, + DOM_VK_PAGE_DOWN: 34, + DOM_VK_END: 35, + DOM_VK_HOME: 36, + DOM_VK_LEFT: 37, + DOM_VK_UP: 38, + DOM_VK_RIGHT: 39, + DOM_VK_DOWN: 40, + DOM_VK_PRINTSCREEN: 44, + DOM_VK_INSERT: 45, + DOM_VK_DELETE: 46, + DOM_VK_0: 48, + DOM_VK_1: 49, + DOM_VK_2: 50, + DOM_VK_3: 51, + DOM_VK_4: 52, + DOM_VK_5: 53, + DOM_VK_6: 54, + DOM_VK_7: 55, + DOM_VK_8: 56, + DOM_VK_9: 57, + DOM_VK_SEMICOLON: 59, + DOM_VK_EQUALS: 61, + DOM_VK_A: 65, + DOM_VK_B: 66, + DOM_VK_C: 67, + DOM_VK_D: 68, + DOM_VK_E: 69, + DOM_VK_F: 70, + DOM_VK_G: 71, + DOM_VK_H: 72, + DOM_VK_I: 73, + DOM_VK_J: 74, + DOM_VK_K: 75, + DOM_VK_L: 76, + DOM_VK_M: 77, + DOM_VK_N: 78, + DOM_VK_O: 79, + DOM_VK_P: 80, + DOM_VK_Q: 81, + DOM_VK_R: 82, + DOM_VK_S: 83, + DOM_VK_T: 84, + DOM_VK_U: 85, + DOM_VK_V: 86, + DOM_VK_W: 87, + DOM_VK_X: 88, + DOM_VK_Y: 89, + DOM_VK_Z: 90, + DOM_VK_CONTEXT_MENU: 93, + DOM_VK_NUMPAD0: 96, + DOM_VK_NUMPAD1: 97, + DOM_VK_NUMPAD2: 98, + DOM_VK_NUMPAD3: 99, + DOM_VK_NUMPAD4: 100, + DOM_VK_NUMPAD5: 101, + DOM_VK_NUMPAD6: 102, + DOM_VK_NUMPAD7: 103, + DOM_VK_NUMPAD8: 104, + DOM_VK_NUMPAD9: 105, + DOM_VK_MULTIPLY: 106, + DOM_VK_ADD: 107, + DOM_VK_SEPARATOR: 108, + DOM_VK_SUBTRACT: 109, + DOM_VK_DECIMAL: 110, + DOM_VK_DIVIDE: 111, + DOM_VK_F1: 112, + DOM_VK_F2: 113, + DOM_VK_F3: 114, + DOM_VK_F4: 115, + DOM_VK_F5: 116, + DOM_VK_F6: 117, + DOM_VK_F7: 118, + DOM_VK_F8: 119, + DOM_VK_F9: 120, + DOM_VK_F10: 121, + DOM_VK_F11: 122, + DOM_VK_F12: 123, + DOM_VK_F13: 124, + DOM_VK_F14: 125, + DOM_VK_F15: 126, + DOM_VK_F16: 127, + DOM_VK_F17: 128, + DOM_VK_F18: 129, + DOM_VK_F19: 130, + DOM_VK_F20: 131, + DOM_VK_F21: 132, + DOM_VK_F22: 133, + DOM_VK_F23: 134, + DOM_VK_F24: 135, + DOM_VK_NUM_LOCK: 144, + DOM_VK_SCROLL_LOCK: 145, + DOM_VK_COMMA: 188, + DOM_VK_PERIOD: 190, + DOM_VK_SLASH: 191, + DOM_VK_BACK_QUOTE: 192, + DOM_VK_OPEN_BRACKET: 219, + DOM_VK_BACK_SLASH: 220, + DOM_VK_CLOSE_BRACKET: 221, + DOM_VK_QUOTE: 222, + DOM_VK_META: 224, + + // A few that did not appear in gcli, but that are apparently used + // in devtools. + DOM_VK_COLON: 58, + DOM_VK_VOLUME_MUTE: 181, + DOM_VK_VOLUME_DOWN: 182, + DOM_VK_VOLUME_UP: 183, +}; diff --git a/devtools/client/shared/moz.build b/devtools/client/shared/moz.build index 25cfc36e1aea..40c2a0d0d2e0 100644 --- a/devtools/client/shared/moz.build +++ b/devtools/client/shared/moz.build @@ -35,6 +35,7 @@ DevToolsModules( 'inplace-editor.js', 'Jsbeautify.jsm', 'key-shortcuts.js', + 'keycodes.js', 'l10n.js', 'node-attribute-parser.js', 'options-view.js', diff --git a/devtools/client/shared/test/browser.ini b/devtools/client/shared/test/browser.ini index 1db64254e7fb..19c4b3ab6f04 100644 --- a/devtools/client/shared/test/browser.ini +++ b/devtools/client/shared/test/browser.ini @@ -133,6 +133,7 @@ skip-if = e10s # Bug 1221911, bug 1222289, frequent e10s timeouts [browser_inplace-editor_autocomplete_02.js] [browser_inplace-editor_autocomplete_offset.js] [browser_inplace-editor_maxwidth.js] +[browser_keycodes.js] [browser_key_shortcuts.js] [browser_layoutHelpers.js] skip-if = e10s # Layouthelpers test should not run in a content page. diff --git a/devtools/client/shared/test/browser_flame-graph-05.js b/devtools/client/shared/test/browser_flame-graph-05.js index 400a3d51c2ed..691b3a59dba6 100644 --- a/devtools/client/shared/test/browser_flame-graph-05.js +++ b/devtools/client/shared/test/browser_flame-graph-05.js @@ -80,10 +80,18 @@ function* testGraph(host, graph) { function pressKeyForTime(graph, keyCode, ms) { let deferred = defer(); - graph._onKeyDown({ keyCode }); + graph._onKeyDown({ + keyCode, + preventDefault: () => { }, + stopPropagation: () => { }, + }); setTimeout(() => { - graph._onKeyUp({ keyCode }); + graph._onKeyUp({ + keyCode, + preventDefault: () => { }, + stopPropagation: () => { }, + }); deferred.resolve(); }, ms); diff --git a/devtools/client/shared/test/browser_keycodes.js b/devtools/client/shared/test/browser_keycodes.js new file mode 100644 index 000000000000..9e6b4a4ee16b --- /dev/null +++ b/devtools/client/shared/test/browser_keycodes.js @@ -0,0 +1,12 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const {KeyCodes} = require("devtools/client/shared/keycodes"); + +add_task(function* () { + for (let key in KeyCodes) { + is(KeyCodes[key], Ci.nsIDOMKeyEvent[key], "checking value for " + key); + } +}); diff --git a/devtools/client/shared/widgets/AbstractTreeItem.jsm b/devtools/client/shared/widgets/AbstractTreeItem.jsm index 53378dc3020f..541ab6777916 100644 --- a/devtools/client/shared/widgets/AbstractTreeItem.jsm +++ b/devtools/client/shared/widgets/AbstractTreeItem.jsm @@ -10,6 +10,7 @@ const { interfaces: Ci, utils: Cu } = Components; const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {}); const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm"); const { ViewHelpers } = require("devtools/client/shared/widgets/view-helpers"); +const { KeyCodes } = require("devtools/client/shared/keycodes"); XPCOMUtils.defineLazyModuleGetter(this, "EventEmitter", "resource://devtools/shared/event-emitter.js"); @@ -588,15 +589,15 @@ AbstractTreeItem.prototype = { ViewHelpers.preventScrolling(e); switch (e.keyCode) { - case e.DOM_VK_UP: + case KeyCodes.DOM_VK_UP: this._focusPrevNode(); return; - case e.DOM_VK_DOWN: + case KeyCodes.DOM_VK_DOWN: this._focusNextNode(); return; - case e.DOM_VK_LEFT: + case KeyCodes.DOM_VK_LEFT: if (this._expanded && this._populated) { this.collapse(); } else { @@ -604,7 +605,7 @@ AbstractTreeItem.prototype = { } return; - case e.DOM_VK_RIGHT: + case KeyCodes.DOM_VK_RIGHT: if (!this._expanded) { this.expand(); } else { @@ -612,7 +613,7 @@ AbstractTreeItem.prototype = { } return; - case e.DOM_VK_PAGE_UP: + case KeyCodes.DOM_VK_PAGE_UP: let pageUpElement = this._getSiblingAtDelta(-this._getNodesPerPageSize()); // There's a chance that the root node is hidden. In this case, its @@ -624,7 +625,7 @@ AbstractTreeItem.prototype = { } return; - case e.DOM_VK_PAGE_DOWN: + case KeyCodes.DOM_VK_PAGE_DOWN: let pageDownElement = this._getSiblingAtDelta(this._getNodesPerPageSize()); if (pageDownElement) { @@ -634,11 +635,11 @@ AbstractTreeItem.prototype = { } return; - case e.DOM_VK_HOME: + case KeyCodes.DOM_VK_HOME: this._focusFirstNode(); return; - case e.DOM_VK_END: + case KeyCodes.DOM_VK_END: this._focusLastNode(); return; } diff --git a/devtools/client/shared/widgets/TableWidget.js b/devtools/client/shared/widgets/TableWidget.js index c6a49c27a83d..07f437579628 100644 --- a/devtools/client/shared/widgets/TableWidget.js +++ b/devtools/client/shared/widgets/TableWidget.js @@ -8,6 +8,7 @@ loader.lazyRequireGetter(this, "setNamedTimeout", "devtools/client/shared/widgets/view-helpers", true); loader.lazyRequireGetter(this, "clearNamedTimeout", "devtools/client/shared/widgets/view-helpers", true); +const {KeyCodes} = require("devtools/client/shared/keycodes"); const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; const HTML_NS = "http://www.w3.org/1999/xhtml"; @@ -469,7 +470,7 @@ TableWidget.prototype = { let cell; switch (event.keyCode) { - case event.DOM_VK_UP: + case KeyCodes.DOM_VK_UP: event.preventDefault(); colName = selectedCell.parentNode.id; @@ -487,7 +488,7 @@ TableWidget.prototype = { this.emit(EVENTS.ROW_SELECTED, cell.getAttribute("data-id")); break; - case event.DOM_VK_DOWN: + case KeyCodes.DOM_VK_DOWN: event.preventDefault(); colName = selectedCell.parentNode.id; @@ -1664,14 +1665,14 @@ EditableFieldsEngine.prototype = { } switch (event.keyCode) { - case event.DOM_VK_ESCAPE: + case KeyCodes.DOM_VK_ESCAPE: this.cancelEdit(); event.preventDefault(); break; - case event.DOM_VK_RETURN: + case KeyCodes.DOM_VK_RETURN: this.completeEdit(); break; - case event.DOM_VK_TAB: + case KeyCodes.DOM_VK_TAB: if (this.onTab) { this.onTab(event); } diff --git a/devtools/client/shared/widgets/Tooltip.js b/devtools/client/shared/widgets/Tooltip.js index ba21f0087311..a78d44e3790c 100644 --- a/devtools/client/shared/widgets/Tooltip.js +++ b/devtools/client/shared/widgets/Tooltip.js @@ -4,7 +4,6 @@ "use strict"; -const {Ci} = require("chrome"); const defer = require("devtools/shared/defer"); const {Spectrum} = require("devtools/client/shared/widgets/Spectrum"); const {CubicBezierWidget} = @@ -18,6 +17,7 @@ const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm"); const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts"); const {Task} = require("devtools/shared/task"); +const {KeyCodes} = require("devtools/client/shared/keycodes"); loader.lazyRequireGetter(this, "beautify", "devtools/shared/jsbeautify/beautify"); loader.lazyRequireGetter(this, "setNamedTimeout", "devtools/client/shared/widgets/view-helpers", true); @@ -30,7 +30,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "VariablesViewController", "resource://devtools/client/shared/widgets/VariablesViewController.jsm"); const XHTML_NS = "http://www.w3.org/1999/xhtml"; -const ESCAPE_KEYCODE = Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE; +const ESCAPE_KEYCODE = KeyCodes.DOM_VK_ESCAPE; const POPUP_EVENTS = ["shown", "hidden", "showing", "hiding"]; /** diff --git a/devtools/client/shared/widgets/TreeWidget.js b/devtools/client/shared/widgets/TreeWidget.js index 27277415027f..1f766cc6ba04 100644 --- a/devtools/client/shared/widgets/TreeWidget.js +++ b/devtools/client/shared/widgets/TreeWidget.js @@ -8,6 +8,7 @@ const HTML_NS = "http://www.w3.org/1999/xhtml"; const EventEmitter = require("devtools/shared/event-emitter"); +const {KeyCodes} = require("devtools/client/shared/keycodes"); /** * A tree widget with keyboard navigation and collapsable structure. @@ -345,15 +346,15 @@ TreeWidget.prototype = { */ onKeypress: function (event) { switch (event.keyCode) { - case event.DOM_VK_UP: + case KeyCodes.DOM_VK_UP: this.selectPreviousItem(); break; - case event.DOM_VK_DOWN: + case KeyCodes.DOM_VK_DOWN: this.selectNextItem(); break; - case event.DOM_VK_RIGHT: + case KeyCodes.DOM_VK_RIGHT: if (this._selectedLabel.hasAttribute("expanded")) { this.selectNextItem(); } else { @@ -361,7 +362,7 @@ TreeWidget.prototype = { } break; - case event.DOM_VK_LEFT: + case KeyCodes.DOM_VK_LEFT: if (this._selectedLabel.hasAttribute("expanded") && !this._selectedLabel.hasAttribute("empty")) { this._selectedLabel.removeAttribute("expanded"); diff --git a/devtools/client/shared/widgets/VariablesView.jsm b/devtools/client/shared/widgets/VariablesView.jsm index 1d0e743cfb61..dcf8c89aa44b 100644 --- a/devtools/client/shared/widgets/VariablesView.jsm +++ b/devtools/client/shared/widgets/VariablesView.jsm @@ -28,6 +28,7 @@ const { Heritage, ViewHelpers, setNamedTimeout } = require("devtools/client/shared/widgets/view-helpers"); const { Task } = require("devtools/shared/task"); const nodeConstants = require("devtools/shared/dom-node-constants"); +const {KeyCodes} = require("devtools/client/shared/keycodes"); XPCOMUtils.defineLazyModuleGetter(this, "PluralForm", "resource://gre/modules/PluralForm.jsm"); @@ -513,10 +514,10 @@ VariablesView.prototype = { */ _onSearchboxKeyPress: function (e) { switch (e.keyCode) { - case e.DOM_VK_RETURN: + case KeyCodes.DOM_VK_RETURN: this._onSearchboxInput(); return; - case e.DOM_VK_ESCAPE: + case KeyCodes.DOM_VK_ESCAPE: this._searchboxNode.value = ""; this._onSearchboxInput(); return; @@ -826,17 +827,17 @@ VariablesView.prototype = { ViewHelpers.preventScrolling(e); switch (e.keyCode) { - case e.DOM_VK_UP: + case KeyCodes.DOM_VK_UP: // Always rewind focus. this.focusPrevItem(true); return; - case e.DOM_VK_DOWN: + case KeyCodes.DOM_VK_DOWN: // Always advance focus. this.focusNextItem(true); return; - case e.DOM_VK_LEFT: + case KeyCodes.DOM_VK_LEFT: // Collapse scopes, variables and properties before rewinding focus. if (item._isExpanded && item._isArrowVisible) { item.collapse(); @@ -845,7 +846,7 @@ VariablesView.prototype = { } return; - case e.DOM_VK_RIGHT: + case KeyCodes.DOM_VK_RIGHT: // Nothing to do here if this item never expands. if (!item._isArrowVisible) { return; @@ -858,29 +859,29 @@ VariablesView.prototype = { } return; - case e.DOM_VK_PAGE_UP: + case KeyCodes.DOM_VK_PAGE_UP: // Rewind a certain number of elements based on the container height. this.focusItemAtDelta(-(this.scrollPageSize || Math.min(Math.floor(this._list.scrollHeight / PAGE_SIZE_SCROLL_HEIGHT_RATIO), PAGE_SIZE_MAX_JUMPS))); return; - case e.DOM_VK_PAGE_DOWN: + case KeyCodes.DOM_VK_PAGE_DOWN: // Advance a certain number of elements based on the container height. this.focusItemAtDelta(+(this.scrollPageSize || Math.min(Math.floor(this._list.scrollHeight / PAGE_SIZE_SCROLL_HEIGHT_RATIO), PAGE_SIZE_MAX_JUMPS))); return; - case e.DOM_VK_HOME: + case KeyCodes.DOM_VK_HOME: this.focusFirstVisibleItem(); return; - case e.DOM_VK_END: + case KeyCodes.DOM_VK_END: this.focusLastVisibleItem(); return; - case e.DOM_VK_RETURN: + case KeyCodes.DOM_VK_RETURN: // Start editing the value or name of the Variable or Property. if (item instanceof Variable) { if (e.metaKey || e.altKey || e.shiftKey) { @@ -891,15 +892,15 @@ VariablesView.prototype = { } return; - case e.DOM_VK_DELETE: - case e.DOM_VK_BACK_SPACE: + case KeyCodes.DOM_VK_DELETE: + case KeyCodes.DOM_VK_BACK_SPACE: // Delete the Variable or Property if allowed. if (item instanceof Variable) { item._onDelete(e); } return; - case e.DOM_VK_INSERT: + case KeyCodes.DOM_VK_INSERT: item._onAddProperty(e); return; } @@ -909,7 +910,7 @@ VariablesView.prototype = { * Listener handling a key down event on the view. */ _onViewKeyDown: function (e) { - if (e.keyCode == e.DOM_VK_C) { + if (e.keyCode == KeyCodes.DOM_VK_C) { // Copy current selection to clipboard. if (e.ctrlKey || e.metaKey) { let item = this.getFocusedItem(); @@ -4082,13 +4083,13 @@ Editable.prototype = { e.stopPropagation(); switch (e.keyCode) { - case e.DOM_VK_TAB: + case KeyCodes.DOM_VK_TAB: this._next(); break; - case e.DOM_VK_RETURN: + case KeyCodes.DOM_VK_RETURN: this._save(); break; - case e.DOM_VK_ESCAPE: + case KeyCodes.DOM_VK_ESCAPE: this._reset(); break; } diff --git a/devtools/client/shared/widgets/view-helpers.js b/devtools/client/shared/widgets/view-helpers.js index 8f4c0e296dd5..ac716bad4630 100644 --- a/devtools/client/shared/widgets/view-helpers.js +++ b/devtools/client/shared/widgets/view-helpers.js @@ -5,6 +5,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; +const {KeyCodes} = require("devtools/client/shared/keycodes"); + const PANE_APPEARANCE_DELAY = 50; const PAGE_SIZE_ITEM_COUNT_RATIO = 5; const WIDGET_FOCUSABLE_NODES = new Set(["vbox", "hbox"]); @@ -201,14 +203,14 @@ const ViewHelpers = exports.ViewHelpers = { */ preventScrolling: function (e) { switch (e.keyCode) { - case e.DOM_VK_UP: - case e.DOM_VK_DOWN: - case e.DOM_VK_LEFT: - case e.DOM_VK_RIGHT: - case e.DOM_VK_PAGE_UP: - case e.DOM_VK_PAGE_DOWN: - case e.DOM_VK_HOME: - case e.DOM_VK_END: + case KeyCodes.DOM_VK_UP: + case KeyCodes.DOM_VK_DOWN: + case KeyCodes.DOM_VK_LEFT: + case KeyCodes.DOM_VK_RIGHT: + case KeyCodes.DOM_VK_PAGE_UP: + case KeyCodes.DOM_VK_PAGE_DOWN: + case KeyCodes.DOM_VK_HOME: + case KeyCodes.DOM_VK_END: e.preventDefault(); e.stopPropagation(); } @@ -221,8 +223,8 @@ const ViewHelpers = exports.ViewHelpers = { * The event triggered by a keypress on an element */ isSpaceOrReturn: function (event) { - return event.keyCode === event.DOM_VK_SPACE || - event.keyCode === event.DOM_VK_RETURN; + return event.keyCode === KeyCodes.DOM_VK_SPACE || + event.keyCode === KeyCodes.DOM_VK_RETURN; }, /** @@ -1501,26 +1503,26 @@ const WidgetMethods = exports.WidgetMethods = { ViewHelpers.preventScrolling(event); switch (event.keyCode) { - case event.DOM_VK_UP: - case event.DOM_VK_LEFT: + case KeyCodes.DOM_VK_UP: + case KeyCodes.DOM_VK_LEFT: this.focusPrevItem(); return; - case event.DOM_VK_DOWN: - case event.DOM_VK_RIGHT: + case KeyCodes.DOM_VK_DOWN: + case KeyCodes.DOM_VK_RIGHT: this.focusNextItem(); return; - case event.DOM_VK_PAGE_UP: + case KeyCodes.DOM_VK_PAGE_UP: this.focusItemAtDelta(-(this.pageSize || (this.itemCount / PAGE_SIZE_ITEM_COUNT_RATIO))); return; - case event.DOM_VK_PAGE_DOWN: + case KeyCodes.DOM_VK_PAGE_DOWN: this.focusItemAtDelta(+(this.pageSize || (this.itemCount / PAGE_SIZE_ITEM_COUNT_RATIO))); return; - case event.DOM_VK_HOME: + case KeyCodes.DOM_VK_HOME: this.focusFirstVisibleItem(); return; - case event.DOM_VK_END: + case KeyCodes.DOM_VK_END: this.focusLastVisibleItem(); return; } diff --git a/devtools/client/sourceeditor/autocomplete.js b/devtools/client/sourceeditor/autocomplete.js index f54cf76ffe2b..3fc81f5b6be9 100644 --- a/devtools/client/sourceeditor/autocomplete.js +++ b/devtools/client/sourceeditor/autocomplete.js @@ -7,6 +7,7 @@ const CSSCompleter = require("devtools/client/sourceeditor/css-autocompleter"); const { AutocompletePopup } = require("devtools/client/shared/autocomplete-popup"); +const {KeyCodes} = require("devtools/client/shared/keycodes"); const CM_TERN_SCRIPTS = [ "chrome://devtools/content/sourceeditor/codemirror/addon/tern/tern.js", @@ -316,7 +317,7 @@ function onEditorKeypress({ ed, Editor }, cm, event) { return; } - if ((event.ctrlKey || event.metaKey) && event.keyCode == event.DOM_VK_SPACE) { + if ((event.ctrlKey || event.metaKey) && event.keyCode == KeyCodes.DOM_VK_SPACE) { // When Ctrl/Cmd + Space is pressed, two simultaneous keypresses are emitted // first one for just the Ctrl/Cmd and second one for combo. The first one // leave the autocompleteOpts.doNotAutocomplete as true, so we have to make @@ -332,23 +333,23 @@ function onEditorKeypress({ ed, Editor }, cm, event) { } switch (event.keyCode) { - case event.DOM_VK_RETURN: + case KeyCodes.DOM_VK_RETURN: autocompleteOpts.doNotAutocomplete = true; break; - case event.DOM_VK_ESCAPE: + case KeyCodes.DOM_VK_ESCAPE: if (autocompleteOpts.popup.isOpen) { event.preventDefault(); } break; - case event.DOM_VK_LEFT: - case event.DOM_VK_RIGHT: - case event.DOM_VK_HOME: - case event.DOM_VK_END: + case KeyCodes.DOM_VK_LEFT: + case KeyCodes.DOM_VK_RIGHT: + case KeyCodes.DOM_VK_HOME: + case KeyCodes.DOM_VK_END: autocompleteOpts.doNotAutocomplete = true; autocompleteOpts.popup.hidePopup(); break; - case event.DOM_VK_BACK_SPACE: - case event.DOM_VK_DELETE: + case KeyCodes.DOM_VK_BACK_SPACE: + case KeyCodes.DOM_VK_DELETE: if (ed.config.mode == Editor.modes.css) { autocompleteOpts.completer.invalidateCache(ed.getCursor().line); } diff --git a/devtools/client/storage/ui.js b/devtools/client/storage/ui.js index b64825c3ccc7..7a69faf2a7e2 100644 --- a/devtools/client/storage/ui.js +++ b/devtools/client/storage/ui.js @@ -10,6 +10,7 @@ const EventEmitter = require("devtools/shared/event-emitter"); const {LocalizationHelper} = require("devtools/client/shared/l10n"); const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts"); const JSOL = require("devtools/client/shared/vendor/jsol"); +const {KeyCodes} = require("devtools/client/shared/keycodes"); loader.lazyRequireGetter(this, "TreeWidget", "devtools/client/shared/widgets/TreeWidget", true); @@ -845,7 +846,7 @@ StorageUI.prototype = { * The event passed by the keypress event. */ handleKeypress: function (event) { - if (event.keyCode == event.DOM_VK_ESCAPE && !this.sidebar.hidden) { + if (event.keyCode == KeyCodes.DOM_VK_ESCAPE && !this.sidebar.hidden) { // Stop Propagation to prevent opening up of split console this.hideSidebar(); event.stopPropagation(); diff --git a/devtools/client/styleeditor/StyleEditorUI.jsm b/devtools/client/styleeditor/StyleEditorUI.jsm index 9f8c07d12576..77491977b2ba 100644 --- a/devtools/client/styleeditor/StyleEditorUI.jsm +++ b/devtools/client/styleeditor/StyleEditorUI.jsm @@ -34,6 +34,7 @@ const promise = require("promise"); const defer = require("devtools/shared/defer"); const {ResponsiveUIManager} = require("resource://devtools/client/responsivedesign/responsivedesign.jsm"); +const {KeyCodes} = require("devtools/client/shared/keycodes"); const LOAD_ERROR = "error-load"; const STYLE_EDITOR_TEMPLATE = "stylesheet"; @@ -532,7 +533,7 @@ StyleEditorUI.prototype = { wire(summary, ".stylesheet-name", { events: { "keypress": (event) => { - if (event.keyCode == event.DOM_VK_RETURN) { + if (event.keyCode == KeyCodes.DOM_VK_RETURN) { this._view.activeSummary = summary; } } diff --git a/devtools/client/webconsole/jsterm.js b/devtools/client/webconsole/jsterm.js index c7efc0fdfd3c..a8387f329eb0 100644 --- a/devtools/client/webconsole/jsterm.js +++ b/devtools/client/webconsole/jsterm.js @@ -6,13 +6,12 @@ "use strict"; -const {Ci} = require("chrome"); - const {Utils: WebConsoleUtils} = require("devtools/client/webconsole/utils"); const promise = require("promise"); const Debugger = require("Debugger"); const Services = require("Services"); +const {KeyCodes} = require("devtools/client/shared/keycodes"); loader.lazyServiceGetter(this, "clipboardHelper", "@mozilla.org/widget/clipboardhelper;1", @@ -688,7 +687,7 @@ JSTerm.prototype = { */ _onKeypressInVariablesView: function (event) { let tag = event.target.nodeName; - if (event.keyCode != Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE || event.shiftKey || + if (event.keyCode != KeyCodes.DOM_VK_ESCAPE || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey || ["input", "textarea", "select", "textbox"].indexOf(tag) > -1) { return; @@ -1117,7 +1116,7 @@ JSTerm.prototype = { break; } return; - } else if (event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_RETURN) { + } else if (event.keyCode == KeyCodes.DOM_VK_RETURN) { let autoMultiline = Services.prefs.getBoolPref(PREF_AUTO_MULTILINE); if (event.shiftKey || (!Debugger.isCompilableUnit(inputNode.value) && autoMultiline)) { @@ -1127,7 +1126,7 @@ JSTerm.prototype = { } switch (event.keyCode) { - case Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE: + case KeyCodes.DOM_VK_ESCAPE: if (this.autocompletePopup.isOpen) { this.clearCompletion(); event.preventDefault(); @@ -1139,7 +1138,7 @@ JSTerm.prototype = { } break; - case Ci.nsIDOMKeyEvent.DOM_VK_RETURN: + case KeyCodes.DOM_VK_RETURN: if (this._autocompletePopupNavigated && this.autocompletePopup.isOpen && this.autocompletePopup.selectedIndex > -1) { @@ -1151,7 +1150,7 @@ JSTerm.prototype = { event.preventDefault(); break; - case Ci.nsIDOMKeyEvent.DOM_VK_UP: + case KeyCodes.DOM_VK_UP: if (this.autocompletePopup.isOpen) { inputUpdated = this.complete(this.COMPLETE_BACKWARD); if (inputUpdated) { @@ -1165,7 +1164,7 @@ JSTerm.prototype = { } break; - case Ci.nsIDOMKeyEvent.DOM_VK_DOWN: + case KeyCodes.DOM_VK_DOWN: if (this.autocompletePopup.isOpen) { inputUpdated = this.complete(this.COMPLETE_FORWARD); if (inputUpdated) { @@ -1179,7 +1178,7 @@ JSTerm.prototype = { } break; - case Ci.nsIDOMKeyEvent.DOM_VK_PAGE_UP: + case KeyCodes.DOM_VK_PAGE_UP: if (this.autocompletePopup.isOpen) { inputUpdated = this.complete(this.COMPLETE_PAGEUP); if (inputUpdated) { @@ -1195,7 +1194,7 @@ JSTerm.prototype = { event.preventDefault(); break; - case Ci.nsIDOMKeyEvent.DOM_VK_PAGE_DOWN: + case KeyCodes.DOM_VK_PAGE_DOWN: if (this.autocompletePopup.isOpen) { inputUpdated = this.complete(this.COMPLETE_PAGEDOWN); if (inputUpdated) { @@ -1211,7 +1210,7 @@ JSTerm.prototype = { event.preventDefault(); break; - case Ci.nsIDOMKeyEvent.DOM_VK_HOME: + case KeyCodes.DOM_VK_HOME: if (this.autocompletePopup.isOpen) { this.autocompletePopup.selectedIndex = 0; event.preventDefault(); @@ -1221,7 +1220,7 @@ JSTerm.prototype = { } break; - case Ci.nsIDOMKeyEvent.DOM_VK_END: + case KeyCodes.DOM_VK_END: if (this.autocompletePopup.isOpen) { this.autocompletePopup.selectedIndex = this.autocompletePopup.itemCount - 1; @@ -1233,13 +1232,13 @@ JSTerm.prototype = { } break; - case Ci.nsIDOMKeyEvent.DOM_VK_LEFT: + case KeyCodes.DOM_VK_LEFT: if (this.autocompletePopup.isOpen || this.lastCompletion.value) { this.clearCompletion(); } break; - case Ci.nsIDOMKeyEvent.DOM_VK_RIGHT: + case KeyCodes.DOM_VK_RIGHT: let cursorAtTheEnd = this.inputNode.selectionStart == this.inputNode.selectionEnd && this.inputNode.selectionStart == @@ -1258,7 +1257,7 @@ JSTerm.prototype = { } break; - case Ci.nsIDOMKeyEvent.DOM_VK_TAB: + case KeyCodes.DOM_VK_TAB: // Generate a completion and accept the first proposed value. if (this.complete(this.COMPLETE_HINT_ONLY) && this.lastCompletion && diff --git a/devtools/shared/gcli/source/lib/gcli/util/util.js b/devtools/shared/gcli/source/lib/gcli/util/util.js index 4c30a19a78c5..d76fa0da21ac 100644 --- a/devtools/shared/gcli/source/lib/gcli/util/util.js +++ b/devtools/shared/gcli/source/lib/gcli/util/util.js @@ -559,7 +559,7 @@ exports.createEmptyNodeList = function(doc) { * Keyboard handling is a mess. http://unixpapa.com/js/key.html * It would be good to use DOM L3 Keyboard events, * http://www.w3.org/TR/2010/WD-DOM-Level-3-Events-20100907/#events-keyboardevents - * however only Webkit supports them, and there isn't a shim on Monernizr: + * however only Webkit supports them, and there isn't a shim on Modernizr: * https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills * and when the code that uses this KeyEvent was written, nothing was clear, * so instead, we're using this unmodern shim: