Skip to content

Commit

Permalink
Pop open a message when user deletes an annotation
Browse files Browse the repository at this point in the history
When a user deletes any number of annotations, they are notified of the action
by a popup message with an undo button. Besides that, this change reuses the
existing messageBar CSS class from the new alt-text dialog as much as possible.
  • Loading branch information
ryzokuken committed Nov 18, 2024
1 parent 28490bd commit 87f3dc3
Show file tree
Hide file tree
Showing 12 changed files with 300 additions and 3 deletions.
1 change: 1 addition & 0 deletions gulpfile.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1152,6 +1152,7 @@ function buildComponents(defines, dir) {
"web/images/messageBar_*.svg",
"web/images/toolbarButton-{editorHighlight,menuArrow}.svg",
"web/images/cursor-*.svg",
"web/images/secondaryToolbarButton-documentProperties.svg",
];

return ordered([
Expand Down
21 changes: 21 additions & 0 deletions l10n/en-US/viewer.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -503,3 +503,24 @@ pdfjs-editor-alt-text-settings-editor-title = Alt text editor
pdfjs-editor-alt-text-settings-show-dialog-button-label = Show alt text editor right away when adding an image
pdfjs-editor-alt-text-settings-show-dialog-description = Helps you make sure all your images have alt text.
pdfjs-editor-alt-text-settings-close-button = Close
## "Annotations removed" bar

pdfjs-editor-undo-bar-message-highlight = Highlight removed
pdfjs-editor-undo-bar-message-freetext = Text removed
pdfjs-editor-undo-bar-message-ink = Drawing removed
pdfjs-editor-undo-bar-message-stamp = Image removed
# Variables:
# $count (Number) - the number of removed annotations.
pdfjs-editor-undo-bar-message-multiple =
{ $count ->
[one] { $count } annotation removed
*[other] { $count } annotations removed
}
pdfjs-editor-undo-bar-undo-button =
.title = Undo
pdfjs-editor-undo-bar-undo-button-label = Undo
pdfjs-editor-undo-bar-close-button =
.title = Close
pdfjs-editor-undo-bar-close-button-label = Close
3 changes: 3 additions & 0 deletions src/display/editor/annotation_editor_layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,9 @@ class AnnotationEditorLayer {
// Do nothing on right click.
return;
}

this.#uiManager._editorUndoBar?.hide();

this.#uiManager.showAllEditors(
"highlight",
true,
Expand Down
2 changes: 2 additions & 0 deletions src/display/editor/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,8 @@ class AnnotationEditor {

bindEvents(this, this.div, ["pointerdown"]);

this._uiManager._editorUndoBar?.hide();

return this.div;
}

Expand Down
2 changes: 2 additions & 0 deletions src/display/editor/ink.js
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,8 @@ class InkEditor extends AnnotationEditor {
});
}

this._uiManager._editorUndoBar?.hide();

this.#startDrawing(event.offsetX, event.offsetY);
}

