Skip to content

Commit

Permalink
Merge pull request #1107 from nextcloud/move-initialization-from-help…
Browse files Browse the repository at this point in the history
…er-script-to-vue-component

Move initialization from helper script to Vue component
  • Loading branch information
danxuliu authored Feb 5, 2025
2 parents 3207770 + 8c322b5 commit b8bc356
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 116 deletions.
4 changes: 2 additions & 2 deletions js/files_pdfviewer-main.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/files_pdfviewer-main.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions js/files_pdfviewer-workersrc.js

Large diffs are not rendered by default.

15 changes: 0 additions & 15 deletions js/files_pdfviewer-workersrc.js.license
Original file line number Diff line number Diff line change
@@ -1,23 +1,8 @@
SPDX-License-Identifier: MIT
SPDX-License-Identifier: ISC
SPDX-License-Identifier: GPL-3.0-or-later
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-FileCopyrightText: Roman Shtylman <shtylman@gmail.com>
SPDX-FileCopyrightText: John Molakvoæ <skjnldsv@protonmail.com>
SPDX-FileCopyrightText: GitHub Inc.
SPDX-FileCopyrightText: Christoph Wurst


This file is generated from multiple sources. Included packages:
- @nextcloud/browser-storage
- version: 0.4.0
- license: GPL-3.0-or-later
- semver
- version: 7.6.2
- license: ISC
- process
- version: 0.11.10
- license: MIT
- files_pdfviewer
- version: 5.0.0-dev.0
- license: AGPL-3.0-or-later
2 changes: 1 addition & 1 deletion js/files_pdfviewer-workersrc.js.map

Large diffs are not rendered by default.

