Skip to content

Commit

Permalink
[REF] *: keyboard: replace deprecated charCode, keyCode and which pro…
Browse files Browse the repository at this point in the history
…perties

These properties are deprecated.

We should consider to use `KeyboardEvent.key` or `KeyboardEvent.code` for new code.
Note that we prefer to use the `key` property as multiple physical keys
can send the same value (e.g. Enter can also be sent by the numeric pad).
We should only use `code` when we explicitly want to target a single physical
key on the keyboard.

By doing this, we can now remove the dependency of `jQuery.ui.keyCode`
that was used as mapping of key code descriptions to their numeric values.

References:
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/charCode (deprecated)
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode (deprecated)
https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/which (deprecated)

https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key

https://api.jqueryui.com/1.12/jQuery.ui.keyCode/

Some links that helps:
https://w3c.github.io/uievents/tools/key-event-viewer.html
https://www.toptal.com/developers/keycode/table

closes odoo#139809

Related: odoo/enterprise#49591
Signed-off-by: Pierre Paridans (app) <app@odoo.com>
  • Loading branch information
adr-odoo committed Oct 26, 2023
1 parent 5dc625f commit e6c747b
Show file tree
Hide file tree
Showing 32 changed files with 55 additions and 176 deletions.
2 changes: 1 addition & 1 deletion addons/account/static/tests/tours/tax_group_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ registry.category("web_tour.tours").add('account_tax_group', {
trigger: 'div[name="invoice_line_ids"] tbody tr.o_data_row .o_list_number[name="quantity"] input',
run: function (actions) {
let keydownEvent = jQuery.Event('keydown');
keydownEvent.which = 13;
keydownEvent.key = "Enter";
this.$anchor.trigger(keydownEvent);
},
},
Expand Down
9 changes: 0 additions & 9 deletions addons/barcodes/static/tests/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,8 @@ import { triggerEvent } from "@web/../tests/helpers/utils";

export function simulateBarCode(chars, target = document.body, selector = undefined) {
for (let char of chars) {
let keycode;
if (char === "Enter") {
keycode = $.ui.keyCode.ENTER;
} else if (char === "Tab") {
keycode = $.ui.keyCode.TAB;
} else {
keycode = char.charCodeAt(0);
}
triggerEvent(target, selector, "keydown", {
key: char,
keyCode: keycode,
});
}
}
9 changes: 0 additions & 9 deletions addons/barcodes/static/tests/mobile/barcode_mobile_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,8 @@
var triggerEvent = testUtils.dom.triggerEvent;

function triggerKeyDown(char, target = document.body) {
let keycode;
if (char === 'Enter') {
keycode = $.ui.keyCode.ENTER;
} else if (char === "Tab") {
keycode = $.ui.keyCode.TAB;
} else {
keycode = char.charCodeAt(0);
}
triggerEvent(target, 'keydown', {
key: char,
keyCode: keycode,
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class BomOverviewControlPanel extends Component {
}

onKeyPress(ev) {
if (ev.keyCode === 13 || ev.which === 13) {
if (ev.key === "Enter") {
ev.preventDefault();
this.updateQuantity(ev);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<t t-name="point_of_sale.ProductCard">
<article tabindex="0"
t-attf-class="{{props.class}} product position-relative btn btn-light d-flex align-items-stretch p-0 m-0 text-start cursor-pointer overflow-hidden transition-base"
t-on-keypress="(event) => event.which === 32 ? props.onClick(event) : ()=>{}"
t-on-keypress="(event) => event.code === 'Space' ? props.onClick(event) : ()=>{}"
t-on-click="props.onClick"
t-att-data-product-id="props.productId"
t-attf-aria-labelledby="article_product_{{props.productId}}">
Expand Down
4 changes: 0 additions & 4 deletions addons/purchase/static/src/js/tours/purchase.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@ registry.category("web_tour.tours").add("purchase_tour", {
run: function (actions) {
var $input = this.$anchor.find("input");
actions.text("DESK0001", $input.length === 0 ? this.$anchor : $input);
// fake keydown to trigger search
var keyDownEvent = jQuery.Event("keydown");
keyDownEvent.which = 42;
this.$anchor.trigger(keyDownEvent);
var $descriptionElement = $('.o_form_editable textarea[name="name"]');
// when description changes, we know the product has been created
$descriptionElement.change(function () {
Expand Down
4 changes: 0 additions & 4 deletions addons/sale/static/src/js/tours/sale.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,6 @@ registry.category("web_tour.tours").add("sale_quote_tour", {
run: function (actions) {
var $input = this.$anchor.find("input");
actions.text("DESK0001", $input.length === 0 ? this.$anchor : $input);
// fake keydown to trigger search
var keyDownEvent = jQuery.Event("keydown");
keyDownEvent.which = 42;
this.$anchor.trigger(keyDownEvent);
var $descriptionElement = $(".o_form_editable textarea[name='name']");
// when description changes, we know the product has been created
$descriptionElement.change(function () {
Expand Down
13 changes: 6 additions & 7 deletions addons/survey/static/src/js/survey_form.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,35 +108,34 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend(SurveyPreloa
*/
_onKeyDown: function (event) {
var self = this;
var keyCode = event.keyCode;

// If user is answering a text input, do not handle keydown
// CTRL+enter will force submission (meta key for Mac)
if ((this.$("textarea").is(":focus") || this.$('input').is(':focus')) &&
(!(event.ctrlKey || event.metaKey) || keyCode !== 13)) {
(!(event.ctrlKey || event.metaKey) || event.key !== "Enter")) {
return;
}
// If in session mode and question already answered, do not handle keydown
if (this.$('fieldset[disabled="disabled"]').length !== 0) {
return;
}
// Disable all navigation keys when zoom modal is open, except the ESC.
if ((this.imgZoomer && !this.imgZoomer.isDestroyed()) && keyCode !== 27) {
if ((this.imgZoomer && !this.imgZoomer.isDestroyed()) && event.key !== "Escape") {
return;
}

var letter = String.fromCharCode(keyCode).toUpperCase();
var letter = event.key.toUpperCase();

// Handle Start / Next / Submit
if (keyCode === 13 || keyCode === 39) { // Enter or arrow-right: go Next
if (event.key === "Enter" || event.key === "ArrowRight") { // Enter or arrow-right: go Next
event.preventDefault();
if (!this.preventEnterSubmit) {
this._submitForm({
isFinish: this.el.querySelectorAll('button[value="finish"]').length !== 0,
nextSkipped: this.el.querySelectorAll('button[value="next_skipped"]').length !== 0 ? keyCode === 13 : false,
nextSkipped: this.el.querySelectorAll('button[value="next_skipped"]').length !== 0 ? event.key === "Enter" : false,
});
}
} else if (keyCode === 37) { // arrow-left: previous (if available)
} else if (event.key === "ArrowLeft") { // arrow-left: previous (if available)
// It's easier to actually click on the button (if in the DOM) as it contains necessary
// data that are used in the event handler.
// Again, global selector necessary since the navigation is outside of the form.
Expand Down
2 changes: 1 addition & 1 deletion addons/survey/static/src/js/survey_quick_access.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ publicWidget.registry.SurveyQuickAccessWidget = publicWidget.Widget.extend({
},

_onKeyPress: function (event) {
if (event.keyCode === 13) { // Enter
if (event.key === "Enter") {
event.preventDefault();
this._submitCode();
}
Expand Down
10 changes: 2 additions & 8 deletions addons/survey/static/src/js/survey_session_manage.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,18 +121,12 @@ publicWidget.registry.SurveySessionManage = publicWidget.Widget.extend(SurveyPre
/**
* Listeners for keyboard arrow / spacebar keys.
*
* - 39 = arrow-right
* - 32 = spacebar
* - 37 = arrow-left
*
* @param {KeyboardEvent} ev
*/
_onKeyDown: function (ev) {
var keyCode = ev.keyCode;

if (keyCode === 39 || keyCode === 32) {
if (ev.key === "ArrowRight" || ev.key === " ") {
this._onNext(ev);
} else if (keyCode === 37) {
} else if (ev.key === "ArrowLeft") {
this._onBack(ev);
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ const getChartData = () => {

const nextScreen = () => {
const e = $.Event('keydown');
e.keyCode = 39; // arrow-right
e.key = "ArrowRight";
$(document).trigger(e);
};

const previousScreen = () => {
const e = $.Event('keydown');
e.keyCode = 37; // arrow-left
e.key = "ArrowLeft";
$(document).trigger(e);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ registry.category("web_tour.tours").add('test_survey_session_start_tour', {
trigger: 'h1',
run: function () {
var e = $.Event('keydown');
e.keyCode = 39; // arrow-right
e.key = "ArrowRight";
$(document).trigger(e); // start session
}
}, {
Expand Down
2 changes: 1 addition & 1 deletion addons/web/static/src/core/colorpicker/colorpicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ export class Colorpicker extends Component {
* @param {Event} ev
*/
_onKeypress(ev) {
if (ev.charCode === $.ui.keyCode.ENTER) {
if (ev.key === "Enter") {
if (ev.target.tagName === "INPUT") {
this._onChangeInputs(ev);
}
Expand Down
4 changes: 2 additions & 2 deletions addons/web/static/src/legacy/js/core/dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,8 @@ var Dialog = Widget.extend({
* @private
*/
_onFooterButtonKeyDown: function (e) {
switch(e.which) {
case $.ui.keyCode.TAB:
switch(e.key) {
case "Tab":
if (!e.shiftKey && e.target.classList.contains("btn-primary")) {
e.preventDefault();
var $primaryButton = $(e.target);
Expand Down
6 changes: 0 additions & 6 deletions addons/web/static/tests/core/dropdown_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -794,9 +794,6 @@ QUnit.module("Components", ({ beforeEach }) => {
// Define the ArrowDown key with standard API (for hotkey_service)
key: "ArrowDown",
code: "ArrowDown",
// Define the ArrowDown key with deprecated API (for bootstrap)
keyCode: 40,
which: 40,
});
select.dispatchEvent(ev);
await nextTick();
Expand All @@ -806,9 +803,6 @@ QUnit.module("Components", ({ beforeEach }) => {
// Define the ESC key with standard API (for hotkey_service)
key: "Escape",
code: "Escape",
// Define the ESC key with deprecated API (for bootstrap)
keyCode: 27,
which: 27,
});
select.dispatchEvent(ev);
await nextTick();
Expand Down
1 change: 0 additions & 1 deletion addons/web/static/tests/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,6 @@ const mapKeyboardEvent = (args) => ({
...args,
bubbles: true,
cancelable: true,
keyCode: args.which,
});

/**
Expand Down
2 changes: 1 addition & 1 deletion addons/web/static/tests/legacy/helpers/test_utils_dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { delay } from "@web/core/utils/concurrency";
//-------------------------------------------------------------------------

// TriggerEvent helpers
const keyboardEventBubble = args => Object.assign({}, args, { bubbles: true, keyCode: args.which });
const keyboardEventBubble = args => Object.assign({}, args, { bubbles: true});
const mouseEventMapping = args => Object.assign({}, args, {
bubbles: true,
cancelable: true,
Expand Down
37 changes: 6 additions & 31 deletions addons/web/static/tests/legacy/helpers/test_utils_fields.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,6 @@

import testUtilsDom from "@web/../tests/legacy/helpers/test_utils_dom";

const ARROW_KEYS_MAPPING = {
down: 'ArrowDown',
left: 'ArrowLeft',
right: 'ArrowRight',
up: 'ArrowUp',
};

//-------------------------------------------------------------------------
// Public functions
//-------------------------------------------------------------------------
Expand Down Expand Up @@ -67,43 +60,25 @@
*
* @param {string} type type of key event ('press', 'up' or 'down')
* @param {jQuery} $el
* @param {number|string} keyCode used as number, but if string, it'll check if
* the string corresponds to a key -otherwise it will keep only the first
* char to get a letter key- and convert it into a keyCode.
* @param {string} key
* @returns {Promise}
*/
function triggerKey(type, $el, keyCode) {
function triggerKey(type, $el, key) {
type = 'key' + type;
const params = {};
if (typeof keyCode === 'string') {
// Key (new API)
if (keyCode in ARROW_KEYS_MAPPING) {
params.key = ARROW_KEYS_MAPPING[keyCode];
} else {
params.key = keyCode[0].toUpperCase() + keyCode.slice(1).toLowerCase();
}
// KeyCode/which (jQuery)
if (keyCode.length > 1) {
keyCode = keyCode.toUpperCase();
keyCode = $.ui.keyCode[keyCode];
} else {
keyCode = keyCode.charCodeAt(0);
}
}
params.keyCode = keyCode;
params.which = keyCode;
params.key = key;
return testUtilsDom.triggerEvent($el, type, params);
}

/**
* Helper to trigger a keydown event on an element.
*
* @param {jQuery} $el
* @param {number|string} keyCode @see triggerKey
* @param {number|string} key @see triggerKey
* @returns {Promise}
*/
function triggerKeydown($el, keyCode) {
return triggerKey('down', $el, keyCode);
function triggerKeydown($el, key) {
return triggerKey('down', $el, key);
}

export default {
Expand Down
12 changes: 6 additions & 6 deletions addons/web_editor/static/src/js/editor/snippets.options.js
Original file line number Diff line number Diff line change
Expand Up @@ -1383,12 +1383,12 @@ const InputUserValueWidget = UnitUserValueWidget.extend({
if (!params.unit && !params.step) {
return;
}
switch (ev.which) {
case $.ui.keyCode.ENTER:
switch (ev.key) {
case "Enter":
this._onUserValueChange(ev);
break;
case $.ui.keyCode.UP:
case $.ui.keyCode.DOWN: {
case "ArrowUp":
case "ArrowDown": {
const input = ev.currentTarget;
let value = parseFloat(input.value || input.placeholder);
if (isNaN(value)) {
Expand All @@ -1399,7 +1399,7 @@ const InputUserValueWidget = UnitUserValueWidget.extend({
step = 1.0;
}

const increasing = ev.which === $.ui.keyCode.UP;
const increasing = ev.key === "ArrowUp";
const hasMin = ('min' in params);
const hasMax = ('max' in params);

Expand Down Expand Up @@ -2947,7 +2947,7 @@ const Many2oneUserValueWidget = SelectUserValueWidget.extend({
* @private
*/
_onSearchKeydown(ev) {
if (ev.which !== $.ui.keyCode.ENTER) {
if (ev.key !== "Enter") {
return;
}
const action = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -968,7 +968,7 @@ export class ColorPalette extends Component {
* @param {Event} ev
*/
_onGradientInputKeyPress(ev) {
if (ev.charCode === $.ui.keyCode.ENTER) {
if (ev.key === "Enter") {
ev.preventDefault();
this._onGradientInputChange();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ export class LinkTools extends Link {
* @param {Event} ev
*/
_onKeyPressCustomBorderWidth(ev) {
if (ev.keyCode === $.ui.keyCode.ENTER) {
if (ev.key === "Enter") {
this._onChangeCustomBorderWidth(ev);
}
}
Expand Down
Loading

0 comments on commit e6c747b

Please sign in to comment.