Skip to content

Commit

Permalink
Merge pull request #15075 from Snuffleupagus/issue-15049
Browse files Browse the repository at this point in the history
[editor] Support disabling of editing when `pdfjs.enablePermissions` is set (issue 15049)
  • Loading branch information
Snuffleupagus authored Jun 21, 2022
2 parents db6f675 + 35a6a50 commit 05cab5c
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 73 deletions.
21 changes: 11 additions & 10 deletions web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@ const PDFViewerApplication = {

const container = appConfig.mainContainer,
viewer = appConfig.viewerContainer;
const annotationEditorEnabled = AppOptions.get("annotationEditorEnabled");
const pageColors = {
background: AppOptions.get("pageColorsBackground"),
foreground: AppOptions.get("pageColorsForeground"),
Expand All @@ -529,7 +530,7 @@ const PDFViewerApplication = {
l10n: this.l10n,
textLayerMode: AppOptions.get("textLayerMode"),
annotationMode: AppOptions.get("annotationMode"),
annotationEditorEnabled: AppOptions.get("annotationEditorEnabled"),
annotationEditorEnabled,
imageResourcesPath: AppOptions.get("imageResourcesPath"),
enablePrintAutoRotate: AppOptions.get("enablePrintAutoRotate"),
useOnlyCssZoom: AppOptions.get("useOnlyCssZoom"),
Expand Down Expand Up @@ -565,6 +566,15 @@ const PDFViewerApplication = {
this.findBar = new PDFFindBar(appConfig.findBar, eventBus, this.l10n);
}

if (annotationEditorEnabled) {
for (const element of [
document.getElementById("editorModeButtons"),
document.getElementById("editorModeSeparator"),
]) {
element.classList.remove("hidden");
}
}

this.pdfDocumentProperties = new PDFDocumentProperties(
appConfig.documentProperties,
this.overlayManager,
Expand Down Expand Up @@ -1196,11 +1206,6 @@ const PDFViewerApplication = {
this.toolbar.setPagesCount(pdfDocument.numPages, false);
this.secondaryToolbar.setPagesCount(pdfDocument.numPages);

if (pdfDocument.isPureXfa) {
console.warn("Warning: XFA-editing is not implemented.");
this.toolbar.updateEditorModeButtonsState(/* disabled = */ true);
}

let baseDocumentUrl;
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
baseDocumentUrl = null;
Expand Down Expand Up @@ -2242,10 +2247,6 @@ function webViewerInitialized() {
appConfig.toolbar.viewFind.classList.add("hidden");
}

if (PDFViewerApplication.pdfViewer.enableAnnotationEditor) {
appConfig.toolbar.editorModeButtons.classList.remove("hidden");
}

appConfig.mainContainer.addEventListener(
"transitionend",
function (evt) {
Expand Down
4 changes: 3 additions & 1 deletion web/app_options.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ const OptionKind = {
const defaultOptions = {
annotationEditorEnabled: {
/** @type {boolean} */
value: typeof PDFJSDev !== "undefined" && PDFJSDev.test("TESTING"),
value:
typeof PDFJSDev === "undefined" ||
PDFJSDev.test("!PRODUCTION || TESTING"),
kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
},
annotationMode: {
Expand Down
86 changes: 53 additions & 33 deletions web/base_viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,6 @@ class BaseViewer {

#annotationMode = AnnotationMode.ENABLE_FORMS;

#previousAnnotationMode = null;

#enablePermissions = false;

#previousContainerHeight = 0;
Expand Down Expand Up @@ -275,6 +273,9 @@ class BaseViewer {
this.textLayerMode = options.textLayerMode ?? TextLayerMode.ENABLE;
this.#annotationMode =
options.annotationMode ?? AnnotationMode.ENABLE_FORMS;
this.#annotationEditorMode = options.annotationEditorEnabled
? AnnotationEditorType.NONE
: null;
this.imageResourcesPath = options.imageResourcesPath || "";
this.enablePrintAutoRotate = options.enablePrintAutoRotate || false;
this.renderer = options.renderer || RendererType.CANVAS;
Expand All @@ -284,10 +285,6 @@ class BaseViewer {
this.#enablePermissions = options.enablePermissions || false;
this.pageColors = options.pageColors || null;

if (options.annotationEditorEnabled === true) {
this.#annotationEditorUIManager = new AnnotationEditorUIManager();
}

if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
if (
this.pageColors &&
Expand Down Expand Up @@ -354,13 +351,6 @@ class BaseViewer {
return this.#annotationMode === AnnotationMode.ENABLE_FORMS;
}

/**
* @type {boolean}
*/
get enableAnnotationEditor() {
return !!this.#annotationEditorUIManager;
}

/**
* @type {boolean}
*/
Expand Down Expand Up @@ -553,25 +543,35 @@ class BaseViewer {

/**
* Currently only *some* permissions are supported.
* @returns {Object}
*/
#initializePermissions(permissions) {
const params = {
annotationEditorMode: this.#annotationEditorMode,
annotationMode: this.#annotationMode,
textLayerMode: this.textLayerMode,
};
if (!permissions) {
return;
return params;
}

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

if (!permissions.includes(PermissionFlag.MODIFY_CONTENTS)) {
params.annotationEditorMode = null;
}

if (
!permissions.includes(PermissionFlag.MODIFY_ANNOTATIONS) &&
!permissions.includes(PermissionFlag.FILL_INTERACTIVE_FORMS)
!permissions.includes(PermissionFlag.FILL_INTERACTIVE_FORMS) &&
this.#annotationMode === AnnotationMode.ENABLE_FORMS
) {
if (this.#annotationMode === AnnotationMode.ENABLE_FORMS) {
this.#previousAnnotationMode = this.#annotationMode; // Allow resetting.
this.#annotationMode = AnnotationMode.ENABLE;
}
params.annotationMode = AnnotationMode.ENABLE;
}

return params;
}

#onePageRenderedOrForceFetch() {
Expand Down Expand Up @@ -706,7 +706,23 @@ class BaseViewer {
}
this._firstPageCapability.resolve(firstPdfPage);
this._optionalContentConfigPromise = optionalContentConfigPromise;
this.#initializePermissions(permissions);

const { annotationEditorMode, annotationMode, textLayerMode } =
this.#initializePermissions(permissions);

if (annotationEditorMode !== null) {
if (isPureXfa) {
console.warn("Warning: XFA-editing is not implemented.");
} else {
// Ensure that the Editor buttons, in the toolbar, are updated.
this.eventBus.dispatch("annotationeditormodechanged", {
source: this,
mode: annotationEditorMode,
});

this.#annotationEditorUIManager = new AnnotationEditorUIManager();
}
}

const viewerElement =
this._scrollMode === ScrollMode.PAGE ? null : this.viewer;
Expand All @@ -715,14 +731,13 @@ class BaseViewer {
scale: scale * PixelsPerInch.PDF_TO_CSS_UNITS,
});
const textLayerFactory =
this.textLayerMode !== TextLayerMode.DISABLE && !isPureXfa
? this
: null;
textLayerMode !== TextLayerMode.DISABLE && !isPureXfa ? this : null;
const annotationLayerFactory =
this.#annotationMode !== AnnotationMode.DISABLE ? this : null;
annotationMode !== AnnotationMode.DISABLE ? this : null;
const xfaLayerFactory = isPureXfa ? this : null;
const annotationEditorLayerFactory =
this.#annotationEditorUIManager && !isPureXfa ? this : null;
const annotationEditorLayerFactory = this.#annotationEditorUIManager
? this
: null;

for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) {
const pageView = new PDFPageView({
Expand All @@ -734,9 +749,9 @@ class BaseViewer {
optionalContentConfigPromise,
renderingQueue: this.renderingQueue,
textLayerFactory,
textLayerMode: this.textLayerMode,
textLayerMode,
annotationLayerFactory,
annotationMode: this.#annotationMode,
annotationMode,
xfaLayerFactory,
annotationEditorLayerFactory,
textHighlighterFactory: this,
Expand Down Expand Up @@ -868,6 +883,10 @@ class BaseViewer {
}

_resetView() {
if (this.#annotationEditorMode !== null) {
this.#annotationEditorMode = AnnotationEditorType.NONE;
}
this.#annotationEditorUIManager = null;
this._pages = [];
this._currentPageNumber = 1;
this._currentScale = UNKNOWN_SCALE;
Expand Down Expand Up @@ -913,11 +932,6 @@ class BaseViewer {
this.viewer.removeAttribute("lang");
// Reset all PDF document permissions.
this.viewer.classList.remove(ENABLE_PERMISSIONS_CLASS);

if (this.#previousAnnotationMode !== null) {
this.#annotationMode = this.#previousAnnotationMode;
this.#previousAnnotationMode = null;
}
}

#ensurePageViewVisible() {
Expand Down Expand Up @@ -2125,6 +2139,9 @@ class BaseViewer {
}
}

/**
* @type {number | null}
*/
get annotationEditorMode() {
return this.#annotationEditorMode;
}
Expand All @@ -2142,6 +2159,9 @@ class BaseViewer {
if (!isValidAnnotationEditorMode(mode)) {
throw new Error(`Invalid AnnotationEditor mode: ${mode}`);
}
if (!this.pdfDocument) {
return;
}
this.#annotationEditorMode = mode;
this.eventBus.dispatch("annotationeditormodechanged", {
source: this,
Expand Down
26 changes: 15 additions & 11 deletions web/toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@ class Toolbar {
this.pageScale = DEFAULT_SCALE;
this._updateUIState(true);
this.updateLoadingIndicatorState();
this.updateEditorModeButtonsState();

// Reset the Editor buttons too, since they're document specific.
this.eventBus.dispatch("toolbarreset", { source: this });
}

_bindListeners(options) {
Expand Down Expand Up @@ -212,7 +214,7 @@ class Toolbar {
editorFreeTextButton,
editorInkButton,
}) {
this.eventBus._on("annotationeditormodechanged", evt => {
const editorModeChanged = (evt, disableButtons = false) => {
const editorButtons = [
[AnnotationEditorType.NONE, editorNoneButton],
[AnnotationEditorType.FREETEXT, editorFreeTextButton],
Expand All @@ -223,6 +225,17 @@ class Toolbar {
const checked = mode === evt.mode;
button.classList.toggle("toggled", checked);
button.setAttribute("aria-checked", checked);
button.disabled = disableButtons;
}
};
this.eventBus._on("annotationeditormodechanged", editorModeChanged);

this.eventBus._on("toolbarreset", evt => {
if (evt.source === this) {
editorModeChanged(
{ mode: AnnotationEditorType.NONE },
/* disableButtons = */ true
);
}
});
}
Expand Down Expand Up @@ -286,15 +299,6 @@ class Toolbar {
pageNumber.classList.toggle(PAGE_NUMBER_LOADING_INDICATOR, loading);
}

updateEditorModeButtonsState(disabled = false) {
const { editorNoneButton, editorFreeTextButton, editorInkButton } =
this.items;

editorNoneButton.disabled = disabled;
editorFreeTextButton.disabled = disabled;
editorInkButton.disabled = disabled;
}

/**
* Increase the width of the zoom dropdown DOM element if, and only if, it's
* too narrow to fit the *longest* of the localized strings.
Expand Down
37 changes: 20 additions & 17 deletions web/viewer.html
Original file line number Diff line number Diff line change
Expand Up @@ -263,41 +263,44 @@
<span id="numPages" class="toolbarLabel"></span>
</div>
<div id="toolbarViewerRight">
<div id="editorModeButtons" class="splitToolbarButton toggled hidden" role="radiogroup">
<button id="editorNone" class="toolbarButton toggled" title="Disable Annotation Editing" role="radio" aria-checked="true" tabindex="31" data-l10n-id="editor_none">
<span data-l10n-id="editor_none_label">Disable Editing</span>
</button>
<button id="editorFreeText" class="toolbarButton" title="Add FreeText Annotation" role="radio" aria-checked="false" tabindex="32" data-l10n-id="editor_free_text">
<span data-l10n-id="editor_free_text_label">FreeText Annotation</span>
</button>
<button id="editorInk" class="toolbarButton" title="Add Ink Annotation" role="radio" aria-checked="false" tabindex="33" data-l10n-id="editor_ink">
<span data-l10n-id="editor_ink_label">Ink Annotation</span>
</button>
</div>

<button id="presentationMode" class="toolbarButton hiddenLargeView" title="Switch to Presentation Mode" tabindex="43" data-l10n-id="presentation_mode">
<button id="presentationMode" class="toolbarButton hiddenLargeView" title="Switch to Presentation Mode" tabindex="31" data-l10n-id="presentation_mode">
<span data-l10n-id="presentation_mode_label">Presentation Mode</span>
</button>

<!--#if GENERIC-->
<button id="openFile" class="toolbarButton hiddenLargeView" title="Open File" tabindex="44" data-l10n-id="open_file">
<button id="openFile" class="toolbarButton hiddenLargeView" title="Open File" tabindex="32" data-l10n-id="open_file">
<span data-l10n-id="open_file_label">Open</span>
</button>
<!--#endif-->

<button id="print" class="toolbarButton hiddenMediumView" title="Print" tabindex="45" data-l10n-id="print">
<button id="print" class="toolbarButton hiddenMediumView" title="Print" tabindex="33" data-l10n-id="print">
<span data-l10n-id="print_label">Print</span>
</button>

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

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

<div id="editorModeButtons" class="splitToolbarButton toggled hidden" role="radiogroup">
<button id="editorNone" class="toolbarButton toggled" disabled="disabled" title="Disable Annotation Editing" role="radio" aria-checked="true" tabindex="36" data-l10n-id="editor_none">
<span data-l10n-id="editor_none_label">Disable Editing</span>
</button>
<button id="editorFreeText" class="toolbarButton" disabled="disabled" title="Add FreeText Annotation" role="radio" aria-checked="false" tabindex="37" data-l10n-id="editor_free_text">
<span data-l10n-id="editor_free_text_label">FreeText Annotation</span>
</button>
<button id="editorInk" class="toolbarButton" disabled="disabled" title="Add Ink Annotation" role="radio" aria-checked="false" tabindex="38" data-l10n-id="editor_ink">
<span data-l10n-id="editor_ink_label">Ink Annotation</span>
</button>
</div>

<!-- Should be visible when the "editorModeButtons" are visible. -->
<div id="editorModeSeparator" class="verticalToolbarSeparator hidden"></div>

<button id="secondaryToolbarToggle" class="toolbarButton" title="Tools" tabindex="48" data-l10n-id="tools" aria-expanded="false" aria-controls="secondaryToolbar">
<span data-l10n-id="tools_label">Tools</span>
</button>
Expand Down
1 change: 0 additions & 1 deletion web/viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ function getViewerConfiguration() {
? document.getElementById("openFile")
: null,
print: document.getElementById("print"),
editorModeButtons: document.getElementById("editorModeButtons"),
editorNoneButton: document.getElementById("editorNone"),
editorFreeTextButton: document.getElementById("editorFreeText"),
editorInkButton: document.getElementById("editorInk"),
Expand Down

0 comments on commit 05cab5c

Please sign in to comment.