[Editor] Add a new popup for comments (bug 1987425)

And:
 - improve the editing dialog in removing menu;
 - position correctly the popup on the left/right depending on the direction value.
This commit is contained in:
Calixte Denizet 2025-09-08 18:27:12 +02:00
parent d77f89026f
commit b660b721f9
19 changed files with 1337 additions and 703 deletions

View File

@ -71,6 +71,10 @@
"type": "string", "type": "string",
"default": "" "default": ""
}, },
"commentLearnMoreUrl": {
"type": "string",
"default": ""
},
"enableSignatureEditor": { "enableSignatureEditor": {
"type": "boolean", "type": "boolean",
"default": false "default": false

View File

@ -414,7 +414,8 @@ pdfjs-editor-comments-sidebar-close-button =
pdfjs-editor-comments-sidebar-close-button-label = Close the sidebar pdfjs-editor-comments-sidebar-close-button-label = Close the sidebar
# Instructional copy to add a comment by selecting text or an annotations. # Instructional copy to add a comment by selecting text or an annotations.
pdfjs-editor-comments-sidebar-no-comments = Add a comment by selecting text or an annotation. pdfjs-editor-comments-sidebar-no-comments1 = See something noteworthy? Highlight it and leave a comment.
pdfjs-editor-comments-sidebar-no-comments-link = Learn more
## Alt-text dialog ## Alt-text dialog
@ -670,21 +671,28 @@ pdfjs-editor-edit-signature-dialog-title = Edit description
pdfjs-editor-edit-signature-update-button = Update pdfjs-editor-edit-signature-update-button = Update
## Comment popup
pdfjs-editor-edit-comment-popup-button-label = Edit comment
pdfjs-editor-edit-comment-popup-button =
.title = Edit comment
pdfjs-editor-delete-comment-popup-button-label = Remove comment
pdfjs-editor-delete-comment-popup-button =
.title = Remove comment
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Actions # An existing comment is edited
pdfjs-editor-edit-comment-actions-button = pdfjs-editor-edit-comment-dialog-title-when-editing = Edit comment
.title = Actions
pdfjs-editor-edit-comment-close-button-label = Close
pdfjs-editor-edit-comment-close-button =
.title = Close
pdfjs-editor-edit-comment-actions-edit-button-label = Edit
pdfjs-editor-edit-comment-actions-delete-button-label = Delete
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Enter your comment
pdfjs-editor-edit-comment-manager-cancel-button = Cancel # No existing comment
pdfjs-editor-edit-comment-manager-save-button = Save pdfjs-editor-edit-comment-dialog-title-when-adding = Add comment
pdfjs-editor-edit-comment-dialog-text-input =
.placeholder = Start typing…
pdfjs-editor-edit-comment-dialog-cancel-button = Cancel
pdfjs-editor-edit-comment-dialog-save-button = Save
## Edit a comment button in the editor toolbar ## Edit a comment button in the editor toolbar

View File

@ -334,7 +334,7 @@ class AnnotationEditorLayer {
if (editor?.annotationElementId === null) { if (editor?.annotationElementId === null) {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
editor.dblclick(); editor.dblclick(e);
} }
}, },
{ signal, capture: true } { signal, capture: true }

View File

@ -13,7 +13,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { noContextMenu } from "../display_utils.js"; import { noContextMenu, stopEvent } from "../display_utils.js";
class Comment { class Comment {
#commentStandaloneButton = null; #commentStandaloneButton = null;
@ -34,6 +34,8 @@ class Comment {
#deleted = false; #deleted = false;
#popupPosition = null;
constructor(editor) { constructor(editor) {
this.#editor = editor; this.#editor = editor;
} }
@ -42,7 +44,7 @@ class Comment {
const button = (this.#commentToolbarButton = const button = (this.#commentToolbarButton =
document.createElement("button")); document.createElement("button"));
button.className = "comment"; button.className = "comment";
return this.#render(button); return this.#render(button, false);
} }
renderForStandalone() { renderForStandalone() {
@ -66,16 +68,87 @@ class Comment {
} }
} }
return this.#render(button); return this.#render(button, true);
} }
#render(comment) { onUpdatedColor() {
if (!this.#commentStandaloneButton) {
return;
}
const color = this.#editor.commentButtonColor;
if (color) {
this.#commentStandaloneButton.style.backgroundColor = color;
}
this.#editor._uiManager.updatePopupColor(this.#editor);
}
get commentButtonWidth() {
return (
(this.#commentStandaloneButton?.getBoundingClientRect().width ?? 0) /
this.#editor.parent.boundingClientRect.width
);
}
get commentPopupPositionInLayer() {
if (this.#popupPosition) {
return this.#popupPosition;
}
if (!this.#commentStandaloneButton) {
return null;
}
const { x, y, height } =
this.#commentStandaloneButton.getBoundingClientRect();
const {
x: parentX,
y: parentY,
width: parentWidth,
height: parentHeight,
} = this.#editor.parent.boundingClientRect;
const OFFSET_UNDER_BUTTON = 2;
return [
(x - parentX) / parentWidth,
(y + height + OFFSET_UNDER_BUTTON - parentY) / parentHeight,
];
}
set commentPopupPositionInLayer(pos) {
this.#popupPosition = pos;
}
removeStandaloneCommentButton() {
this.#commentStandaloneButton?.remove();
this.#commentStandaloneButton = null;
}
removeToolbarCommentButton() {
this.#commentToolbarButton?.remove();
this.#commentToolbarButton = null;
}
setCommentButtonStates({ selected, hasPopup }) {
if (!this.#commentStandaloneButton) {
return;
}
this.#commentStandaloneButton.classList.toggle("selected", selected);
this.#commentStandaloneButton.ariaExpanded = hasPopup;
}
#render(comment, isStandalone) {
if (!this.#editor._uiManager.hasCommentManager()) { if (!this.#editor._uiManager.hasCommentManager()) {
return null; return null;
} }
comment.tabIndex = "0"; comment.tabIndex = "0";
comment.ariaHasPopup = "dialog";
if (isStandalone) {
comment.ariaControls = "commentPopup";
} else {
comment.ariaControlsElements = [
this.#editor._uiManager.getCommentDialogElement(),
];
comment.setAttribute("data-l10n-id", "pdfjs-editor-edit-comment-button"); comment.setAttribute("data-l10n-id", "pdfjs-editor-edit-comment-button");
}
const signal = this.#editor._uiManager._signal; const signal = this.#editor._uiManager._signal;
if (!(signal instanceof AbortSignal) || signal.aborted) { if (!(signal instanceof AbortSignal) || signal.aborted) {
@ -83,6 +156,30 @@ class Comment {
} }
comment.addEventListener("contextmenu", noContextMenu, { signal }); comment.addEventListener("contextmenu", noContextMenu, { signal });
if (isStandalone) {
comment.addEventListener(
"focusin",
e => {
this.#editor._focusEventsAllowed = false;
stopEvent(e);
},
{
capture: true,
signal,
}
);
comment.addEventListener(
"focusout",
e => {
this.#editor._focusEventsAllowed = true;
stopEvent(e);
},
{
capture: true,
signal,
}
);
}
comment.addEventListener("pointerdown", event => event.stopPropagation(), { comment.addEventListener("pointerdown", event => event.stopPropagation(), {
signal, signal,
}); });
@ -92,7 +189,7 @@ class Comment {
if (comment === this.#commentToolbarButton) { if (comment === this.#commentToolbarButton) {
this.edit(); this.edit();
} else { } else {
this.#editor._uiManager.toggleComment(this.#editor); this.#editor.toggleComment(/* isSelected = */ true);
} }
}; };
comment.addEventListener("click", onClick, { capture: true, signal }); comment.addEventListener("click", onClick, { capture: true, signal });
@ -107,18 +204,55 @@ class Comment {
{ signal } { signal }
); );
comment.addEventListener(
"pointerenter",
() => {
this.#editor.toggleComment(
/* isSelected = */ false,
/* visibility = */ true
);
},
{ signal }
);
comment.addEventListener(
"pointerleave",
() => {
this.#editor.toggleComment(
/* isSelected = */ false,
/* visibility = */ false
);
},
{ signal }
);
return comment; return comment;
} }
edit() { edit(options) {
const { bottom, left, right } = this.#editor.getClientDimensions(); const position = this.commentPopupPositionInLayer;
const position = { top: bottom }; let posX, posY;
if (this.#editor._uiManager.direction === "ltr") { if (position) {
position.right = right; [posX, posY] = position;
} else { } else {
position.left = left; // The position is in the editor coordinates.
[posX, posY] = this.#editor.commentButtonPosition;
const { width, height, x, y } = this.#editor;
posX = x + posX * width;
posY = y + posY * height;
} }
this.#editor._uiManager.editComment(this.#editor, position); const parentDimensions = this.#editor.parent.boundingClientRect;
const {
x: parentX,
y: parentY,
width: parentWidth,
height: parentHeight,
} = parentDimensions;
this.#editor._uiManager.editComment(
this.#editor,
parentX + posX * parentWidth,
parentY + posY * parentHeight,
{ ...options, parentDimensions }
);
} }
finish() { finish() {

View File

@ -98,6 +98,12 @@ class DrawingEditor extends AnnotationEditor {
this._addOutlines(params); this._addOutlines(params);
} }
/** @inheritdoc */
onUpdatedColor() {
this._colorPicker?.update(this.color);
super.onUpdatedColor();
}
_addOutlines(params) { _addOutlines(params) {
if (params.drawOutlines) { if (params.drawOutlines) {
this.#createDrawOutlines(params); this.#createDrawOutlines(params);
@ -243,7 +249,7 @@ class DrawingEditor extends AnnotationEditor {
options.toSVGProperties() options.toSVGProperties()
); );
if (type === this.colorType) { if (type === this.colorType) {
this._colorPicker?.update(val); this.onUpdatedColor();
} }
}; };
this.addCommands({ this.addCommands({

View File

@ -22,19 +22,13 @@ import {
ColorManager, ColorManager,
KeyboardManager, KeyboardManager,
} from "./tools.js"; } from "./tools.js";
import {
applyOpacity,
CSSConstants,
findContrastColor,
noContextMenu,
stopEvent,
} from "../display_utils.js";
import { import {
FeatureTest, FeatureTest,
MathClamp, MathClamp,
shadow, shadow,
unreachable, unreachable,
} from "../../shared/util.js"; } from "../../shared/util.js";
import { noContextMenu, stopEvent } from "../display_utils.js";
import { AltText } from "./alt_text.js"; import { AltText } from "./alt_text.js";
import { Comment } from "./comment.js"; import { Comment } from "./comment.js";
import { EditorToolbar } from "./toolbar.js"; import { EditorToolbar } from "./toolbar.js";
@ -1098,28 +1092,28 @@ class AnnotationEditor {
await this._editToolbar.addButton(name, tool); await this._editToolbar.addButton(name, tool);
} }
} }
if (!this.hasComment) {
this._editToolbar.addButton("comment", this.addCommentButton()); this._editToolbar.addButton("comment", this.addCommentButton());
}
this._editToolbar.addButton("delete"); this._editToolbar.addButton("delete");
return this._editToolbar; return this._editToolbar;
} }
addCommentButtonInToolbar() { addCommentButtonInToolbar() {
if (!this._editToolbar) { this._editToolbar?.addButtonBefore(
return;
}
this._editToolbar.addButtonBefore(
"comment", "comment",
this.addCommentButton(), this.addCommentButton(),
".deleteButton" ".deleteButton"
); );
} }
removeEditToolbar() { removeCommentButtonFromToolbar() {
if (!this._editToolbar) { this._editToolbar?.removeButton("comment");
return;
} }
this._editToolbar.remove();
removeEditToolbar() {
this._editToolbar?.remove();
this._editToolbar = null; this._editToolbar = null;
// We destroy the alt text but we don't null it because we want to be able // We destroy the alt text but we don't null it because we want to be able
@ -1195,8 +1189,11 @@ class AnnotationEditor {
} }
addStandaloneCommentButton() { addStandaloneCommentButton() {
this.#comment ||= new Comment(this);
if (this.#commentStandaloneButton) { if (this.#commentStandaloneButton) {
this.#commentStandaloneButton.classList.remove("hidden");
return;
}
if (!this.hasComment) {
return; return;
} }
this.#commentStandaloneButton = this.#comment.renderForStandalone(); this.#commentStandaloneButton = this.#comment.renderForStandalone();
@ -1204,12 +1201,12 @@ class AnnotationEditor {
} }
removeStandaloneCommentButton() { removeStandaloneCommentButton() {
this.#commentStandaloneButton?.remove(); this.#comment.removeStandaloneCommentButton();
this.#commentStandaloneButton = null; this.#commentStandaloneButton = null;
} }
get commentColor() { hideStandaloneCommentButton() {
return null; this.#commentStandaloneButton?.classList.add("hidden");
} }
get comment() { get comment() {
@ -1221,7 +1218,8 @@ class AnnotationEditor {
richText, richText,
date, date,
deleted, deleted,
color: this.commentColor, color: this.getNonHCMColor(),
opacity: this.opacity ?? 1,
}; };
} }
@ -1229,17 +1227,18 @@ class AnnotationEditor {
this.#comment ||= new Comment(this); this.#comment ||= new Comment(this);
this.#comment.data = text; this.#comment.data = text;
if (this.hasComment) { if (this.hasComment) {
this.removeCommentButtonFromToolbar();
this.addStandaloneCommentButton(); this.addStandaloneCommentButton();
this._uiManager.updateComment(this);
} else { } else {
this.addCommentButtonInToolbar(); this.addCommentButtonInToolbar();
this.removeStandaloneCommentButton(); this.removeStandaloneCommentButton();
this._uiManager.removeComment(this);
} }
} }
setCommentData({ comment, richText }) { setCommentData({ comment, richText }) {
if (!this.#comment) { this.#comment ||= new Comment(this);
this.#comment = new Comment(this);
}
this.#comment.setInitialText(comment, richText); this.#comment.setInitialText(comment, richText);
} }
@ -1253,14 +1252,20 @@ class AnnotationEditor {
); );
} }
async editComment() { async editComment(options) {
if (!this.#comment) { this.#comment ||= new Comment(this);
this.#comment = new Comment(this); this.#comment.edit(options);
}
this.#comment.edit();
} }
showComment() {} toggleComment(isSelected, visibility = undefined) {
if (this.hasComment) {
this._uiManager.toggleComment(this, isSelected, visibility);
}
}
setSelectedCommentButton(selected) {
this.#comment.setSelectedButton(selected);
}
addComment(serialized) { addComment(serialized) {
if (this.hasEditedComment) { if (this.hasEditedComment) {
@ -1280,6 +1285,10 @@ class AnnotationEditor {
} }
} }
get parentBoundingClientRect() {
return this.parent.boundingClientRect;
}
/** /**
* Render this editor in a div. * Render this editor in a div.
* @returns {HTMLDivElement | null} * @returns {HTMLDivElement | null}
@ -1327,6 +1336,7 @@ class AnnotationEditor {
}); });
} }
this.addStandaloneCommentButton();
this._uiManager._editorUndoBar?.hide(); this._uiManager._editorUndoBar?.hide();
return div; return div;
@ -1467,6 +1477,11 @@ class AnnotationEditor {
e => { e => {
if (!hasDraggingStarted) { if (!hasDraggingStarted) {
hasDraggingStarted = true; hasDraggingStarted = true;
this._uiManager.toggleComment(
this,
/* isSelected = */ true,
/* visibility = */ false
);
this._onStartDragging(); this._onStartDragging();
} }
const { clientX: x, clientY: y, pointerId } = e; const { clientX: x, clientY: y, pointerId } = e;
@ -1632,9 +1647,25 @@ class AnnotationEditor {
return this.getRect(0, 0); return this.getRect(0, 0);
} }
getNonHCMColor() {
return (
this.color &&
AnnotationEditor._colorManager.convert(
this._uiManager.getNonHCMColor(this.color)
)
);
}
/**
* The color has been changed.
*/
onUpdatedColor() {
this.#comment?.onUpdatedColor();
}
getData() { getData() {
const { const {
comment: { text: str, date, deleted, richText }, comment: { text: str, color, date, opacity, deleted, richText },
uid: id, uid: id,
pageIndex, pageIndex,
creationDate, creationDate,
@ -1649,6 +1680,8 @@ class AnnotationEditor {
creationDate, creationDate,
modificationDate: date || modificationDate, modificationDate: date || modificationDate,
popupRef: !deleted, popupRef: !deleted,
color,
opacity,
}; };
} }
@ -1903,16 +1936,30 @@ class AnnotationEditor {
} }
get commentButtonColor() { get commentButtonColor() {
if (!this.color) { return this._uiManager.makeCommentColor(
return null; this.getNonHCMColor(),
this.opacity
);
} }
const [r, g, b] = AnnotationEditor._colorManager.convert(
this._uiManager.getNonHCMColor(this.color) get commentPopupPosition() {
); return this.#comment.commentPopupPositionInLayer;
return findContrastColor( }
applyOpacity(r, g, b, this.opacity),
CSSConstants.commentForegroundColor set commentPopupPosition(pos) {
); this.#comment.commentPopupPositionInLayer = pos;
}
get commentButtonWidth() {
return this.#comment.commentButtonWidth;
}
get elementBeforePopup() {
return this.div;
}
setCommentButtonStates(options) {
this.#comment.setCommentButtonStates(options);
} }
/** /**
@ -2047,6 +2094,7 @@ class AnnotationEditor {
*/ */
select() { select() {
if (this.isSelected && this._editToolbar) { if (this.isSelected && this._editToolbar) {
this._editToolbar.show();
return; return;
} }
this.isSelected = true; this.isSelected = true;
@ -2086,6 +2134,13 @@ class AnnotationEditor {
} }
this._editToolbar?.hide(); this._editToolbar?.hide();
this.#altText?.toggleAltTextBadge(true); this.#altText?.toggleAltTextBadge(true);
if (this.hasComment) {
this._uiManager.toggleComment(
this,
/* isSelected = */ false,
/* visibility = */ false
);
}
} }
/** /**
@ -2133,6 +2188,10 @@ class AnnotationEditor {
* @param {MouseEvent} event * @param {MouseEvent} event
*/ */
dblclick(event) { dblclick(event) {
if (event.target.nodeName === "BUTTON") {
// Avoid entering in edit mode when clicking on the comment button.
return;
}
this.enterInEditMode(); this.enterInEditMode();
this.parent.updateToolbar({ this.parent.updateToolbar({
mode: this.constructor._editorType, mode: this.constructor._editorType,

View File

@ -236,14 +236,21 @@ class FreeTextEditor extends AnnotationEditor {
}); });
} }
/** @inheritdoc */
onUpdatedColor() {
this.editorDiv.style.color = this.color;
this._colorPicker?.update(this.color);
super.onUpdatedColor();
}
/** /**
* Update the color and make this action undoable. * Update the color and make this action undoable.
* @param {string} color * @param {string} color
*/ */
#updateColor(color) { #updateColor(color) {
const setColor = col => { const setColor = col => {
this.color = this.editorDiv.style.color = col; this.color = col;
this._colorPicker?.update(col); this.onUpdatedColor();
}; };
const savedColor = this.color; const savedColor = this.color;
this.addCommands({ this.addCommands({

View File

@ -348,6 +348,18 @@ class HighlightEditor extends AnnotationEditor {
]; ];
} }
/** @inheritdoc */
onUpdatedColor() {
this.parent?.drawLayer.updateProperties(this.#id, {
root: {
fill: this.color,
"fill-opacity": this.opacity,
},
});
this.#colorPicker?.updateColor(this.color);
super.onUpdatedColor();
}
/** /**
* Update the color and make this action undoable. * Update the color and make this action undoable.
* @param {string} color * @param {string} color
@ -356,13 +368,7 @@ class HighlightEditor extends AnnotationEditor {
const setColorAndOpacity = (col, opa) => { const setColorAndOpacity = (col, opa) => {
this.color = col; this.color = col;
this.opacity = opa; this.opacity = opa;
this.parent?.drawLayer.updateProperties(this.#id, { this.onUpdatedColor();
root: {
fill: col,
"fill-opacity": opa,
},
});
this.#colorPicker?.updateColor(col);
}; };
const savedColor = this.color; const savedColor = this.color;
const savedOpacity = this.opacity; const savedOpacity = this.opacity;

View File

@ -28,6 +28,8 @@ class EditorToolbar {
#comment = null; #comment = null;
#commentButtonDivider = null;
#signatureDescriptionButton = null; #signatureDescriptionButton = null;
static #l10nRemove = null; static #l10nRemove = null;
@ -167,11 +169,12 @@ class EditorToolbar {
return; return;
} }
this.#addListenersToElement(button); this.#addListenersToElement(button);
const divider = (this.#commentButtonDivider = this.#divider);
if (!beforeElement) { if (!beforeElement) {
this.#buttons.append(button, this.#divider); this.#buttons.append(button, divider);
} else { } else {
this.#buttons.insertBefore(button, beforeElement); this.#buttons.insertBefore(button, beforeElement);
this.#buttons.insertBefore(this.#divider, beforeElement); this.#buttons.insertBefore(divider, beforeElement);
} }
this.#comment = comment; this.#comment = comment;
comment.toolbar = this; comment.toolbar = this;
@ -194,6 +197,17 @@ class EditorToolbar {
this.#buttons.append(button, this.#divider); this.#buttons.append(button, this.#divider);
} }
removeButton(name) {
switch (name) {
case "comment":
this.#comment?.removeToolbarCommentButton();
this.#comment = null;
this.#commentButtonDivider?.remove();
this.#commentButtonDivider = null;
break;
}
}
async addButton(name, tool) { async addButton(name, tool) {
switch (name) { switch (name) {
case "colorPicker": case "colorPicker":

View File

@ -1068,14 +1068,40 @@ class AnnotationEditorUIManager {
return !!this.#commentManager; return !!this.#commentManager;
} }
editComment(editor, position) { editComment(editor, posX, posY, options) {
this.#commentManager?.open(this, editor, position); this.#commentManager?.showDialog(this, editor, posX, posY, options);
} }
showComment(pageIndex, uid) { selectComment(pageIndex, uid) {
const layer = this.#allLayers.get(pageIndex); const layer = this.#allLayers.get(pageIndex);
const editor = layer?.getEditorByUID(uid); const editor = layer?.getEditorByUID(uid);
editor?.showComment(); editor?.toggleComment(/* isSelected */ true, /* visibility */ true);
}
updateComment(editor) {
this.#commentManager?.updateComment(editor.getData());
}
updatePopupColor(editor) {
this.#commentManager?.updatePopupColor(editor);
}
removeComment(editor) {
this.#commentManager?.removeComments([editor.uid]);
}
toggleComment(editor, isSelected, visibility = undefined) {
this.#commentManager?.toggleCommentPopup(editor, isSelected, visibility);
}
makeCommentColor(color, opacity) {
return (
(color && this.#commentManager?.makeCommentColor(color, opacity)) || null
);
}
getCommentDialogElement() {
return this.#commentManager?.dialogElement || null;
} }
async waitForEditorsRendered(pageNumber) { async waitForEditorsRendered(pageNumber) {
@ -1821,22 +1847,28 @@ class AnnotationEditorUIManager {
if (this.#mode === AnnotationEditorType.POPUP) { if (this.#mode === AnnotationEditorType.POPUP) {
this.#commentManager?.hideSidebar(); this.#commentManager?.hideSidebar();
for (const editor of this.#allEditors.values()) {
editor.removeStandaloneCommentButton();
}
} }
this.#commentManager?.destroyPopup();
this.#mode = mode; this.#mode = mode;
if (mode === AnnotationEditorType.NONE) { if (mode === AnnotationEditorType.NONE) {
this.setEditingState(false); this.setEditingState(false);
this.#disableAll(); this.#disableAll();
for (const editor of this.#allEditors.values()) {
editor.hideStandaloneCommentButton();
}
this._editorUndoBar?.hide(); this._editorUndoBar?.hide();
this.toggleComment(/* editor = */ null);
this.#updateModeCapability.resolve(); this.#updateModeCapability.resolve();
return; return;
} }
for (const editor of this.#allEditors.values()) {
editor.addStandaloneCommentButton();
}
if (mode === AnnotationEditorType.SIGNATURE) { if (mode === AnnotationEditorType.SIGNATURE) {
await this.#signatureManager?.loadSignatures(); await this.#signatureManager?.loadSignatures();
} }
@ -1862,7 +1894,6 @@ class AnnotationEditorUIManager {
} }
if (hasComment && !deleted) { if (hasComment && !deleted) {
allComments.push(editor.getData()); allComments.push(editor.getData());
editor.addStandaloneCommentButton();
} }
} }
for (const annotation of this.#allEditableAnnotations) { for (const annotation of this.#allEditableAnnotations) {
@ -1891,7 +1922,7 @@ class AnnotationEditorUIManager {
} }
for (const editor of this.#allEditors.values()) { for (const editor of this.#allEditors.values()) {
if (editor.annotationElementId === editId || editor.id === editId) { if (editor.uid === editId) {
this.setSelected(editor); this.setSelected(editor);
if (editComment) { if (editComment) {
editor.editComment(); editor.editComment();

View File

@ -142,7 +142,13 @@
pointer-events: none; pointer-events: none;
&.highlightEditing &.highlightEditing
:is(.freeTextEditor, .inkEditor, .stampEditor, .signatureEditor) { :is(
.freeTextEditor,
.inkEditor,
.stampEditor,
.signatureEditor,
.commentPopup
) {
pointer-events: auto; pointer-events: auto;
} }
} }

View File

@ -491,11 +491,16 @@ const PDFViewerApplication = {
eventBus eventBus
) )
: null; : null;
const ltr = appConfig.viewerContainer
? getComputedStyle(appConfig.viewerContainer).direction === "ltr"
: true;
const commentManager = const commentManager =
AppOptions.get("enableComment") && appConfig.editCommentDialog AppOptions.get("enableComment") && appConfig.editCommentDialog
? new CommentManager( ? new CommentManager(
appConfig.editCommentDialog, appConfig.editCommentDialog,
{ {
learnMoreUrl: AppOptions.get("commentLearnMoreUrl"),
sidebar: sidebar:
appConfig.annotationEditorParams?.editorCommentsSidebar || null, appConfig.annotationEditorParams?.editorCommentsSidebar || null,
commentsList: commentsList:
@ -515,7 +520,8 @@ const PDFViewerApplication = {
}, },
eventBus, eventBus,
linkService, linkService,
overlayManager overlayManager,
ltr
) )
: null; : null;

View File

@ -173,6 +173,14 @@ const defaultOptions = {
value: 200, value: 200,
kind: OptionKind.VIEWER + OptionKind.PREFERENCE, kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
}, },
commentLearnMoreUrl: {
/** @type {string} */
value:
typeof PDFJSDev === "undefined" || PDFJSDev.test("MOZCENTRAL")
? "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/pdf-comment"
: "",
kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
},
cursorToolOnLoad: { cursorToolOnLoad: {
/** @type {number} */ /** @type {number} */
value: 0, value: 0,

View File

@ -13,75 +13,23 @@
* limitations under the License. * limitations under the License.
*/ */
.commentPopup,
#commentManagerDialog {
width: 360px;
max-width: 100%;
min-width: 200px;
position: absolute;
padding: 8px 16px 16px;
margin: 0;
box-sizing: border-box;
border-radius: 8px;
}
#commentManagerDialog { #commentManagerDialog {
--comment-actions-button-icon: url(images/comment-actionsButton.svg); --comment-actions-button-icon: url(images/comment-actionsButton.svg);
--comment-close-button-icon: url(images/comment-closeButton.svg); --comment-close-button-icon: url(images/comment-closeButton.svg);
--default-dialog-bg-color: #ffff98;
--dialog-base-color: var(--default-dialog-bg-color);
--dialog-bg-color: color-mix(in srgb, var(--dialog-base-color), white 30%);
--dialog-border-color: var(--dialog-base-color);
--menuitem-bg-color: transparent;
--menuitem-fg-color: black;
--menuitem-hover-bg-color: #3383e7;
--menuitem-hover-fg-color: white;
--comment-text-input-bg: white;
--comment-text-input-fg: black;
--comment-text-input-border: #0060df;
--comment-focus-outline-color: #0060df;
--hover-filter: brightness(0.9);
--text-primary-color: #15141a;
--button-secondary-bg-color: #f0f0f4;
--button-secondary-active-bg-color: color-mix(
in srgb,
var(--button-secondary-bg-color),
black 14%
);
--button-secondary-hover-bg-color: color-mix(
in srgb,
var(--button-secondary-bg-color),
black 7%
);
--button-primary-bg-color: #0060df;
--button-primary-fg-color: #fbfbfe;
--button-primary-active-bg-color: #0050c0;
--button-primary-hover-bg-color: #0250bb;
--menu-bg-color: rgb(253 250 244);
--menu-button-border-color: transparent;
--menu-button-focus-outline-color: var(--comment-text-input-border);
@media screen and (forced-colors: active) {
--hover-filter: none;
--text-primary-color: CanvasText;
--button-secondary-bg-color: HighlightText;
--button-secondary-active-bg-color: HighlightText;
--button-secondary-hover-bg-color: HighlightText;
--button-primary-bg-color: ButtonText;
--button-primary-fg-color: HighlightText;
--button-primary-active-bg-color: SelectedItem;
--button-primary-hover-bg-color: SelectedItem;
--menu-button-border-color: Canvas;
--menu-button-focus-outline-color: CanvasText;
}
width: 308px;
padding: 8px 16px 16px;
overflow: visible;
position: absolute;
margin: 0;
border-radius: 4px;
border: 1px solid var(--dialog-border-color);
background: var(--dialog-bg-color);
box-shadow: 0 2px 14px 0 rgb(58 57 68 / 0.2);
.mainContainer { .mainContainer {
width: 100%; width: 100%;
height: auto; height: auto;
@ -97,156 +45,20 @@
#commentManagerToolbar { #commentManagerToolbar {
width: 100%; width: 100%;
height: 32px;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-start;
align-items: flex-start; align-items: flex-start;
gap: 8px; gap: 8px;
align-self: stretch; align-self: stretch;
cursor: move; cursor: move;
> button {
color-scheme: light;
width: 24px;
height: 24px;
padding: 0;
border: none;
cursor: pointer;
&::before {
content: "";
display: inline-block;
width: 100%;
height: 100%;
mask-repeat: no-repeat;
mask-position: center;
}
&#commentActionsButton::before {
mask-image: var(--comment-actions-button-icon);
}
&#commentCloseButton::before {
mask-image: var(--comment-close-button-icon);
}
> span {
display: inline-block;
width: 0;
height: 0;
overflow: hidden;
}
}
menu {
width: max-content;
min-width: 90px;
display: flex;
flex-direction: column;
align-items: center;
gap: 1px;
padding: 5px 6px;
cursor: auto;
z-index: 1;
margin: 0;
position: absolute;
top: 8px;
right: -6.5px;
border-radius: 6px;
border: 0.5px solid #b4b4b6;
background-color: var(--menu-bg-color);
box-shadow:
1px -1px 0 0 #fff inset,
-1px 1px 0 0 #fff inset,
-1px -1px 0 0 #fff inset,
1px 1px 0 0 #fff inset,
0 0 15px 0 rgb(0 0 0 / 0.25);
button {
background-color: var(--menuitem-bg-color);
width: 100%;
height: 24px;
padding: 0;
box-sizing: border-box;
display: flex;
border: 2px solid var(--menu-button-border-color);
color: var(--menuitem-fg-color);
&:hover {
background-color: var(--menuitem-hover-bg-color);
color: var(--menuitem-hover-fg-color);
}
&:is(:focus-visible, :focus) {
outline: none;
border: 2px solid var(--menu-button-focus-outline-color);
}
&:disabled {
opacity: 0.5;
pointer-events: none;
}
span {
align-content: center;
width: 100%;
max-width: min-content;
padding-inline: 8px;
color: inherit;
text-align: start;
font: menu;
font-size: 15px;
font-weight: 400;
line-height: normal;
}
}
}
} }
#commentManagerTextInput { #commentManagerTextInput {
width: 100%; width: 100%;
min-height: 132px; min-height: 132px;
resize: none;
box-sizing: border-box;
margin-bottom: 12px; margin-bottom: 12px;
border-radius: 4px;
border: 2px solid var(--comment-text-input-border);
background-color: var(--comment-text-input-bg);
color: var(--comment-text-input-fg);
}
#commentManagerTextView {
width: 100%;
height: max-content;
resize: none;
box-sizing: border-box;
margin-bottom: 12px;
border: none;
background-color: transparent;
color: var(--comment-text-input-fg);
}
.dialogButtonsGroup {
gap: 8px;
#commentManagerSaveButton:disabled {
background-color: color-mix(
in srgb,
var(--button-primary-disabled-bg-color),
transparent 50%
);
border-color: color-mix(
in srgb,
var(--button-primary-disabled-border-color),
transparent 50%
);
opacity: 1;
}
} }
} }
} }
@ -279,12 +91,14 @@
@media screen and (forced-colors: active) { @media screen and (forced-colors: active) {
--comment-button-bg: Canvas; --comment-button-bg: Canvas;
--comment-button-fg: CanvasText; --comment-button-fg: ButtonText;
--comment-button-hover-bg: Highlight; --comment-button-hover-bg: Canvas;
--comment-button-hover-fg: ButtonFace; --comment-button-hover-fg: Highlight;
--comment-button-active-bg: Highlight; --comment-button-active-bg: Canvas;
--comment-button-active-fg: ButtonFace; --comment-button-active-fg: Highlight;
--comment-button-border-color: ButtonBorder; --comment-button-border-color: ButtonBorder;
--comment-button-active-border-color: ButtonBorder;
--comment-button-hover-border-color: Highlight;
--comment-button-box-shadow: none; --comment-button-box-shadow: none;
--comment-button-focus-outline-color: CanvasText; --comment-button-focus-outline-color: CanvasText;
--comment-button-selected-bg: ButtonBorder; --comment-button-selected-bg: ButtonBorder;
@ -358,36 +172,54 @@
} }
} }
.comment.sidebar { #editorCommentsSidebar,
.commentPopup {
--comment-close-button-icon: url(images/comment-closeButton.svg); --comment-close-button-icon: url(images/comment-closeButton.svg);
--comment-popup-edit-button-icon: url(images/comment-popup-editButton.svg);
--comment-popup-delete-button-icon: url(images/editor-toolbar-delete.svg);
--comment-date-fg-color: light-dark( --comment-date-fg-color: light-dark(
rgb(21 20 26 / 0.69), rgb(21 20 26 / 0.69),
rgb(251 251 254 / 0.69) rgb(251 251 254 / 0.69)
); );
--comment-bg-color: light-dark(#f9f9fb, #1c1b22); --comment-bg-color: light-dark(#f9f9fb, #1c1b22);
--comment-hover-bg-color: light-dark( --comment-hover-bg-color: light-dark(#e0e0e6, #2c2b33);
rgb(21 20 26 / 0.14), --comment-active-bg-color: light-dark(#d1d1d9, #3a3944);
rgb(251 251 254 / 0.14) --comment-hover-brightness: 0.89;
); --comment-hover-filter: brightness(var(--comment-hover-brightness));
--comment-active-bg-color: light-dark( --comment-active-brightness: 0.825;
rgb(21 20 26 / 0.21), --comment-active-filter: brightness(var(--comment-active-brightness));
rgb(251 251 254 / 0.21)
);
--comment-border-color: light-dark(#f0f0f4, #52525e); --comment-border-color: light-dark(#f0f0f4, #52525e);
--comment-focus-outline-color: light-dark(#0062fa, #00cadb); --comment-focus-outline-color: light-dark(#0062fa, #00cadb);
--comment-fg-color: light-dark(#15141a, #fbfbfe); --comment-fg-color: light-dark(#15141a, #fbfbfe);
--comment-count-bg-color: light-dark(#e2f7ff, #00317e); --comment-count-bg-color: light-dark(#e2f7ff, #00317e);
--comment-indicator-active-fg-color: light-dark(#0041a4, #a6ecf4); --comment-indicator-active-fg-color: light-dark(#0041a4, #a6ecf4);
--comment-indicator-active-filter: brightness(
calc(1 / var(--comment-active-brightness))
);
--comment-indicator-focus-fg-color: light-dark(#5b5b66, #fbfbfe); --comment-indicator-focus-fg-color: light-dark(#5b5b66, #fbfbfe);
--comment-indicator-hover-fg-color: light-dark(#0053cb, #61dce9); --comment-indicator-hover-fg-color: light-dark(#0053cb, #61dce9);
--comment-indicator-hover-filter: brightness(
calc(1 / var(--comment-hover-brightness))
);
--comment-indicator-selected-fg-color: light-dark(#0062fa, #00cadb); --comment-indicator-selected-fg-color: light-dark(#0062fa, #00cadb);
--button-comment-bg: transparent;
--button-comment-color: var(--main-color);
--button-comment-active-bg: light-dark(#cfcfd8, #5b5b66);
--button-comment-active-border: none;
--button-comment-active-color: var(--button-comment-color);
--button-comment-border: none;
--button-comment-hover-bg: light-dark(#e0e0e6, #52525e);
--button-comment-hover-color: var(--button-comment-color);
@media screen and (forced-colors: active) { @media screen and (forced-colors: active) {
--comment-date-fg-color: CanvasText; --comment-date-fg-color: CanvasText;
--comment-bg-color: Canvas; --comment-bg-color: Canvas;
--comment-hover-bg-color: SelectedItemText; --comment-hover-bg-color: SelectedItemText;
--comment-hover-filter: none;
--comment-active-bg-color: SelectedItemText; --comment-active-bg-color: SelectedItemText;
--comment-active-filter: none;
--comment-border-color: CanvasText; --comment-border-color: CanvasText;
--comment-fg-color: CanvasText; --comment-fg-color: CanvasText;
--comment-count-bg-color: Canvas; --comment-count-bg-color: Canvas;
@ -395,8 +227,17 @@
--comment-indicator-focus-fg-color: CanvasText; --comment-indicator-focus-fg-color: CanvasText;
--comment-indicator-hover-fg-color: CanvasText; --comment-indicator-hover-fg-color: CanvasText;
--comment-indicator-selected-fg-color: SelectedItem; --comment-indicator-selected-fg-color: SelectedItem;
--button-comment-bg: HighlightText;
--button-comment-color: ButtonText;
--button-comment-active-bg: ButtonText;
--button-comment-active-color: HighlightText;
--button-comment-border: 1px solid ButtonText;
--button-comment-hover-bg: Highlight;
--button-comment-hover-color: HighlightText;
} }
}
#editorCommentsSidebar {
display: flex; display: flex;
width: 239px; width: 239px;
height: auto; height: auto;
@ -449,6 +290,7 @@
width: 32px; width: 32px;
height: 32px; height: 32px;
padding: 8px; padding: 8px;
border-radius: 4px;
border: none; border: none;
background: none; background: none;
cursor: pointer; cursor: pointer;
@ -472,6 +314,10 @@
background-color: var(--comment-active-bg-color); background-color: var(--comment-active-bg-color);
} }
&:focus-visible {
outline: var(--focus-ring-outline);
}
> span { > span {
display: inline-block; display: inline-block;
width: 0; width: 0;
@ -483,18 +329,18 @@
#editorCommentsSidebarListContainer { #editorCommentsSidebarListContainer {
overflow: scroll; overflow: scroll;
width: 100%;
#editorCommentsSidebarList { #editorCommentsSidebarList {
display: flex; display: flex;
width: auto; width: auto;
padding: 1px 16px 0; padding: 4px 16px;
gap: 10px; gap: 10px;
flex: 1 0 0; flex: 1 0 0;
align-self: stretch; align-self: stretch;
align-items: flex-start; align-items: flex-start;
flex-direction: column; flex-direction: column;
list-style-type: none; list-style-type: none;
overflow: scroll;
.sidebarComment { .sidebarComment {
display: flex; display: flex;
@ -511,20 +357,28 @@
&:not(.noComments) { &:not(.noComments) {
&:hover { &:hover {
@media screen and (forced-colors: active) {
background-color: var(--comment-hover-bg-color); background-color: var(--comment-hover-bg-color);
}
filter: var(--comment-hover-filter);
time::after { time::after {
display: inline-block; display: inline-block;
background-color: var(--comment-indicator-hover-fg-color); background-color: var(--comment-indicator-hover-fg-color);
filter: var(--comment-indicator-hover-filter);
} }
} }
&:active { &:active {
@media screen and (forced-colors: active) {
background-color: var(--comment-active-bg-color); background-color: var(--comment-active-bg-color);
}
filter: var(--comment-active-filter);
time::after { time::after {
display: inline-block; display: inline-block;
background-color: var(--comment-indicator-active-fg-color); background-color: var(--comment-indicator-active-fg-color);
filter: var(--comment-indicator-active-filter);
} }
} }
@ -565,14 +419,36 @@
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
overflow: hidden; overflow: hidden;
overflow-wrap: break-word; overflow-wrap: break-word;
.richText {
--total-scale-factor: 1.5;
}
} }
&.noComments .sidebarCommentText { &.noComments {
.sidebarCommentText {
max-height: fit-content; max-height: fit-content;
-webkit-line-clamp: unset; -webkit-line-clamp: unset;
user-select: none; user-select: none;
} }
a {
font: menu;
font-style: normal;
font-weight: 400;
line-height: normal;
font-size: 15px;
width: 100%;
height: auto;
overflow-wrap: break-word;
margin-block-start: 15px;
&:focus-visible {
outline: var(--focus-ring-outline);
}
}
}
time { time {
width: 100%; width: 100%;
display: inline-flex; display: inline-flex;
@ -600,3 +476,163 @@
} }
} }
} }
.commentPopup {
color-scheme: light dark;
--divider-color: light-dark(#cfcfd8, #3a3944);
--comment-shadow:
0 0.5px 2px 0 light-dark(rgb(0 0 0 / 0.05), rgb(0 0 0 / 0.2)),
0 4px 16px 0 light-dark(rgb(0 0 0 / 0.1), rgb(0 0 0 / 0.4));
@media screen and (forced-colors: active) {
--divider-color: CanvasText;
--comment-shadow: none;
}
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 12px;
z-index: 100001; /* above selected annotation editor */
pointer-events: auto;
border: 0.5px solid var(--comment-border-color);
background: var(--comment-bg-color);
box-shadow: var(--comment-shadow);
&:focus-visible {
outline: none;
}
&.dragging {
cursor: move !important;
* {
cursor: move !important;
}
button {
pointer-events: none !important;
}
}
&:not(.selected) .commentPopupButtons {
visibility: hidden !important;
}
hr {
width: 100%;
height: 1px;
border: none;
border-top: 1px solid var(--divider-color);
margin: 0;
padding: 0;
}
.commentPopupTop {
display: flex;
width: 100%;
height: auto;
padding-bottom: 4px;
justify-content: space-between;
align-items: center;
align-self: stretch;
cursor: move;
user-select: none;
.commentPopupTime {
font: menu;
font-style: normal;
font-weight: 400;
line-height: normal;
font-size: 13px;
color: var(--comment-date-fg-color);
}
.commentPopupButtons {
display: flex;
align-items: center;
gap: 2px;
cursor: default;
> button {
width: 32px;
height: 32px;
padding: 8px;
border: none;
border-radius: 4px;
background-color: var(--button-comment-bg);
color: var(--button-comment-color);
&:hover {
background-color: var(--button-comment-hover-bg);
}
&:active {
border: var(--button-comment-active-border);
background-color: var(--button-comment-active-bg);
color: var(--button-comment-active-color);
&::before {
background-color: var(--button-comment-active-color);
}
}
&:focus-visible {
background-color: var(--button-comment-hover-bg);
outline: 2px solid var(--comment-focus-outline-color);
outline-offset: 0;
}
&::before {
content: "";
display: inline-block;
width: 100%;
height: 100%;
mask-repeat: no-repeat;
mask-position: center;
}
&.commentPopupEdit::before {
mask-image: var(--comment-popup-edit-button-icon);
}
&.commentPopupDelete::before {
mask-image: var(--comment-popup-delete-button-icon);
}
}
}
}
.commentPopupText {
width: 100%;
height: auto;
font: menu;
font-style: normal;
font-weight: 400;
line-height: normal;
font-size: 15px;
color: var(--comment-fg-color);
}
}
.commentPopupText,
.sidebarCommentText .richText {
margin-block: 0;
p:first-of-type {
margin-block: 0;
}
> * {
white-space: pre-wrap;
font-size: max(15px, calc(10px * var(--total-scale-factor)));
overflow-wrap: break-word;
}
span {
color: var(--comment-fg-color) !important;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.0189877 13.6645L0.612989 10.4635C0.687989 10.0545 0.884989 9.6805 1.18099 9.3825L9.98199 0.5805C10.756 -0.1925 12.015 -0.1945 12.792 0.5805L14.42 2.2085C15.194 2.9835 15.194 4.2435 14.42 5.0185L5.61599 13.8215C5.31999 14.1165 4.94599 14.3125 4.53799 14.3875L1.33599 14.9815C1.26599 14.9935 1.19799 15.0005 1.12999 15.0005C0.832989 15.0005 0.544988 14.8835 0.330988 14.6695C0.0679874 14.4055 -0.0490122 14.0305 0.0189877 13.6645ZM12.472 5.1965L13.632 4.0365L13.631 3.1885L11.811 1.3675L10.963 1.3685L9.80299 2.5285L12.472 5.1965ZM4.31099 13.1585C4.47099 13.1285 4.61799 13.0515 4.73399 12.9345L11.587 6.0815L8.91899 3.4135L2.06599 10.2655C1.94899 10.3835 1.87199 10.5305 1.84099 10.6915L1.36699 13.2485L1.75199 13.6335L4.31099 13.1585Z" fill="black"/>
</svg>
<!--path d="M0.0189877 14.1645L0.612989 10.9635C0.687989 10.5545 0.884989 10.1805 1.18099 9.8825L9.98199 1.0805C10.756 0.3075 12.015 0.3055 12.792 1.0805L14.42 2.7085C15.194 3.4835 15.194 4.7435 14.42 5.5185L5.61599 14.3215C5.31999 14.6165 4.94599 14.8125 4.53799 14.8875L1.33599 15.4815C1.26599 15.4935 1.19799 15.5005 1.12999 15.5005C0.832989 15.5005 0.544988 15.3835 0.330988 15.1695C0.0679874 14.9055 -0.0490122 14.5305 0.0189877 14.1645ZM12.472 5.6965L13.632 4.5365L13.631 3.6885L11.811 1.8675L10.963 1.8685L9.80299 3.0285L12.472 5.6965ZM4.31099 13.6585C4.47099 13.6285 4.61799 13.5515 4.73399 13.4345L11.587 6.5815L8.91899 3.9135L2.06599 10.7655C1.94899 10.8835 1.87199 11.0305 1.84099 11.1915L1.36699 13.7485L1.75199 14.1335L4.31099 13.6585Z" fill="black"/-->

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1057,6 +1057,7 @@ class PDFViewer {
enableHWA: this.#enableHWA, enableHWA: this.#enableHWA,
enableAutoLinking: this.#enableAutoLinking, enableAutoLinking: this.#enableAutoLinking,
minDurationToUpdateCanvas: this.#minDurationToUpdateCanvas, minDurationToUpdateCanvas: this.#minDurationToUpdateCanvas,
commentManager: this.#commentManager,
}); });
this._pages.push(pageView); this._pages.push(pageView);
} }

View File

@ -249,7 +249,7 @@ See https://github.com/adobe-type-tools/cmap-resources
<button id="editorCommentButton" class="toolbarButton" type="button" tabindex="0" disabled="disabled" role="radio" aria-expanded="false" aria-haspopup="true" aria-controls="editorCommentParamsToolbar" data-l10n-id="pdfjs-editor-comment-button"> <button id="editorCommentButton" class="toolbarButton" type="button" tabindex="0" disabled="disabled" role="radio" aria-expanded="false" aria-haspopup="true" aria-controls="editorCommentParamsToolbar" data-l10n-id="pdfjs-editor-comment-button">
<span data-l10n-id="pdfjs-editor-comment-button-label"></span> <span data-l10n-id="pdfjs-editor-comment-button-label"></span>
</button> </button>
<div class="editorParamsToolbar sidebar hidden menu" id="editorCommentParamsToolbar"> <div class="editorParamsToolbar hidden menu" id="editorCommentParamsToolbar">
<div id="editorCommentsSidebar" class="menuContainer comment sidebar" role="landmark" aria-labelledby="editorCommentsSidebarHeader"> <div id="editorCommentsSidebar" class="menuContainer comment sidebar" role="landmark" aria-labelledby="editorCommentsSidebarHeader">
<div id="editorCommentsSidebarHeader" role="heading" aria-level="2"> <div id="editorCommentsSidebarHeader" role="heading" aria-level="2">
<span class="commentCount"> <span class="commentCount">
@ -260,7 +260,7 @@ See https://github.com/adobe-type-tools/cmap-resources
<span data-l10n-id="pdfjs-editor-comments-sidebar-close-button-label"></span> <span data-l10n-id="pdfjs-editor-comments-sidebar-close-button-label"></span>
</button> </button>
</div> </div>
<div id="editorCommentsSidebarListContainer"> <div id="editorCommentsSidebarListContainer" tabindex="-1">
<ul id="editorCommentsSidebarList"></ul> <ul id="editorCommentsSidebarList"></ul>
</div> </div>
</div> </div>
@ -794,30 +794,16 @@ See https://github.com/adobe-type-tools/cmap-resources
<dialog class="dialog commentManager" id="commentManagerDialog"> <dialog class="dialog commentManager" id="commentManagerDialog">
<div class="mainContainer"> <div class="mainContainer">
<div id="commentManagerToolbar"> <div class="title" id="commentManagerToolbar">
<button id="commentActionsButton" class="toolbarButton" type="button" aria-expanded="false" aria-haspopup="true" aria-controls="commentActionsMenu" tabindex="0" data-l10n-id="pdfjs-editor-edit-comment-actions-button"> <span id="commentManagerTitle" role="sectionhead" data-l10n-id="pdfjs-editor-edit-comment-dialog-title-when-adding" tabindex="0"></span>
<span data-l10n-id="pdfjs-editor-edit-comment-actions-button-label"></span>
</button>
<menu class="hidden" role="menu" id="commentActionsMenu">
<button id="commentActionsEditButton" role="menuitem" type="button" tabindex="0">
<span data-l10n-id="pdfjs-editor-edit-comment-actions-edit-button-label"></span>
</button>
<button id="commentActionsDeleteButton" role="menuitem" type="button" tabindex="0">
<span data-l10n-id="pdfjs-editor-edit-comment-actions-delete-button-label"></span>
</button>
</menu>
<button id="commentCloseButton" class="toolbarButton" type="button" tabindex="0" data-l10n-id="pdfjs-editor-edit-comment-close-button">
<span data-l10n-id="pdfjs-editor-edit-comment-close-button-label"></span>
</button>
</div> </div>
<textarea class="hidden" id="commentManagerTextInput" data-l10n-id="pdfjs-editor-edit-comment-manager-text-input"></textarea> <textarea id="commentManagerTextInput" data-l10n-id="pdfjs-editor-edit-comment-dialog-text-input"></textarea>
<div class="hidden" id="commentManagerTextView"></div>
<div class="dialogButtonsGroup"> <div class="dialogButtonsGroup">
<button id="commentManagerCancelButton" type="button" class="secondaryButton" tabindex="0"> <button id="commentManagerCancelButton" type="button" class="secondaryButton" tabindex="0">
<span data-l10n-id="pdfjs-editor-edit-comment-manager-cancel-button"></span> <span data-l10n-id="pdfjs-editor-edit-comment-dialog-cancel-button"></span>
</button> </button>
<button id="commentManagerSaveButton" type="button" class="primaryButton" disabled tabindex="0"> <button id="commentManagerSaveButton" type="button" class="primaryButton" disabled tabindex="0">
<span data-l10n-id="pdfjs-editor-edit-comment-manager-save-button"></span> <span data-l10n-id="pdfjs-editor-edit-comment-dialog-save-button"></span>
</button> </button>
</div> </div>
</div> </div>

View File

@ -282,13 +282,8 @@ function getViewerConfiguration() {
editCommentDialog: { editCommentDialog: {
dialog: document.getElementById("commentManagerDialog"), dialog: document.getElementById("commentManagerDialog"),
toolbar: document.getElementById("commentManagerToolbar"), toolbar: document.getElementById("commentManagerToolbar"),
actions: document.getElementById("commentActionsButton"), title: document.getElementById("commentManagerTitle"),
menu: document.getElementById("commentActionsMenu"),
editMenuItem: document.getElementById("commentActionsEditButton"),
deleteMenuItem: document.getElementById("commentActionsDeleteButton"),
closeButton: document.getElementById("commentCloseButton"),
textInput: document.getElementById("commentManagerTextInput"), textInput: document.getElementById("commentManagerTextInput"),
textView: document.getElementById("commentManagerTextView"),
cancelButton: document.getElementById("commentManagerCancelButton"), cancelButton: document.getElementById("commentManagerCancelButton"),
saveButton: document.getElementById("commentManagerSaveButton"), saveButton: document.getElementById("commentManagerSaveButton"),
}, },