mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-02-08 00:21:11 +01:00
Bug 1999154 - Add the ability to undo comment deletion
This commit is contained in:
parent
6a4a3b060d
commit
d9f67bd8ee
@ -561,6 +561,7 @@ pdfjs-editor-undo-bar-message-freetext = Text removed
|
||||
pdfjs-editor-undo-bar-message-ink = Drawing removed
|
||||
pdfjs-editor-undo-bar-message-stamp = Image removed
|
||||
pdfjs-editor-undo-bar-message-signature = Signature removed
|
||||
pdfjs-editor-undo-bar-message-comment = Comment removed
|
||||
# Variables:
|
||||
# $count (Number) - the number of removed annotations.
|
||||
pdfjs-editor-undo-bar-message-multiple =
|
||||
|
||||
@ -1177,6 +1177,22 @@ class AnnotationEditorUIManager {
|
||||
this.#commentManager?.removeComments([editor.uid]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a comment from an editor with undo support.
|
||||
* @param {AnnotationEditor} editor - The editor whose comment to delete.
|
||||
* @param {string} savedComment - The comment text to save for undo.
|
||||
*/
|
||||
deleteComment(editor, savedComment) {
|
||||
const undo = () => {
|
||||
editor.comment = savedComment;
|
||||
};
|
||||
const cmd = () => {
|
||||
this._editorUndoBar?.show(undo, "comment");
|
||||
editor.comment = null;
|
||||
};
|
||||
this.addCommands({ cmd, undo, mustExec: true });
|
||||
}
|
||||
|
||||
toggleComment(editor, isSelected, visibility = undefined) {
|
||||
this.#commentManager?.toggleCommentPopup(editor, isSelected, visibility);
|
||||
}
|
||||
|
||||
@ -965,4 +965,159 @@ describe("Comment", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Undo deletion popup for comments (bug 1999154)", () => {
|
||||
let pages;
|
||||
|
||||
beforeEach(async () => {
|
||||
pages = await loadAndWait(
|
||||
"tracemonkey.pdf",
|
||||
".annotationEditorLayer",
|
||||
"page-fit",
|
||||
null,
|
||||
{ enableComment: true }
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await closePages(pages);
|
||||
});
|
||||
|
||||
it("must check that deleting a comment can be undone using the undo button", async () => {
|
||||
await Promise.all(
|
||||
pages.map(async ([browserName, page]) => {
|
||||
await switchToHighlight(page);
|
||||
await highlightSpan(page, 1, "Abstract");
|
||||
const editorSelector = getEditorSelector(0);
|
||||
const comment = "Test comment for undo";
|
||||
await editComment(page, editorSelector, comment);
|
||||
|
||||
// Stay in highlight mode - don't disable it
|
||||
await waitAndClick(
|
||||
page,
|
||||
`${editorSelector} .annotationCommentButton`
|
||||
);
|
||||
|
||||
await page.waitForSelector("#commentPopup", { visible: true });
|
||||
await waitAndClick(page, "button.commentPopupDelete");
|
||||
|
||||
await page.waitForSelector("#editorUndoBar", { visible: true });
|
||||
await page.waitForSelector("#editorUndoBarUndoButton", {
|
||||
visible: true,
|
||||
});
|
||||
await page.click("#editorUndoBarUndoButton");
|
||||
|
||||
// Check that the comment is restored by hovering to show the popup
|
||||
await page.hover(`${editorSelector} .annotationCommentButton`);
|
||||
await page.waitForSelector("#commentPopup", { visible: true });
|
||||
const popupText = await page.evaluate(
|
||||
() =>
|
||||
document.querySelector("#commentPopup .commentPopupText")
|
||||
?.textContent
|
||||
);
|
||||
expect(popupText).withContext(`In ${browserName}`).toEqual(comment);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it("must check that the undo deletion popup displays 'Comment removed' message", async () => {
|
||||
await Promise.all(
|
||||
pages.map(async ([browserName, page]) => {
|
||||
await switchToHighlight(page);
|
||||
await highlightSpan(page, 1, "Abstract");
|
||||
const editorSelector = getEditorSelector(0);
|
||||
await editComment(page, editorSelector, "Test comment");
|
||||
|
||||
// Stay in highlight mode - don't disable it
|
||||
await waitAndClick(
|
||||
page,
|
||||
`${editorSelector} .annotationCommentButton`
|
||||
);
|
||||
|
||||
await page.waitForSelector("#commentPopup", { visible: true });
|
||||
await waitAndClick(page, "button.commentPopupDelete");
|
||||
|
||||
await page.waitForFunction(() => {
|
||||
const messageElement = document.querySelector(
|
||||
"#editorUndoBarMessage"
|
||||
);
|
||||
return messageElement && messageElement.textContent.trim() !== "";
|
||||
});
|
||||
const message = await page.waitForSelector("#editorUndoBarMessage");
|
||||
const messageText = await page.evaluate(
|
||||
el => el.textContent,
|
||||
message
|
||||
);
|
||||
expect(messageText)
|
||||
.withContext(`In ${browserName}`)
|
||||
.toContain("Comment removed");
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it("must check that the undo bar closes when clicking the close button", async () => {
|
||||
await Promise.all(
|
||||
pages.map(async ([browserName, page]) => {
|
||||
await switchToHighlight(page);
|
||||
await highlightSpan(page, 1, "Abstract");
|
||||
const editorSelector = getEditorSelector(0);
|
||||
await editComment(page, editorSelector, "Test comment");
|
||||
|
||||
// Stay in highlight mode - don't disable it
|
||||
await waitAndClick(
|
||||
page,
|
||||
`${editorSelector} .annotationCommentButton`
|
||||
);
|
||||
|
||||
await page.waitForSelector("#commentPopup", { visible: true });
|
||||
await waitAndClick(page, "button.commentPopupDelete");
|
||||
|
||||
await page.waitForSelector("#editorUndoBar", { visible: true });
|
||||
await waitAndClick(page, "#editorUndoBarCloseButton");
|
||||
await page.waitForSelector("#editorUndoBar", { hidden: true });
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it("must check that deleting a comment can be undone using Ctrl+Z", async () => {
|
||||
await Promise.all(
|
||||
pages.map(async ([browserName, page]) => {
|
||||
await switchToHighlight(page);
|
||||
await highlightSpan(page, 1, "Abstract");
|
||||
const editorSelector = getEditorSelector(0);
|
||||
const comment = "Test comment for Ctrl+Z undo";
|
||||
await editComment(page, editorSelector, comment);
|
||||
|
||||
// Stay in highlight mode - don't disable it
|
||||
await waitAndClick(
|
||||
page,
|
||||
`${editorSelector} .annotationCommentButton`
|
||||
);
|
||||
|
||||
await page.waitForSelector("#commentPopup", { visible: true });
|
||||
await waitAndClick(page, "button.commentPopupDelete");
|
||||
|
||||
await page.waitForSelector("#editorUndoBar", { visible: true });
|
||||
|
||||
// Use Ctrl+Z to undo
|
||||
await kbModifierDown(page);
|
||||
await page.keyboard.press("z");
|
||||
await kbModifierUp(page);
|
||||
|
||||
// The undo bar should be hidden after undo
|
||||
await page.waitForSelector("#editorUndoBar", { hidden: true });
|
||||
|
||||
// Check that the comment is restored by hovering to show the popup
|
||||
await page.hover(`${editorSelector} .annotationCommentButton`);
|
||||
await page.waitForSelector("#commentPopup", { visible: true });
|
||||
const popupText = await page.evaluate(
|
||||
() =>
|
||||
document.querySelector("#commentPopup .commentPopupText")
|
||||
?.textContent
|
||||
);
|
||||
expect(popupText).withContext(`In ${browserName}`).toEqual(comment);
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -982,9 +982,15 @@ class CommentPopup {
|
||||
},
|
||||
},
|
||||
});
|
||||
this.#editor.comment = null;
|
||||
this.#editor.focus();
|
||||
const savedComment = this.#editor.comment?.text;
|
||||
const editor = this.#editor;
|
||||
this.destroy();
|
||||
if (savedComment) {
|
||||
editor._uiManager.deleteComment(editor, savedComment);
|
||||
} else {
|
||||
editor.comment = null;
|
||||
}
|
||||
editor.focus();
|
||||
});
|
||||
del.addEventListener("contextmenu", noContextMenu);
|
||||
buttons.append(edit, del);
|
||||
|
||||
@ -40,6 +40,7 @@ class EditorUndoBar {
|
||||
stamp: "pdfjs-editor-undo-bar-message-stamp",
|
||||
ink: "pdfjs-editor-undo-bar-message-ink",
|
||||
signature: "pdfjs-editor-undo-bar-message-signature",
|
||||
comment: "pdfjs-editor-undo-bar-message-comment",
|
||||
_multiple: "pdfjs-editor-undo-bar-message-multiple",
|
||||
});
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user