Skip to content

Commit 05cab5c

Browse files
Merge pull request #15075 from Snuffleupagus/issue-15049
[editor] Support disabling of editing when `pdfjs.enablePermissions` is set (issue 15049)
2 parents db6f675 + 35a6a50 commit 05cab5c

File tree

6 files changed

+102
-73
lines changed

6 files changed

+102
-73
lines changed

web/app.js

+11-10
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,7 @@ const PDFViewerApplication = {
506506

507507
const container = appConfig.mainContainer,
508508
viewer = appConfig.viewerContainer;
509+
const annotationEditorEnabled = AppOptions.get("annotationEditorEnabled");
509510
const pageColors = {
510511
background: AppOptions.get("pageColorsBackground"),
511512
foreground: AppOptions.get("pageColorsForeground"),
@@ -529,7 +530,7 @@ const PDFViewerApplication = {
529530
l10n: this.l10n,
530531
textLayerMode: AppOptions.get("textLayerMode"),
531532
annotationMode: AppOptions.get("annotationMode"),
532-
annotationEditorEnabled: AppOptions.get("annotationEditorEnabled"),
533+
annotationEditorEnabled,
533534
imageResourcesPath: AppOptions.get("imageResourcesPath"),
534535
enablePrintAutoRotate: AppOptions.get("enablePrintAutoRotate"),
535536
useOnlyCssZoom: AppOptions.get("useOnlyCssZoom"),
@@ -565,6 +566,15 @@ const PDFViewerApplication = {
565566
this.findBar = new PDFFindBar(appConfig.findBar, eventBus, this.l10n);
566567
}
567568

569+
if (annotationEditorEnabled) {
570+
for (const element of [
571+
document.getElementById("editorModeButtons"),
572+
document.getElementById("editorModeSeparator"),
573+
]) {
574+
element.classList.remove("hidden");
575+
}
576+
}
577+
568578
this.pdfDocumentProperties = new PDFDocumentProperties(
569579
appConfig.documentProperties,
570580
this.overlayManager,
@@ -1196,11 +1206,6 @@ const PDFViewerApplication = {
11961206
this.toolbar.setPagesCount(pdfDocument.numPages, false);
11971207
this.secondaryToolbar.setPagesCount(pdfDocument.numPages);
11981208

1199-
if (pdfDocument.isPureXfa) {
1200-
console.warn("Warning: XFA-editing is not implemented.");
1201-
this.toolbar.updateEditorModeButtonsState(/* disabled = */ true);
1202-
}
1203-
12041209
let baseDocumentUrl;
12051210
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
12061211
baseDocumentUrl = null;
@@ -2242,10 +2247,6 @@ function webViewerInitialized() {
22422247
appConfig.toolbar.viewFind.classList.add("hidden");
22432248
}
22442249

2245-
if (PDFViewerApplication.pdfViewer.enableAnnotationEditor) {
2246-
appConfig.toolbar.editorModeButtons.classList.remove("hidden");
2247-
}
2248-
22492250
appConfig.mainContainer.addEventListener(
22502251
"transitionend",
22512252
function (evt) {

web/app_options.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ const OptionKind = {
6161
const defaultOptions = {
6262
annotationEditorEnabled: {
6363
/** @type {boolean} */
64-
value: typeof PDFJSDev !== "undefined" && PDFJSDev.test("TESTING"),
64+
value:
65+
typeof PDFJSDev === "undefined" ||
66+
PDFJSDev.test("!PRODUCTION || TESTING"),
6567
kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
6668
},
6769
annotationMode: {

web/base_viewer.js

+53-33
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,6 @@ class BaseViewer {
219219

220220
#annotationMode = AnnotationMode.ENABLE_FORMS;
221221

222-
#previousAnnotationMode = null;
223-
224222
#enablePermissions = false;
225223

226224
#previousContainerHeight = 0;
@@ -275,6 +273,9 @@ class BaseViewer {
275273
this.textLayerMode = options.textLayerMode ?? TextLayerMode.ENABLE;
276274
this.#annotationMode =
277275
options.annotationMode ?? AnnotationMode.ENABLE_FORMS;
276+
this.#annotationEditorMode = options.annotationEditorEnabled
277+
? AnnotationEditorType.NONE
278+
: null;
278279
this.imageResourcesPath = options.imageResourcesPath || "";
279280
this.enablePrintAutoRotate = options.enablePrintAutoRotate || false;
280281
this.renderer = options.renderer || RendererType.CANVAS;
@@ -284,10 +285,6 @@ class BaseViewer {
284285
this.#enablePermissions = options.enablePermissions || false;
285286
this.pageColors = options.pageColors || null;
286287

287-
if (options.annotationEditorEnabled === true) {
288-
this.#annotationEditorUIManager = new AnnotationEditorUIManager();
289-
}
290-
291288
if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
292289
if (
293290
this.pageColors &&
@@ -354,13 +351,6 @@ class BaseViewer {
354351
return this.#annotationMode === AnnotationMode.ENABLE_FORMS;
355352
}
356353

357-
/**
358-
* @type {boolean}
359-
*/
360-
get enableAnnotationEditor() {
361-
return !!this.#annotationEditorUIManager;
362-
}
363-
364354
/**
365355
* @type {boolean}
366356
*/
@@ -553,25 +543,35 @@ class BaseViewer {
553543

554544
/**
555545
* Currently only *some* permissions are supported.
546+
* @returns {Object}
556547
*/
557548
#initializePermissions(permissions) {
549+
const params = {
550+
annotationEditorMode: this.#annotationEditorMode,
551+
annotationMode: this.#annotationMode,
552+
textLayerMode: this.textLayerMode,
553+
};
558554
if (!permissions) {
559-
return;
555+
return params;
560556
}
561557

562558
if (!permissions.includes(PermissionFlag.COPY)) {
563559
this.viewer.classList.add(ENABLE_PERMISSIONS_CLASS);
564560
}
565561

562+
if (!permissions.includes(PermissionFlag.MODIFY_CONTENTS)) {
563+
params.annotationEditorMode = null;
564+
}
565+
566566
if (
567567
!permissions.includes(PermissionFlag.MODIFY_ANNOTATIONS) &&
568-
!permissions.includes(PermissionFlag.FILL_INTERACTIVE_FORMS)
568+
!permissions.includes(PermissionFlag.FILL_INTERACTIVE_FORMS) &&
569+
this.#annotationMode === AnnotationMode.ENABLE_FORMS
569570
) {
570-
if (this.#annotationMode === AnnotationMode.ENABLE_FORMS) {
571-
this.#previousAnnotationMode = this.#annotationMode; // Allow resetting.
572-
this.#annotationMode = AnnotationMode.ENABLE;
573-
}
571+
params.annotationMode = AnnotationMode.ENABLE;
574572
}
573+
574+
return params;
575575
}
576576

577577
#onePageRenderedOrForceFetch() {
@@ -706,7 +706,23 @@ class BaseViewer {
706706
}
707707
this._firstPageCapability.resolve(firstPdfPage);
708708
this._optionalContentConfigPromise = optionalContentConfigPromise;
709-
this.#initializePermissions(permissions);
709+
710+
const { annotationEditorMode, annotationMode, textLayerMode } =
711+
this.#initializePermissions(permissions);
712+
713+
if (annotationEditorMode !== null) {
714+
if (isPureXfa) {
715+
console.warn("Warning: XFA-editing is not implemented.");
716+
} else {
717+
// Ensure that the Editor buttons, in the toolbar, are updated.
718+
this.eventBus.dispatch("annotationeditormodechanged", {
719+
source: this,
720+
mode: annotationEditorMode,
721+
});
722+
723+
this.#annotationEditorUIManager = new AnnotationEditorUIManager();
724+
}
725+
}
710726

711727
const viewerElement =
712728
this._scrollMode === ScrollMode.PAGE ? null : this.viewer;
@@ -715,14 +731,13 @@ class BaseViewer {
715731
scale: scale * PixelsPerInch.PDF_TO_CSS_UNITS,
716732
});
717733
const textLayerFactory =
718-
this.textLayerMode !== TextLayerMode.DISABLE && !isPureXfa
719-
? this
720-
: null;
734+
textLayerMode !== TextLayerMode.DISABLE && !isPureXfa ? this : null;
721735
const annotationLayerFactory =
722-
this.#annotationMode !== AnnotationMode.DISABLE ? this : null;
736+
annotationMode !== AnnotationMode.DISABLE ? this : null;
723737
const xfaLayerFactory = isPureXfa ? this : null;
724-
const annotationEditorLayerFactory =
725-
this.#annotationEditorUIManager && !isPureXfa ? this : null;
738+
const annotationEditorLayerFactory = this.#annotationEditorUIManager
739+
? this
740+
: null;
726741

727742
for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) {
728743
const pageView = new PDFPageView({
@@ -734,9 +749,9 @@ class BaseViewer {
734749
optionalContentConfigPromise,
735750
renderingQueue: this.renderingQueue,
736751
textLayerFactory,
737-
textLayerMode: this.textLayerMode,
752+
textLayerMode,
738753
annotationLayerFactory,
739-
annotationMode: this.#annotationMode,
754+
annotationMode,
740755
xfaLayerFactory,
741756
annotationEditorLayerFactory,
742757
textHighlighterFactory: this,
@@ -868,6 +883,10 @@ class BaseViewer {
868883
}
869884

870885
_resetView() {
886+
if (this.#annotationEditorMode !== null) {
887+
this.#annotationEditorMode = AnnotationEditorType.NONE;
888+
}
889+
this.#annotationEditorUIManager = null;
871890
this._pages = [];
872891
this._currentPageNumber = 1;
873892
this._currentScale = UNKNOWN_SCALE;
@@ -913,11 +932,6 @@ class BaseViewer {
913932
this.viewer.removeAttribute("lang");
914933
// Reset all PDF document permissions.
915934
this.viewer.classList.remove(ENABLE_PERMISSIONS_CLASS);
916-
917-
if (this.#previousAnnotationMode !== null) {
918-
this.#annotationMode = this.#previousAnnotationMode;
919-
this.#previousAnnotationMode = null;
920-
}
921935
}
922936

923937
#ensurePageViewVisible() {
@@ -2125,6 +2139,9 @@ class BaseViewer {
21252139
}
21262140
}
21272141

2142+
/**
2143+
* @type {number | null}
2144+
*/
21282145
get annotationEditorMode() {
21292146
return this.#annotationEditorMode;
21302147
}
@@ -2142,6 +2159,9 @@ class BaseViewer {
21422159
if (!isValidAnnotationEditorMode(mode)) {
21432160
throw new Error(`Invalid AnnotationEditor mode: ${mode}`);
21442161
}
2162+
if (!this.pdfDocument) {
2163+
return;
2164+
}
21452165
this.#annotationEditorMode = mode;
21462166
this.eventBus.dispatch("annotationeditormodechanged", {
21472167
source: this,

web/toolbar.js

+15-11
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,9 @@ class Toolbar {
141141
this.pageScale = DEFAULT_SCALE;
142142
this._updateUIState(true);
143143
this.updateLoadingIndicatorState();
144-
this.updateEditorModeButtonsState();
144+
145+
// Reset the Editor buttons too, since they're document specific.
146+
this.eventBus.dispatch("toolbarreset", { source: this });
145147
}
146148

147149
_bindListeners(options) {
@@ -212,7 +214,7 @@ class Toolbar {
212214
editorFreeTextButton,
213215
editorInkButton,
214216
}) {
215-
this.eventBus._on("annotationeditormodechanged", evt => {
217+
const editorModeChanged = (evt, disableButtons = false) => {
216218
const editorButtons = [
217219
[AnnotationEditorType.NONE, editorNoneButton],
218220
[AnnotationEditorType.FREETEXT, editorFreeTextButton],
@@ -223,6 +225,17 @@ class Toolbar {
223225
const checked = mode === evt.mode;
224226
button.classList.toggle("toggled", checked);
225227
button.setAttribute("aria-checked", checked);
228+
button.disabled = disableButtons;
229+
}
230+
};
231+
this.eventBus._on("annotationeditormodechanged", editorModeChanged);
232+
233+
this.eventBus._on("toolbarreset", evt => {
234+
if (evt.source === this) {
235+
editorModeChanged(
236+
{ mode: AnnotationEditorType.NONE },
237+
/* disableButtons = */ true
238+
);
226239
}
227240
});
228241
}
@@ -286,15 +299,6 @@ class Toolbar {
286299
pageNumber.classList.toggle(PAGE_NUMBER_LOADING_INDICATOR, loading);
287300
}
288301

289-
updateEditorModeButtonsState(disabled = false) {
290-
const { editorNoneButton, editorFreeTextButton, editorInkButton } =
291-
this.items;
292-
293-
editorNoneButton.disabled = disabled;
294-
editorFreeTextButton.disabled = disabled;
295-
editorInkButton.disabled = disabled;
296-
}
297-
298302
/**
299303
* Increase the width of the zoom dropdown DOM element if, and only if, it's
300304
* too narrow to fit the *longest* of the localized strings.

web/viewer.html

+20-17
Original file line numberDiff line numberDiff line change
@@ -263,41 +263,44 @@
263263
<span id="numPages" class="toolbarLabel"></span>
264264
</div>
265265
<div id="toolbarViewerRight">
266-
<div id="editorModeButtons" class="splitToolbarButton toggled hidden" role="radiogroup">
267-
<button id="editorNone" class="toolbarButton toggled" title="Disable Annotation Editing" role="radio" aria-checked="true" tabindex="31" data-l10n-id="editor_none">
268-
<span data-l10n-id="editor_none_label">Disable Editing</span>
269-
</button>
270-
<button id="editorFreeText" class="toolbarButton" title="Add FreeText Annotation" role="radio" aria-checked="false" tabindex="32" data-l10n-id="editor_free_text">
271-
<span data-l10n-id="editor_free_text_label">FreeText Annotation</span>
272-
</button>
273-
<button id="editorInk" class="toolbarButton" title="Add Ink Annotation" role="radio" aria-checked="false" tabindex="33" data-l10n-id="editor_ink">
274-
<span data-l10n-id="editor_ink_label">Ink Annotation</span>
275-
</button>
276-
</div>
277-
278-
<button id="presentationMode" class="toolbarButton hiddenLargeView" title="Switch to Presentation Mode" tabindex="43" data-l10n-id="presentation_mode">
266+
<button id="presentationMode" class="toolbarButton hiddenLargeView" title="Switch to Presentation Mode" tabindex="31" data-l10n-id="presentation_mode">
279267
<span data-l10n-id="presentation_mode_label">Presentation Mode</span>
280268
</button>
281269

282270
<!--#if GENERIC-->
283-
<button id="openFile" class="toolbarButton hiddenLargeView" title="Open File" tabindex="44" data-l10n-id="open_file">
271+
<button id="openFile" class="toolbarButton hiddenLargeView" title="Open File" tabindex="32" data-l10n-id="open_file">
284272
<span data-l10n-id="open_file_label">Open</span>
285273
</button>
286274
<!--#endif-->
287275

288-
<button id="print" class="toolbarButton hiddenMediumView" title="Print" tabindex="45" data-l10n-id="print">
276+
<button id="print" class="toolbarButton hiddenMediumView" title="Print" tabindex="33" data-l10n-id="print">
289277
<span data-l10n-id="print_label">Print</span>
290278
</button>
291279

292-
<button id="download" class="toolbarButton hiddenMediumView" title="Download" tabindex="46" data-l10n-id="download">
280+
<button id="download" class="toolbarButton hiddenMediumView" title="Download" tabindex="34" data-l10n-id="download">
293281
<span data-l10n-id="download_label">Download</span>
294282
</button>
295-
<a href="#" id="viewBookmark" class="toolbarButton hiddenSmallView" title="Current view (copy or open in new window)" tabindex="47" data-l10n-id="bookmark">
283+
<a href="#" id="viewBookmark" class="toolbarButton hiddenSmallView" title="Current view (copy or open in new window)" tabindex="35" data-l10n-id="bookmark">
296284
<span data-l10n-id="bookmark_label">Current View</span>
297285
</a>
298286

299287
<div class="verticalToolbarSeparator hiddenSmallView"></div>
300288

289+
<div id="editorModeButtons" class="splitToolbarButton toggled hidden" role="radiogroup">
290+
<button id="editorNone" class="toolbarButton toggled" disabled="disabled" title="Disable Annotation Editing" role="radio" aria-checked="true" tabindex="36" data-l10n-id="editor_none">
291+
<span data-l10n-id="editor_none_label">Disable Editing</span>
292+
</button>
293+
<button id="editorFreeText" class="toolbarButton" disabled="disabled" title="Add FreeText Annotation" role="radio" aria-checked="false" tabindex="37" data-l10n-id="editor_free_text">
294+
<span data-l10n-id="editor_free_text_label">FreeText Annotation</span>
295+
</button>
296+
<button id="editorInk" class="toolbarButton" disabled="disabled" title="Add Ink Annotation" role="radio" aria-checked="false" tabindex="38" data-l10n-id="editor_ink">
297+
<span data-l10n-id="editor_ink_label">Ink Annotation</span>
298+
</button>
299+
</div>
300+
301+
<!-- Should be visible when the "editorModeButtons" are visible. -->
302+
<div id="editorModeSeparator" class="verticalToolbarSeparator hidden"></div>
303+
301304
<button id="secondaryToolbarToggle" class="toolbarButton" title="Tools" tabindex="48" data-l10n-id="tools" aria-expanded="false" aria-controls="secondaryToolbar">
302305
<span data-l10n-id="tools_label">Tools</span>
303306
</button>

web/viewer.js

-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ function getViewerConfiguration() {
9393
? document.getElementById("openFile")
9494
: null,
9595
print: document.getElementById("print"),
96-
editorModeButtons: document.getElementById("editorModeButtons"),
9796
editorNoneButton: document.getElementById("editorNone"),
9897
editorFreeTextButton: document.getElementById("editorFreeText"),
9998
editorInkButton: document.getElementById("editorInk"),

0 commit comments

Comments
 (0)