121 changes: 91 additions & 30 deletions src/views/PDFView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ export default {

computed: {
iframeSrc() {
return generateUrl('/apps/files_pdfviewer/?file={file}&hideDownload={hideDownload}', {
hideDownload: hideDownload() ? 1 : 0,
return generateUrl('/apps/files_pdfviewer/?file={file}', {
file: this.source ?? this.davPath,
})
},
Expand Down Expand Up @@ -111,9 +110,28 @@ export default {
return this.getIframeDocument().getElementById('download')
},

handleWebviewerloaded() {
getViewerTemplateParameter(parameterName) {
// templates/viewer.php provides the PDF viewer parameters in the
// data attributes of the head element.
return this.getIframeDocument().getElementsByTagName('head')[0].getAttribute('data-' + parameterName)
},

initializePDFViewerApplicationOptions() {
const PDFViewerApplicationOptions = this.$refs.iframe.contentWindow.PDFViewerApplicationOptions

// Preferences override options, so they must be disabled for
// "externalLinkTarget" and "annotationMode" to take effect.
PDFViewerApplicationOptions.set('disablePreferences', true)
// TODO https://github.com/mozilla/pdf.js/pull/14424#issuecomment-1092947792
PDFViewerApplicationOptions.set('externalLinkTarget', 2)
PDFViewerApplicationOptions.set('isEvalSupported', false)
PDFViewerApplicationOptions.set('workerSrc', this.getViewerTemplateParameter('workersrc'))
PDFViewerApplicationOptions.set('cMapUrl', this.getViewerTemplateParameter('cmapurl'))
PDFViewerApplicationOptions.set('sandboxBundleSrc', this.getViewerTemplateParameter('sandbox'))
PDFViewerApplicationOptions.set('enablePermissions', true)
PDFViewerApplicationOptions.set('imageResourcesPath', this.getViewerTemplateParameter('imageresourcespath'))
PDFViewerApplicationOptions.set('enableScripting', this.getViewerTemplateParameter('enableScripting') === true)

const language = getLanguage()
const supportedLanguages = SUPPORTED_LANGUAGES
// If the user language is supported we use that language,
Expand All @@ -132,10 +150,6 @@ export default {
}

if (!this.isEditable) {
// Preferences override options, so they must be disabled for
// "annotationMode" to take effect.
PDFViewerApplicationOptions.set('disablePreferences', true)

// AnnotationMode.ENABLE value is 1 in PDF.js, which shows
// forms, but does not allow to interact with them
PDFViewerApplicationOptions.set('annotationMode', 1)
Expand All @@ -144,6 +158,75 @@ export default {
// prevents editing annotations
PDFViewerApplicationOptions.set('annotationEditorMode', -1)
}
},

initializePDFViewerApplication() {
this.PDFViewerApplication = this.$refs.iframe.contentWindow.PDFViewerApplication

this.PDFViewerApplication.save = this.handleSave

// Not all fields of PDFViewerApplication are reactive.
// Specifically, it can not be known if annotations were created by
// watching "pdfDocument.annotationStorage.size" (maybe because
// "size" is a getter based on a private field, so it does not work
// even if the rest of the chain is skipped and "size" is directly
// watched). However, "annotationStorage" has callbacks used by
// PDFViewerApplication to know when an annotation was set, so that
// callback can be wrapped to also enable the save button.
this.PDFViewerApplication.eventBus.on('documentinit', () => {
const annotationStorage = this.PDFViewerApplication.pdfDocument.annotationStorage

const onSetModifiedOriginal = annotationStorage.onSetModified
annotationStorage.onSetModified = () => {
onSetModifiedOriginal.apply(null, arguments)

this.getDownloadElement().removeAttribute('disabled')
}
})

if (hideDownload()) {
const pdfViewer = this.getIframeDocument().querySelector('.pdfViewer')

if (pdfViewer) {
pdfViewer.classList.add('disabledTextSelection')
}

// Disable download function when downloads are hidden, as even
// if the buttons in the UI are hidden the download could still
// be triggered with Ctrl|Meta+S.
this.PDFViewerApplication.download = () => {
}

// Disable printing service when downloads are hidden, as even
// if the buttons in the UI are hidden the printing could still
// be triggered with Ctrl|Meta+P.
// Abuse the "supportsPrinting" parameter, which signals that
// the browser does not fully support printing, to make
// PDFViewer disable the printing service.
// "supportsPrinting" is a getter function, so it needs to be
// deleted before replacing it with a simple value.
delete this.PDFViewerApplication.supportsPrinting
this.PDFViewerApplication.supportsPrinting = false

// When printing is not supported a warning is shown by the
// default "beforePrint" function when trying to print. That
// function needs to be replaced with an empty one to prevent
// that warning to be shown.
this.PDFViewerApplication.beforePrint = () => {
}

logger.info('Download, print and user interaction disabled')
} else {
logger.info('Download and print available')
}

const PDFViewerApplicationOptions = this.$refs.iframe.contentWindow.PDFViewerApplicationOptions

logger.debug('Initialized files_pdfviewer', PDFViewerApplicationOptions.getAll())
},

handleWebviewerloaded() {
this.initializePDFViewerApplicationOptions()

// PDFViewerApplication can not be set when the "webviewerloaded"
// event is dispatched, as at this point the application was not
Expand All @@ -155,29 +238,7 @@ export default {
// PDFViewerApplication.pdfViewer to be set already and thus uses it
// unconditionally).
this.$refs.iframe.contentWindow.PDFViewerApplication.initializedPromise.then(() => {
this.PDFViewerApplication = this.$refs.iframe.contentWindow.PDFViewerApplication

this.PDFViewerApplication.save = this.handleSave

// Not all fields of PDFViewerApplication are reactive.
// Specifically, it can not be known if annotations were created
// by watching "pdfDocument.annotationStorage.size" (maybe
// because "size" is a getter based on a private field, so it
// does not work even if the rest of the chain is skipped and
// "size" is directly watched). However, "annotationStorage" has
// callbacks used by PDFViewerApplication to know when an
// annotation was set, so that callback can be wrapped to also
// enable the save button.
this.PDFViewerApplication.eventBus.on('documentinit', () => {
const annotationStorage = this.PDFViewerApplication.pdfDocument.annotationStorage

const onSetModifiedOriginal = annotationStorage.onSetModified
annotationStorage.onSetModified = () => {
onSetModifiedOriginal.apply(null, arguments)

this.getDownloadElement().removeAttribute('disabled')
}
})
this.initializePDFViewerApplication()
})
},

Expand Down
65 changes: 0 additions & 65 deletions src/workersrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,72 +4,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import logger from './services/logger.js'
import redirectIfNotIframe from './utils/redirectIfNotIframe.js'

// Checks if the page is displayed in an iframe. If not redirect to /.
redirectIfNotIframe()

// Retrieve the hideDownload from the url, this is
// the most easy way to pass the prop to this iframe
const queryString = window.location.search
const urlParams = new URLSearchParams(queryString)
const hideDownload = urlParams.get('hideDownload')

function initializeCustomPDFViewerApplication() {
const head = document.getElementsByTagName('head')[0]

// Preferences override options, so they must be disabled for
// "externalLinkTarget" to take effect.
PDFViewerApplicationOptions.set('disablePreferences', true)
// TODO https://github.com/mozilla/pdf.js/pull/14424#issuecomment-1092947792
PDFViewerApplicationOptions.set('externalLinkTarget', 2)
PDFViewerApplicationOptions.set('isEvalSupported', false)
PDFViewerApplicationOptions.set('workerSrc', head.getAttribute('data-workersrc'))
PDFViewerApplicationOptions.set('cMapUrl', head.getAttribute('data-cmapurl'))
PDFViewerApplicationOptions.set('sandboxBundleSrc', head.getAttribute('data-sandbox'))
PDFViewerApplicationOptions.set('enablePermissions', true)
PDFViewerApplicationOptions.set('imageResourcesPath', head.getAttribute('data-imageresourcespath'))
PDFViewerApplicationOptions.set('enableScripting', head.getAttribute('data-enableScripting') === true)

if (hideDownload === '1') {
const pdfViewer = window.document.querySelector('.pdfViewer')

if (pdfViewer) {
pdfViewer.classList.add('disabledTextSelection')
}

if (PDFViewerApplication) {
// Disable download function when downloads are hidden, as even if the
// buttons in the UI are hidden the download could still be triggered
// with Ctrl|Meta+S.
PDFViewerApplication.download = function() {
}

// Disable printing service when downloads are hidden, as even if the
// buttons in the UI are hidden the printing could still be triggered
// with Ctrl|Meta+P.
// Abuse the "supportsPrinting" parameter, which signals that the
// browser does not fully support printing, to make PDFViewer disable
// the printing service.
// "supportsPrinting" is a getter function, so it needs to be deleted
// before replacing it with a simple value.
delete PDFViewerApplication.supportsPrinting
PDFViewerApplication.supportsPrinting = false

// When printing is not supported a warning is shown by the default
// "beforePrint" function when trying to print. That function needs to
// be replaced with an empty one to prevent that warning to be shown.
PDFViewerApplication.beforePrint = function() {
}
}

logger.info('Download, print and user interaction disabled')
} else {
logger.info('Download and print available')
}

logger.debug('Initialized files_pdfviewer', PDFViewerApplicationOptions.getAll())
}

document.addEventListener('DOMContentLoaded', initializeCustomPDFViewerApplication, true)

0 comments on commit b8bc356

Please sign in to comment.