Skip to content

Commit 13d7c53

Browse files
ryzokukennicolo-ribaudo
authored andcommitted
Pop open a message when user deletes an annotation
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.
1 parent 8a37d90 commit 13d7c53

File tree

10 files changed

+193
-4
lines changed

10 files changed

+193
-4
lines changed

l10n/en-US/viewer.ftl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,3 +493,13 @@ pdfjs-editor-alt-text-settings-editor-title = Alt text editor
493493
pdfjs-editor-alt-text-settings-show-dialog-button-label = Show alt text editor right away when adding an image
494494
pdfjs-editor-alt-text-settings-show-dialog-description = Helps you make sure all your images have alt text.
495495
pdfjs-editor-alt-text-settings-close-button = Close
496+
497+
# Variables:
498+
# $type (String) - the type of annotation that was just removed with an optional quantity.
499+
pdfjs-editor-undo-bar-message = { $type } removed
500+
pdfjs-editor-undo-bar-undo-button =
501+
.title = Undo
502+
pdfjs-editor-undo-bar-undo-button-label = Undo
503+
pdfjs-editor-undo-bar-close-button =
504+
.title = Close
505+
pdfjs-editor-undo-bar-close-button-label = Close

src/display/editor/tools.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,8 @@ class AnnotationEditorUIManager {
562562

563563
#editorsToRescale = new Set();
564564

565+
#editorUndoBar = null;
566+
565567
#enableHighlightFloatingButton = false;
566568

567569
#enableUpdatedAddImage = false;
@@ -769,7 +771,8 @@ class AnnotationEditorUIManager {
769771
enableHighlightFloatingButton,
770772
enableUpdatedAddImage,
771773
enableNewAltTextWhenAddingImage,
772-
mlManager
774+
mlManager,
775+
editorUndoBar
773776
) {
774777
const signal = (this._signal = this.#abortController.signal);
775778
this.#container = container;
@@ -804,6 +807,7 @@ class AnnotationEditorUIManager {
804807
rotation: 0,
805808
};
806809
this.isShiftKeyDown = false;
810+
this.#editorUndoBar = editorUndoBar;
807811

808812
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("TESTING")) {
809813
Object.defineProperty(this, "reset", {
@@ -2002,6 +2006,12 @@ class AnnotationEditorUIManager {
20022006

20032007
const editors = [...this.#selectedEditors];
20042008
const cmd = () => {
2009+
this.#editorUndoBar?.show(
2010+
undo,
2011+
editors.length > 1
2012+
? `${editors.length} annotations`
2013+
: editors[0].editorType
2014+
);
20052015
for (const editor of editors) {
20062016
editor.remove();
20072017
}

web/app.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ import { AltTextManager } from "web-alt_text_manager";
6868
import { AnnotationEditorParams } from "web-annotation_editor_params";
6969
import { CaretBrowsingMode } from "./caret_browsing.js";
7070
import { DownloadManager } from "web-download_manager";
71+
import { EditorUndoBar } from "./editor_undo_bar.js";
7172
import { OverlayManager } from "./overlay_manager.js";
7273
import { PasswordPrompt } from "./password_prompt.js";
7374
import { PDFAttachmentViewer } from "web-pdf_attachment_viewer";
@@ -182,6 +183,7 @@ const PDFViewerApplication = {
182183
_isCtrlKeyDown: false,
183184
_caretBrowsing: null,
184185
_isScrolling: false,
186+
editorUndoBar: null,
185187

186188
// Called once when the document is loaded.
187189
async initialize(appConfig) {
@@ -450,6 +452,9 @@ const PDFViewerApplication = {
450452
)
451453
: null;
452454
}
455+
const editorUndoBar = (this.editorUndoBar = appConfig.editorUndoBar
456+
? new EditorUndoBar(appConfig.editorUndoBar, eventBus)
457+
: null);
453458

454459
const enableHWA = AppOptions.get("enableHWA");
455460
const pdfViewer = new PDFViewer({
@@ -460,6 +465,7 @@ const PDFViewerApplication = {
460465
linkService: pdfLinkService,
461466
downloadManager,
462467
altTextManager,
468+
editorUndoBar,
463469
findController,
464470
scriptingManager:
465471
AppOptions.get("enableScripting") && pdfScriptingManager,
@@ -2962,6 +2968,10 @@ function onKeyDown(evt) {
29622968
this.findBar.close();
29632969
handled = true;
29642970
}
2971+
if (this.editorUndoBar?.isOpen) {
2972+
this.editorUndoBar.hide();
2973+
handled = true;
2974+
}
29652975
break;
29662976
case 40: // down arrow
29672977
if (this.supportsCaretBrowsingMode) {

web/dialog.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,8 @@
291291
}
292292

293293
> div {
294-
&::before, > div {
294+
&::before,
295+
> div {
295296
margin-block: 4px;
296297
}
297298

web/editor_undo_bar.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/* Copyright 2024 Mozilla Foundation
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
class EditorUndoBar {
17+
#container;
18+
19+
#controller = null;
20+
21+
isOpen = false;
22+
23+
#message;
24+
25+
#undoButton;
26+
27+
constructor({ container, message, undoButton, closeButton }, eventBus) {
28+
this.#container = container;
29+
this.#message = message;
30+
this.#undoButton = undoButton;
31+
32+
// Caveat: we have to pick between registering these everytime the bar is
33+
// shown and not having the ability to cleanup using AbortController.
34+
const boundHide = this.hide.bind(this);
35+
closeButton.addEventListener("click", boundHide);
36+
eventBus._on("beforeprint", boundHide);
37+
eventBus._on("download", boundHide);
38+
}
39+
40+
show(action, type) {
41+
this.hide();
42+
this.#message.setAttribute("data-l10n-args", JSON.stringify({ type }));
43+
this.#container.hidden = false;
44+
this.isOpen = true;
45+
46+
this.#controller = new AbortController();
47+
const opts = { signal: this.#controller.signal };
48+
49+
this.#undoButton.addEventListener(
50+
"click",
51+
() => {
52+
action();
53+
this.hide();
54+
},
55+
opts
56+
);
57+
this.#undoButton.focus();
58+
}
59+
60+
hide() {
61+
if (!this.isOpen) {
62+
return;
63+
}
64+
this.isOpen = false;
65+
this.#container.hidden = true;
66+
this.#controller?.abort();
67+
this.#controller = null;
68+
}
69+
}
70+
71+
export { EditorUndoBar };

web/message_bar.css

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
/* Copyright 2024 Mozilla Foundation
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
116
.messageBar {
217
--closing-button-icon: url(images/messageBar_closingButton.svg);
318
--message-bar-close-button-color: var(--text-primary-color);
@@ -100,3 +115,51 @@
100115
}
101116
}
102117
}
118+
119+
#editorUndoBar {
120+
--message-bar-icon: url(images/secondaryToolbarButton-documentProperties.svg);
121+
--message-bar-icon-color: #0060df;
122+
--message-bar-bg-color: #deeafc;
123+
--message-bar-fg-color: #15141a;
124+
--text-primary-color: #15141a;
125+
--message-bar-border-color: rgb(0 0 0 / 0.08);
126+
127+
position: fixed;
128+
bottom: 100px;
129+
left: 50%;
130+
transform: translateX(-50%);
131+
132+
padding: 8px 8px 8px 16px;
133+
134+
font-family: sans-serif;
135+
font-size: 15px;
136+
137+
#editorUndoBarUndoButton {
138+
border-radius: 4px;
139+
font-weight: 590;
140+
line-height: 19.5px;
141+
color: #15141a;
142+
border: none;
143+
padding: 4px 16px;
144+
height: 32px;
145+
146+
background-color: rgba(21 20 26 / 0.07);
147+
148+
&:hover {
149+
background-color: rgba(21 20 26 / 0.14);
150+
}
151+
152+
&:active {
153+
background-color: rgba(21 20 26 / 0.21);
154+
}
155+
156+
&:focus {
157+
outline: 2px solid #0060df;
158+
outline-offset: 2px;
159+
}
160+
}
161+
162+
> div {
163+
align-items: center;
164+
}
165+
}

web/pdf_viewer.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212
* See the License for the specific language governing permissions and
1313
* limitations under the License.
1414
*/
15+
@import url(message_bar.css);
1516
@import url(dialog.css);
1617
@import url(text_layer_builder.css);
1718
@import url(annotation_layer_builder.css);
1819
@import url(xfa_layer_builder.css);
19-
@import url(message_bar.css);
2020
/* Ignored in GECKOVIEW builds: */
2121
@import url(annotation_editor_layer_builder.css);
2222

web/pdf_viewer.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ class PDFViewer {
213213

214214
#containerTopLeft = null;
215215

216+
#editorUndoBar = null;
217+
216218
#enableHWA = false;
217219

218220
#enableHighlightFloatingButton = false;
@@ -280,6 +282,7 @@ class PDFViewer {
280282
this.downloadManager = options.downloadManager || null;
281283
this.findController = options.findController || null;
282284
this.#altTextManager = options.altTextManager || null;
285+
this.#editorUndoBar = options.editorUndoBar || null;
283286

284287
if (this.findController) {
285288
this.findController.onIsPageVisible = pageNumber =>
@@ -901,7 +904,8 @@ class PDFViewer {
901904
this.#enableHighlightFloatingButton,
902905
this.#enableUpdatedAddImage,
903906
this.#enableNewAltTextWhenAddingImage,
904-
this.#mlManager
907+
this.#mlManager,
908+
this.#editorUndoBar
905909
);
906910
eventBus.dispatch("annotationeditoruimanager", {
907911
source: this,

web/viewer.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,20 @@
686686
<!--#endif-->
687687
</div> <!-- dialogContainer -->
688688

689+
<div id="editorUndoBar" class="messageBar" hidden>
690+
<div>
691+
<div>
692+
<span id="editorUndoBarMessage" class="description" data-l10n-id="pdfjs-editor-undo-bar-message" data-l10n-args='{ "type": "Annotation" }'>[Annotation] removed</span>
693+
</div>
694+
<button id="editorUndoBarUndoButton" class="undoButton" type="button" tabindex="0" title="Undo" data-l10n-id="pdfjs-editor-undo-bar-undo-button">
695+
<span data-l10n-id="pdfjs-editor-undo-bar-undo-button-label">Undo</span>
696+
</button>
697+
<button id="editorUndoBarCloseButton" class="closeButton" type="button" tabindex="0" title="Close" data-l10n-id="pdfjs-editor-undo-bar-close-button">
698+
<span data-l10n-id="pdfjs-editor-undo-bar-close-button-label">Close</span>
699+
</button>
700+
</div>
701+
</div> <!-- editorUndoBar -->
702+
689703
</div> <!-- outerContainer -->
690704
<div id="printContainer"></div>
691705
</body>

web/viewer.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,12 @@ function getViewerConfiguration() {
223223
editorHighlightShowAll: document.getElementById("editorHighlightShowAll"),
224224
},
225225
printContainer: document.getElementById("printContainer"),
226+
editorUndoBar: {
227+
container: document.getElementById("editorUndoBar"),
228+
message: document.getElementById("editorUndoBarMessage"),
229+
undoButton: document.getElementById("editorUndoBarUndoButton"),
230+
closeButton: document.getElementById("editorUndoBarCloseButton"),
231+
},
226232
};
227233
}
228234

0 commit comments

Comments
 (0)