[FIX] web: codeEditor: initial value is not up to be undone

Open the code editor (wrapper around aceEditor) with an initial value -- in Odoo, that is any instance of the code editor.
Press Ctrl+Z.

Before this commit, the value disappears -- is undone -- even though no real change happened.
This was because we used editor.setValue, instead of editor.session.setValue. The latter resetting the undo history.

This behavior is "documented" [here: Common Operations](https://ace.c9.io/#nav=howto) with:
```js
//Set and get content:

editor.setValue("the new text here");
editor.setValue("text2", -1); // set value and move cursor to the start of the text
editor.session.setValue("the new text here"); // set value and reset undo history
editor.getValue(); // or session.getValue
```

After this commit, the initial value is not undoable.

opw-3793546

closes odoo/odoo#158548

X-original-commit: b33086599383a4c0ab43126598a63e8721f682fc
Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
This commit is contained in:
Lucas Perais
2024-03-21 23:03:04 +00:00
parent 7a73e120ca
commit d8024733a7
2 changed files with 38 additions and 2 deletions
@@ -89,7 +89,7 @@ export class CodeEditor extends Component {
if (!sessions[this.props.sessionId]) {
sessions[this.props.sessionId] = session;
}
aceEditor.setValue(this.props.value);
session.setValue(this.props.value);
session.on("change", () => {
if (this.props.onChange && !ignoredAceChange) {
this.props.onChange(this.aceEditor.getValue());
@@ -8,6 +8,7 @@ import {
mount,
nextTick,
editInput,
triggerEvents,
} from "@web/../tests/helpers/utils";
import { Component, markup, useState, xml } from "@odoo/owl";
@@ -184,7 +185,8 @@ QUnit.module("Web Components", (hooks) => {
const codeEditor = await mount(Parent, target, { env });
await nextTick();
assert.equal(getDomValue(), textA, "Default value correctly set");
const aceEditor = window.ace.edit(target.querySelector(".ace_editor"));
aceEditor.selectAll();
await edit(textB);
assert.equal(
getDomValue(),
@@ -261,4 +263,38 @@ QUnit.module("Web Components", (hooks) => {
await nextTick();
assert.verifySteps(["ace/theme/monokai"], "Monokai theme should be loaded");
});
QUnit.test("initial value cannot be undone", async (assert) => {
class Parent extends Component {
static components = { CodeEditor };
static template = xml`<CodeEditor mode="'xml'" value="'some value'" />`;
}
await mount(Parent, target, { env });
await nextTick();
assert.containsOnce(target, ".ace_editor", "Code editor is rendered");
assert.strictEqual(
target.querySelector(".ace_editor .ace_content").textContent,
"some value"
);
const editor = window.ace.edit(target.querySelector(".ace_editor"));
const undo = editor.session.$undoManager.undo.bind(editor.session.$undoManager);
editor.session.$undoManager.undo = (...args) => {
assert.step("ace undo");
return undo(...args);
};
await triggerEvents(target, ".ace_editor textarea.ace_text-input", [
["keydown", { key: "Control", keyCode: 17, which: 17 }],
["keypress", { key: "Control", ctrlKey: true, keyCode: 17, which: 17 }],
["keydown", { key: "z", ctrlKey: true, keyCode: 90, which: 90 }],
["keypress", { key: "z", ctrlKey: true, keyCode: 90, which: 90 }],
["keyup", { key: "z", ctrlKey: true, keyCode: 90, which: 90 }],
["keyup", { key: "Control", keyCode: 17, which: 17 }],
]);
await nextTick();
assert.strictEqual(
target.querySelector(".ace_editor .ace_content").textContent,
"some value"
);
assert.verifySteps(["ace undo"]);
});
});