@@ -35,8 +35,7 @@ export default {
3535
3636 computed: {
3737 iframeSrc () {
38- return generateUrl (' /apps/files_pdfviewer/?file={file}&hideDownload={hideDownload}' , {
39- hideDownload: hideDownload () ? 1 : 0 ,
38+ return generateUrl (' /apps/files_pdfviewer/?file={file}' , {
4039 file: this .source ?? this .davPath ,
4140 })
4241 },
@@ -111,9 +110,28 @@ export default {
111110 return this .getIframeDocument ().getElementById (' download' )
112111 },
113112
114- handleWebviewerloaded () {
113+ getViewerTemplateParameter (parameterName ) {
114+ // templates/viewer.php provides the PDF viewer parameters in the
115+ // data attributes of the head element.
116+ return this .getIframeDocument ().getElementsByTagName (' head' )[0 ].getAttribute (' data-' + parameterName)
117+ },
118+
119+ initializePDFViewerApplicationOptions () {
115120 const PDFViewerApplicationOptions = this .$refs .iframe .contentWindow .PDFViewerApplicationOptions
116121
122+ // Preferences override options, so they must be disabled for
123+ // "externalLinkTarget" and "annotationMode" to take effect.
124+ PDFViewerApplicationOptions .set (' disablePreferences' , true )
125+ // TODO https://github.com/mozilla/pdf.js/pull/14424#issuecomment-1092947792
126+ PDFViewerApplicationOptions .set (' externalLinkTarget' , 2 )
127+ PDFViewerApplicationOptions .set (' isEvalSupported' , false )
128+ PDFViewerApplicationOptions .set (' workerSrc' , this .getViewerTemplateParameter (' workersrc' ))
129+ PDFViewerApplicationOptions .set (' cMapUrl' , this .getViewerTemplateParameter (' cmapurl' ))
130+ PDFViewerApplicationOptions .set (' sandboxBundleSrc' , this .getViewerTemplateParameter (' sandbox' ))
131+ PDFViewerApplicationOptions .set (' enablePermissions' , true )
132+ PDFViewerApplicationOptions .set (' imageResourcesPath' , this .getViewerTemplateParameter (' imageresourcespath' ))
133+ PDFViewerApplicationOptions .set (' enableScripting' , this .getViewerTemplateParameter (' enableScripting' ) === true )
134+
117135 const language = getLanguage ()
118136 const supportedLanguages = SUPPORTED_LANGUAGES
119137 // If the user language is supported we use that language,
@@ -132,10 +150,6 @@ export default {
132150 }
133151
134152 if (! this .isEditable ) {
135- // Preferences override options, so they must be disabled for
136- // "annotationMode" to take effect.
137- PDFViewerApplicationOptions .set (' disablePreferences' , true )
138-
139153 // AnnotationMode.ENABLE value is 1 in PDF.js, which shows
140154 // forms, but does not allow to interact with them
141155 PDFViewerApplicationOptions .set (' annotationMode' , 1 )
@@ -144,6 +158,75 @@ export default {
144158 // prevents editing annotations
145159 PDFViewerApplicationOptions .set (' annotationEditorMode' , - 1 )
146160 }
161+ },
162+
163+ initializePDFViewerApplication () {
164+ this .PDFViewerApplication = this .$refs .iframe .contentWindow .PDFViewerApplication
165+
166+ this .PDFViewerApplication .save = this .handleSave
167+
168+ // Not all fields of PDFViewerApplication are reactive.
169+ // Specifically, it can not be known if annotations were created by
170+ // watching "pdfDocument.annotationStorage.size" (maybe because
171+ // "size" is a getter based on a private field, so it does not work
172+ // even if the rest of the chain is skipped and "size" is directly
173+ // watched). However, "annotationStorage" has callbacks used by
174+ // PDFViewerApplication to know when an annotation was set, so that
175+ // callback can be wrapped to also enable the save button.
176+ this .PDFViewerApplication .eventBus .on (' documentinit' , () => {
177+ const annotationStorage = this .PDFViewerApplication .pdfDocument .annotationStorage
178+
179+ const onSetModifiedOriginal = annotationStorage .onSetModified
180+ annotationStorage .onSetModified = () => {
181+ onSetModifiedOriginal .apply (null , arguments )
182+
183+ this .getDownloadElement ().removeAttribute (' disabled' )
184+ }
185+ })
186+
187+ if (hideDownload ()) {
188+ const pdfViewer = this .getIframeDocument ().querySelector (' .pdfViewer' )
189+
190+ if (pdfViewer) {
191+ pdfViewer .classList .add (' disabledTextSelection' )
192+ }
193+
194+ // Disable download function when downloads are hidden, as even
195+ // if the buttons in the UI are hidden the download could still
196+ // be triggered with Ctrl|Meta+S.
197+ this .PDFViewerApplication .download = () => {
198+ }
199+
200+ // Disable printing service when downloads are hidden, as even
201+ // if the buttons in the UI are hidden the printing could still
202+ // be triggered with Ctrl|Meta+P.
203+ // Abuse the "supportsPrinting" parameter, which signals that
204+ // the browser does not fully support printing, to make
205+ // PDFViewer disable the printing service.
206+ // "supportsPrinting" is a getter function, so it needs to be
207+ // deleted before replacing it with a simple value.
208+ delete this .PDFViewerApplication .supportsPrinting
209+ this .PDFViewerApplication .supportsPrinting = false
210+
211+ // When printing is not supported a warning is shown by the
212+ // default "beforePrint" function when trying to print. That
213+ // function needs to be replaced with an empty one to prevent
214+ // that warning to be shown.
215+ this .PDFViewerApplication .beforePrint = () => {
216+ }
217+
218+ logger .info (' Download, print and user interaction disabled' )
219+ } else {
220+ logger .info (' Download and print available' )
221+ }
222+
223+ const PDFViewerApplicationOptions = this .$refs .iframe .contentWindow .PDFViewerApplicationOptions
224+
225+ logger .debug (' Initialized files_pdfviewer' , PDFViewerApplicationOptions .getAll ())
226+ },
227+
228+ handleWebviewerloaded () {
229+ this .initializePDFViewerApplicationOptions ()
147230
148231 // PDFViewerApplication can not be set when the "webviewerloaded"
149232 // event is dispatched, as at this point the application was not
@@ -155,29 +238,7 @@ export default {
155238 // PDFViewerApplication.pdfViewer to be set already and thus uses it
156239 // unconditionally).
157240 this .$refs .iframe .contentWindow .PDFViewerApplication .initializedPromise .then (() => {
158- this .PDFViewerApplication = this .$refs .iframe .contentWindow .PDFViewerApplication
159-
160- this .PDFViewerApplication .save = this .handleSave
161-
162- // Not all fields of PDFViewerApplication are reactive.
163- // Specifically, it can not be known if annotations were created
164- // by watching "pdfDocument.annotationStorage.size" (maybe
165- // because "size" is a getter based on a private field, so it
166- // does not work even if the rest of the chain is skipped and
167- // "size" is directly watched). However, "annotationStorage" has
168- // callbacks used by PDFViewerApplication to know when an
169- // annotation was set, so that callback can be wrapped to also
170- // enable the save button.
171- this .PDFViewerApplication .eventBus .on (' documentinit' , () => {
172- const annotationStorage = this .PDFViewerApplication .pdfDocument .annotationStorage
173-
174- const onSetModifiedOriginal = annotationStorage .onSetModified
175- annotationStorage .onSetModified = () => {
176- onSetModifiedOriginal .apply (null , arguments )
177-
178- this .getDownloadElement ().removeAttribute (' disabled' )
179- }
180- })
241+ this .initializePDFViewerApplication ()
181242 })
182243 },
183244
0 commit comments