Expand Down
14 changes: 13 additions & 1 deletion src/display/editor/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,8 @@ class AnnotationEditorUIManager {

#editorsToRescale = new Set();

_editorUndoBar = null;

#enableHighlightFloatingButton = false;

#enableUpdatedAddImage = false;
Expand Down Expand Up @@ -814,7 +816,8 @@ class AnnotationEditorUIManager {
enableHighlightFloatingButton,
enableUpdatedAddImage,
enableNewAltTextWhenAddingImage,
mlManager
mlManager,
editorUndoBar
) {
const signal = (this._signal = this.#abortController.signal);
this.#container = container;
Expand Down Expand Up @@ -849,6 +852,7 @@ class AnnotationEditorUIManager {
rotation: 0,
};
this.isShiftKeyDown = false;
this._editorUndoBar = editorUndoBar || null;

if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("TESTING")) {
Object.defineProperty(this, "reset", {
Expand Down Expand Up @@ -889,6 +893,7 @@ class AnnotationEditorUIManager {
clearTimeout(this.#translationTimeoutId);
this.#translationTimeoutId = null;
}
this._editorUndoBar?.destroy();
}

combinedSignal(ac) {
Expand Down Expand Up @@ -1640,6 +1645,8 @@ class AnnotationEditorUIManager {
this.setEditingState(false);
this.#disableAll();

this._editorUndoBar?.hide();

this.#updateModeCapability.resolve();
return;
}
Expand Down Expand Up @@ -2017,6 +2024,7 @@ class AnnotationEditorUIManager {
hasSomethingToRedo: true,
isEmpty: this.#isEmpty(),
});
this._editorUndoBar?.hide();
}

/**
Expand Down Expand Up @@ -2069,6 +2077,10 @@ class AnnotationEditorUIManager {

const editors = [...this.#selectedEditors];
const cmd = () => {
this._editorUndoBar?.show(
undo,
editors.length === 1 ? editors[0].editorType : editors.length
);
for (const editor of editors) {
editor.remove();
}
Expand Down
28 changes: 27 additions & 1 deletion web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import { AltTextManager } from "web-alt_text_manager";
import { AnnotationEditorParams } from "web-annotation_editor_params";
import { CaretBrowsingMode } from "./caret_browsing.js";
import { DownloadManager } from "web-download_manager";
import { EditorUndoBar } from "./editor_undo_bar.js";
import { OverlayManager } from "./overlay_manager.js";
import { PasswordPrompt } from "./password_prompt.js";
import { PDFAttachmentViewer } from "web-pdf_attachment_viewer";
Expand Down Expand Up @@ -182,6 +183,7 @@ const PDFViewerApplication = {
_isCtrlKeyDown: false,
_caretBrowsing: null,
_isScrolling: false,
editorUndoBar: null,

// Called once when the document is loaded.
async initialize(appConfig) {
Expand Down Expand Up @@ -451,6 +453,10 @@ const PDFViewerApplication = {
: null;
}

if (appConfig.editorUndoBar) {
this.editorUndoBar = new EditorUndoBar(appConfig.editorUndoBar, eventBus);
}

const enableHWA = AppOptions.get("enableHWA");
const pdfViewer = new PDFViewer({
container,
Expand All @@ -460,6 +466,7 @@ const PDFViewerApplication = {
linkService: pdfLinkService,
downloadManager,
altTextManager,
editorUndoBar: this.editorUndoBar,
findController,
scriptingManager:
AppOptions.get("enableScripting") && pdfScriptingManager,
Expand Down Expand Up @@ -2747,7 +2754,7 @@ function onTouchEnd(evt) {
this._touchUnusedFactor = 1;
}

function onClick(evt) {
function closeSecondaryToolbar(evt) {
if (!this.secondaryToolbar?.isOpen) {
return;
}
Expand All @@ -2764,6 +2771,20 @@ function onClick(evt) {
}
}

function closeEditorUndoBar(evt) {
if (!this.editorUndoBar?.isOpen) {
return;
}
if (this.appConfig.secondaryToolbar?.toolbar.contains(evt.target)) {
this.editorUndoBar.hide();
}
}

function onClick(evt) {
closeSecondaryToolbar.call(this, evt);
closeEditorUndoBar.call(this, evt);
}

function onKeyUp(evt) {
// evt.ctrlKey is false hence we use evt.key.
if (evt.key === "Control") {
Expand All @@ -2774,6 +2795,11 @@ function onKeyUp(evt) {
function onKeyDown(evt) {
this._isCtrlKeyDown = evt.key === "Control";

if (this.editorUndoBar?.isOpen && evt.keyCode !== 9 && evt.keyCode !== 16) {
// Hide undo bar on keypress except for Shift, Tab or Shift+Tab
this.editorUndoBar.hide();
}

if (this.overlayManager.active) {
return;
}
Expand Down
112 changes: 112 additions & 0 deletions web/editor_undo_bar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/* Copyright 2024 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

class EditorUndoBar {
#closeButton = null;

#container;

#eventBus = null;

#initController = null;

isOpen = false;

#message;

#showController = null;

#undoButton;

static #l10nMessages = Object.freeze({
highlight: "pdfjs-editor-undo-bar-message-highlight",
freetext: "pdfjs-editor-undo-bar-message-freetext",
stamp: "pdfjs-editor-undo-bar-message-stamp",
ink: "pdfjs-editor-undo-bar-message-ink",
_multiple: "pdfjs-editor-undo-bar-message-multiple",
});

constructor({ container, message, undoButton, closeButton }, eventBus) {
this.#container = container;
this.#message = message;
this.#undoButton = undoButton;
this.#closeButton = closeButton;
this.#eventBus = eventBus;
}

destroy() {
this.#initController?.abort();
this.#initController = null;

this.hide();
}

show(undoAction, messageData) {
if (!this.#initController) {
this.#initController = new AbortController();
const opts = { signal: this.#initController.signal };
const boundHide = this.hide.bind(this);

this.#closeButton.addEventListener("click", boundHide, opts);
this.#eventBus._on("beforeprint", boundHide, opts);
this.#eventBus._on("download", boundHide, opts);
}

this.hide();

if (typeof messageData === "string") {
this.#message.setAttribute(
"data-l10n-id",
EditorUndoBar.#l10nMessages[messageData]
);
} else {
this.#message.setAttribute(
"data-l10n-id",
EditorUndoBar.#l10nMessages._multiple
);
this.#message.setAttribute(
"data-l10n-args",
JSON.stringify({ count: messageData })
);
}
this.isOpen = true;
this.#container.hidden = false;

this.#showController = new AbortController();

this.#undoButton.addEventListener(
"click",
() => {
undoAction();
this.hide();
},
{ signal: this.#showController.signal }
);
this.#undoButton.focus();
}

hide() {
if (!this.isOpen) {
return;
}
this.isOpen = false;
this.#container.hidden = true;

this.#showController?.abort();
this.#showController = null;
}
}

export { EditorUndoBar };
Loading

0 comments on commit 87f3dc3

Please sign in to comment.