[FIX] mail: fix debounce onchangeOnKeydownMixin

UseDebounce to avoid executing debounced code when the component
is unmounted. This prevents crashes.

closes odoo/odoo#131782

X-original-commit: c81714a3eb5825758637cacaf830b63b2e5dfdd5
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Signed-off-by: Francois Georis (fge) <fge@odoo.com>
This commit is contained in:
FrancoisGe
2023-08-12 20:05:48 +02:00
parent a024d150cf
commit 41def9680a
2 changed files with 50 additions and 6 deletions
@@ -1,9 +1,9 @@
/* @odoo-module */
import { patch } from "@web/core/utils/patch";
import { debounce } from "@web/core/utils/timing";
import { CharField, charField } from "@web/views/fields/char/char_field";
import { TextField, textField } from "@web/views/fields/text/text_field";
import { useDebounced } from "@web/core/utils/timing";
import { charField, CharField } from "@web/views/fields/char/char_field";
import { textField, TextField } from "@web/views/fields/text/text_field";
import { archParseBoolean } from "@web/views/utils";
const { useEffect } = owl;
@@ -21,10 +21,16 @@ const onchangeOnKeydownMixin = () => ({
if (this.props.onchangeOnKeydown) {
const input = this.input || this.textareaRef;
const triggerOnChange = debounce(this.triggerOnChange, this.props.keydownDebounceDelay);
const triggerOnChange = useDebounced(
this.triggerOnChange,
this.props.keydownDebounceDelay
);
useEffect(() => {
if (input.el) {
input.el.addEventListener("keydown", triggerOnChange.bind(this));
input.el.addEventListener("keydown", triggerOnChange);
return () => {
input.el.removeEventListener("keydown", triggerOnChange);
};
}
});
}
@@ -1,24 +1,34 @@
/* @odoo-module */
import { nextTick } from "@web/../tests/helpers/utils";
import {
editInput,
getFixture,
mockTimeout,
nextTick,
triggerEvent,
} from "@web/../tests/helpers/utils";
import { makeView, setupViewRegistries } from "@web/../tests/views/helpers";
import { dom } from "@web/../tests/legacy/helpers/test_utils";
let serverData;
let target;
QUnit.module("onchange on keydown", {
async beforeEach() {
target = getFixture();
serverData = {
models: {
"res.partner": {
fields: {
id: { type: "integer" },
description: { type: "text" },
display_name: { type: "char" },
},
records: [
{
id: 1,
description: "",
display_name: "first record",
},
],
onchanges: {
@@ -74,3 +84,31 @@ QUnit.test(
await nextTick();
}
);
QUnit.test(
"Editing a text field with the onchange_on_keydown option disappearing shouldn't trigger a crash",
async function (assert) {
const { execRegisteredTimeouts } = mockTimeout();
await makeView({
type: "form",
resModel: "res.partner",
serverData,
resId: 1,
arch: `
<form>
<field name="description" onchange_on_keydown="True" attrs="{'invisible': [('display_name','=','yop')]}"/>
<field name="display_name"/>
</form>`,
mockRPC(route, params) {
if (params.method === "onchange") {
assert.step("onchange");
}
},
});
await triggerEvent(target, 'textarea[id="description_0"]', "keydown", { key: "a" });
await editInput(target, "[name=display_name] input", "yop");
await execRegisteredTimeouts();
assert.verifySteps([]);
}
);