Skip to content

Commit 1869767

Browse files
calixtemanpull[bot]
authored andcommitted
[Editor] Allow to undo/redo committed text modifications for FreeText
1 parent 04bb59b commit 1869767

File tree

2 files changed

+111
-9
lines changed

2 files changed

+111
-9
lines changed

src/display/editor/freetext.js

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,26 @@ class FreeTextEditor extends AnnotationEditor {
355355
}
356356

357357
this.disableEditMode();
358-
this.#content = this.#extractText().trimEnd();
358+
const savedText = this.#content;
359+
const newText = (this.#content = this.#extractText().trimEnd());
360+
if (savedText === newText) {
361+
return;
362+
}
359363

364+
const setText = text => {
365+
this.#content = text;
366+
this.#setContent();
367+
this.#setEditorDimensions();
368+
};
369+
this.addCommands({
370+
cmd: () => {
371+
setText(newText);
372+
},
373+
undo: () => {
374+
setText(savedText);
375+
},
376+
mustExec: false,
377+
});
360378
this.#setEditorDimensions();
361379
}
362380

@@ -466,14 +484,7 @@ class FreeTextEditor extends AnnotationEditor {
466484
this.height * parentHeight
467485
);
468486

469-
for (const line of this.#content.split("\n")) {
470-
const div = document.createElement("div");
471-
div.append(
472-
line ? document.createTextNode(line) : document.createElement("br")
473-
);
474-
this.editorDiv.append(div);
475-
}
476-
487+
this.#setContent();
477488
this.div.draggable = true;
478489
this.editorDiv.contentEditable = false;
479490
} else {
@@ -484,6 +495,20 @@ class FreeTextEditor extends AnnotationEditor {
484495
return this.div;
485496
}
486497

498+
#setContent() {
499+
this.editorDiv.replaceChildren();
500+
if (!this.#content) {
501+
return;
502+
}
503+
for (const line of this.#content.split("\n")) {
504+
const div = document.createElement("div");
505+
div.append(
506+
line ? document.createTextNode(line) : document.createElement("br")
507+
);
508+
this.editorDiv.append(div);
509+
}
510+
}
511+
487512
get contentDiv() {
488513
return this.editorDiv;
489514
}

test/integration/freetext_editor_spec.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,83 @@ describe("Editor", () => {
343343
})
344344
);
345345
});
346+
347+
it("must check that text change can be undone/redone", async () => {
348+
// Run sequentially to avoid clipboard issues.
349+
for (const [browserName, page] of pages) {
350+
const rect = await page.$eval(".annotationEditorLayer", el => {
351+
const { x, y } = el.getBoundingClientRect();
352+
return { x, y };
353+
});
354+
355+
await page.keyboard.down("Control");
356+
await page.keyboard.press("a");
357+
await page.keyboard.up("Control");
358+
359+
await page.keyboard.down("Control");
360+
await page.keyboard.press("Backspace");
361+
await page.keyboard.up("Control");
362+
363+
await page.mouse.click(rect.x + 200, rect.y + 100);
364+
365+
for (let i = 0; i < 5; i++) {
366+
await page.type(`${getEditorSelector(9)} .internal`, "A");
367+
368+
const editorRect = await page.$eval(getEditorSelector(9), el => {
369+
const { x, y, width, height } = el.getBoundingClientRect();
370+
return { x, y, width, height };
371+
});
372+
373+
// Commit.
374+
await page.mouse.click(
375+
editorRect.x,
376+
editorRect.y + 2 * editorRect.height
377+
);
378+
379+
if (i < 4) {
380+
// And select it again.
381+
await page.mouse.click(
382+
editorRect.x + editorRect.width / 2,
383+
editorRect.y + editorRect.height / 2,
384+
{ clickCount: 2 }
385+
);
386+
}
387+
}
388+
389+
await page.keyboard.down("Control");
390+
await page.keyboard.press("z");
391+
await page.keyboard.up("Control");
392+
await page.waitForTimeout(10);
393+
394+
let text = await page.$eval(`${getEditorSelector(9)} .internal`, el => {
395+
return el.innerText;
396+
});
397+
398+
expect(text).withContext(`In ${browserName}`).toEqual("AAAA");
399+
400+
await page.keyboard.down("Control");
401+
await page.keyboard.press("z");
402+
await page.keyboard.up("Control");
403+
await page.waitForTimeout(10);
404+
405+
text = await page.$eval(`${getEditorSelector(9)} .internal`, el => {
406+
return el.innerText;
407+
});
408+
409+
expect(text).withContext(`In ${browserName}`).toEqual("AAA");
410+
411+
await page.keyboard.down("Control");
412+
await page.keyboard.press("y");
413+
await page.keyboard.up("Control");
414+
await page.waitForTimeout(10);
415+
416+
text = await page.$eval(`${getEditorSelector(9)} .internal`, el => {
417+
return el.innerText;
418+
});
419+
420+
expect(text).withContext(`In ${browserName}`).toEqual("AAAA");
421+
}
422+
});
346423
});
347424

348425
describe("FreeText (multiselection)", () => {

0 commit comments

Comments
 (0)