[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:
@@ -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([]);
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user