From 4acc086292301b8c43e30fa1a15f8afb426ee373 Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Fri, 29 Nov 2024 16:22:44 +0100 Subject: [PATCH] [Editor] Allow to abort the current drawing It fixes #19126. --- src/display/editor/annotation_editor_layer.js | 6 +-- src/display/editor/draw.js | 43 +++++++++++------- src/display/editor/tools.js | 9 +++- test/integration/ink_editor_spec.mjs | 45 +++++++++++++++++++ test/integration/test_utils.mjs | 9 ++++ 5 files changed, 91 insertions(+), 21 deletions(-) diff --git a/src/display/editor/annotation_editor_layer.js b/src/display/editor/annotation_editor_layer.js index 72ee6c57a5579..fbc5bc52869eb 100644 --- a/src/display/editor/annotation_editor_layer.js +++ b/src/display/editor/annotation_editor_layer.js @@ -820,14 +820,14 @@ class AnnotationEditorLayer { this.#currentEditorType.startDrawing(this, this.#uiManager, false, event); } - endDrawingSession() { + endDrawingSession(isAborted = false) { if (!this.#drawingAC) { - return; + return null; } this.#drawingAC.abort(); this.#drawingAC = null; this.#uiManager.disableUserSelect(false); - this.#currentEditorType.endDrawing(); + return this.#currentEditorType.endDrawing(isAborted); } /** diff --git a/src/display/editor/draw.js b/src/display/editor/draw.js index f9cf60fa95005..553c5708fd343 100644 --- a/src/display/editor/draw.js +++ b/src/display/editor/draw.js @@ -739,13 +739,13 @@ class DrawingEditor extends AnnotationEditor { return; } - this.endDrawing(); + this.endDrawing(/* isAborted = */ false); } - static endDrawing() { + static endDrawing(isAborted) { const parent = this._currentParent; if (!parent) { - return; + return null; } parent.toggleDrawing(true); parent.cleanUndoStack(AnnotationEditorParamsType.DRAW_STEP); @@ -756,20 +756,31 @@ class DrawingEditor extends AnnotationEditor { scale, } = parent; - parent.createAndAddNewEditor({ offsetX: 0, offsetY: 0 }, false, { - drawId: this._currentDrawId, - drawOutlines: this._currentDraw.getOutlines( - pageWidth * scale, - pageHeight * scale, - scale, - this._INNER_MARGIN - ), - drawingOptions: this._currentDrawingOptions, - mustBeCommitted: true, - }); - } else { - parent.drawLayer.remove(this._currentDrawId); + const editor = parent.createAndAddNewEditor( + { offsetX: 0, offsetY: 0 }, + false, + { + drawId: this._currentDrawId, + drawOutlines: this._currentDraw.getOutlines( + pageWidth * scale, + pageHeight * scale, + scale, + this._INNER_MARGIN + ), + drawingOptions: this._currentDrawingOptions, + mustBeCommitted: !isAborted, + } + ); + this._cleanup(); + return editor; } + + parent.drawLayer.remove(this._currentDrawId); + this._cleanup(); + return null; + } + + static _cleanup() { this._currentDrawId = -1; this._currentDraw = null; this._currentDrawingOptions = null; diff --git a/src/display/editor/tools.js b/src/display/editor/tools.js index b8ce3bec393b5..d608324885a28 100644 --- a/src/display/editor/tools.js +++ b/src/display/editor/tools.js @@ -2088,11 +2088,16 @@ class AnnotationEditorUIManager { */ delete() { this.commitOrRemove(); - if (!this.hasSelection) { + const drawingEditor = this.currentLayer?.endDrawingSession( + /* isAborted = */ true + ); + if (!this.hasSelection && !drawingEditor) { return; } - const editors = [...this.#selectedEditors]; + const editors = drawingEditor + ? [drawingEditor] + : [...this.#selectedEditors]; const cmd = () => { for (const editor of editors) { editor.remove(); diff --git a/test/integration/ink_editor_spec.mjs b/test/integration/ink_editor_spec.mjs index 67fe9fccfbdfc..3375b58463502 100644 --- a/test/integration/ink_editor_spec.mjs +++ b/test/integration/ink_editor_spec.mjs @@ -26,6 +26,7 @@ import { loadAndWait, scrollIntoView, switchToEditor, + waitForNoElement, waitForSerialized, waitForStorageEntries, } from "./test_utils.mjs"; @@ -567,4 +568,48 @@ describe("Ink Editor", () => { ); }); }); + + describe("Can delete the drawing in progress and undo the deletion", () => { + let pages; + + beforeAll(async () => { + pages = await loadAndWait("empty.pdf", ".annotationEditorLayer"); + }); + + afterAll(async () => { + await closePages(pages); + }); + + it("must check that the color has been changed", async () => { + await Promise.all( + pages.map(async ([browserName, page]) => { + await switchToInk(page); + + const rect = await getRect(page, ".annotationEditorLayer"); + + const x = rect.x + 20; + const y = rect.y + 20; + const clickHandle = await waitForPointerUp(page); + await page.mouse.move(x, y); + await page.mouse.down(); + await page.mouse.move(x + 50, y + 50); + await page.mouse.up(); + await awaitPromise(clickHandle); + + const drawSelector = `.canvasWrapper svg.draw path[d]:not([d=""])`; + await page.waitForSelector(drawSelector); + + await page.keyboard.press("Backspace"); + + const editorSelector = getEditorSelector(0); + await waitForNoElement(page, drawSelector); + await waitForNoElement(page, editorSelector); + + await kbUndo(page); + await page.waitForSelector(editorSelector, { visible: true }); + await page.waitForSelector(drawSelector); + }) + ); + }); + }); }); diff --git a/test/integration/test_utils.mjs b/test/integration/test_utils.mjs index 4cdc400bffe34..65213567aa6c9 100644 --- a/test/integration/test_utils.mjs +++ b/test/integration/test_utils.mjs @@ -773,6 +773,14 @@ async function switchToEditor(name, page, disable = false) { await awaitPromise(modeChangedHandle); } +function waitForNoElement(page, selector) { + return page.waitForFunction( + sel => !document.querySelector(sel), + {}, + selector + ); +} + export { applyFunctionToEditor, awaitPromise, @@ -826,6 +834,7 @@ export { waitForAnnotationModeChanged, waitForEntryInStorage, waitForEvent, + waitForNoElement, waitForPageRendered, waitForSandboxTrip, waitForSelectedEditor,