Skip to content

Commit d85fd12

Browse files
Merge pull request #20274 from calixteman/save_comment_reading_mode
[Annotation] Save the comment changes made in reading mode (bug 1987427)
2 parents a68630e + 5feb467 commit d85fd12

4 files changed

Lines changed: 113 additions & 24 deletions

File tree

src/display/annotation_layer.js

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
import {
3131
AnnotationBorderStyleType,
32+
AnnotationEditorPrefix,
3233
AnnotationEditorType,
3334
AnnotationPrefix,
3435
AnnotationType,
@@ -242,6 +243,16 @@ class AnnotationElement {
242243
return point;
243244
}
244245

246+
get commentText() {
247+
const { data } = this;
248+
return (
249+
this.annotationStorage.getRawValue(`${AnnotationEditorPrefix}${data.id}`)
250+
?.popup?.contents ||
251+
data.contentsObj?.str ||
252+
""
253+
);
254+
}
255+
245256
removePopup() {
246257
(this.#popupElement?.popup || this.popup)?.remove();
247258
this.#popupElement = this.popup = null;
@@ -2335,6 +2346,8 @@ class PopupElement {
23352346

23362347
#firstElement = null;
23372348

2349+
#commentText = null;
2350+
23382351
constructor({
23392352
container,
23402353
color,
@@ -2495,30 +2508,52 @@ class PopupElement {
24952508
}
24962509

24972510
getData() {
2498-
return this.#firstElement.data;
2511+
const { richText, color, opacity, creationDate, modificationDate } =
2512+
this.#firstElement.data;
2513+
return {
2514+
contentsObj: { str: this.comment },
2515+
richText,
2516+
color,
2517+
opacity,
2518+
creationDate,
2519+
modificationDate,
2520+
};
24992521
}
25002522

25012523
get elementBeforePopup() {
25022524
return this.#commentButton;
25032525
}
25042526

25052527
get comment() {
2506-
return this.#firstElement.data.contentsObj?.str || "";
2528+
this.#commentText ||= this.#firstElement.commentText;
2529+
return this.#commentText;
25072530
}
25082531

25092532
set comment(text) {
25102533
const element = this.#firstElement;
2511-
if (text) {
2512-
element.data.contentsObj = { str: text };
2513-
// TODO: Support saving the text.
2514-
// element.annotationStorage.setValue(element.data.id, {
2515-
// popup: { contents: text },
2516-
// });
2517-
} else {
2518-
element.data.contentsObj = null;
2534+
const { data } = element;
2535+
if (text === this.comment) {
2536+
return;
2537+
}
2538+
const popup = { deleted: !text, contents: text || "" };
2539+
if (!element.annotationStorage.updateEditor(data.id, { popup })) {
2540+
element.annotationStorage.setValue(
2541+
`${AnnotationEditorPrefix}${data.id}`,
2542+
{
2543+
id: data.id,
2544+
annotationType: data.annotationType,
2545+
pageIndex: element.parent.page._pageIndex,
2546+
popup,
2547+
popupRef: data.popupRef,
2548+
modificationDate: new Date(),
2549+
}
2550+
);
2551+
}
2552+
2553+
this.#commentText = text;
2554+
if (!text) {
25192555
element.removePopup();
25202556
}
2521-
element.data.modificationDate = new Date();
25222557
}
25232558

25242559
get parentBoundingClientRect() {
@@ -2707,6 +2742,10 @@ class PopupElement {
27072742
}
27082743

27092744
updateEdited({ rect, popup, deleted }) {
2745+
if (this.#commentManager) {
2746+
this.#commentText = deleted ? null : popup.text;
2747+
return;
2748+
}
27102749
if (deleted || popup?.deleted) {
27112750
this.remove();
27122751
return;

src/display/annotation_storage.js

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class AnnotationStorage {
3131

3232
#modifiedIds = null;
3333

34+
#editorsMap = null;
35+
3436
#storage = new Map();
3537

3638
constructor() {
@@ -83,6 +85,13 @@ class AnnotationStorage {
8385
* @param {string} key
8486
*/
8587
remove(key) {
88+
const storedValue = this.#storage.get(key);
89+
if (storedValue === undefined) {
90+
return;
91+
}
92+
if (storedValue instanceof AnnotationEditor) {
93+
this.#editorsMap.delete(storedValue.annotationElementId);
94+
}
8695
this.#storage.delete(key);
8796

8897
if (this.#storage.size === 0) {
@@ -122,11 +131,11 @@ class AnnotationStorage {
122131
this.#setModified();
123132
}
124133

125-
if (
126-
value instanceof AnnotationEditor &&
127-
typeof this.onAnnotationEditor === "function"
128-
) {
129-
this.onAnnotationEditor(value.constructor._type);
134+
if (value instanceof AnnotationEditor) {
135+
(this.#editorsMap ||= new Map()).set(value.annotationElementId, value);
136+
if (typeof this.onAnnotationEditor === "function") {
137+
this.onAnnotationEditor(value.constructor._type);
138+
}
130139
}
131140
}
132141

@@ -250,6 +259,15 @@ class AnnotationStorage {
250259
this.#modifiedIds = null;
251260
}
252261

262+
updateEditor(annotationId, data) {
263+
const value = this.#editorsMap?.get(annotationId);
264+
if (value) {
265+
value.updateFromAnnotationLayer(data);
266+
return true;
267+
}
268+
return false;
269+
}
270+
253271
/**
254272
* @returns {{ids: Set<string>, hash: string}}
255273
*/
@@ -258,15 +276,13 @@ class AnnotationStorage {
258276
return this.#modifiedIds;
259277
}
260278
const ids = [];
261-
for (const value of this.#storage.values()) {
262-
if (
263-
!(value instanceof AnnotationEditor) ||
264-
!value.annotationElementId ||
265-
!value.serialize()
266-
) {
267-
continue;
279+
if (this.#editorsMap) {
280+
for (const value of this.#editorsMap.values()) {
281+
if (!value.serialize()) {
282+
continue;
283+
}
284+
ids.push(value.annotationElementId);
268285
}
269-
ids.push(value.annotationElementId);
270286
}
271287
return (this.#modifiedIds = {
272288
ids: new Set(ids),

src/display/editor/editor.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,16 @@ class AnnotationEditor {
12431243
}
12441244
this.#comment ||= new Comment(this);
12451245
this.#comment.setInitialText(comment, richText);
1246+
1247+
if (!this.annotationElementId) {
1248+
return;
1249+
}
1250+
const storedData = this._uiManager.getAndRemoveDataFromAnnotationStorage(
1251+
this.annotationElementId
1252+
);
1253+
if (storedData) {
1254+
this.updateFromAnnotationLayer(storedData);
1255+
}
12461256
}
12471257

12481258
get hasEditedComment() {
@@ -1288,6 +1298,10 @@ class AnnotationEditor {
12881298
}
12891299
}
12901300

1301+
updateFromAnnotationLayer({ popup: { contents, deleted } }) {
1302+
this.#comment.data = deleted ? null : contents;
1303+
}
1304+
12911305
get parentBoundingClientRect() {
12921306
return this.parent.boundingClientRect;
12931307
}

src/display/editor/tools.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,26 @@ class AnnotationEditorUIManager {
12881288
this.#floatingToolbar.show(textLayer, boxes, this.direction === "ltr");
12891289
}
12901290

1291+
/**
1292+
* Some annotations may have been modified in the annotation layer
1293+
* (e.g. comments added or modified).
1294+
* So this function retrieves the data from the storage and removes
1295+
* them from the storage in order to be able to save them later.
1296+
* @param {string} annotationId
1297+
* @returns {Object|null} The data associated to the annotation or null.
1298+
*/
1299+
getAndRemoveDataFromAnnotationStorage(annotationId) {
1300+
if (!this.#annotationStorage) {
1301+
return null;
1302+
}
1303+
const key = `${AnnotationEditorPrefix}${annotationId}`;
1304+
const storedValue = this.#annotationStorage.getRawValue(key);
1305+
if (storedValue) {
1306+
this.#annotationStorage.remove(key);
1307+
}
1308+
return storedValue;
1309+
}
1310+
12911311
/**
12921312
* Add an editor in the annotation storage.
12931313
* @param {AnnotationEditor} editor

0 commit comments

Comments
 (0)