[Annotation] In reading mode with new commment stuff enabled, use the comment popup for annotations without a popup but with some contents (bug 1991029)
This commit is contained in:
parent
91384738f8
commit
7fc7b79cd0
@ -718,9 +718,6 @@ class AnnotationElement {
|
|||||||
* @memberof AnnotationElement
|
* @memberof AnnotationElement
|
||||||
*/
|
*/
|
||||||
_createPopup(popupData = null) {
|
_createPopup(popupData = null) {
|
||||||
if (this.parent._commentManager) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { data } = this;
|
const { data } = this;
|
||||||
|
|
||||||
let contentsObj, modificationDate;
|
let contentsObj, modificationDate;
|
||||||
@ -750,13 +747,19 @@ class AnnotationElement {
|
|||||||
parent: this.parent,
|
parent: this.parent,
|
||||||
elements: [this],
|
elements: [this],
|
||||||
}));
|
}));
|
||||||
this.parent.div.append(popup.render());
|
if (!this.parent._commentManager) {
|
||||||
|
this.parent.div.append(popup.render());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get hasPopupElement() {
|
get hasPopupElement() {
|
||||||
return !!(this.#popupElement || this.popup || this.data.popupRef);
|
return !!(this.#popupElement || this.popup || this.data.popupRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get extraPopupElement() {
|
||||||
|
return this.#popupElement;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the annotation's HTML element(s).
|
* Render the annotation's HTML element(s).
|
||||||
*
|
*
|
||||||
@ -2410,10 +2413,12 @@ class PopupElement {
|
|||||||
// consistent with other viewers such as Adobe Acrobat.
|
// consistent with other viewers such as Adobe Acrobat.
|
||||||
this.#dateObj = PDFDateString.toDateObject(modificationDate);
|
this.#dateObj = PDFDateString.toDateObject(modificationDate);
|
||||||
|
|
||||||
|
// The elements that will trigger the popup.
|
||||||
|
this.trigger = elements.flatMap(e => e.getElementsToTriggerPopup());
|
||||||
|
|
||||||
if (commentManager) {
|
if (commentManager) {
|
||||||
this.#renderCommentButton();
|
this.renderCommentButton();
|
||||||
} else {
|
} else {
|
||||||
this.trigger = elements.flatMap(e => e.getElementsToTriggerPopup());
|
|
||||||
this.#addEventListeners();
|
this.#addEventListeners();
|
||||||
|
|
||||||
this.#container.hidden = true;
|
this.#container.hidden = true;
|
||||||
@ -2443,8 +2448,8 @@ class PopupElement {
|
|||||||
// Attach the event listeners to the trigger element.
|
// Attach the event listeners to the trigger element.
|
||||||
for (const element of this.trigger) {
|
for (const element of this.trigger) {
|
||||||
element.addEventListener("click", this.#boundToggle, { signal });
|
element.addEventListener("click", this.#boundToggle, { signal });
|
||||||
element.addEventListener("mouseenter", this.#boundShow, { signal });
|
element.addEventListener("pointerenter", this.#boundShow, { signal });
|
||||||
element.addEventListener("mouseleave", this.#boundHide, { signal });
|
element.addEventListener("pointerleave", this.#boundHide, { signal });
|
||||||
element.classList.add("popupTriggerArea");
|
element.classList.add("popupTriggerArea");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2466,7 +2471,7 @@ class PopupElement {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#renderCommentButton() {
|
renderCommentButton() {
|
||||||
if (this.#commentButton) {
|
if (this.#commentButton) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2479,53 +2484,67 @@ class PopupElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const button = (this.#commentButton = document.createElement("button"));
|
|
||||||
button.className = "annotationCommentButton";
|
|
||||||
const parentContainer = this.#firstElement.container;
|
|
||||||
button.style.zIndex = parentContainer.style.zIndex + 1;
|
|
||||||
button.tabIndex = 0;
|
|
||||||
button.ariaHasPopup = "dialog";
|
|
||||||
button.ariaControls = "commentPopup";
|
|
||||||
button.setAttribute("data-l10n-id", "pdfjs-show-comment-button");
|
|
||||||
|
|
||||||
const { signal } = (this.#popupAbortController = new AbortController());
|
const { signal } = (this.#popupAbortController = new AbortController());
|
||||||
button.addEventListener("keydown", this.#boundKeyDown, { signal });
|
const hasOwnButton = !!this.#firstElement.extraPopupElement;
|
||||||
button.addEventListener(
|
const togglePopup = () => {
|
||||||
"click",
|
this.#commentManager.toggleCommentPopup(
|
||||||
() => {
|
this,
|
||||||
this.#commentManager.toggleCommentPopup(this, /* isSelected = */ true);
|
/* isSelected = */ true,
|
||||||
},
|
/* visibility = */ undefined,
|
||||||
{ signal }
|
/* isEditable = */ !hasOwnButton
|
||||||
);
|
);
|
||||||
button.addEventListener(
|
};
|
||||||
"pointerenter",
|
const showPopup = () => {
|
||||||
() => {
|
this.#commentManager.toggleCommentPopup(
|
||||||
this.#commentManager.toggleCommentPopup(
|
this,
|
||||||
this,
|
/* isSelected = */ false,
|
||||||
/* isSelected = */ false,
|
/* visibility = */ true,
|
||||||
/* visibility = */ true
|
/* isEditable = */ !hasOwnButton
|
||||||
);
|
);
|
||||||
},
|
};
|
||||||
{ signal }
|
const hidePopup = () => {
|
||||||
);
|
this.#commentManager.toggleCommentPopup(
|
||||||
button.addEventListener(
|
this,
|
||||||
"pointerleave",
|
/* isSelected = */ false,
|
||||||
() => {
|
/* visibility = */ false
|
||||||
this.#commentManager.toggleCommentPopup(
|
);
|
||||||
this,
|
};
|
||||||
/* isSelected = */ false,
|
|
||||||
/* visibility = */ false
|
if (!hasOwnButton) {
|
||||||
);
|
const button = (this.#commentButton = document.createElement("button"));
|
||||||
},
|
button.className = "annotationCommentButton";
|
||||||
{ signal }
|
const parentContainer = this.#firstElement.container;
|
||||||
);
|
button.style.zIndex = parentContainer.style.zIndex + 1;
|
||||||
this.#updateColor();
|
button.tabIndex = 0;
|
||||||
this.#updateCommentButtonPosition();
|
button.ariaHasPopup = "dialog";
|
||||||
parentContainer.after(button);
|
button.ariaControls = "commentPopup";
|
||||||
|
button.setAttribute("data-l10n-id", "pdfjs-show-comment-button");
|
||||||
|
this.#updateColor();
|
||||||
|
this.#updateCommentButtonPosition();
|
||||||
|
button.addEventListener("keydown", this.#boundKeyDown, { signal });
|
||||||
|
button.addEventListener("click", togglePopup, { signal });
|
||||||
|
button.addEventListener("pointerenter", showPopup, { signal });
|
||||||
|
button.addEventListener("pointerleave", hidePopup, { signal });
|
||||||
|
parentContainer.after(button);
|
||||||
|
} else {
|
||||||
|
this.#commentButton = this.#firstElement.container;
|
||||||
|
for (const element of this.trigger) {
|
||||||
|
element.ariaHasPopup = "dialog";
|
||||||
|
element.ariaControls = "commentPopup";
|
||||||
|
element.addEventListener("keydown", this.#boundKeyDown, { signal });
|
||||||
|
element.addEventListener("click", togglePopup, { signal });
|
||||||
|
element.addEventListener("pointerenter", showPopup, { signal });
|
||||||
|
element.addEventListener("pointerleave", hidePopup, { signal });
|
||||||
|
element.classList.add("popupTriggerArea");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#updateCommentButtonPosition() {
|
#updateCommentButtonPosition() {
|
||||||
this.#renderCommentButton();
|
if (this.#firstElement.extraPopupElement) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.renderCommentButton();
|
||||||
const [x, y] = this.#commentButtonPosition;
|
const [x, y] = this.#commentButtonPosition;
|
||||||
const { style } = this.#commentButton;
|
const { style } = this.#commentButton;
|
||||||
style.left = `calc(${x}%)`;
|
style.left = `calc(${x}%)`;
|
||||||
@ -2533,7 +2552,10 @@ class PopupElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#updateColor() {
|
#updateColor() {
|
||||||
this.#renderCommentButton();
|
if (this.#firstElement.extraPopupElement) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.renderCommentButton();
|
||||||
this.#commentButton.style.backgroundColor = this.commentButtonColor || "";
|
this.#commentButton.style.backgroundColor = this.commentButtonColor || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3792,6 +3814,7 @@ class AnnotationLayer {
|
|||||||
rendered.style.visibility = "hidden";
|
rendered.style.visibility = "hidden";
|
||||||
}
|
}
|
||||||
await this.#appendElement(rendered, data.id, elementParams.elements);
|
await this.#appendElement(rendered, data.id, elementParams.elements);
|
||||||
|
element.extraPopupElement?.popup?.renderCommentButton();
|
||||||
|
|
||||||
if (element._isEditable) {
|
if (element._isEditable) {
|
||||||
this.#editableAnnotations.set(element.data.id, element);
|
this.#editableAnnotations.set(element.data.id, element);
|
||||||
|
|||||||
@ -810,4 +810,72 @@ a dynamic compiler for JavaScript based on our`);
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("Annotation without popup and enableComment set to true", () => {
|
||||||
|
describe("annotation-text-without-popup.pdf", () => {
|
||||||
|
let pages;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
pages = await loadAndWait(
|
||||||
|
"annotation-text-without-popup.pdf",
|
||||||
|
getAnnotationSelector("4R"),
|
||||||
|
"page-fit",
|
||||||
|
null,
|
||||||
|
{ enableComment: true }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await closePages(pages);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("must check that the popup is shown", async () => {
|
||||||
|
await Promise.all(
|
||||||
|
pages.map(async ([browserName, page]) => {
|
||||||
|
const rect = await getRect(page, getAnnotationSelector("4R"));
|
||||||
|
|
||||||
|
// Hover the annotation, the popup should be visible.
|
||||||
|
let promisePopup = page.waitForSelector("#commentPopup", {
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
await page.mouse.move(
|
||||||
|
rect.x + rect.width / 2,
|
||||||
|
rect.y + rect.height / 2
|
||||||
|
);
|
||||||
|
await promisePopup;
|
||||||
|
|
||||||
|
// Move the mouse away, the popup should be hidden.
|
||||||
|
promisePopup = page.waitForSelector("#commentPopup", {
|
||||||
|
visible: false,
|
||||||
|
});
|
||||||
|
await page.mouse.move(
|
||||||
|
rect.x - rect.width / 2,
|
||||||
|
rect.y - rect.height / 2
|
||||||
|
);
|
||||||
|
await promisePopup;
|
||||||
|
|
||||||
|
// Click the annotation, the popup should be visible.
|
||||||
|
promisePopup = page.waitForSelector("#commentPopup", {
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
await page.mouse.click(
|
||||||
|
rect.x + rect.width / 2,
|
||||||
|
rect.y + rect.height / 2
|
||||||
|
);
|
||||||
|
await promisePopup;
|
||||||
|
|
||||||
|
// Click again, the popup should be hidden.
|
||||||
|
promisePopup = page.waitForSelector("#commentPopup", {
|
||||||
|
visible: false,
|
||||||
|
});
|
||||||
|
await page.mouse.click(
|
||||||
|
rect.x + rect.width / 2,
|
||||||
|
rect.y + rect.height / 2
|
||||||
|
);
|
||||||
|
await promisePopup;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -92,11 +92,11 @@ class CommentManager {
|
|||||||
this.#sidebar.updateComment(annotation);
|
this.#sidebar.updateComment(annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleCommentPopup(editor, isSelected, visibility) {
|
toggleCommentPopup(editor, isSelected, visibility, isEditable) {
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
this.selectComment(editor.uid);
|
this.selectComment(editor.uid);
|
||||||
}
|
}
|
||||||
this.#popup.toggle(editor, isSelected, visibility);
|
this.#popup.toggle(editor, isSelected, visibility, isEditable);
|
||||||
}
|
}
|
||||||
|
|
||||||
destroyPopup() {
|
destroyPopup() {
|
||||||
@ -880,6 +880,8 @@ class CommentDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class CommentPopup {
|
class CommentPopup {
|
||||||
|
#buttonsContainer = null;
|
||||||
|
|
||||||
#commentDialog;
|
#commentDialog;
|
||||||
|
|
||||||
#dateFormat;
|
#dateFormat;
|
||||||
@ -954,7 +956,7 @@ class CommentPopup {
|
|||||||
const time = (this.#time = document.createElement("time"));
|
const time = (this.#time = document.createElement("time"));
|
||||||
time.className = "commentPopupTime";
|
time.className = "commentPopupTime";
|
||||||
|
|
||||||
const buttons = document.createElement("div");
|
const buttons = (this.#buttonsContainer = document.createElement("div"));
|
||||||
buttons.className = "commentPopupButtons";
|
buttons.className = "commentPopupButtons";
|
||||||
const edit = document.createElement("button");
|
const edit = document.createElement("button");
|
||||||
edit.classList.add("commentPopupEdit", "toolbarButton");
|
edit.classList.add("commentPopupEdit", "toolbarButton");
|
||||||
@ -1089,7 +1091,7 @@ class CommentPopup {
|
|||||||
this.sidebar.selectComment(null);
|
this.sidebar.selectComment(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
toggle(editor, isSelected, visibility = undefined) {
|
toggle(editor, isSelected, visibility = undefined, isEditable = true) {
|
||||||
if (!editor) {
|
if (!editor) {
|
||||||
this.destroy();
|
this.destroy();
|
||||||
return;
|
return;
|
||||||
@ -1119,6 +1121,7 @@ class CommentPopup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const container = this.#createPopup();
|
const container = this.#createPopup();
|
||||||
|
this.#buttonsContainer.classList.toggle("hidden", !isEditable);
|
||||||
container.classList.toggle("hidden", false);
|
container.classList.toggle("hidden", false);
|
||||||
container.classList.toggle("selected", isSelected);
|
container.classList.toggle("selected", isSelected);
|
||||||
this.#selected = isSelected;
|
this.#selected = isSelected;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user