@@ -35,8 +35,7 @@ export default {
35
35
36
36
computed: {
37
37
iframeSrc () {
38
- return generateUrl (' /apps/files_pdfviewer/?file={file}&hideDownload={hideDownload}' , {
39
- hideDownload: hideDownload () ? 1 : 0 ,
38
+ return generateUrl (' /apps/files_pdfviewer/?file={file}' , {
40
39
file: this .source ?? this .davPath ,
41
40
})
42
41
},
@@ -111,9 +110,28 @@ export default {
111
110
return this .getIframeDocument ().getElementById (' download' )
112
111
},
113
112
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 () {
115
120
const PDFViewerApplicationOptions = this .$refs .iframe .contentWindow .PDFViewerApplicationOptions
116
121
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
+
117
135
const language = getLanguage ()
118
136
const supportedLanguages = SUPPORTED_LANGUAGES
119
137
// If the user language is supported we use that language,
@@ -132,10 +150,6 @@ export default {
132
150
}
133
151
134
152
if (! this .isEditable ) {
135
- // Preferences override options, so they must be disabled for
136
- // "annotationMode" to take effect.
137
- PDFViewerApplicationOptions .set (' disablePreferences' , true )
138
-
139
153
// AnnotationMode.ENABLE value is 1 in PDF.js, which shows
140
154
// forms, but does not allow to interact with them
141
155
PDFViewerApplicationOptions .set (' annotationMode' , 1 )
@@ -144,6 +158,75 @@ export default {
144
158
// prevents editing annotations
145
159
PDFViewerApplicationOptions .set (' annotationEditorMode' , - 1 )
146
160
}
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 ()
147
230
148
231
// PDFViewerApplication can not be set when the "webviewerloaded"
149
232
// event is dispatched, as at this point the application was not
@@ -155,29 +238,7 @@ export default {
155
238
// PDFViewerApplication.pdfViewer to be set already and thus uses it
156
239
// unconditionally).
157
240
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 ()
181
242
})
182
243
},
183
244
0 commit comments