Skip to content

Commit

Permalink
[Editor] Add the possibility to change a signature description (bug 1…
Browse files Browse the repository at this point in the history
…948116)
  • Loading branch information
calixteman committed Feb 13, 2025
1 parent 74a7576 commit dd978b8
Show file tree
Hide file tree
Showing 16 changed files with 485 additions and 142 deletions.
12 changes: 12 additions & 0 deletions l10n/en-US/viewer.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -597,3 +597,15 @@ pdfjs-editor-add-signature-add-button = Add
pdfjs-editor-delete-signature-button =
.title = Remove signature
pdfjs-editor-delete-signature-button-label = Remove signature
## Editor toolbar

pdfjs-editor-add-signature-edit-button-label = Edit description
## Edit signature description dialog

pdfjs-editor-edit-signature-dialog-title = Edit description
## Dialog buttons

pdfjs-editor-edit-signature-update-button = Update
3 changes: 2 additions & 1 deletion src/display/editor/drawers/signaturedraw.js
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,8 @@ class SignatureExtractor {
[pageWidth, pageHeight] = [pageHeight, pageWidth];
}

const { curves, thickness, width, height } = lines;
const { curves, width, height } = lines;
const thickness = lines.thickness ?? 0;
const linesAndPoints = [];
const ratio = Math.min(pageWidth / width, pageHeight / height);
const xScale = ratio / pageWidth;
Expand Down
69 changes: 61 additions & 8 deletions src/display/editor/signature.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ class DrawnSignatureOptions extends InkDrawingOptions {
class SignatureEditor extends DrawingEditor {
#isExtracted = false;

#signatureData = null;

#description = null;

#signatureData = null;

#signatureUUID = null;

static _type = "signature";
Expand All @@ -78,6 +78,7 @@ class SignatureEditor extends DrawingEditor {
super({ ...params, mustBeCommitted: true, name: "signatureEditor" });
this._willKeepAspectRatio = true;
this.#signatureData = params.signatureData || null;
this.#description = null;
}

/** @inheritdoc */
Expand Down Expand Up @@ -155,9 +156,7 @@ class SignatureEditor extends DrawingEditor {
mustSmooth,
areContours,
});
this.#signatureData = null;
this.#signatureUUID = uuid;
this.addSignature(outline.outline, heightInPage, description);
this.addSignature(outline, heightInPage, description, uuid);
} else {
this.div.hidden = true;
this._uiManager.getSignature(this);
Expand All @@ -169,14 +168,67 @@ class SignatureEditor extends DrawingEditor {

setUuid(uuid) {
this.#signatureUUID = uuid;
this.addEditToolbar();
}

getUuid() {
return this.#signatureUUID;
}

setDescription(description) {
get description() {
return this.#description;
}

set description(description) {
this.#description = description;
super.addEditToolbar().then(toolbar => {
if (toolbar) {
toolbar.updateEditSignatureButton(description);
}
});
}

getSignaturePreview() {
const { newCurves, areContours, thickness, width, height } =
this.#signatureData;
const maxDim = Math.max(width, height);
const outlineData = SignatureExtractor.processDrawnLines({
lines: {
curves: newCurves.map(points => ({ points })),
thickness,
width,
height,
},
pageWidth: maxDim,
pageHeight: maxDim,
rotation: 0,
innerMargin: 0,
mustSmooth: false,
areContours,
});
return { areContours, outline: outlineData.outline };
}

/** @inheritdoc */
async addEditToolbar() {
const toolbar = await super.addEditToolbar();
if (!toolbar) {
return null;
}
if (this._uiManager.signatureManager && this.#description !== null) {
await toolbar.addEditSignatureButton(
this._uiManager.signatureManager,
this.#signatureUUID,
this.#description
);
toolbar.show();
}
return toolbar;
}

addSignature(outline, heightInPage, description) {
addSignature(data, heightInPage, description, uuid) {
const { x: savedX, y: savedY } = this;
const { outline } = (this.#signatureData = data);
this.#isExtracted = outline instanceof ContourDrawOutline;
this.#description = description;
let drawingOptions;
Expand Down Expand Up @@ -208,6 +260,7 @@ class SignatureEditor extends DrawingEditor {
this.onScaleChanging();
this.rotate();
this._uiManager.addToAnnotationStorage(this);
this.setUuid(uuid);

this.div.hidden = false;
}
Expand Down Expand Up @@ -335,7 +388,7 @@ class SignatureEditor extends DrawingEditor {
static async deserialize(data, parent, uiManager) {
const editor = await super.deserialize(data, parent, uiManager);
editor.#isExtracted = data.areContours;
editor.#description = data.accessibilityData?.alt || "";
editor.description = data.accessibilityData?.alt || "";
editor.#signatureUUID = data.uuid;
return editor;
}
Expand Down
15 changes: 15 additions & 0 deletions src/display/editor/toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class EditorToolbar {

#altText = null;

#signatureDescriptionButton = null;

static #l10nRemove = null;

constructor(editor) {
Expand Down Expand Up @@ -154,6 +156,19 @@ class EditorToolbar {
this.#buttons.prepend(button, this.#divider);
}

async addEditSignatureButton(signatureManager) {
const button = (this.#signatureDescriptionButton =
await signatureManager.renderEditButton(this.#editor));
this.#addListenersToElement(button);
this.#buttons.prepend(button, this.#divider);
}

updateEditSignatureButton(description) {
if (this.#signatureDescriptionButton) {
this.#signatureDescriptionButton.title = description;
}
}

remove() {
this.#toolbar.remove();
this.#colorPicker?.destroy();
Expand Down
4 changes: 4 additions & 0 deletions src/display/editor/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -1012,6 +1012,10 @@ class AnnotationEditorUIManager {
this.#signatureManager?.getSignature({ uiManager: this, editor });
}

get signatureManager() {
return this.#signatureManager;
}

switchToMode(mode, callback) {
// Switching to a mode can be asynchronous.
this._eventBus.on("annotationeditormodechanged", callback, {
Expand Down
6 changes: 5 additions & 1 deletion web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -465,11 +465,15 @@ const PDFViewerApplication = {
AppOptions.get("enableSignatureEditor") && appConfig.addSignatureDialog
? new SignatureManager(
appConfig.addSignatureDialog,
appConfig.editSignatureDialog,
appConfig.annotationEditorParams?.editorSignatureAddSignature ||
null,
this.overlayManager,
l10n,
externalServices.createSignatureStorage(),
externalServices.createSignatureStorage(
eventBus,
this._globalAbortController.signal
),
eventBus
)
: null;
Expand Down
4 changes: 2 additions & 2 deletions web/chromecom.js
Original file line number Diff line number Diff line change
Expand Up @@ -422,8 +422,8 @@ class ExternalServices extends BaseExternalServices {
return new GenericScripting(AppOptions.get("sandboxBundleSrc"));
}

createSignatureStorage() {
return new SignatureStorage();
createSignatureStorage(eventBus, signal) {
return new SignatureStorage(eventBus, signal);
}
}

Expand Down
2 changes: 1 addition & 1 deletion web/dialog.css
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@
}
}

button:not(:is(.toggle-button, .closeButton)) {
button:not(:is(.toggle-button, .closeButton, .clearInputButton)) {
border-radius: 4px;
border: 1px solid;
font: menu;
Expand Down
37 changes: 22 additions & 15 deletions web/firefoxcom.js
Original file line number Diff line number Diff line change
Expand Up @@ -496,13 +496,33 @@ class MLManager {
}

class SignatureStorage {
#eventBus = null;

#signatures = null;

#signal = null;

constructor(eventBus, signal) {
this.#eventBus = eventBus;
this.#signal = signal;
}

#handleSignature(data) {
return FirefoxCom.requestAsync("handleSignature", data);
}

async getAll() {
if (this.#signal) {
window.addEventListener(
"storedSignaturesChanged",
() => {
this.#signatures = null;
this.#eventBus?.dispatch("storedsignatureschanged", { source: this });
},
{ signal: this.#signal }
);
this.#signal = null;
}
if (!this.#signatures) {
this.#signatures = new Map();
const data = await this.#handleSignature({ action: "get" });
Expand Down Expand Up @@ -546,19 +566,6 @@ class SignatureStorage {
}
return false;
}

async update(uuid, data) {
const signatures = await this.getAll();
const oldData = signatures.get(uuid);
if (!oldData) {
return false;
}
if (await this.#handleSignature({ action: "update", uuid, ...data })) {
Object.assign(oldData, data);
return true;
}
return false;
}
}

class ExternalServices extends BaseExternalServices {
Expand Down Expand Up @@ -647,8 +654,8 @@ class ExternalServices extends BaseExternalServices {
return FirefoxScripting;
}

createSignatureStorage() {
return new SignatureStorage();
createSignatureStorage(eventBus, signal) {
return new SignatureStorage(eventBus, signal);
}

dispatchGlobalEvent(event) {
Expand Down
44 changes: 29 additions & 15 deletions web/generic_signature_storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,50 @@

import { getUuid } from "pdfjs-lib";

const KEY_STORAGE = "pdfjs.signature";

class SignatureStorage {
// TODO: Encrypt the data in using a password and add a UI for entering it.
// We could use the Web Crypto API for this (see https://bradyjoslin.com/blog/encryption-webcrypto/
// for an example).

#eventBus;

#signatures = null;

#signal = null;

constructor(eventBus, signal) {
this.#eventBus = eventBus;
this.#signal = signal;
}

#save() {
localStorage.setItem(
"pdfjs.signature",
window.localStorage.setItem(
KEY_STORAGE,
JSON.stringify(Object.fromEntries(this.#signatures.entries()))
);
}

async getAll() {
if (this.#signal) {
window.addEventListener(
"storage",
({ key }) => {
if (key === KEY_STORAGE) {
this.#signatures = null;
this.#eventBus?.dispatch("storedsignatureschanged", {
source: this,
});
}
},
{ signal: this.#signal }
);
this.#signal = null;
}
if (!this.#signatures) {
this.#signatures = new Map();
const data = localStorage.getItem("pdfjs.signature");
const data = window.localStorage.getItem(KEY_STORAGE);
if (data) {
for (const [key, value] of Object.entries(JSON.parse(data))) {
this.#signatures.set(key, value);
Expand Down Expand Up @@ -68,18 +94,6 @@ class SignatureStorage {

return true;
}

async update(uuid, data) {
const signatures = await this.getAll();
const oldData = signatures.get(uuid);
if (!oldData) {
return false;
}
Object.assign(oldData, data);
this.#save();

return true;
}
}

export { SignatureStorage };
4 changes: 2 additions & 2 deletions web/genericcom.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ class ExternalServices extends BaseExternalServices {
return new GenericScripting(AppOptions.get("sandboxBundleSrc"));
}

createSignatureStorage() {
return new SignatureStorage();
createSignatureStorage(eventBus, signal) {
return new SignatureStorage(eventBus, signal);
}
}

Expand Down
3 changes: 3 additions & 0 deletions web/images/editor-toolbar-edit.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit dd978b8

Please sign in to comment.