Merge pull request #19478 from calixteman/signature_init
[Editor] Populate the 'Add signature' menu with the saved signatures (bug 1947828)
This commit is contained in:
commit
74a7576c2c
@ -320,6 +320,9 @@ pdfjs-highlight-floating-button1 =
|
|||||||
.title = Highlight
|
.title = Highlight
|
||||||
.aria-label = Highlight
|
.aria-label = Highlight
|
||||||
pdfjs-highlight-floating-button-label = Highlight
|
pdfjs-highlight-floating-button-label = Highlight
|
||||||
|
pdfjs-editor-signature-button =
|
||||||
|
.title = Add signature
|
||||||
|
pdfjs-editor-signature-button-label = Add signature
|
||||||
|
|
||||||
## Remove button for the various kind of editor.
|
## Remove button for the various kind of editor.
|
||||||
|
|
||||||
@ -349,6 +352,9 @@ pdfjs-editor-stamp-add-image-button-label = Add image
|
|||||||
pdfjs-editor-free-highlight-thickness-input = Thickness
|
pdfjs-editor-free-highlight-thickness-input = Thickness
|
||||||
pdfjs-editor-free-highlight-thickness-title =
|
pdfjs-editor-free-highlight-thickness-title =
|
||||||
.title = Change thickness when highlighting items other than text
|
.title = Change thickness when highlighting items other than text
|
||||||
|
pdfjs-editor-signature-add-signature-button =
|
||||||
|
.title = Add new signature
|
||||||
|
pdfjs-editor-signature-add-signature-button-label = Add new signature
|
||||||
|
|
||||||
# .default-content is used as a placeholder in an empty text editor.
|
# .default-content is used as a placeholder in an empty text editor.
|
||||||
pdfjs-free-text2 =
|
pdfjs-free-text2 =
|
||||||
@ -585,3 +591,9 @@ pdfjs-editor-add-signature-error-close-button = Close
|
|||||||
|
|
||||||
pdfjs-editor-add-signature-cancel-button = Cancel
|
pdfjs-editor-add-signature-cancel-button = Cancel
|
||||||
pdfjs-editor-add-signature-add-button = Add
|
pdfjs-editor-add-signature-add-button = Add
|
||||||
|
|
||||||
|
## Main menu for adding/removing signatures
|
||||||
|
|
||||||
|
pdfjs-editor-delete-signature-button =
|
||||||
|
.title = Remove signature
|
||||||
|
pdfjs-editor-delete-signature-button-label = Remove signature
|
||||||
|
|||||||
@ -698,8 +698,12 @@ class AnnotationEditorLayer {
|
|||||||
/**
|
/**
|
||||||
* Create and add a new editor.
|
* Create and add a new editor.
|
||||||
*/
|
*/
|
||||||
addNewEditor() {
|
addNewEditor(data = {}) {
|
||||||
this.createAndAddNewEditor(this.#getCenterPoint(), /* isCentered = */ true);
|
this.createAndAddNewEditor(
|
||||||
|
this.#getCenterPoint(),
|
||||||
|
/* isCentered = */ true,
|
||||||
|
data
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -784,7 +784,7 @@ class SignatureExtractor {
|
|||||||
let data = null;
|
let data = null;
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
for await (const chunk of readable) {
|
for await (const chunk of readable) {
|
||||||
data ||= new Uint8Array(new Uint32Array(chunk.buffer)[0]);
|
data ||= new Uint8Array(new Uint32Array(chunk.buffer, 0, 4)[0]);
|
||||||
data.set(chunk, offset);
|
data.set(chunk, offset);
|
||||||
offset += chunk.length;
|
offset += chunk.length;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,7 +26,7 @@ class SignatureOptions extends DrawingOptions {
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
super.updateProperties({
|
super.updateProperties({
|
||||||
fill: "black",
|
fill: "CanvasText",
|
||||||
"stroke-width": 0,
|
"stroke-width": 0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -43,7 +43,7 @@ class DrawnSignatureOptions extends InkDrawingOptions {
|
|||||||
super(viewerParameters);
|
super(viewerParameters);
|
||||||
|
|
||||||
super.updateProperties({
|
super.updateProperties({
|
||||||
stroke: "black",
|
stroke: "CanvasText",
|
||||||
"stroke-width": 1,
|
"stroke-width": 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -62,6 +62,12 @@ class DrawnSignatureOptions extends InkDrawingOptions {
|
|||||||
class SignatureEditor extends DrawingEditor {
|
class SignatureEditor extends DrawingEditor {
|
||||||
#isExtracted = false;
|
#isExtracted = false;
|
||||||
|
|
||||||
|
#signatureData = null;
|
||||||
|
|
||||||
|
#description = null;
|
||||||
|
|
||||||
|
#signatureUUID = null;
|
||||||
|
|
||||||
static _type = "signature";
|
static _type = "signature";
|
||||||
|
|
||||||
static _editorType = AnnotationEditorType.SIGNATURE;
|
static _editorType = AnnotationEditorType.SIGNATURE;
|
||||||
@ -71,8 +77,7 @@ class SignatureEditor extends DrawingEditor {
|
|||||||
constructor(params) {
|
constructor(params) {
|
||||||
super({ ...params, mustBeCommitted: true, name: "signatureEditor" });
|
super({ ...params, mustBeCommitted: true, name: "signatureEditor" });
|
||||||
this._willKeepAspectRatio = true;
|
this._willKeepAspectRatio = true;
|
||||||
this._description = "";
|
this.#signatureData = params.signatureData || null;
|
||||||
this._signatureUUID = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @inheritdoc */
|
/** @inheritdoc */
|
||||||
@ -128,17 +133,52 @@ class SignatureEditor extends DrawingEditor {
|
|||||||
this.div.setAttribute("role", "figure");
|
this.div.setAttribute("role", "figure");
|
||||||
|
|
||||||
if (this._drawId === null) {
|
if (this._drawId === null) {
|
||||||
this.div.hidden = true;
|
if (this.#signatureData) {
|
||||||
this._uiManager.getSignature(this);
|
const {
|
||||||
|
lines,
|
||||||
|
mustSmooth,
|
||||||
|
areContours,
|
||||||
|
description,
|
||||||
|
uuid,
|
||||||
|
heightInPage,
|
||||||
|
} = this.#signatureData;
|
||||||
|
const {
|
||||||
|
rawDims: { pageWidth, pageHeight },
|
||||||
|
rotation,
|
||||||
|
} = this.parent.viewport;
|
||||||
|
const outline = SignatureExtractor.processDrawnLines({
|
||||||
|
lines,
|
||||||
|
pageWidth,
|
||||||
|
pageHeight,
|
||||||
|
rotation,
|
||||||
|
innerMargin: SignatureEditor._INNER_MARGIN,
|
||||||
|
mustSmooth,
|
||||||
|
areContours,
|
||||||
|
});
|
||||||
|
this.#signatureData = null;
|
||||||
|
this.#signatureUUID = uuid;
|
||||||
|
this.addSignature(outline.outline, heightInPage, description);
|
||||||
|
} else {
|
||||||
|
this.div.hidden = true;
|
||||||
|
this._uiManager.getSignature(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.div;
|
return this.div;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setUuid(uuid) {
|
||||||
|
this.#signatureUUID = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
setDescription(description) {
|
||||||
|
this.#description = description;
|
||||||
|
}
|
||||||
|
|
||||||
addSignature(outline, heightInPage, description) {
|
addSignature(outline, heightInPage, description) {
|
||||||
const { x: savedX, y: savedY } = this;
|
const { x: savedX, y: savedY } = this;
|
||||||
this.#isExtracted = outline instanceof ContourDrawOutline;
|
this.#isExtracted = outline instanceof ContourDrawOutline;
|
||||||
this._description = description;
|
this.#description = description;
|
||||||
let drawingOptions;
|
let drawingOptions;
|
||||||
if (this.#isExtracted) {
|
if (this.#isExtracted) {
|
||||||
drawingOptions = SignatureEditor.getDefaultDrawingOptions();
|
drawingOptions = SignatureEditor.getDefaultDrawingOptions();
|
||||||
@ -251,11 +291,12 @@ class SignatureEditor extends DrawingEditor {
|
|||||||
};
|
};
|
||||||
if (isForCopying) {
|
if (isForCopying) {
|
||||||
serialized.paths = { lines, points };
|
serialized.paths = { lines, points };
|
||||||
|
serialized.uuid = this.#signatureUUID;
|
||||||
} else {
|
} else {
|
||||||
serialized.lines = lines;
|
serialized.lines = lines;
|
||||||
}
|
}
|
||||||
if (this._description) {
|
if (this.#description) {
|
||||||
serialized.accessibilityData = { type: "Figure", alt: this._description };
|
serialized.accessibilityData = { type: "Figure", alt: this.#description };
|
||||||
}
|
}
|
||||||
return serialized;
|
return serialized;
|
||||||
}
|
}
|
||||||
@ -294,7 +335,8 @@ class SignatureEditor extends DrawingEditor {
|
|||||||
static async deserialize(data, parent, uiManager) {
|
static async deserialize(data, parent, uiManager) {
|
||||||
const editor = await super.deserialize(data, parent, uiManager);
|
const editor = await super.deserialize(data, parent, uiManager);
|
||||||
editor.#isExtracted = data.areContours;
|
editor.#isExtracted = data.areContours;
|
||||||
editor._description = data.accessibilityData?.alt || "";
|
editor.#description = data.accessibilityData?.alt || "";
|
||||||
|
editor.#signatureUUID = data.uuid;
|
||||||
return editor;
|
return editor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1698,6 +1698,9 @@ class AnnotationEditorUIManager {
|
|||||||
this.#updateModeCapability.resolve();
|
this.#updateModeCapability.resolve();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (mode === AnnotationEditorType.SIGNATURE) {
|
||||||
|
await this.#signatureManager?.loadSignatures();
|
||||||
|
}
|
||||||
this.setEditingState(true);
|
this.setEditingState(true);
|
||||||
await this.#enableAll();
|
await this.#enableAll();
|
||||||
this.unselectAll();
|
this.unselectAll();
|
||||||
@ -1758,7 +1761,7 @@ class AnnotationEditorUIManager {
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case AnnotationEditorParamsType.CREATE:
|
case AnnotationEditorParamsType.CREATE:
|
||||||
this.currentLayer.addNewEditor();
|
this.currentLayer.addNewEditor(value);
|
||||||
return;
|
return;
|
||||||
case AnnotationEditorParamsType.HIGHLIGHT_DEFAULT_COLOR:
|
case AnnotationEditorParamsType.HIGHLIGHT_DEFAULT_COLOR:
|
||||||
this.#mainHighlightColorPicker?.updateColor(value);
|
this.#mainHighlightColorPicker?.updateColor(value);
|
||||||
|
|||||||
@ -465,9 +465,12 @@ const PDFViewerApplication = {
|
|||||||
AppOptions.get("enableSignatureEditor") && appConfig.addSignatureDialog
|
AppOptions.get("enableSignatureEditor") && appConfig.addSignatureDialog
|
||||||
? new SignatureManager(
|
? new SignatureManager(
|
||||||
appConfig.addSignatureDialog,
|
appConfig.addSignatureDialog,
|
||||||
|
appConfig.annotationEditorParams?.editorSignatureAddSignature ||
|
||||||
|
null,
|
||||||
this.overlayManager,
|
this.overlayManager,
|
||||||
this.l10n,
|
l10n,
|
||||||
externalServices.createSignatureStorage()
|
externalServices.createSignatureStorage(),
|
||||||
|
eventBus
|
||||||
)
|
)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
|
|||||||
@ -20,8 +20,6 @@
|
|||||||
--text-primary-color: #15141a;
|
--text-primary-color: #15141a;
|
||||||
--text-secondary-color: #5b5b66;
|
--text-secondary-color: #5b5b66;
|
||||||
--hover-filter: brightness(0.9);
|
--hover-filter: brightness(0.9);
|
||||||
--focus-ring-color: #0060df;
|
|
||||||
--focus-ring-outline: 2px solid var(--focus-ring-color);
|
|
||||||
--link-fg-color: #0060df;
|
--link-fg-color: #0060df;
|
||||||
--link-hover-fg-color: #0250bb;
|
--link-hover-fg-color: #0250bb;
|
||||||
--separator-color: #f0f0f4;
|
--separator-color: #f0f0f4;
|
||||||
@ -58,7 +56,6 @@
|
|||||||
--dialog-shadow: 0 2px 14px 0 #15141a;
|
--dialog-shadow: 0 2px 14px 0 #15141a;
|
||||||
--text-primary-color: #fbfbfe;
|
--text-primary-color: #fbfbfe;
|
||||||
--text-secondary-color: #cfcfd8;
|
--text-secondary-color: #cfcfd8;
|
||||||
--focus-ring-color: #0df;
|
|
||||||
--hover-filter: brightness(1.4);
|
--hover-filter: brightness(1.4);
|
||||||
--link-fg-color: #0df;
|
--link-fg-color: #0df;
|
||||||
--link-hover-fg-color: #80ebff;
|
--link-hover-fg-color: #80ebff;
|
||||||
@ -82,7 +79,6 @@
|
|||||||
--text-primary-color: CanvasText;
|
--text-primary-color: CanvasText;
|
||||||
--text-secondary-color: CanvasText;
|
--text-secondary-color: CanvasText;
|
||||||
--hover-filter: none;
|
--hover-filter: none;
|
||||||
--focus-ring-color: ButtonBorder;
|
|
||||||
--link-fg-color: LinkText;
|
--link-fg-color: LinkText;
|
||||||
--link-hover-fg-color: LinkText;
|
--link-hover-fg-color: LinkText;
|
||||||
--separator-color: CanvasText;
|
--separator-color: CanvasText;
|
||||||
|
|||||||
@ -504,11 +504,11 @@ class SignatureStorage {
|
|||||||
|
|
||||||
async getAll() {
|
async getAll() {
|
||||||
if (!this.#signatures) {
|
if (!this.#signatures) {
|
||||||
this.#signatures = Object.create(null);
|
this.#signatures = new Map();
|
||||||
const data = await this.#handleSignature({ action: "get" });
|
const data = await this.#handleSignature({ action: "get" });
|
||||||
if (data) {
|
if (data) {
|
||||||
for (const { uuid, description, signatureData } of data) {
|
for (const { uuid, description, signatureData } of data) {
|
||||||
this.#signatures[uuid] = { description, signatureData };
|
this.#signatures.set(uuid, { description, signatureData });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -517,7 +517,7 @@ class SignatureStorage {
|
|||||||
|
|
||||||
async isFull() {
|
async isFull() {
|
||||||
// We want to store at most 5 signatures.
|
// We want to store at most 5 signatures.
|
||||||
return Object.keys(await this.getAll()).length === 5;
|
return (await this.getAll()).size === 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(data) {
|
async create(data) {
|
||||||
@ -531,17 +531,17 @@ class SignatureStorage {
|
|||||||
if (!uuid) {
|
if (!uuid) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
this.#signatures[uuid] = data;
|
this.#signatures.set(uuid, data);
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(uuid) {
|
async delete(uuid) {
|
||||||
const signatures = await this.getAll();
|
const signatures = await this.getAll();
|
||||||
if (!signatures[uuid]) {
|
if (!signatures.has(uuid)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (await this.#handleSignature({ action: "delete", uuid })) {
|
if (await this.#handleSignature({ action: "delete", uuid })) {
|
||||||
delete signatures[uuid];
|
signatures.delete(uuid);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -549,7 +549,7 @@ class SignatureStorage {
|
|||||||
|
|
||||||
async update(uuid, data) {
|
async update(uuid, data) {
|
||||||
const signatures = await this.getAll();
|
const signatures = await this.getAll();
|
||||||
const oldData = signatures[uuid];
|
const oldData = signatures.get(uuid);
|
||||||
if (!oldData) {
|
if (!oldData) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,19 +23,28 @@ class SignatureStorage {
|
|||||||
#signatures = null;
|
#signatures = null;
|
||||||
|
|
||||||
#save() {
|
#save() {
|
||||||
localStorage.setItem("pdfjs.signature", JSON.stringify(this.#signatures));
|
localStorage.setItem(
|
||||||
|
"pdfjs.signature",
|
||||||
|
JSON.stringify(Object.fromEntries(this.#signatures.entries()))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAll() {
|
async getAll() {
|
||||||
if (!this.#signatures) {
|
if (!this.#signatures) {
|
||||||
|
this.#signatures = new Map();
|
||||||
const data = localStorage.getItem("pdfjs.signature");
|
const data = localStorage.getItem("pdfjs.signature");
|
||||||
this.#signatures = data ? JSON.parse(data) : Object.create(null);
|
if (data) {
|
||||||
|
for (const [key, value] of Object.entries(JSON.parse(data))) {
|
||||||
|
this.#signatures.set(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this.#signatures;
|
return this.#signatures;
|
||||||
}
|
}
|
||||||
|
|
||||||
async isFull() {
|
async isFull() {
|
||||||
return Object.keys(await this.getAll()).length === 5;
|
// Only allow 5 signatures to be saved.
|
||||||
|
return (await this.getAll()).size === 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(data) {
|
async create(data) {
|
||||||
@ -43,7 +52,7 @@ class SignatureStorage {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const uuid = getUuid();
|
const uuid = getUuid();
|
||||||
this.#signatures[uuid] = data;
|
this.#signatures.set(uuid, data);
|
||||||
this.#save();
|
this.#save();
|
||||||
|
|
||||||
return uuid;
|
return uuid;
|
||||||
@ -51,10 +60,10 @@ class SignatureStorage {
|
|||||||
|
|
||||||
async delete(uuid) {
|
async delete(uuid) {
|
||||||
const signatures = await this.getAll();
|
const signatures = await this.getAll();
|
||||||
if (!signatures[uuid]) {
|
if (!signatures.has(uuid)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
delete signatures[uuid];
|
signatures.delete(uuid);
|
||||||
this.#save();
|
this.#save();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -62,7 +71,7 @@ class SignatureStorage {
|
|||||||
|
|
||||||
async update(uuid, data) {
|
async update(uuid, data) {
|
||||||
const signatures = await this.getAll();
|
const signatures = await this.getAll();
|
||||||
const oldData = signatures[uuid];
|
const oldData = signatures.get(uuid);
|
||||||
if (!oldData) {
|
if (!oldData) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -143,9 +143,6 @@
|
|||||||
--undo-button-fg-color-hover: var(--undo-button-fg-color);
|
--undo-button-fg-color-hover: var(--undo-button-fg-color);
|
||||||
--undo-button-fg-color-active: var(--undo-button-fg-color);
|
--undo-button-fg-color-active: var(--undo-button-fg-color);
|
||||||
|
|
||||||
--focus-ring-color: #0060df;
|
|
||||||
--focus-ring-outline: 2px solid var(--focus-ring-color);
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
--text-primary-color: #fbfbfe;
|
--text-primary-color: #fbfbfe;
|
||||||
|
|
||||||
@ -172,8 +169,6 @@
|
|||||||
--undo-button-fg-color: ButtonFace;
|
--undo-button-fg-color: ButtonFace;
|
||||||
--undo-button-fg-color-hover: SelectedItemText;
|
--undo-button-fg-color-hover: SelectedItemText;
|
||||||
--undo-button-fg-color-active: SelectedItemText;
|
--undo-button-fg-color-active: SelectedItemText;
|
||||||
|
|
||||||
--focus-ring-color: CanvasText;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|||||||
@ -27,14 +27,19 @@
|
|||||||
--page-border: 9px solid transparent;
|
--page-border: 9px solid transparent;
|
||||||
--spreadHorizontalWrapped-margin-LR: -3.5px;
|
--spreadHorizontalWrapped-margin-LR: -3.5px;
|
||||||
--loading-icon-delay: 400ms;
|
--loading-icon-delay: 400ms;
|
||||||
}
|
--focus-ring-color: #0060df;
|
||||||
|
--focus-ring-outline: 2px solid var(--focus-ring-color);
|
||||||
|
|
||||||
@media screen and (forced-colors: active) {
|
@media (prefers-color-scheme: dark) {
|
||||||
:root {
|
--focus-ring-color: #0df;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (forced-colors: active) {
|
||||||
--pdfViewer-padding-bottom: 9px;
|
--pdfViewer-padding-bottom: 9px;
|
||||||
--page-margin: 8px auto -1px;
|
--page-margin: 8px auto -1px;
|
||||||
--page-border: 1px solid CanvasText;
|
--page-border: 1px solid CanvasText;
|
||||||
--spreadHorizontalWrapped-margin-LR: 3.5px;
|
--spreadHorizontalWrapped-margin-LR: 3.5px;
|
||||||
|
--focus-ring-color: CanvasText;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -933,9 +933,7 @@ class PDFViewer {
|
|||||||
uiManager: this.#annotationEditorUIManager,
|
uiManager: this.#annotationEditorUIManager,
|
||||||
});
|
});
|
||||||
if (mode !== AnnotationEditorType.NONE) {
|
if (mode !== AnnotationEditorType.NONE) {
|
||||||
if (mode === AnnotationEditorType.STAMP) {
|
this.#preloadEditingData(mode);
|
||||||
this.#mlManager?.loadModel("altText");
|
|
||||||
}
|
|
||||||
this.#annotationEditorUIManager.updateMode(mode);
|
this.#annotationEditorUIManager.updateMode(mode);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -2315,6 +2313,18 @@ class PDFViewer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#preloadEditingData(mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case AnnotationEditorType.STAMP:
|
||||||
|
this.#mlManager?.loadModel("altText");
|
||||||
|
break;
|
||||||
|
case AnnotationEditorType.SIGNATURE:
|
||||||
|
// Start to load the signature data.
|
||||||
|
this.#signatureManager?.loadSignatures();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get annotationEditorMode() {
|
get annotationEditorMode() {
|
||||||
return this.#annotationEditorUIManager
|
return this.#annotationEditorUIManager
|
||||||
? this.#annotationEditorMode
|
? this.#annotationEditorMode
|
||||||
@ -2345,9 +2355,7 @@ class PDFViewer {
|
|||||||
if (!this.pdfDocument) {
|
if (!this.pdfDocument) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mode === AnnotationEditorType.STAMP) {
|
this.#preloadEditingData(mode);
|
||||||
this.#mlManager?.loadModel("altText");
|
|
||||||
}
|
|
||||||
|
|
||||||
const { eventBus, pdfDocument } = this;
|
const { eventBus, pdfDocument } = this;
|
||||||
const updater = async () => {
|
const updater = async () => {
|
||||||
|
|||||||
@ -13,6 +13,39 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--clear-signature-button-icon: url(images/editor-toolbar-delete.svg);
|
||||||
|
--signature-bg: #f9f9fb;
|
||||||
|
--signature-hover-bg: #f0f0f4;
|
||||||
|
--button-signature-bg: transparent;
|
||||||
|
--button-signature-color: var(--main-color);
|
||||||
|
--button-signature-active-bg: #cfcfd8;
|
||||||
|
--button-signature-active-border: none;
|
||||||
|
--button-signature-active-color: var(--button-signature-color);
|
||||||
|
--button-signature-border: none;
|
||||||
|
--button-signature-hover-bg: #e0e0e6;
|
||||||
|
--button-signature-hover-color: var(--button-signature-color);
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
--signature-bg: #2b2a33;
|
||||||
|
--signature-hover-bg: var(--signature-bg);
|
||||||
|
--button-signature-active-bg: #5b5b66;
|
||||||
|
--button-signature-hover-bg: #52525e;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (forced-colors: active) {
|
||||||
|
--signature-bg: HighlightText;
|
||||||
|
--signature-hover-bg: var(--signature-bg);
|
||||||
|
--button-signature-bg: HighlightText;
|
||||||
|
--button-signature-color: ButtonText;
|
||||||
|
--button-signature-active-bg: ButtonText;
|
||||||
|
--button-signature-active-color: HighlightText;
|
||||||
|
--button-signature-border: 1px solid ButtonText;
|
||||||
|
--button-signature-hover-bg: Highlight;
|
||||||
|
--button-signature-hover-color: HighlightText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#addSignatureDialog {
|
#addSignatureDialog {
|
||||||
--border-color: #8f8f9d;
|
--border-color: #8f8f9d;
|
||||||
--primary-color: var(--text-primary-color);
|
--primary-color: var(--text-primary-color);
|
||||||
@ -31,8 +64,8 @@
|
|||||||
--tab-bg-hover: var(--bg-hover);
|
--tab-bg-hover: var(--bg-hover);
|
||||||
--tab-text-color: var(--primary-color);
|
--tab-text-color: var(--primary-color);
|
||||||
--tab-text-active-color: var(--tab-top-line-active-color);
|
--tab-text-active-color: var(--tab-top-line-active-color);
|
||||||
|
--tab-text-active-hover-color: var(--tab-text-hover-color);
|
||||||
--tab-text-hover-color: var(--tab-text-color);
|
--tab-text-hover-color: var(--tab-text-color);
|
||||||
--signature-bg: #f9f9fb;
|
|
||||||
--signature-placeholder-color: var(--secondary-color);
|
--signature-placeholder-color: var(--secondary-color);
|
||||||
--signature-draw-placeholder-color: var(--primary-color);
|
--signature-draw-placeholder-color: var(--primary-color);
|
||||||
--signature-color: var(--primary-color);
|
--signature-color: var(--primary-color);
|
||||||
@ -43,7 +76,6 @@
|
|||||||
--clear-signature-button-border-style: solid;
|
--clear-signature-button-border-style: solid;
|
||||||
--clear-signature-button-border-color: transparent;
|
--clear-signature-button-border-color: transparent;
|
||||||
--clear-signature-button-border-disabled-color: transparent;
|
--clear-signature-button-border-disabled-color: transparent;
|
||||||
--clear-signature-button-icon: url(images/editor-toolbar-delete.svg);
|
|
||||||
--clear-signature-button-color: var(--primary-color);
|
--clear-signature-button-color: var(--primary-color);
|
||||||
--clear-signature-button-hover-color: var(--clear-signature-button-color);
|
--clear-signature-button-hover-color: var(--clear-signature-button-color);
|
||||||
--clear-signature-button-active-color: var(--clear-signature-button-color);
|
--clear-signature-button-active-color: var(--clear-signature-button-color);
|
||||||
@ -72,7 +104,6 @@
|
|||||||
--secondary-color: #cfcfd8;
|
--secondary-color: #cfcfd8;
|
||||||
--tab-top-line-active-color: #0df;
|
--tab-top-line-active-color: #0df;
|
||||||
--tab-top-line-inactive-color: #8f8f9d;
|
--tab-top-line-inactive-color: #8f8f9d;
|
||||||
--signature-bg: #2b2a33;
|
|
||||||
--clear-signature-button-bg-active: #5b5b66;
|
--clear-signature-button-bg-active: #5b5b66;
|
||||||
--clear-signature-button-bg-focus: #2b2a33;
|
--clear-signature-button-bg-focus: #2b2a33;
|
||||||
--clear-signature-button-bg-disabled: color-mix(
|
--clear-signature-button-bg-disabled: color-mix(
|
||||||
@ -99,8 +130,8 @@
|
|||||||
--tab-bg-active-hover-color: SelectedItem;
|
--tab-bg-active-hover-color: SelectedItem;
|
||||||
--tab-text-color: ButtonText;
|
--tab-text-color: ButtonText;
|
||||||
--tab-text-active-color: HighlightText;
|
--tab-text-active-color: HighlightText;
|
||||||
|
--tab-text-active-hover-color: HighlightText;
|
||||||
--tab-text-hover-color: SelectedItem;
|
--tab-text-hover-color: SelectedItem;
|
||||||
--signature-bg: var(--bg);
|
|
||||||
--signature-color: ButtonText;
|
--signature-color: ButtonText;
|
||||||
--clear-signature-button-border-width: 1px;
|
--clear-signature-button-border-width: 1px;
|
||||||
--clear-signature-button-border-style: solid;
|
--clear-signature-button-border-style: solid;
|
||||||
@ -214,7 +245,7 @@
|
|||||||
&:hover {
|
&:hover {
|
||||||
border-block-start-color: var(--tab-top-line-active-hover-color);
|
border-block-start-color: var(--tab-top-line-active-hover-color);
|
||||||
background-color: var(--tab-bg-active-hover-color);
|
background-color: var(--tab-bg-active-hover-color);
|
||||||
color: var(--tab-text-hover-color);
|
color: var(--tab-text-active-hover-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -594,3 +625,138 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#editorSignatureParamsToolbar {
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
#addSignatureDoorHanger {
|
||||||
|
gap: 8px;
|
||||||
|
overflow-y: unset;
|
||||||
|
|
||||||
|
.toolbarAddSignatureButtonContainer {
|
||||||
|
height: 32px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
align-self: stretch;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
button {
|
||||||
|
border: var(--button-signature-border);
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: var(--button-signature-bg);
|
||||||
|
color: var(--button-signature-color);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--button-signature-hover-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
border: var(--button-signature-active-border);
|
||||||
|
background-color: var(--button-signature-active-bg);
|
||||||
|
color: var(--button-signature-active-color);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
background-color: var(--button-signature-active-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-visible {
|
||||||
|
outline: var(--focus-ring-outline);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
background-color: var(--button-signature-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.deleteButton {
|
||||||
|
&::before {
|
||||||
|
mask-image: var(--clear-signature-button-icon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbarAddSignatureButton {
|
||||||
|
width: auto;
|
||||||
|
height: 100%;
|
||||||
|
min-height: var(--menuitem-height);
|
||||||
|
aspect-ratio: unset;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
outline: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font: message-box;
|
||||||
|
position: relative;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
padding: 0;
|
||||||
|
gap: 8px;
|
||||||
|
text-align: start;
|
||||||
|
white-space: normal;
|
||||||
|
cursor: default;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
> svg {
|
||||||
|
display: inline-block;
|
||||||
|
height: 100%;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
background-color: var(--signature-bg);
|
||||||
|
flex: none;
|
||||||
|
padding: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
> path {
|
||||||
|
stroke: var(--button-signature-color);
|
||||||
|
stroke-width: 1px;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: round;
|
||||||
|
stroke-miterlimit: 10;
|
||||||
|
vector-effect: non-scaling-stroke;
|
||||||
|
fill: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.contours > path {
|
||||||
|
fill: var(--button-signature-color);
|
||||||
|
stroke-width: 0.5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:is(:hover, :active) > svg {
|
||||||
|
border-radius: 4px 0 0 4px;
|
||||||
|
background-color: var(--signature-hover-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
> span {
|
||||||
|
color: var(--button-signature-hover-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: var(--button-signature-active-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:is([disabled="disabled"], [disabled]) {
|
||||||
|
opacity: 0.5;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
> span {
|
||||||
|
height: auto;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
font: menu;
|
||||||
|
font-size: 13px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: normal;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
AnnotationEditorParamsType,
|
||||||
DOMSVGFactory,
|
DOMSVGFactory,
|
||||||
noContextMenu,
|
noContextMenu,
|
||||||
SignatureExtractor,
|
SignatureExtractor,
|
||||||
@ -21,6 +22,9 @@ import {
|
|||||||
SupportedImageMimeTypes,
|
SupportedImageMimeTypes,
|
||||||
} from "pdfjs-lib";
|
} from "pdfjs-lib";
|
||||||
|
|
||||||
|
// Default height of the added signature in page coordinates.
|
||||||
|
const DEFAULT_HEIGHT_IN_PAGE = 40;
|
||||||
|
|
||||||
class SignatureManager {
|
class SignatureManager {
|
||||||
#addButton;
|
#addButton;
|
||||||
|
|
||||||
@ -70,6 +74,10 @@ class SignatureManager {
|
|||||||
|
|
||||||
#tabButtons;
|
#tabButtons;
|
||||||
|
|
||||||
|
#addSignatureToolbarButton;
|
||||||
|
|
||||||
|
#loadSignaturesPromise = null;
|
||||||
|
|
||||||
#typeInput;
|
#typeInput;
|
||||||
|
|
||||||
#currentTab = null;
|
#currentTab = null;
|
||||||
@ -78,6 +86,8 @@ class SignatureManager {
|
|||||||
|
|
||||||
#hasDescriptionChanged = false;
|
#hasDescriptionChanged = false;
|
||||||
|
|
||||||
|
#eventBus;
|
||||||
|
|
||||||
#l10n;
|
#l10n;
|
||||||
|
|
||||||
#overlayManager;
|
#overlayManager;
|
||||||
@ -113,9 +123,11 @@ class SignatureManager {
|
|||||||
saveCheckbox,
|
saveCheckbox,
|
||||||
saveContainer,
|
saveContainer,
|
||||||
},
|
},
|
||||||
|
addSignatureToolbarButton,
|
||||||
overlayManager,
|
overlayManager,
|
||||||
l10n,
|
l10n,
|
||||||
signatureStorage
|
signatureStorage,
|
||||||
|
eventBus
|
||||||
) {
|
) {
|
||||||
this.#addButton = addButton;
|
this.#addButton = addButton;
|
||||||
this.#clearButton = clearButton;
|
this.#clearButton = clearButton;
|
||||||
@ -133,9 +145,11 @@ class SignatureManager {
|
|||||||
this.#overlayManager = overlayManager;
|
this.#overlayManager = overlayManager;
|
||||||
this.#saveCheckbox = saveCheckbox;
|
this.#saveCheckbox = saveCheckbox;
|
||||||
this.#saveContainer = saveContainer;
|
this.#saveContainer = saveContainer;
|
||||||
|
this.#addSignatureToolbarButton = addSignatureToolbarButton;
|
||||||
this.#typeInput = typeInput;
|
this.#typeInput = typeInput;
|
||||||
this.#l10n = l10n;
|
this.#l10n = l10n;
|
||||||
this.#signatureStorage = signatureStorage;
|
this.#signatureStorage = signatureStorage;
|
||||||
|
this.#eventBus = eventBus;
|
||||||
|
|
||||||
SignatureManager.#l10nDescription ||= Object.freeze({
|
SignatureManager.#l10nDescription ||= Object.freeze({
|
||||||
signature: "pdfjs-editor-add-signature-description-default-when-drawing",
|
signature: "pdfjs-editor-add-signature-description-default-when-drawing",
|
||||||
@ -360,7 +374,7 @@ class SignatureManager {
|
|||||||
this.#drawCurves = {
|
this.#drawCurves = {
|
||||||
width: drawWidth,
|
width: drawWidth,
|
||||||
height: drawHeight,
|
height: drawHeight,
|
||||||
thickness: this.#drawThickness.value,
|
thickness: parseInt(this.#drawThickness.value),
|
||||||
curves: [],
|
curves: [],
|
||||||
};
|
};
|
||||||
this.#disableButtons(true);
|
this.#disableButtons(true);
|
||||||
@ -610,10 +624,147 @@ class SignatureManager {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#addToolbarButton(signatureData, uuid, description) {
|
||||||
|
const { curves, areContours, thickness, width, height } = signatureData;
|
||||||
|
const maxDim = Math.max(width, height);
|
||||||
|
const outlineData = SignatureExtractor.processDrawnLines({
|
||||||
|
lines: {
|
||||||
|
curves,
|
||||||
|
thickness,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
},
|
||||||
|
pageWidth: maxDim,
|
||||||
|
pageHeight: maxDim,
|
||||||
|
rotation: 0,
|
||||||
|
innerMargin: 0,
|
||||||
|
mustSmooth: false,
|
||||||
|
areContours,
|
||||||
|
});
|
||||||
|
if (!outlineData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { outline } = outlineData;
|
||||||
|
const svgFactory = new DOMSVGFactory();
|
||||||
|
|
||||||
|
const div = document.createElement("div");
|
||||||
|
const button = document.createElement("button");
|
||||||
|
button.addEventListener("click", () => {
|
||||||
|
this.#eventBus.dispatch("switchannotationeditorparams", {
|
||||||
|
source: this,
|
||||||
|
type: AnnotationEditorParamsType.CREATE,
|
||||||
|
value: {
|
||||||
|
signatureData: {
|
||||||
|
lines: {
|
||||||
|
curves,
|
||||||
|
thickness,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
},
|
||||||
|
mustSmooth: false,
|
||||||
|
areContours,
|
||||||
|
description,
|
||||||
|
uuid,
|
||||||
|
heightInPage: DEFAULT_HEIGHT_IN_PAGE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
div.append(button);
|
||||||
|
div.classList.add("toolbarAddSignatureButtonContainer");
|
||||||
|
|
||||||
|
const svg = svgFactory.create(1, 1, true);
|
||||||
|
button.append(svg);
|
||||||
|
|
||||||
|
const span = document.createElement("span");
|
||||||
|
button.append(span);
|
||||||
|
|
||||||
|
button.classList.add("toolbarAddSignatureButton");
|
||||||
|
button.type = "button";
|
||||||
|
button.title = span.textContent = description;
|
||||||
|
button.tabIndex = 0;
|
||||||
|
|
||||||
|
const path = svgFactory.createElement("path");
|
||||||
|
svg.append(path);
|
||||||
|
svg.setAttribute("viewBox", outline.viewBox);
|
||||||
|
svg.setAttribute("preserveAspectRatio", "xMidYMid meet");
|
||||||
|
if (areContours) {
|
||||||
|
svg.classList.add("contours");
|
||||||
|
}
|
||||||
|
path.setAttribute("d", outline.toSVGPath());
|
||||||
|
|
||||||
|
const deleteButton = document.createElement("button");
|
||||||
|
div.append(deleteButton);
|
||||||
|
deleteButton.classList.add("toolbarButton", "deleteButton");
|
||||||
|
deleteButton.setAttribute(
|
||||||
|
"data-l10n-id",
|
||||||
|
"pdfjs-editor-delete-signature-button"
|
||||||
|
);
|
||||||
|
deleteButton.type = "button";
|
||||||
|
deleteButton.tabIndex = 0;
|
||||||
|
deleteButton.addEventListener("click", async () => {
|
||||||
|
if (await this.#signatureStorage.delete(uuid)) {
|
||||||
|
div.remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const deleteSpan = document.createElement("span");
|
||||||
|
deleteButton.append(deleteSpan);
|
||||||
|
deleteSpan.setAttribute(
|
||||||
|
"data-l10n-id",
|
||||||
|
"pdfjs-editor-delete-signature-button-label"
|
||||||
|
);
|
||||||
|
|
||||||
|
this.#addSignatureToolbarButton.before(div);
|
||||||
|
}
|
||||||
|
|
||||||
getSignature(params) {
|
getSignature(params) {
|
||||||
return this.open(params);
|
return this.open(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async loadSignatures() {
|
||||||
|
if (
|
||||||
|
!this.#addSignatureToolbarButton ||
|
||||||
|
this.#addSignatureToolbarButton.previousElementSibling ||
|
||||||
|
!this.#signatureStorage
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.#loadSignaturesPromise) {
|
||||||
|
// The first call of loadSignatures() starts loading the signatures.
|
||||||
|
// The second one will wait until the signatures are loaded in the DOM.
|
||||||
|
this.#loadSignaturesPromise = this.#signatureStorage
|
||||||
|
.getAll()
|
||||||
|
.then(async signatures => [
|
||||||
|
signatures,
|
||||||
|
await Promise.all(
|
||||||
|
Array.from(
|
||||||
|
signatures
|
||||||
|
.values()
|
||||||
|
.map(({ signatureData }) =>
|
||||||
|
SignatureExtractor.decompressSignature(signatureData)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const [signatures, signaturesData] = await this.#loadSignaturesPromise;
|
||||||
|
this.#loadSignaturesPromise = null;
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
|
for (const [uuid, { description }] of signatures) {
|
||||||
|
const data = signaturesData[i++];
|
||||||
|
if (!data) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
data.curves = data.outlines.map(points => ({ points }));
|
||||||
|
delete data.outlines;
|
||||||
|
this.#addToolbarButton(data, uuid, description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async open({ uiManager, editor }) {
|
async open({ uiManager, editor }) {
|
||||||
this.#tabsToAltText ||= new Map(
|
this.#tabsToAltText ||= new Map(
|
||||||
this.#tabButtons.keys().map(name => [name, ""])
|
this.#tabButtons.keys().map(name => [name, ""])
|
||||||
@ -677,9 +828,10 @@ class SignatureManager {
|
|||||||
}
|
}
|
||||||
this.#currentEditor.addSignature(
|
this.#currentEditor.addSignature(
|
||||||
data.outline,
|
data.outline,
|
||||||
/* heightInPage */ 40,
|
DEFAULT_HEIGHT_IN_PAGE,
|
||||||
this.#description.value
|
this.#description.value
|
||||||
);
|
);
|
||||||
|
let uuid = null;
|
||||||
if (this.#saveCheckbox.checked) {
|
if (this.#saveCheckbox.checked) {
|
||||||
const description = this.#description.value;
|
const description = this.#description.value;
|
||||||
const { newCurves, areContours, thickness, width, height } = data;
|
const { newCurves, areContours, thickness, width, height } = data;
|
||||||
@ -690,15 +842,27 @@ class SignatureManager {
|
|||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
});
|
});
|
||||||
const uuid = (this.#currentEditor._signatureUUID =
|
uuid = await this.#signatureStorage.create({
|
||||||
await this.#signatureStorage.create({
|
description,
|
||||||
description,
|
signatureData,
|
||||||
signatureData,
|
});
|
||||||
}));
|
if (uuid) {
|
||||||
if (!uuid) {
|
this.#addToolbarButton(
|
||||||
|
{
|
||||||
|
curves: newCurves.map(points => ({ points })),
|
||||||
|
areContours,
|
||||||
|
thickness,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
},
|
||||||
|
uuid,
|
||||||
|
description
|
||||||
|
);
|
||||||
|
} else {
|
||||||
console.warn("SignatureManager.add: cannot save the signature.");
|
console.warn("SignatureManager.add: cannot save the signature.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.#currentEditor.setUuid(uuid);
|
||||||
this.#finish();
|
this.#finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -245,13 +245,13 @@ See https://github.com/adobe-type-tools/cmap-resources
|
|||||||
<div id="toolbarViewerRight" class="toolbarHorizontalGroup">
|
<div id="toolbarViewerRight" class="toolbarHorizontalGroup">
|
||||||
<div id="editorModeButtons" class="toolbarHorizontalGroup" role="radiogroup">
|
<div id="editorModeButtons" class="toolbarHorizontalGroup" role="radiogroup">
|
||||||
<div id="editorSignature" class="toolbarButtonWithContainer" hidden="true">
|
<div id="editorSignature" class="toolbarButtonWithContainer" hidden="true">
|
||||||
<button id="editorSignatureButton" class="toolbarButton" type="button" disabled="disabled" title="Add or edit signatures" role="radio" aria-expanded="false" aria-haspopup="true" aria-controls="editorSignatureParamsToolbar" tabindex="0">
|
<button id="editorSignatureButton" class="toolbarButton" type="button" disabled="disabled" title="Add signature" role="radio" aria-expanded="false" aria-haspopup="true" aria-controls="editorSignatureParamsToolbar" tabindex="0" data-l10n-id="pdfjs-editor-signature-button">
|
||||||
<span>Add or edit signatures</span>
|
<span data-l10n-id="pdfjs-editor-signature-button-label">Add signature</span>
|
||||||
</button>
|
</button>
|
||||||
<div class="editorParamsToolbar hidden doorHangerRight menu" id="editorSignatureParamsToolbar">
|
<div class="editorParamsToolbar hidden doorHangerRight menu" id="editorSignatureParamsToolbar">
|
||||||
<div class="menuContainer">
|
<div id="addSignatureDoorHanger" class="menuContainer">
|
||||||
<button id="editorSignatureAddSignature" class="toolbarButton labeled" type="button" title="Add signature" tabindex="0">
|
<button id="editorSignatureAddSignature" class="toolbarButton labeled" type="button" title="Add new signature" tabindex="0" data-l10n-id="pdfjs-editor-signature-add-signature-button">
|
||||||
<span class="editorParamsLabel">Add signature</span>
|
<span data-l10n-id="pdfjs-editor-signature-add-signature-button-label" class="editorParamsLabel">Add new signature</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user