diff --git a/app/assets/javascripts/admin/addon/components/permalink-form.js b/app/assets/javascripts/admin/addon/components/permalink-form.js index da8f947170c..27846151d97 100644 --- a/app/assets/javascripts/admin/addon/components/permalink-form.js +++ b/app/assets/javascripts/admin/addon/components/permalink-form.js @@ -28,8 +28,7 @@ export default Component.extend({ schedule("afterRender", () => { $(this.element.querySelector(".external-url")).keydown((e) => { - // enter key - if (e.keyCode === 13) { + if (e.key === "Enter") { this.send("submit"); } }); diff --git a/app/assets/javascripts/admin/addon/components/screened-ip-address-form.js b/app/assets/javascripts/admin/addon/components/screened-ip-address-form.js index 40dd71ad9ab..5636c302dbe 100644 --- a/app/assets/javascripts/admin/addon/components/screened-ip-address-form.js +++ b/app/assets/javascripts/admin/addon/components/screened-ip-address-form.js @@ -83,7 +83,7 @@ export default Component.extend({ _init() { schedule("afterRender", () => { $(this.element.querySelector(".ip-address-input")).keydown((e) => { - if (e.keyCode === 13) { + if (e.key === "Enter") { this.send("submit"); } }); diff --git a/app/assets/javascripts/admin/addon/components/value-list.js b/app/assets/javascripts/admin/addon/components/value-list.js index aa89de7f38d..2daacfd8a4a 100644 --- a/app/assets/javascripts/admin/addon/components/value-list.js +++ b/app/assets/javascripts/admin/addon/components/value-list.js @@ -33,7 +33,7 @@ export default Component.extend({ }, keyDown(event) { - if (event.keyCode === 13) { + if (event.key === "Enter") { this.send("addValue", this.newValue); } }, diff --git a/app/assets/javascripts/admin/addon/components/watched-word-form.js b/app/assets/javascripts/admin/addon/components/watched-word-form.js index 93dbdda7519..7bdd3138de4 100644 --- a/app/assets/javascripts/admin/addon/components/watched-word-form.js +++ b/app/assets/javascripts/admin/addon/components/watched-word-form.js @@ -118,7 +118,7 @@ export default Component.extend({ _init() { schedule("afterRender", () => { $(this.element.querySelector(".watched-word-input")).keydown((e) => { - if (e.keyCode === 13) { + if (e.key === "Enter") { this.send("submit"); } }); diff --git a/app/assets/javascripts/admin/addon/mixins/setting-component.js b/app/assets/javascripts/admin/addon/mixins/setting-component.js index fc6c6c24d5f..b55c0455931 100644 --- a/app/assets/javascripts/admin/addon/mixins/setting-component.js +++ b/app/assets/javascripts/admin/addon/mixins/setting-component.js @@ -138,7 +138,7 @@ export default Mixin.create({ "keydown.setting-enter", ".input-setting-string", (e) => { - if (e.keyCode === 13) { + if (e.key === "Enter") { // enter key this.send("save"); } diff --git a/app/assets/javascripts/discourse/app/components/choose-topic.js b/app/assets/javascripts/discourse/app/components/choose-topic.js index 6786c941066..d7d164d9863 100644 --- a/app/assets/javascripts/discourse/app/components/choose-topic.js +++ b/app/assets/javascripts/discourse/app/components/choose-topic.js @@ -43,7 +43,7 @@ export default Component.extend({ this._super(...arguments); schedule("afterRender", () => { $("#choose-topic-title").keydown((e) => { - if (e.keyCode === 13) { + if (e.key === "Enter") { return false; } }); diff --git a/app/assets/javascripts/discourse/app/components/create-account.js b/app/assets/javascripts/discourse/app/components/create-account.js index 84cc94a70f6..f61d76b8e82 100644 --- a/app/assets/javascripts/discourse/app/components/create-account.js +++ b/app/assets/javascripts/discourse/app/components/create-account.js @@ -44,7 +44,7 @@ export default Component.extend({ } $(this.element).on("keydown.discourse-create-account", (e) => { - if (!this.disabled && e.keyCode === 13) { + if (!this.disabled && e.key === "Enter") { e.preventDefault(); e.stopPropagation(); this.action(); diff --git a/app/assets/javascripts/discourse/app/components/login-modal.js b/app/assets/javascripts/discourse/app/components/login-modal.js index 52f0acef040..c6d0f938a9f 100644 --- a/app/assets/javascripts/discourse/app/components/login-modal.js +++ b/app/assets/javascripts/discourse/app/components/login-modal.js @@ -21,7 +21,7 @@ export default Component.extend({ $( "#login-account-password, #login-account-name, #login-second-factor" ).keydown((e) => { - if (e.keyCode === 13) { + if (e.key === "Enter") { this.action(); } }); diff --git a/app/assets/javascripts/discourse/app/components/share-popup.js b/app/assets/javascripts/discourse/app/components/share-popup.js index 85e815ce507..94776d2107c 100644 --- a/app/assets/javascripts/discourse/app/components/share-popup.js +++ b/app/assets/javascripts/discourse/app/components/share-popup.js @@ -156,7 +156,7 @@ export default Component.extend({ return; } - if (event.keyCode === 27) { + if (event.key === "Escape") { this.send("close"); } }, diff --git a/app/assets/javascripts/discourse/app/controllers/flag.js b/app/assets/javascripts/discourse/app/controllers/flag.js index 7834743e08a..e221f5edc9f 100644 --- a/app/assets/javascripts/discourse/app/controllers/flag.js +++ b/app/assets/javascripts/discourse/app/controllers/flag.js @@ -56,7 +56,7 @@ export default Controller.extend(ModalFunctionality, { @bind keyDown(event) { // CTRL+ENTER or CMD+ENTER - if (event.keyCode === 13 && (event.ctrlKey || event.metaKey)) { + if (event.key === "Enter" && (event.ctrlKey || event.metaKey)) { if (this.submitEnabled) { this.send("createFlag"); return false; diff --git a/app/assets/javascripts/discourse/app/lib/keyboard-shortcuts.js b/app/assets/javascripts/discourse/app/lib/keyboard-shortcuts.js index 1bcb1b6f9aa..4bc5223fdfb 100644 --- a/app/assets/javascripts/discourse/app/lib/keyboard-shortcuts.js +++ b/app/assets/javascripts/discourse/app/lib/keyboard-shortcuts.js @@ -539,7 +539,7 @@ export default { const selection = document.querySelector(selector); // Special case: We're binding to enter. - if (e && e.keyCode === 13) { + if (e && e.key === "Enter") { // Binding to enter should only be effective when there is something // to select. if (!selection) { diff --git a/app/assets/javascripts/discourse/app/mixins/card-contents-base.js b/app/assets/javascripts/discourse/app/mixins/card-contents-base.js index 2b036eb258d..bda3d3f11f8 100644 --- a/app/assets/javascripts/discourse/app/mixins/card-contents-base.js +++ b/app/assets/javascripts/discourse/app/mixins/card-contents-base.js @@ -358,8 +358,7 @@ export default Mixin.create({ }, keyUp(e) { - if (e.keyCode === 27) { - // ESC + if (e.key === "Escape") { const target = this.cardTarget; this._close(); target.focus(); diff --git a/app/assets/javascripts/discourse/tests/acceptance/composer-test.js b/app/assets/javascripts/discourse/tests/acceptance/composer-test.js index 5cbdf0bc912..190017f2da6 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/composer-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/composer-test.js @@ -102,6 +102,7 @@ acceptance("Composer", function (needs) { const event = document.createEvent("Event"); event.initEvent("keydown", true, true); event[mac ? "metaKey" : "ctrlKey"] = true; + event.key = "B"; event.keyCode = 66; run(() => textarea.dispatchEvent(event)); diff --git a/app/assets/javascripts/discourse/tests/acceptance/flag-post-test.js b/app/assets/javascripts/discourse/tests/acceptance/flag-post-test.js index 926e27b9692..0fbfa0a2517 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/flag-post-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/flag-post-test.js @@ -17,9 +17,10 @@ async function openFlagModal() { await click(".topic-post:first-child button.create-flag"); } -function keyDown(element, keyCode, modifier) { +function pressEnter(element, modifier) { const event = document.createEvent("Event"); event.initEvent("keydown", true, true); + event.key = "Enter"; event.keyCode = 13; event[modifier] = true; run(() => element.dispatchEvent(event)); @@ -158,14 +159,14 @@ acceptance("flagging", function (needs) { await openFlagModal(); const modal = query("#discourse-modal"); - keyDown(modal, 13, "ctrlKey"); + pressEnter(modal, "ctrlKey"); assert.ok( exists("#discourse-modal:visible"), "The modal wasn't closed because the accept button was disabled" ); await click("#radio_inappropriate"); // this enables the accept button - keyDown(modal, 13, "ctrlKey"); + pressEnter(modal, "ctrlKey"); assert.ok(!exists("#discourse-modal:visible"), "The modal was closed"); }); @@ -174,14 +175,14 @@ acceptance("flagging", function (needs) { await openFlagModal(); const modal = query("#discourse-modal"); - keyDown(modal, 13, "metaKey"); + pressEnter(modal, "metaKey"); assert.ok( exists("#discourse-modal:visible"), "The modal wasn't closed because the accept button was disabled" ); await click("#radio_inappropriate"); // this enables the accept button - keyDown(modal, 13, "ctrlKey"); + pressEnter(modal, "ctrlKey"); assert.ok(!exists("#discourse-modal:visible"), "The modal was closed"); }); }); diff --git a/app/assets/javascripts/discourse/tests/acceptance/group-manage-membership-test.js b/app/assets/javascripts/discourse/tests/acceptance/group-manage-membership-test.js index 45e0ae73ac3..ef2e6a0d0c0 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/group-manage-membership-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/group-manage-membership-test.js @@ -89,7 +89,7 @@ acceptance("Managing Group Membership", function (needs) { ); await emailDomains.expand(); await emailDomains.fillInFilter("foo.com"); - await emailDomains.keyboard("enter"); + await emailDomains.keyboard("Enter"); assert.equal(emailDomains.header().value(), "foo.com"); }); diff --git a/app/assets/javascripts/discourse/tests/helpers/select-kit-helper.js b/app/assets/javascripts/discourse/tests/helpers/select-kit-helper.js index 9632ad66657..8ac77253c38 100644 --- a/app/assets/javascripts/discourse/tests/helpers/select-kit-helper.js +++ b/app/assets/javascripts/discourse/tests/helpers/select-kit-helper.js @@ -66,23 +66,27 @@ async function keyboardHelper(value, target, selector) { if (value === "selectAll") { // special casing the only one not working with triggerEvent const event = jQuery.Event("keydown"); + event.key = "A"; event.keyCode = 65; event.metaKey = true; target.trigger(event); } else { const mapping = { - enter: { keyCode: 13 }, - backspace: { keyCode: 8 }, - escape: { keyCode: 27 }, - down: { keyCode: 40 }, - up: { keyCode: 38 }, - tab: { keyCode: 9 }, + enter: { key: "Enter", keyCode: 13 }, + backspace: { key: "Backspace", keyCode: 8 }, + escape: { key: "Escape", keyCode: 27 }, + down: { key: "ArrowDown", keyCode: 40 }, + up: { key: "ArrowUp", keyCode: 38 }, + tab: { key: "Tab", keyCode: 9 }, }; await triggerEvent( target[0], "keydown", - mapping[value] || { keyCode: value.charCodeAt(0) } + mapping[value.toLowerCase()] || { + key: value, + keyCode: value.charCodeAt(0), + } ); } } diff --git a/app/assets/javascripts/discourse/tests/integration/components/select-kit/mini-tag-chooser-test.js b/app/assets/javascripts/discourse/tests/integration/components/select-kit/mini-tag-chooser-test.js index 012e8ed3aa9..c9a5bbcd71e 100644 --- a/app/assets/javascripts/discourse/tests/integration/components/select-kit/mini-tag-chooser-test.js +++ b/app/assets/javascripts/discourse/tests/integration/components/select-kit/mini-tag-chooser-test.js @@ -45,7 +45,7 @@ discourseModule( assert.equal(queryAll(".select-kit-row").text().trim(), "monkey x1"); await this.subject.fillInFilter("key"); assert.equal(queryAll(".select-kit-row").text().trim(), "monkey x1"); - await this.subject.keyboard("enter"); + await this.subject.keyboard("Enter"); assert.equal(this.subject.header().value(), "foo,bar,monkey"); }, @@ -64,7 +64,7 @@ discourseModule( await this.subject.expand(); await this.subject.fillInFilter("baz"); - await this.subject.keyboard("enter"); + await this.subject.keyboard("Enter"); const error = queryAll(".select-kit-error").text(); assert.equal( diff --git a/app/assets/javascripts/discourse/tests/integration/components/value-list-test.js b/app/assets/javascripts/discourse/tests/integration/components/value-list-test.js index 3c2e3520ed1..45945469839 100644 --- a/app/assets/javascripts/discourse/tests/integration/components/value-list-test.js +++ b/app/assets/javascripts/discourse/tests/integration/components/value-list-test.js @@ -25,7 +25,7 @@ discourseModule("Integration | Component | value-list", function (hooks) { async test(assert) { await selectKit().expand(); await selectKit().fillInFilter("eviltrout"); - await selectKit().keyboard("enter"); + await selectKit().keyboard("Enter"); assert.equal( count(".values .value"), @@ -109,7 +109,7 @@ discourseModule("Integration | Component | value-list", function (hooks) { await selectKit().expand(); await selectKit().fillInFilter("eviltrout"); - await selectKit().keyboard("enter"); + await selectKit().keyboard("Enter"); assert.equal( count(".values .value"), @@ -137,7 +137,7 @@ discourseModule("Integration | Component | value-list", function (hooks) { async test(assert) { await selectKit().expand(); await selectKit().fillInFilter("eviltrout"); - await selectKit().keyboard("enter"); + await selectKit().keyboard("Enter"); assert.equal( count(".values .value"), diff --git a/app/assets/javascripts/discourse/tests/test_starter.js b/app/assets/javascripts/discourse/tests/test_starter.js index 8f75fcf8e5f..a688f0a940c 100644 --- a/app/assets/javascripts/discourse/tests/test_starter.js +++ b/app/assets/javascripts/discourse/tests/test_starter.js @@ -9,3 +9,106 @@ document.write( let setupTestsLegacy = require("discourse/tests/setup-tests").setupTestsLegacy; setupTestsLegacy(window.Discourse); + +const keyFromKeyCode = { + 8: "Backspace", + 9: "Tab", + 13: "Enter", + 16: "Shift", + 17: "Control", + 18: "Alt", + 20: "CapsLock", + 27: "Escape", + 32: " ", + 37: "ArrowLeft", + 38: "ArrowUp", + 39: "ArrowRight", + 40: "ArrowDown", + 48: "0", + 49: "1", + 50: "2", + 51: "3", + 52: "4", + 53: "5", + 54: "6", + 55: "7", + 56: "8", + 57: "9", + 65: "a", + 66: "b", + 67: "c", + 68: "d", + 69: "e", + 70: "f", + 71: "g", + 72: "h", + 73: "i", + 74: "j", + 75: "k", + 76: "l", + 77: "m", + 78: "n", + 79: "o", + 80: "p", + 81: "q", + 82: "r", + 83: "s", + 84: "t", + 85: "u", + 86: "v", + 87: "w", + 88: "x", + 89: "y", + 90: "z", + 91: "Meta", + 93: "Meta", + 97: "a", + 98: "b", + 99: "c", + 100: "d", + 101: "e", + 102: "f", + 103: "g", + 104: "h", + 105: "i", + 106: "j", + 107: "k", + 108: "l", + 109: "m", + 110: "n", + 111: "o", + 112: "p", + 113: "q", + 114: "r", + 115: "s", + 116: "t", + 117: "u", + 118: "v", + 119: "w", + 120: "x", + 121: "y", + 122: "z", + 187: "=", + 189: "-", +}; + +window.keyEvent = function (selector, contextOrType, typeOrKeyCode, keyCode) { + let context, type; + + if (keyCode === undefined) { + context = null; + keyCode = typeOrKeyCode; + type = contextOrType; + } else { + context = contextOrType; + type = typeOrKeyCode; + } + + let key = keyFromKeyCode[keyCode]; + + return window.triggerEvent(selector, context, type, { + keyCode: keyCode, + which: keyCode, + key: key, + }); +}; diff --git a/app/assets/javascripts/select-kit/addon/components/mini-tag-chooser.js b/app/assets/javascripts/select-kit/addon/components/mini-tag-chooser.js index bce736ca5ed..d1c4cfce065 100644 --- a/app/assets/javascripts/select-kit/addon/components/mini-tag-chooser.js +++ b/app/assets/javascripts/select-kit/addon/components/mini-tag-chooser.js @@ -193,11 +193,11 @@ export default ComboBox.extend(TagsMixin, { _onKeydown(event) { const value = makeArray(this.value); - if (event.keyCode === 8) { + if (event.key === "Backspace") { if (!this.selectKit.filter) { this._onBackspace(this.value, this.highlightedTag); } - } else if (event.keyCode === 37) { + } else if (event.key === "ArrowLeft") { if (this.highlightedTag) { const index = value.indexOf(this.highlightedTag); const highlightedTag = value[index - 1] @@ -207,7 +207,7 @@ export default ComboBox.extend(TagsMixin, { } else { this.set("highlightedTag", value.lastObject); } - } else if (event.keyCode === 39) { + } else if (event.key === "ArrowRight") { if (this.highlightedTag) { const index = value.indexOf(this.highlightedTag); const highlightedTag = value[index + 1] diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-filter.js b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-filter.js index 853b468e109..4e064f5d64d 100644 --- a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-filter.js +++ b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-filter.js @@ -54,7 +54,7 @@ export default Component.extend(UtilsMixin, { }, onKeyup(event) { - if (event.keyCode === 13 && this.selectKit.enterDisabled) { + if (event.key === "Enter" && this.selectKit.enterDisabled) { this.element.querySelector("input").focus(); event.preventDefault(); event.stopPropagation(); @@ -69,30 +69,28 @@ export default Component.extend(UtilsMixin, { } // Do nothing for left/right arrow - if (event.keyCode === 37 || event.keyCode === 39) { + if (event.key === "ArrowLeft" || event.key === "ArrowRight") { return true; } - // Up arrow - if (event.keyCode === 38) { + if (event.key === "ArrowUp") { this.selectKit.highlightPrevious(); return false; } - // Down arrow - if (event.keyCode === 40) { + if (event.key === "ArrowDown") { this.selectKit.highlightNext(); return false; } // Escape - if (event.keyCode === 27) { + if (event.key === "Escape") { this.selectKit.close(event); return false; } // Enter - if (event.keyCode === 13 && this.selectKit.highlighted) { + if (event.key === "Enter" && this.selectKit.highlighted) { this.selectKit.select( this.getValue(this.selectKit.highlighted), this.selectKit.highlighted @@ -101,7 +99,7 @@ export default Component.extend(UtilsMixin, { } if ( - event.keyCode === 13 && + event.key === "Enter" && (!this.selectKit.highlighted || this.selectKit.enterDisabled) ) { this.element.querySelector("input").focus(); @@ -113,7 +111,7 @@ export default Component.extend(UtilsMixin, { } // Tab - if (event.keyCode === 9) { + if (event.key === "Tab") { if (this.selectKit.highlighted && this.selectKit.isExpanded) { this.selectKit.select( this.getValue(this.selectKit.highlighted), @@ -123,6 +121,7 @@ export default Component.extend(UtilsMixin, { this.selectKit.close(event); return; } + this.selectKit.set("highlighted", null); }, }, diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-header.js b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-header.js index 0d389c94550..7e9c361e6c2 100644 --- a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-header.js +++ b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-header.js @@ -84,7 +84,7 @@ export default Component.extend(UtilsMixin, { }, keyUp(event) { - if (event.keyCode === 32) { + if (event.key === " ") { event.preventDefault(); } }, @@ -98,13 +98,12 @@ export default Component.extend(UtilsMixin, { return false; } - const onlyShiftKey = event.shiftKey && event.keyCode === 16; + const onlyShiftKey = event.shiftKey && event.key === "Shift"; if (event.metaKey || onlyShiftKey) { return; } - if (event.keyCode === 13) { - // Enter + if (event.key === "Enter") { if (this.selectKit.isExpanded) { if (this.selectKit.highlighted) { this.selectKit.select( @@ -116,37 +115,31 @@ export default Component.extend(UtilsMixin, { } else { this.selectKit.close(event); } - } else if (event.keyCode === 38) { - // Up arrow + } else if (event.key === "ArrowUp") { if (this.selectKit.isExpanded) { this.selectKit.highlightPrevious(); } else { this.selectKit.open(event); } return false; - } else if (event.keyCode === 40) { - // Down arrow + } else if (event.key === "ArrowDown") { if (this.selectKit.isExpanded) { this.selectKit.highlightNext(); } else { this.selectKit.open(event); } return false; - } else if (event.keyCode === 37 || event.keyCode === 39) { + } else if (event.key === "ArrowLeft" || event.key === "ArrowRight") { // Do nothing for left/right arrow return true; - } else if (event.keyCode === 32) { - // Space + } else if (event.key === " ") { event.preventDefault(); // prevents the space to trigger a scroll page-next this.selectKit.toggle(event); - } else if (event.keyCode === 27) { - // Escape + } else if (event.key === "Escape") { this.selectKit.close(event); - } else if (event.keyCode === 8) { - // Backspace + } else if (event.key === "Backspace") { this._focusFilterInput(); - } else if (event.keyCode === 9) { - // Tab + } else if (event.key === "Tab") { if ( this.selectKit.highlighted && this.selectKit.isExpanded && diff --git a/app/assets/javascripts/wizard/components/invite-list.js b/app/assets/javascripts/wizard/components/invite-list.js index f01f7088844..8a52304d60f 100644 --- a/app/assets/javascripts/wizard/components/invite-list.js +++ b/app/assets/javascripts/wizard/components/invite-list.js @@ -24,7 +24,7 @@ export default Component.extend({ }, keyPress(e) { - if (e.keyCode === 13) { + if (e.key === "Enter") { e.preventDefault(); e.stopPropagation(); this.send("addUser"); diff --git a/app/assets/javascripts/wizard/components/wizard-step.js b/app/assets/javascripts/wizard/components/wizard-step.js index 7baf1ea42fd..80b41ec1307 100644 --- a/app/assets/javascripts/wizard/components/wizard-step.js +++ b/app/assets/javascripts/wizard/components/wizard-step.js @@ -73,8 +73,8 @@ export default Component.extend({ this.autoFocus(); }, - keyPress(key) { - if (key.keyCode === 13) { + keyPress(event) { + if (event.key === "Enter") { if (this.showDoneButton) { this.send("quit"); } else { diff --git a/plugins/poll/assets/javascripts/widgets/discourse-poll.js.es6 b/plugins/poll/assets/javascripts/widgets/discourse-poll.js.es6 index d84407d2746..c74e162cd37 100644 --- a/plugins/poll/assets/javascripts/widgets/discourse-poll.js.es6 +++ b/plugins/poll/assets/javascripts/widgets/discourse-poll.js.es6 @@ -77,7 +77,7 @@ createWidget("discourse-poll-option", { }, keyDown(e) { - if (e.keyCode === 13) { + if (e.key === "Enter") { this.click(e); } },