UNPKG

76.6 kBJavaScriptView Raw
1/**
2 * @licstart The following is the entire license notice for the
3 * JavaScript code in this page
4 *
5 * Copyright 2022 Mozilla Foundation
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * @licend The above is the entire license notice for the
20 * JavaScript code in this page
21 */
22"use strict";
23
24Object.defineProperty(exports, "__esModule", {
25 value: true
26});
27exports.PDFViewerApplication = exports.PDFPrintServiceFactory = exports.DefaultExternalServices = void 0;
28
29var _ui_utils = require("./ui_utils.js");
30
31var _pdf = require("../pdf");
32
33var _app_options = require("./app_options.js");
34
35var _event_utils = require("./event_utils.js");
36
37var _pdf_cursor_tools = require("./pdf_cursor_tools.js");
38
39var _pdf_link_service = require("./pdf_link_service.js");
40
41var _annotation_editor_params = require("./annotation_editor_params.js");
42
43var _overlay_manager = require("./overlay_manager.js");
44
45var _password_prompt = require("./password_prompt.js");
46
47var _pdf_attachment_viewer = require("./pdf_attachment_viewer.js");
48
49var _pdf_document_properties = require("./pdf_document_properties.js");
50
51var _pdf_find_bar = require("./pdf_find_bar.js");
52
53var _pdf_find_controller = require("./pdf_find_controller.js");
54
55var _pdf_history = require("./pdf_history.js");
56
57var _pdf_layer_viewer = require("./pdf_layer_viewer.js");
58
59var _pdf_outline_viewer = require("./pdf_outline_viewer.js");
60
61var _pdf_presentation_mode = require("./pdf_presentation_mode.js");
62
63var _pdf_rendering_queue = require("./pdf_rendering_queue.js");
64
65var _pdf_scripting_manager = require("./pdf_scripting_manager.js");
66
67var _pdf_sidebar = require("./pdf_sidebar.js");
68
69var _pdf_sidebar_resizer = require("./pdf_sidebar_resizer.js");
70
71var _pdf_thumbnail_viewer = require("./pdf_thumbnail_viewer.js");
72
73var _pdf_viewer = require("./pdf_viewer.js");
74
75var _secondary_toolbar = require("./secondary_toolbar.js");
76
77var _toolbar = require("./toolbar.js");
78
79var _view_history = require("./view_history.js");
80
81const DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT = 5000;
82const FORCE_PAGES_LOADED_TIMEOUT = 10000;
83const WHEEL_ZOOM_DISABLED_TIMEOUT = 1000;
84const ViewOnLoad = {
85 UNKNOWN: -1,
86 PREVIOUS: 0,
87 INITIAL: 1
88};
89const ViewerCssTheme = {
90 AUTOMATIC: 0,
91 LIGHT: 1,
92 DARK: 2
93};
94const KNOWN_VERSIONS = ["1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "2.0", "2.1", "2.2", "2.3"];
95const KNOWN_GENERATORS = ["acrobat distiller", "acrobat pdfwriter", "adobe livecycle", "adobe pdf library", "adobe photoshop", "ghostscript", "tcpdf", "cairo", "dvipdfm", "dvips", "pdftex", "pdfkit", "itext", "prince", "quarkxpress", "mac os x", "microsoft", "openoffice", "oracle", "luradocument", "pdf-xchange", "antenna house", "aspose.cells", "fpdf"];
96
97class DefaultExternalServices {
98 constructor() {
99 throw new Error("Cannot initialize DefaultExternalServices.");
100 }
101
102 static updateFindControlState(data) {}
103
104 static updateFindMatchesCount(data) {}
105
106 static initPassiveLoading(callbacks) {}
107
108 static reportTelemetry(data) {}
109
110 static createDownloadManager(options) {
111 throw new Error("Not implemented: createDownloadManager");
112 }
113
114 static createPreferences() {
115 throw new Error("Not implemented: createPreferences");
116 }
117
118 static createL10n(options) {
119 throw new Error("Not implemented: createL10n");
120 }
121
122 static createScripting(options) {
123 throw new Error("Not implemented: createScripting");
124 }
125
126 static get supportsIntegratedFind() {
127 return (0, _pdf.shadow)(this, "supportsIntegratedFind", false);
128 }
129
130 static get supportsDocumentFonts() {
131 return (0, _pdf.shadow)(this, "supportsDocumentFonts", true);
132 }
133
134 static get supportedMouseWheelZoomModifierKeys() {
135 return (0, _pdf.shadow)(this, "supportedMouseWheelZoomModifierKeys", {
136 ctrlKey: true,
137 metaKey: true
138 });
139 }
140
141 static get isInAutomation() {
142 return (0, _pdf.shadow)(this, "isInAutomation", false);
143 }
144
145 static updateEditorStates(data) {
146 throw new Error("Not implemented: updateEditorStates");
147 }
148
149}
150
151exports.DefaultExternalServices = DefaultExternalServices;
152const PDFViewerApplication = {
153 initialBookmark: document.location.hash.substring(1),
154 _initializedCapability: (0, _pdf.createPromiseCapability)(),
155 appConfig: null,
156 pdfDocument: null,
157 pdfLoadingTask: null,
158 printService: null,
159 pdfViewer: null,
160 pdfThumbnailViewer: null,
161 pdfRenderingQueue: null,
162 pdfPresentationMode: null,
163 pdfDocumentProperties: null,
164 pdfLinkService: null,
165 pdfHistory: null,
166 pdfSidebar: null,
167 pdfSidebarResizer: null,
168 pdfOutlineViewer: null,
169 pdfAttachmentViewer: null,
170 pdfLayerViewer: null,
171 pdfCursorTools: null,
172 pdfScriptingManager: null,
173 store: null,
174 downloadManager: null,
175 overlayManager: null,
176 preferences: null,
177 toolbar: null,
178 secondaryToolbar: null,
179 eventBus: null,
180 l10n: null,
181 annotationEditorParams: null,
182 isInitialViewSet: false,
183 downloadComplete: false,
184 isViewerEmbedded: window.parent !== window,
185 url: "",
186 baseUrl: "",
187 _downloadUrl: "",
188 externalServices: DefaultExternalServices,
189 _boundEvents: Object.create(null),
190 documentInfo: null,
191 metadata: null,
192 _contentDispositionFilename: null,
193 _contentLength: null,
194 _saveInProgress: false,
195 _docStats: null,
196 _wheelUnusedTicks: 0,
197 _idleCallbacks: new Set(),
198 _PDFBug: null,
199 _printAnnotationStoragePromise: null,
200
201 async initialize(appConfig) {
202 this.preferences = this.externalServices.createPreferences();
203 this.appConfig = appConfig;
204 await this._readPreferences();
205 await this._parseHashParameters();
206
207 this._forceCssTheme();
208
209 await this._initializeL10n();
210
211 if (this.isViewerEmbedded && _app_options.AppOptions.get("externalLinkTarget") === _pdf_link_service.LinkTarget.NONE) {
212 _app_options.AppOptions.set("externalLinkTarget", _pdf_link_service.LinkTarget.TOP);
213 }
214
215 await this._initializeViewerComponents();
216 this.bindEvents();
217 this.bindWindowEvents();
218 const appContainer = appConfig.appContainer || document.documentElement;
219 this.l10n.translate(appContainer).then(() => {
220 this.eventBus.dispatch("localized", {
221 source: this
222 });
223 });
224
225 this._initializedCapability.resolve();
226 },
227
228 async _readPreferences() {
229 if (_app_options.AppOptions.get("disablePreferences")) {
230 return;
231 }
232
233 if (_app_options.AppOptions._hasUserOptions()) {
234 console.warn("_readPreferences: The Preferences may override manually set AppOptions; " + 'please use the "disablePreferences"-option in order to prevent that.');
235 }
236
237 try {
238 _app_options.AppOptions.setAll(await this.preferences.getAll());
239 } catch (reason) {
240 console.error(`_readPreferences: "${reason?.message}".`);
241 }
242 },
243
244 async _parseHashParameters() {
245 if (!_app_options.AppOptions.get("pdfBugEnabled")) {
246 return;
247 }
248
249 const hash = document.location.hash.substring(1);
250
251 if (!hash) {
252 return;
253 }
254
255 const {
256 mainContainer,
257 viewerContainer
258 } = this.appConfig,
259 params = (0, _ui_utils.parseQueryString)(hash);
260
261 if (params.get("disableworker") === "true") {
262 try {
263 await loadFakeWorker();
264 } catch (ex) {
265 console.error(`_parseHashParameters: "${ex.message}".`);
266 }
267 }
268
269 if (params.has("disablerange")) {
270 _app_options.AppOptions.set("disableRange", params.get("disablerange") === "true");
271 }
272
273 if (params.has("disablestream")) {
274 _app_options.AppOptions.set("disableStream", params.get("disablestream") === "true");
275 }
276
277 if (params.has("disableautofetch")) {
278 _app_options.AppOptions.set("disableAutoFetch", params.get("disableautofetch") === "true");
279 }
280
281 if (params.has("disablefontface")) {
282 _app_options.AppOptions.set("disableFontFace", params.get("disablefontface") === "true");
283 }
284
285 if (params.has("disablehistory")) {
286 _app_options.AppOptions.set("disableHistory", params.get("disablehistory") === "true");
287 }
288
289 if (params.has("verbosity")) {
290 _app_options.AppOptions.set("verbosity", params.get("verbosity") | 0);
291 }
292
293 if (params.has("textlayer")) {
294 switch (params.get("textlayer")) {
295 case "off":
296 _app_options.AppOptions.set("textLayerMode", _ui_utils.TextLayerMode.DISABLE);
297
298 break;
299
300 case "visible":
301 case "shadow":
302 case "hover":
303 viewerContainer.classList.add(`textLayer-${params.get("textlayer")}`);
304
305 try {
306 await loadPDFBug(this);
307
308 this._PDFBug.loadCSS();
309 } catch (ex) {
310 console.error(`_parseHashParameters: "${ex.message}".`);
311 }
312
313 break;
314 }
315 }
316
317 if (params.has("pdfbug")) {
318 _app_options.AppOptions.set("pdfBug", true);
319
320 _app_options.AppOptions.set("fontExtraProperties", true);
321
322 const enabled = params.get("pdfbug").split(",");
323
324 try {
325 await loadPDFBug(this);
326
327 this._PDFBug.init({
328 OPS: _pdf.OPS
329 }, mainContainer, enabled);
330 } catch (ex) {
331 console.error(`_parseHashParameters: "${ex.message}".`);
332 }
333 }
334
335 if (params.has("locale")) {
336 _app_options.AppOptions.set("locale", params.get("locale"));
337 }
338 },
339
340 async _initializeL10n() {
341 this.l10n = this.externalServices.createL10n({
342 locale: _app_options.AppOptions.get("locale")
343 });
344 const dir = await this.l10n.getDirection();
345 document.getElementsByTagName("html")[0].dir = dir;
346 },
347
348 _forceCssTheme() {
349 const cssTheme = _app_options.AppOptions.get("viewerCssTheme");
350
351 if (cssTheme === ViewerCssTheme.AUTOMATIC || !Object.values(ViewerCssTheme).includes(cssTheme)) {
352 return;
353 }
354
355 try {
356 const styleSheet = document.styleSheets[0];
357 const cssRules = styleSheet?.cssRules || [];
358
359 for (let i = 0, ii = cssRules.length; i < ii; i++) {
360 const rule = cssRules[i];
361
362 if (rule instanceof CSSMediaRule && rule.media?.[0] === "(prefers-color-scheme: dark)") {
363 if (cssTheme === ViewerCssTheme.LIGHT) {
364 styleSheet.deleteRule(i);
365 return;
366 }
367
368 const darkRules = /^@media \(prefers-color-scheme: dark\) {\n\s*([\w\s-.,:;/\\{}()]+)\n}$/.exec(rule.cssText);
369
370 if (darkRules?.[1]) {
371 styleSheet.deleteRule(i);
372 styleSheet.insertRule(darkRules[1], i);
373 }
374
375 return;
376 }
377 }
378 } catch (reason) {
379 console.error(`_forceCssTheme: "${reason?.message}".`);
380 }
381 },
382
383 async _initializeViewerComponents() {
384 const {
385 appConfig,
386 externalServices
387 } = this;
388 const eventBus = externalServices.isInAutomation ? new _event_utils.AutomationEventBus() : new _event_utils.EventBus();
389 this.eventBus = eventBus;
390 this.overlayManager = new _overlay_manager.OverlayManager();
391 const pdfRenderingQueue = new _pdf_rendering_queue.PDFRenderingQueue();
392 pdfRenderingQueue.onIdle = this._cleanup.bind(this);
393 this.pdfRenderingQueue = pdfRenderingQueue;
394 const pdfLinkService = new _pdf_link_service.PDFLinkService({
395 eventBus,
396 externalLinkTarget: _app_options.AppOptions.get("externalLinkTarget"),
397 externalLinkRel: _app_options.AppOptions.get("externalLinkRel"),
398 ignoreDestinationZoom: _app_options.AppOptions.get("ignoreDestinationZoom")
399 });
400 this.pdfLinkService = pdfLinkService;
401 const downloadManager = externalServices.createDownloadManager();
402 this.downloadManager = downloadManager;
403 const findController = new _pdf_find_controller.PDFFindController({
404 linkService: pdfLinkService,
405 eventBus
406 });
407 this.findController = findController;
408 const pdfScriptingManager = new _pdf_scripting_manager.PDFScriptingManager({
409 eventBus,
410 sandboxBundleSrc: _app_options.AppOptions.get("sandboxBundleSrc"),
411 scriptingFactory: externalServices,
412 docPropertiesLookup: this._scriptingDocProperties.bind(this)
413 });
414 this.pdfScriptingManager = pdfScriptingManager;
415 const container = appConfig.mainContainer,
416 viewer = appConfig.viewerContainer;
417
418 const annotationEditorMode = _app_options.AppOptions.get("annotationEditorMode");
419
420 const pageColors = _app_options.AppOptions.get("forcePageColors") || window.matchMedia("(forced-colors: active)").matches ? {
421 background: _app_options.AppOptions.get("pageColorsBackground"),
422 foreground: _app_options.AppOptions.get("pageColorsForeground")
423 } : null;
424 this.pdfViewer = new _pdf_viewer.PDFViewer({
425 container,
426 viewer,
427 eventBus,
428 renderingQueue: pdfRenderingQueue,
429 linkService: pdfLinkService,
430 downloadManager,
431 findController,
432 scriptingManager: _app_options.AppOptions.get("enableScripting") && pdfScriptingManager,
433 renderer: _app_options.AppOptions.get("renderer"),
434 l10n: this.l10n,
435 textLayerMode: _app_options.AppOptions.get("textLayerMode"),
436 annotationMode: _app_options.AppOptions.get("annotationMode"),
437 annotationEditorMode,
438 imageResourcesPath: _app_options.AppOptions.get("imageResourcesPath"),
439 enablePrintAutoRotate: _app_options.AppOptions.get("enablePrintAutoRotate"),
440 useOnlyCssZoom: _app_options.AppOptions.get("useOnlyCssZoom"),
441 maxCanvasPixels: _app_options.AppOptions.get("maxCanvasPixels"),
442 enablePermissions: _app_options.AppOptions.get("enablePermissions"),
443 pageColors
444 });
445 pdfRenderingQueue.setViewer(this.pdfViewer);
446 pdfLinkService.setViewer(this.pdfViewer);
447 pdfScriptingManager.setViewer(this.pdfViewer);
448 this.pdfThumbnailViewer = new _pdf_thumbnail_viewer.PDFThumbnailViewer({
449 container: appConfig.sidebar.thumbnailView,
450 eventBus,
451 renderingQueue: pdfRenderingQueue,
452 linkService: pdfLinkService,
453 l10n: this.l10n,
454 pageColors
455 });
456 pdfRenderingQueue.setThumbnailViewer(this.pdfThumbnailViewer);
457
458 if (!this.isViewerEmbedded && !_app_options.AppOptions.get("disableHistory")) {
459 this.pdfHistory = new _pdf_history.PDFHistory({
460 linkService: pdfLinkService,
461 eventBus
462 });
463 pdfLinkService.setHistory(this.pdfHistory);
464 }
465
466 if (!this.supportsIntegratedFind) {
467 this.findBar = new _pdf_find_bar.PDFFindBar(appConfig.findBar, eventBus, this.l10n);
468 }
469
470 if (annotationEditorMode !== _pdf.AnnotationEditorType.DISABLE) {
471 this.annotationEditorParams = new _annotation_editor_params.AnnotationEditorParams(appConfig.annotationEditorParams, eventBus);
472
473 for (const element of [document.getElementById("editorModeButtons"), document.getElementById("editorModeSeparator")]) {
474 element.classList.remove("hidden");
475 }
476 }
477
478 this.pdfDocumentProperties = new _pdf_document_properties.PDFDocumentProperties(appConfig.documentProperties, this.overlayManager, eventBus, this.l10n, () => {
479 return this._docFilename;
480 });
481 this.pdfCursorTools = new _pdf_cursor_tools.PDFCursorTools({
482 container,
483 eventBus,
484 cursorToolOnLoad: _app_options.AppOptions.get("cursorToolOnLoad")
485 });
486 this.toolbar = new _toolbar.Toolbar(appConfig.toolbar, eventBus, this.l10n);
487 this.secondaryToolbar = new _secondary_toolbar.SecondaryToolbar(appConfig.secondaryToolbar, eventBus);
488
489 if (this.supportsFullscreen) {
490 this.pdfPresentationMode = new _pdf_presentation_mode.PDFPresentationMode({
491 container,
492 pdfViewer: this.pdfViewer,
493 eventBus
494 });
495 }
496
497 this.passwordPrompt = new _password_prompt.PasswordPrompt(appConfig.passwordOverlay, this.overlayManager, this.l10n, this.isViewerEmbedded);
498 this.pdfOutlineViewer = new _pdf_outline_viewer.PDFOutlineViewer({
499 container: appConfig.sidebar.outlineView,
500 eventBus,
501 linkService: pdfLinkService
502 });
503 this.pdfAttachmentViewer = new _pdf_attachment_viewer.PDFAttachmentViewer({
504 container: appConfig.sidebar.attachmentsView,
505 eventBus,
506 downloadManager
507 });
508 this.pdfLayerViewer = new _pdf_layer_viewer.PDFLayerViewer({
509 container: appConfig.sidebar.layersView,
510 eventBus,
511 l10n: this.l10n
512 });
513 this.pdfSidebar = new _pdf_sidebar.PDFSidebar({
514 elements: appConfig.sidebar,
515 pdfViewer: this.pdfViewer,
516 pdfThumbnailViewer: this.pdfThumbnailViewer,
517 eventBus,
518 l10n: this.l10n
519 });
520 this.pdfSidebar.onToggled = this.forceRendering.bind(this);
521 this.pdfSidebarResizer = new _pdf_sidebar_resizer.PDFSidebarResizer(appConfig.sidebarResizer, eventBus, this.l10n);
522 },
523
524 run(config) {
525 this.initialize(config).then(webViewerInitialized);
526 },
527
528 get initialized() {
529 return this._initializedCapability.settled;
530 },
531
532 get initializedPromise() {
533 return this._initializedCapability.promise;
534 },
535
536 zoomIn(steps) {
537 if (this.pdfViewer.isInPresentationMode) {
538 return;
539 }
540
541 this.pdfViewer.increaseScale(steps);
542 },
543
544 zoomOut(steps) {
545 if (this.pdfViewer.isInPresentationMode) {
546 return;
547 }
548
549 this.pdfViewer.decreaseScale(steps);
550 },
551
552 zoomReset() {
553 if (this.pdfViewer.isInPresentationMode) {
554 return;
555 }
556
557 this.pdfViewer.currentScaleValue = _ui_utils.DEFAULT_SCALE_VALUE;
558 },
559
560 get pagesCount() {
561 return this.pdfDocument ? this.pdfDocument.numPages : 0;
562 },
563
564 get page() {
565 return this.pdfViewer.currentPageNumber;
566 },
567
568 set page(val) {
569 this.pdfViewer.currentPageNumber = val;
570 },
571
572 get supportsPrinting() {
573 return PDFPrintServiceFactory.instance.supportsPrinting;
574 },
575
576 get supportsFullscreen() {
577 return (0, _pdf.shadow)(this, "supportsFullscreen", document.fullscreenEnabled);
578 },
579
580 get supportsIntegratedFind() {
581 return this.externalServices.supportsIntegratedFind;
582 },
583
584 get supportsDocumentFonts() {
585 return this.externalServices.supportsDocumentFonts;
586 },
587
588 get loadingBar() {
589 const bar = new _ui_utils.ProgressBar("loadingBar");
590 return (0, _pdf.shadow)(this, "loadingBar", bar);
591 },
592
593 get supportedMouseWheelZoomModifierKeys() {
594 return this.externalServices.supportedMouseWheelZoomModifierKeys;
595 },
596
597 initPassiveLoading() {
598 throw new Error("Not implemented: initPassiveLoading");
599 },
600
601 setTitleUsingUrl(url = "", downloadUrl = null) {
602 this.url = url;
603 this.baseUrl = url.split("#")[0];
604
605 if (downloadUrl) {
606 this._downloadUrl = downloadUrl === url ? this.baseUrl : downloadUrl.split("#")[0];
607 }
608
609 let title = (0, _pdf.getPdfFilenameFromUrl)(url, "");
610
611 if (!title) {
612 try {
613 title = decodeURIComponent((0, _pdf.getFilenameFromUrl)(url)) || url;
614 } catch (ex) {
615 title = url;
616 }
617 }
618
619 this.setTitle(title);
620 },
621
622 setTitle(title) {
623 if (this.isViewerEmbedded) {
624 return;
625 }
626
627 document.title = title;
628 },
629
630 get _docFilename() {
631 return this._contentDispositionFilename || (0, _pdf.getPdfFilenameFromUrl)(this.url);
632 },
633
634 _hideViewBookmark() {
635 const {
636 toolbar,
637 secondaryToolbar
638 } = this.appConfig;
639 toolbar.viewBookmark.hidden = true;
640 secondaryToolbar.viewBookmarkButton.hidden = true;
641 },
642
643 _cancelIdleCallbacks() {
644 if (!this._idleCallbacks.size) {
645 return;
646 }
647
648 for (const callback of this._idleCallbacks) {
649 window.cancelIdleCallback(callback);
650 }
651
652 this._idleCallbacks.clear();
653 },
654
655 async close() {
656 this._unblockDocumentLoadEvent();
657
658 this._hideViewBookmark();
659
660 const {
661 container
662 } = this.appConfig.errorWrapper;
663 container.hidden = true;
664
665 if (!this.pdfLoadingTask) {
666 return;
667 }
668
669 if (this.pdfDocument?.annotationStorage.size > 0 && this._annotationStorageModified) {
670 try {
671 await this.save();
672 } catch (reason) {}
673 }
674
675 const promises = [];
676 promises.push(this.pdfLoadingTask.destroy());
677 this.pdfLoadingTask = null;
678
679 if (this.pdfDocument) {
680 this.pdfDocument = null;
681 this.pdfThumbnailViewer.setDocument(null);
682 this.pdfViewer.setDocument(null);
683 this.pdfLinkService.setDocument(null);
684 this.pdfDocumentProperties.setDocument(null);
685 }
686
687 this.pdfLinkService.externalLinkEnabled = true;
688 this.store = null;
689 this.isInitialViewSet = false;
690 this.downloadComplete = false;
691 this.url = "";
692 this.baseUrl = "";
693 this._downloadUrl = "";
694 this.documentInfo = null;
695 this.metadata = null;
696 this._contentDispositionFilename = null;
697 this._contentLength = null;
698 this._saveInProgress = false;
699 this._docStats = null;
700
701 this._cancelIdleCallbacks();
702
703 promises.push(this.pdfScriptingManager.destroyPromise);
704 this.pdfSidebar.reset();
705 this.pdfOutlineViewer.reset();
706 this.pdfAttachmentViewer.reset();
707 this.pdfLayerViewer.reset();
708 this.pdfHistory?.reset();
709 this.findBar?.reset();
710 this.toolbar.reset();
711 this.secondaryToolbar.reset();
712 this._PDFBug?.cleanup();
713 await Promise.all(promises);
714 },
715
716 async open(file, args) {
717 if (this.pdfLoadingTask) {
718 await this.close();
719 }
720
721 const workerParameters = _app_options.AppOptions.getAll(_app_options.OptionKind.WORKER);
722
723 for (const key in workerParameters) {
724 _pdf.GlobalWorkerOptions[key] = workerParameters[key];
725 }
726
727 const parameters = Object.create(null);
728
729 if (typeof file === "string") {
730 this.setTitleUsingUrl(file, file);
731 parameters.url = file;
732 } else if (file && "byteLength" in file) {
733 parameters.data = file;
734 } else if (file.url && file.originalUrl) {
735 this.setTitleUsingUrl(file.originalUrl, file.url);
736 parameters.url = file.url;
737 }
738
739 const apiParameters = _app_options.AppOptions.getAll(_app_options.OptionKind.API);
740
741 for (const key in apiParameters) {
742 let value = apiParameters[key];
743
744 if (key === "docBaseUrl" && !value) {}
745
746 parameters[key] = value;
747 }
748
749 if (args) {
750 for (const key in args) {
751 parameters[key] = args[key];
752 }
753 }
754
755 const loadingTask = (0, _pdf.getDocument)(parameters);
756 this.pdfLoadingTask = loadingTask;
757
758 loadingTask.onPassword = (updateCallback, reason) => {
759 this.pdfLinkService.externalLinkEnabled = false;
760 this.passwordPrompt.setUpdateCallback(updateCallback, reason);
761 this.passwordPrompt.open();
762 };
763
764 loadingTask.onProgress = ({
765 loaded,
766 total
767 }) => {
768 this.progress(loaded / total);
769 };
770
771 loadingTask.onUnsupportedFeature = this.fallback.bind(this);
772 return loadingTask.promise.then(pdfDocument => {
773 this.load(pdfDocument);
774 }, reason => {
775 if (loadingTask !== this.pdfLoadingTask) {
776 return undefined;
777 }
778
779 let key = "loading_error";
780
781 if (reason instanceof _pdf.InvalidPDFException) {
782 key = "invalid_file_error";
783 } else if (reason instanceof _pdf.MissingPDFException) {
784 key = "missing_file_error";
785 } else if (reason instanceof _pdf.UnexpectedResponseException) {
786 key = "unexpected_response_error";
787 }
788
789 return this.l10n.get(key).then(msg => {
790 this._documentError(msg, {
791 message: reason?.message
792 });
793
794 throw reason;
795 });
796 });
797 },
798
799 _ensureDownloadComplete() {
800 if (this.pdfDocument && this.downloadComplete) {
801 return;
802 }
803
804 throw new Error("PDF document not downloaded.");
805 },
806
807 async download() {
808 const url = this._downloadUrl,
809 filename = this._docFilename;
810
811 try {
812 this._ensureDownloadComplete();
813
814 const data = await this.pdfDocument.getData();
815 const blob = new Blob([data], {
816 type: "application/pdf"
817 });
818 await this.downloadManager.download(blob, url, filename);
819 } catch (reason) {
820 await this.downloadManager.downloadUrl(url, filename);
821 }
822 },
823
824 async save() {
825 if (this._saveInProgress) {
826 return;
827 }
828
829 this._saveInProgress = true;
830 await this.pdfScriptingManager.dispatchWillSave();
831 const url = this._downloadUrl,
832 filename = this._docFilename;
833
834 try {
835 this._ensureDownloadComplete();
836
837 const data = await this.pdfDocument.saveDocument();
838 const blob = new Blob([data], {
839 type: "application/pdf"
840 });
841 await this.downloadManager.download(blob, url, filename);
842 } catch (reason) {
843 console.error(`Error when saving the document: ${reason.message}`);
844 await this.download();
845 } finally {
846 await this.pdfScriptingManager.dispatchDidSave();
847 this._saveInProgress = false;
848 }
849 },
850
851 downloadOrSave() {
852 if (this.pdfDocument?.annotationStorage.size > 0) {
853 this.save();
854 } else {
855 this.download();
856 }
857 },
858
859 fallback(featureId) {
860 this.externalServices.reportTelemetry({
861 type: "unsupportedFeature",
862 featureId
863 });
864 },
865
866 _documentError(message, moreInfo = null) {
867 this._unblockDocumentLoadEvent();
868
869 this._otherError(message, moreInfo);
870
871 this.eventBus.dispatch("documenterror", {
872 source: this,
873 message,
874 reason: moreInfo?.message ?? null
875 });
876 },
877
878 _otherError(message, moreInfo = null) {
879 const moreInfoText = [this.l10n.get("error_version_info", {
880 version: _pdf.version || "?",
881 build: _pdf.build || "?"
882 })];
883
884 if (moreInfo) {
885 moreInfoText.push(this.l10n.get("error_message", {
886 message: moreInfo.message
887 }));
888
889 if (moreInfo.stack) {
890 moreInfoText.push(this.l10n.get("error_stack", {
891 stack: moreInfo.stack
892 }));
893 } else {
894 if (moreInfo.filename) {
895 moreInfoText.push(this.l10n.get("error_file", {
896 file: moreInfo.filename
897 }));
898 }
899
900 if (moreInfo.lineNumber) {
901 moreInfoText.push(this.l10n.get("error_line", {
902 line: moreInfo.lineNumber
903 }));
904 }
905 }
906 }
907
908 const errorWrapperConfig = this.appConfig.errorWrapper;
909 const errorWrapper = errorWrapperConfig.container;
910 errorWrapper.hidden = false;
911 const errorMessage = errorWrapperConfig.errorMessage;
912 errorMessage.textContent = message;
913 const closeButton = errorWrapperConfig.closeButton;
914
915 closeButton.onclick = function () {
916 errorWrapper.hidden = true;
917 };
918
919 const errorMoreInfo = errorWrapperConfig.errorMoreInfo;
920 const moreInfoButton = errorWrapperConfig.moreInfoButton;
921 const lessInfoButton = errorWrapperConfig.lessInfoButton;
922
923 moreInfoButton.onclick = function () {
924 errorMoreInfo.hidden = false;
925 moreInfoButton.hidden = true;
926 lessInfoButton.hidden = false;
927 errorMoreInfo.style.height = errorMoreInfo.scrollHeight + "px";
928 };
929
930 lessInfoButton.onclick = function () {
931 errorMoreInfo.hidden = true;
932 moreInfoButton.hidden = false;
933 lessInfoButton.hidden = true;
934 };
935
936 moreInfoButton.oncontextmenu = _ui_utils.noContextMenuHandler;
937 lessInfoButton.oncontextmenu = _ui_utils.noContextMenuHandler;
938 closeButton.oncontextmenu = _ui_utils.noContextMenuHandler;
939 moreInfoButton.hidden = false;
940 lessInfoButton.hidden = true;
941 Promise.all(moreInfoText).then(parts => {
942 errorMoreInfo.value = parts.join("\n");
943 });
944 },
945
946 progress(level) {
947 if (this.downloadComplete) {
948 return;
949 }
950
951 const percent = Math.round(level * 100);
952
953 if (percent <= this.loadingBar.percent) {
954 return;
955 }
956
957 this.loadingBar.percent = percent;
958
959 const disableAutoFetch = this.pdfDocument?.loadingParams.disableAutoFetch ?? _app_options.AppOptions.get("disableAutoFetch");
960
961 if (!disableAutoFetch || isNaN(percent)) {
962 return;
963 }
964
965 if (this.disableAutoFetchLoadingBarTimeout) {
966 clearTimeout(this.disableAutoFetchLoadingBarTimeout);
967 this.disableAutoFetchLoadingBarTimeout = null;
968 }
969
970 this.loadingBar.show();
971 this.disableAutoFetchLoadingBarTimeout = setTimeout(() => {
972 this.loadingBar.hide();
973 this.disableAutoFetchLoadingBarTimeout = null;
974 }, DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT);
975 },
976
977 load(pdfDocument) {
978 this.pdfDocument = pdfDocument;
979 pdfDocument.getDownloadInfo().then(({
980 length
981 }) => {
982 this._contentLength = length;
983 this.downloadComplete = true;
984 this.loadingBar.hide();
985 firstPagePromise.then(() => {
986 this.eventBus.dispatch("documentloaded", {
987 source: this
988 });
989 });
990 });
991 const pageLayoutPromise = pdfDocument.getPageLayout().catch(function () {});
992 const pageModePromise = pdfDocument.getPageMode().catch(function () {});
993 const openActionPromise = pdfDocument.getOpenAction().catch(function () {});
994 this.toolbar.setPagesCount(pdfDocument.numPages, false);
995 this.secondaryToolbar.setPagesCount(pdfDocument.numPages);
996 let baseDocumentUrl;
997 baseDocumentUrl = null;
998 this.pdfLinkService.setDocument(pdfDocument, baseDocumentUrl);
999 this.pdfDocumentProperties.setDocument(pdfDocument);
1000 const pdfViewer = this.pdfViewer;
1001 pdfViewer.setDocument(pdfDocument);
1002 const {
1003 firstPagePromise,
1004 onePageRendered,
1005 pagesPromise
1006 } = pdfViewer;
1007 const pdfThumbnailViewer = this.pdfThumbnailViewer;
1008 pdfThumbnailViewer.setDocument(pdfDocument);
1009 const storedPromise = (this.store = new _view_history.ViewHistory(pdfDocument.fingerprints[0])).getMultiple({
1010 page: null,
1011 zoom: _ui_utils.DEFAULT_SCALE_VALUE,
1012 scrollLeft: "0",
1013 scrollTop: "0",
1014 rotation: null,
1015 sidebarView: _ui_utils.SidebarView.UNKNOWN,
1016 scrollMode: _ui_utils.ScrollMode.UNKNOWN,
1017 spreadMode: _ui_utils.SpreadMode.UNKNOWN
1018 }).catch(() => {
1019 return Object.create(null);
1020 });
1021 firstPagePromise.then(pdfPage => {
1022 this.loadingBar.setWidth(this.appConfig.viewerContainer);
1023
1024 this._initializeAnnotationStorageCallbacks(pdfDocument);
1025
1026 Promise.all([_ui_utils.animationStarted, storedPromise, pageLayoutPromise, pageModePromise, openActionPromise]).then(async ([timeStamp, stored, pageLayout, pageMode, openAction]) => {
1027 const viewOnLoad = _app_options.AppOptions.get("viewOnLoad");
1028
1029 this._initializePdfHistory({
1030 fingerprint: pdfDocument.fingerprints[0],
1031 viewOnLoad,
1032 initialDest: openAction?.dest
1033 });
1034
1035 const initialBookmark = this.initialBookmark;
1036
1037 const zoom = _app_options.AppOptions.get("defaultZoomValue");
1038
1039 let hash = zoom ? `zoom=${zoom}` : null;
1040 let rotation = null;
1041
1042 let sidebarView = _app_options.AppOptions.get("sidebarViewOnLoad");
1043
1044 let scrollMode = _app_options.AppOptions.get("scrollModeOnLoad");
1045
1046 let spreadMode = _app_options.AppOptions.get("spreadModeOnLoad");
1047
1048 if (stored.page && viewOnLoad !== ViewOnLoad.INITIAL) {
1049 hash = `page=${stored.page}&zoom=${zoom || stored.zoom},` + `${stored.scrollLeft},${stored.scrollTop}`;
1050 rotation = parseInt(stored.rotation, 10);
1051
1052 if (sidebarView === _ui_utils.SidebarView.UNKNOWN) {
1053 sidebarView = stored.sidebarView | 0;
1054 }
1055
1056 if (scrollMode === _ui_utils.ScrollMode.UNKNOWN) {
1057 scrollMode = stored.scrollMode | 0;
1058 }
1059
1060 if (spreadMode === _ui_utils.SpreadMode.UNKNOWN) {
1061 spreadMode = stored.spreadMode | 0;
1062 }
1063 }
1064
1065 if (pageMode && sidebarView === _ui_utils.SidebarView.UNKNOWN) {
1066 sidebarView = (0, _ui_utils.apiPageModeToSidebarView)(pageMode);
1067 }
1068
1069 if (pageLayout && scrollMode === _ui_utils.ScrollMode.UNKNOWN && spreadMode === _ui_utils.SpreadMode.UNKNOWN) {
1070 const modes = (0, _ui_utils.apiPageLayoutToViewerModes)(pageLayout);
1071 spreadMode = modes.spreadMode;
1072 }
1073
1074 this.setInitialView(hash, {
1075 rotation,
1076 sidebarView,
1077 scrollMode,
1078 spreadMode
1079 });
1080 this.eventBus.dispatch("documentinit", {
1081 source: this
1082 });
1083
1084 if (!this.isViewerEmbedded) {
1085 pdfViewer.focus();
1086 }
1087
1088 await Promise.race([pagesPromise, new Promise(resolve => {
1089 setTimeout(resolve, FORCE_PAGES_LOADED_TIMEOUT);
1090 })]);
1091
1092 if (!initialBookmark && !hash) {
1093 return;
1094 }
1095
1096 if (pdfViewer.hasEqualPageSizes) {
1097 return;
1098 }
1099
1100 this.initialBookmark = initialBookmark;
1101 pdfViewer.currentScaleValue = pdfViewer.currentScaleValue;
1102 this.setInitialView(hash);
1103 }).catch(() => {
1104 this.setInitialView();
1105 }).then(function () {
1106 pdfViewer.update();
1107 });
1108 });
1109 pagesPromise.then(() => {
1110 this._unblockDocumentLoadEvent();
1111
1112 this._initializeAutoPrint(pdfDocument, openActionPromise);
1113 }, reason => {
1114 this.l10n.get("loading_error").then(msg => {
1115 this._documentError(msg, {
1116 message: reason?.message
1117 });
1118 });
1119 });
1120 onePageRendered.then(data => {
1121 this.externalServices.reportTelemetry({
1122 type: "pageInfo",
1123 timestamp: data.timestamp
1124 });
1125 pdfDocument.getOutline().then(outline => {
1126 if (pdfDocument !== this.pdfDocument) {
1127 return;
1128 }
1129
1130 this.pdfOutlineViewer.render({
1131 outline,
1132 pdfDocument
1133 });
1134 });
1135 pdfDocument.getAttachments().then(attachments => {
1136 if (pdfDocument !== this.pdfDocument) {
1137 return;
1138 }
1139
1140 this.pdfAttachmentViewer.render({
1141 attachments
1142 });
1143 });
1144 pdfViewer.optionalContentConfigPromise.then(optionalContentConfig => {
1145 if (pdfDocument !== this.pdfDocument) {
1146 return;
1147 }
1148
1149 this.pdfLayerViewer.render({
1150 optionalContentConfig,
1151 pdfDocument
1152 });
1153 });
1154
1155 if ("requestIdleCallback" in window) {
1156 const callback = window.requestIdleCallback(() => {
1157 this._collectTelemetry(pdfDocument);
1158
1159 this._idleCallbacks.delete(callback);
1160 }, {
1161 timeout: 1000
1162 });
1163
1164 this._idleCallbacks.add(callback);
1165 }
1166 });
1167
1168 this._initializePageLabels(pdfDocument);
1169
1170 this._initializeMetadata(pdfDocument);
1171 },
1172
1173 async _scriptingDocProperties(pdfDocument) {
1174 if (!this.documentInfo) {
1175 await new Promise(resolve => {
1176 this.eventBus._on("metadataloaded", resolve, {
1177 once: true
1178 });
1179 });
1180
1181 if (pdfDocument !== this.pdfDocument) {
1182 return null;
1183 }
1184 }
1185
1186 if (!this._contentLength) {
1187 await new Promise(resolve => {
1188 this.eventBus._on("documentloaded", resolve, {
1189 once: true
1190 });
1191 });
1192
1193 if (pdfDocument !== this.pdfDocument) {
1194 return null;
1195 }
1196 }
1197
1198 return { ...this.documentInfo,
1199 baseURL: this.baseUrl,
1200 filesize: this._contentLength,
1201 filename: this._docFilename,
1202 metadata: this.metadata?.getRaw(),
1203 authors: this.metadata?.get("dc:creator"),
1204 numPages: this.pagesCount,
1205 URL: this.url
1206 };
1207 },
1208
1209 async _collectTelemetry(pdfDocument) {
1210 const markInfo = await this.pdfDocument.getMarkInfo();
1211
1212 if (pdfDocument !== this.pdfDocument) {
1213 return;
1214 }
1215
1216 const tagged = markInfo?.Marked || false;
1217 this.externalServices.reportTelemetry({
1218 type: "tagged",
1219 tagged
1220 });
1221 },
1222
1223 async _initializeAutoPrint(pdfDocument, openActionPromise) {
1224 const [openAction, javaScript] = await Promise.all([openActionPromise, !this.pdfViewer.enableScripting ? pdfDocument.getJavaScript() : null]);
1225
1226 if (pdfDocument !== this.pdfDocument) {
1227 return;
1228 }
1229
1230 let triggerAutoPrint = false;
1231
1232 if (openAction?.action === "Print") {
1233 triggerAutoPrint = true;
1234 }
1235
1236 if (javaScript) {
1237 javaScript.some(js => {
1238 if (!js) {
1239 return false;
1240 }
1241
1242 console.warn("Warning: JavaScript support is not enabled");
1243 this.fallback(_pdf.UNSUPPORTED_FEATURES.javaScript);
1244 return true;
1245 });
1246
1247 if (!triggerAutoPrint) {
1248 for (const js of javaScript) {
1249 if (js && _ui_utils.AutoPrintRegExp.test(js)) {
1250 triggerAutoPrint = true;
1251 break;
1252 }
1253 }
1254 }
1255 }
1256
1257 if (triggerAutoPrint) {
1258 this.triggerPrinting();
1259 }
1260 },
1261
1262 async _initializeMetadata(pdfDocument) {
1263 const {
1264 info,
1265 metadata,
1266 contentDispositionFilename,
1267 contentLength
1268 } = await pdfDocument.getMetadata();
1269
1270 if (pdfDocument !== this.pdfDocument) {
1271 return;
1272 }
1273
1274 this.documentInfo = info;
1275 this.metadata = metadata;
1276 this._contentDispositionFilename ??= contentDispositionFilename;
1277 this._contentLength ??= contentLength;
1278 console.log(`PDF ${pdfDocument.fingerprints[0]} [${info.PDFFormatVersion} ` + `${(info.Producer || "-").trim()} / ${(info.Creator || "-").trim()}] ` + `(PDF.js: ${_pdf.version || "-"})`);
1279 let pdfTitle = info.Title;
1280 const metadataTitle = metadata?.get("dc:title");
1281
1282 if (metadataTitle) {
1283 if (metadataTitle !== "Untitled" && !/[\uFFF0-\uFFFF]/g.test(metadataTitle)) {
1284 pdfTitle = metadataTitle;
1285 }
1286 }
1287
1288 if (pdfTitle) {
1289 this.setTitle(`${pdfTitle} - ${this._contentDispositionFilename || document.title}`);
1290 } else if (this._contentDispositionFilename) {
1291 this.setTitle(this._contentDispositionFilename);
1292 }
1293
1294 if (info.IsXFAPresent && !info.IsAcroFormPresent && !pdfDocument.isPureXfa) {
1295 if (pdfDocument.loadingParams.enableXfa) {
1296 console.warn("Warning: XFA Foreground documents are not supported");
1297 } else {
1298 console.warn("Warning: XFA support is not enabled");
1299 }
1300
1301 this.fallback(_pdf.UNSUPPORTED_FEATURES.forms);
1302 } else if ((info.IsAcroFormPresent || info.IsXFAPresent) && !this.pdfViewer.renderForms) {
1303 console.warn("Warning: Interactive form support is not enabled");
1304 this.fallback(_pdf.UNSUPPORTED_FEATURES.forms);
1305 }
1306
1307 if (info.IsSignaturesPresent) {
1308 console.warn("Warning: Digital signatures validation is not supported");
1309 this.fallback(_pdf.UNSUPPORTED_FEATURES.signatures);
1310 }
1311
1312 let versionId = "other";
1313
1314 if (KNOWN_VERSIONS.includes(info.PDFFormatVersion)) {
1315 versionId = `v${info.PDFFormatVersion.replace(".", "_")}`;
1316 }
1317
1318 let generatorId = "other";
1319
1320 if (info.Producer) {
1321 const producer = info.Producer.toLowerCase();
1322 KNOWN_GENERATORS.some(function (generator) {
1323 if (!producer.includes(generator)) {
1324 return false;
1325 }
1326
1327 generatorId = generator.replace(/[ .-]/g, "_");
1328 return true;
1329 });
1330 }
1331
1332 let formType = null;
1333
1334 if (info.IsXFAPresent) {
1335 formType = "xfa";
1336 } else if (info.IsAcroFormPresent) {
1337 formType = "acroform";
1338 }
1339
1340 this.externalServices.reportTelemetry({
1341 type: "documentInfo",
1342 version: versionId,
1343 generator: generatorId,
1344 formType
1345 });
1346 this.eventBus.dispatch("metadataloaded", {
1347 source: this
1348 });
1349 },
1350
1351 async _initializePageLabels(pdfDocument) {
1352 const labels = await pdfDocument.getPageLabels();
1353
1354 if (pdfDocument !== this.pdfDocument) {
1355 return;
1356 }
1357
1358 if (!labels || _app_options.AppOptions.get("disablePageLabels")) {
1359 return;
1360 }
1361
1362 const numLabels = labels.length;
1363 let standardLabels = 0,
1364 emptyLabels = 0;
1365
1366 for (let i = 0; i < numLabels; i++) {
1367 const label = labels[i];
1368
1369 if (label === (i + 1).toString()) {
1370 standardLabels++;
1371 } else if (label === "") {
1372 emptyLabels++;
1373 } else {
1374 break;
1375 }
1376 }
1377
1378 if (standardLabels >= numLabels || emptyLabels >= numLabels) {
1379 return;
1380 }
1381
1382 const {
1383 pdfViewer,
1384 pdfThumbnailViewer,
1385 toolbar
1386 } = this;
1387 pdfViewer.setPageLabels(labels);
1388 pdfThumbnailViewer.setPageLabels(labels);
1389 toolbar.setPagesCount(numLabels, true);
1390 toolbar.setPageNumber(pdfViewer.currentPageNumber, pdfViewer.currentPageLabel);
1391 },
1392
1393 _initializePdfHistory({
1394 fingerprint,
1395 viewOnLoad,
1396 initialDest = null
1397 }) {
1398 if (!this.pdfHistory) {
1399 return;
1400 }
1401
1402 this.pdfHistory.initialize({
1403 fingerprint,
1404 resetHistory: viewOnLoad === ViewOnLoad.INITIAL,
1405 updateUrl: _app_options.AppOptions.get("historyUpdateUrl")
1406 });
1407
1408 if (this.pdfHistory.initialBookmark) {
1409 this.initialBookmark = this.pdfHistory.initialBookmark;
1410 this.initialRotation = this.pdfHistory.initialRotation;
1411 }
1412
1413 if (initialDest && !this.initialBookmark && viewOnLoad === ViewOnLoad.UNKNOWN) {
1414 this.initialBookmark = JSON.stringify(initialDest);
1415 this.pdfHistory.push({
1416 explicitDest: initialDest,
1417 pageNumber: null
1418 });
1419 }
1420 },
1421
1422 _initializeAnnotationStorageCallbacks(pdfDocument) {
1423 if (pdfDocument !== this.pdfDocument) {
1424 return;
1425 }
1426
1427 const {
1428 annotationStorage
1429 } = pdfDocument;
1430
1431 annotationStorage.onSetModified = () => {
1432 window.addEventListener("beforeunload", beforeUnload);
1433 this._annotationStorageModified = true;
1434 };
1435
1436 annotationStorage.onResetModified = () => {
1437 window.removeEventListener("beforeunload", beforeUnload);
1438 delete this._annotationStorageModified;
1439 };
1440 },
1441
1442 setInitialView(storedHash, {
1443 rotation,
1444 sidebarView,
1445 scrollMode,
1446 spreadMode
1447 } = {}) {
1448 const setRotation = angle => {
1449 if ((0, _ui_utils.isValidRotation)(angle)) {
1450 this.pdfViewer.pagesRotation = angle;
1451 }
1452 };
1453
1454 const setViewerModes = (scroll, spread) => {
1455 if ((0, _ui_utils.isValidScrollMode)(scroll)) {
1456 this.pdfViewer.scrollMode = scroll;
1457 }
1458
1459 if ((0, _ui_utils.isValidSpreadMode)(spread)) {
1460 this.pdfViewer.spreadMode = spread;
1461 }
1462 };
1463
1464 this.isInitialViewSet = true;
1465 this.pdfSidebar.setInitialView(sidebarView);
1466 setViewerModes(scrollMode, spreadMode);
1467
1468 if (this.initialBookmark) {
1469 setRotation(this.initialRotation);
1470 delete this.initialRotation;
1471 this.pdfLinkService.setHash(this.initialBookmark);
1472 this.initialBookmark = null;
1473 } else if (storedHash) {
1474 setRotation(rotation);
1475 this.pdfLinkService.setHash(storedHash);
1476 }
1477
1478 this.toolbar.setPageNumber(this.pdfViewer.currentPageNumber, this.pdfViewer.currentPageLabel);
1479 this.secondaryToolbar.setPageNumber(this.pdfViewer.currentPageNumber);
1480
1481 if (!this.pdfViewer.currentScaleValue) {
1482 this.pdfViewer.currentScaleValue = _ui_utils.DEFAULT_SCALE_VALUE;
1483 }
1484 },
1485
1486 _cleanup() {
1487 if (!this.pdfDocument) {
1488 return;
1489 }
1490
1491 this.pdfViewer.cleanup();
1492 this.pdfThumbnailViewer.cleanup();
1493 this.pdfDocument.cleanup(this.pdfViewer.renderer === _ui_utils.RendererType.SVG);
1494 },
1495
1496 forceRendering() {
1497 this.pdfRenderingQueue.printing = !!this.printService;
1498 this.pdfRenderingQueue.isThumbnailViewEnabled = this.pdfSidebar.visibleView === _ui_utils.SidebarView.THUMBS;
1499 this.pdfRenderingQueue.renderHighestPriority();
1500 },
1501
1502 beforePrint() {
1503 this._printAnnotationStoragePromise = this.pdfScriptingManager.dispatchWillPrint().catch(() => {}).then(() => {
1504 return this.pdfDocument?.annotationStorage.print;
1505 });
1506
1507 if (this.printService) {
1508 return;
1509 }
1510
1511 if (!this.supportsPrinting) {
1512 this.l10n.get("printing_not_supported").then(msg => {
1513 this._otherError(msg);
1514 });
1515 return;
1516 }
1517
1518 if (!this.pdfViewer.pageViewsReady) {
1519 this.l10n.get("printing_not_ready").then(msg => {
1520 window.alert(msg);
1521 });
1522 return;
1523 }
1524
1525 const pagesOverview = this.pdfViewer.getPagesOverview();
1526 const printContainer = this.appConfig.printContainer;
1527
1528 const printResolution = _app_options.AppOptions.get("printResolution");
1529
1530 const optionalContentConfigPromise = this.pdfViewer.optionalContentConfigPromise;
1531 const printService = PDFPrintServiceFactory.instance.createPrintService(this.pdfDocument, pagesOverview, printContainer, printResolution, optionalContentConfigPromise, this._printAnnotationStoragePromise, this.l10n);
1532 this.printService = printService;
1533 this.forceRendering();
1534 printService.layout();
1535 this.externalServices.reportTelemetry({
1536 type: "print"
1537 });
1538 },
1539
1540 afterPrint() {
1541 if (this._printAnnotationStoragePromise) {
1542 this._printAnnotationStoragePromise.then(() => {
1543 this.pdfScriptingManager.dispatchDidPrint();
1544 });
1545
1546 this._printAnnotationStoragePromise = null;
1547 }
1548
1549 if (this.printService) {
1550 this.printService.destroy();
1551 this.printService = null;
1552 this.pdfDocument?.annotationStorage.resetModified();
1553 }
1554
1555 this.forceRendering();
1556 },
1557
1558 rotatePages(delta) {
1559 this.pdfViewer.pagesRotation += delta;
1560 },
1561
1562 requestPresentationMode() {
1563 this.pdfPresentationMode?.request();
1564 },
1565
1566 triggerPrinting() {
1567 if (!this.supportsPrinting) {
1568 return;
1569 }
1570
1571 window.print();
1572 },
1573
1574 bindEvents() {
1575 const {
1576 eventBus,
1577 _boundEvents
1578 } = this;
1579 _boundEvents.beforePrint = this.beforePrint.bind(this);
1580 _boundEvents.afterPrint = this.afterPrint.bind(this);
1581
1582 eventBus._on("resize", webViewerResize);
1583
1584 eventBus._on("hashchange", webViewerHashchange);
1585
1586 eventBus._on("beforeprint", _boundEvents.beforePrint);
1587
1588 eventBus._on("afterprint", _boundEvents.afterPrint);
1589
1590 eventBus._on("pagerendered", webViewerPageRendered);
1591
1592 eventBus._on("updateviewarea", webViewerUpdateViewarea);
1593
1594 eventBus._on("pagechanging", webViewerPageChanging);
1595
1596 eventBus._on("scalechanging", webViewerScaleChanging);
1597
1598 eventBus._on("rotationchanging", webViewerRotationChanging);
1599
1600 eventBus._on("sidebarviewchanged", webViewerSidebarViewChanged);
1601
1602 eventBus._on("pagemode", webViewerPageMode);
1603
1604 eventBus._on("namedaction", webViewerNamedAction);
1605
1606 eventBus._on("presentationmodechanged", webViewerPresentationModeChanged);
1607
1608 eventBus._on("presentationmode", webViewerPresentationMode);
1609
1610 eventBus._on("switchannotationeditormode", webViewerSwitchAnnotationEditorMode);
1611
1612 eventBus._on("switchannotationeditorparams", webViewerSwitchAnnotationEditorParams);
1613
1614 eventBus._on("print", webViewerPrint);
1615
1616 eventBus._on("download", webViewerDownload);
1617
1618 eventBus._on("firstpage", webViewerFirstPage);
1619
1620 eventBus._on("lastpage", webViewerLastPage);
1621
1622 eventBus._on("nextpage", webViewerNextPage);
1623
1624 eventBus._on("previouspage", webViewerPreviousPage);
1625
1626 eventBus._on("zoomin", webViewerZoomIn);
1627
1628 eventBus._on("zoomout", webViewerZoomOut);
1629
1630 eventBus._on("zoomreset", webViewerZoomReset);
1631
1632 eventBus._on("pagenumberchanged", webViewerPageNumberChanged);
1633
1634 eventBus._on("scalechanged", webViewerScaleChanged);
1635
1636 eventBus._on("rotatecw", webViewerRotateCw);
1637
1638 eventBus._on("rotateccw", webViewerRotateCcw);
1639
1640 eventBus._on("optionalcontentconfig", webViewerOptionalContentConfig);
1641
1642 eventBus._on("switchscrollmode", webViewerSwitchScrollMode);
1643
1644 eventBus._on("scrollmodechanged", webViewerScrollModeChanged);
1645
1646 eventBus._on("switchspreadmode", webViewerSwitchSpreadMode);
1647
1648 eventBus._on("spreadmodechanged", webViewerSpreadModeChanged);
1649
1650 eventBus._on("documentproperties", webViewerDocumentProperties);
1651
1652 eventBus._on("findfromurlhash", webViewerFindFromUrlHash);
1653
1654 eventBus._on("updatefindmatchescount", webViewerUpdateFindMatchesCount);
1655
1656 eventBus._on("updatefindcontrolstate", webViewerUpdateFindControlState);
1657
1658 if (_app_options.AppOptions.get("pdfBug")) {
1659 _boundEvents.reportPageStatsPDFBug = reportPageStatsPDFBug;
1660
1661 eventBus._on("pagerendered", _boundEvents.reportPageStatsPDFBug);
1662
1663 eventBus._on("pagechanging", _boundEvents.reportPageStatsPDFBug);
1664 }
1665
1666 eventBus._on("fileinputchange", webViewerFileInputChange);
1667
1668 eventBus._on("openfile", webViewerOpenFile);
1669 },
1670
1671 bindWindowEvents() {
1672 const {
1673 eventBus,
1674 _boundEvents
1675 } = this;
1676
1677 _boundEvents.windowResize = () => {
1678 eventBus.dispatch("resize", {
1679 source: window
1680 });
1681 };
1682
1683 _boundEvents.windowHashChange = () => {
1684 eventBus.dispatch("hashchange", {
1685 source: window,
1686 hash: document.location.hash.substring(1)
1687 });
1688 };
1689
1690 _boundEvents.windowBeforePrint = () => {
1691 eventBus.dispatch("beforeprint", {
1692 source: window
1693 });
1694 };
1695
1696 _boundEvents.windowAfterPrint = () => {
1697 eventBus.dispatch("afterprint", {
1698 source: window
1699 });
1700 };
1701
1702 _boundEvents.windowUpdateFromSandbox = event => {
1703 eventBus.dispatch("updatefromsandbox", {
1704 source: window,
1705 detail: event.detail
1706 });
1707 };
1708
1709 window.addEventListener("visibilitychange", webViewerVisibilityChange);
1710 window.addEventListener("wheel", webViewerWheel, {
1711 passive: false
1712 });
1713 window.addEventListener("touchstart", webViewerTouchStart, {
1714 passive: false
1715 });
1716 window.addEventListener("click", webViewerClick);
1717 window.addEventListener("keydown", webViewerKeyDown);
1718 window.addEventListener("resize", _boundEvents.windowResize);
1719 window.addEventListener("hashchange", _boundEvents.windowHashChange);
1720 window.addEventListener("beforeprint", _boundEvents.windowBeforePrint);
1721 window.addEventListener("afterprint", _boundEvents.windowAfterPrint);
1722 window.addEventListener("updatefromsandbox", _boundEvents.windowUpdateFromSandbox);
1723 },
1724
1725 unbindEvents() {
1726 const {
1727 eventBus,
1728 _boundEvents
1729 } = this;
1730
1731 eventBus._off("resize", webViewerResize);
1732
1733 eventBus._off("hashchange", webViewerHashchange);
1734
1735 eventBus._off("beforeprint", _boundEvents.beforePrint);
1736
1737 eventBus._off("afterprint", _boundEvents.afterPrint);
1738
1739 eventBus._off("pagerendered", webViewerPageRendered);
1740
1741 eventBus._off("updateviewarea", webViewerUpdateViewarea);
1742
1743 eventBus._off("pagechanging", webViewerPageChanging);
1744
1745 eventBus._off("scalechanging", webViewerScaleChanging);
1746
1747 eventBus._off("rotationchanging", webViewerRotationChanging);
1748
1749 eventBus._off("sidebarviewchanged", webViewerSidebarViewChanged);
1750
1751 eventBus._off("pagemode", webViewerPageMode);
1752
1753 eventBus._off("namedaction", webViewerNamedAction);
1754
1755 eventBus._off("presentationmodechanged", webViewerPresentationModeChanged);
1756
1757 eventBus._off("presentationmode", webViewerPresentationMode);
1758
1759 eventBus._off("print", webViewerPrint);
1760
1761 eventBus._off("download", webViewerDownload);
1762
1763 eventBus._off("firstpage", webViewerFirstPage);
1764
1765 eventBus._off("lastpage", webViewerLastPage);
1766
1767 eventBus._off("nextpage", webViewerNextPage);
1768
1769 eventBus._off("previouspage", webViewerPreviousPage);
1770
1771 eventBus._off("zoomin", webViewerZoomIn);
1772
1773 eventBus._off("zoomout", webViewerZoomOut);
1774
1775 eventBus._off("zoomreset", webViewerZoomReset);
1776
1777 eventBus._off("pagenumberchanged", webViewerPageNumberChanged);
1778
1779 eventBus._off("scalechanged", webViewerScaleChanged);
1780
1781 eventBus._off("rotatecw", webViewerRotateCw);
1782
1783 eventBus._off("rotateccw", webViewerRotateCcw);
1784
1785 eventBus._off("optionalcontentconfig", webViewerOptionalContentConfig);
1786
1787 eventBus._off("switchscrollmode", webViewerSwitchScrollMode);
1788
1789 eventBus._off("scrollmodechanged", webViewerScrollModeChanged);
1790
1791 eventBus._off("switchspreadmode", webViewerSwitchSpreadMode);
1792
1793 eventBus._off("spreadmodechanged", webViewerSpreadModeChanged);
1794
1795 eventBus._off("documentproperties", webViewerDocumentProperties);
1796
1797 eventBus._off("findfromurlhash", webViewerFindFromUrlHash);
1798
1799 eventBus._off("updatefindmatchescount", webViewerUpdateFindMatchesCount);
1800
1801 eventBus._off("updatefindcontrolstate", webViewerUpdateFindControlState);
1802
1803 if (_boundEvents.reportPageStatsPDFBug) {
1804 eventBus._off("pagerendered", _boundEvents.reportPageStatsPDFBug);
1805
1806 eventBus._off("pagechanging", _boundEvents.reportPageStatsPDFBug);
1807
1808 _boundEvents.reportPageStatsPDFBug = null;
1809 }
1810
1811 eventBus._off("fileinputchange", webViewerFileInputChange);
1812
1813 eventBus._off("openfile", webViewerOpenFile);
1814
1815 _boundEvents.beforePrint = null;
1816 _boundEvents.afterPrint = null;
1817 },
1818
1819 unbindWindowEvents() {
1820 const {
1821 _boundEvents
1822 } = this;
1823 window.removeEventListener("visibilitychange", webViewerVisibilityChange);
1824 window.removeEventListener("wheel", webViewerWheel, {
1825 passive: false
1826 });
1827 window.removeEventListener("touchstart", webViewerTouchStart, {
1828 passive: false
1829 });
1830 window.removeEventListener("click", webViewerClick);
1831 window.removeEventListener("keydown", webViewerKeyDown);
1832 window.removeEventListener("resize", _boundEvents.windowResize);
1833 window.removeEventListener("hashchange", _boundEvents.windowHashChange);
1834 window.removeEventListener("beforeprint", _boundEvents.windowBeforePrint);
1835 window.removeEventListener("afterprint", _boundEvents.windowAfterPrint);
1836 window.removeEventListener("updatefromsandbox", _boundEvents.windowUpdateFromSandbox);
1837 _boundEvents.windowResize = null;
1838 _boundEvents.windowHashChange = null;
1839 _boundEvents.windowBeforePrint = null;
1840 _boundEvents.windowAfterPrint = null;
1841 _boundEvents.windowUpdateFromSandbox = null;
1842 },
1843
1844 accumulateWheelTicks(ticks) {
1845 if (this._wheelUnusedTicks > 0 && ticks < 0 || this._wheelUnusedTicks < 0 && ticks > 0) {
1846 this._wheelUnusedTicks = 0;
1847 }
1848
1849 this._wheelUnusedTicks += ticks;
1850 const wholeTicks = Math.sign(this._wheelUnusedTicks) * Math.floor(Math.abs(this._wheelUnusedTicks));
1851 this._wheelUnusedTicks -= wholeTicks;
1852 return wholeTicks;
1853 },
1854
1855 _unblockDocumentLoadEvent() {
1856 document.blockUnblockOnload?.(false);
1857
1858 this._unblockDocumentLoadEvent = () => {};
1859 },
1860
1861 _reportDocumentStatsTelemetry() {
1862 const {
1863 stats
1864 } = this.pdfDocument;
1865
1866 if (stats !== this._docStats) {
1867 this._docStats = stats;
1868 this.externalServices.reportTelemetry({
1869 type: "documentStats",
1870 stats
1871 });
1872 }
1873 },
1874
1875 get scriptingReady() {
1876 return this.pdfScriptingManager.ready;
1877 }
1878
1879};
1880exports.PDFViewerApplication = PDFViewerApplication;
1881let validateFileURL;
1882{
1883 const HOSTED_VIEWER_ORIGINS = ["null", "http://mozilla.github.io", "https://mozilla.github.io"];
1884
1885 validateFileURL = function (file) {
1886 if (!file) {
1887 return;
1888 }
1889
1890 try {
1891 const viewerOrigin = new URL(window.location.href).origin || "null";
1892
1893 if (HOSTED_VIEWER_ORIGINS.includes(viewerOrigin)) {
1894 return;
1895 }
1896
1897 const fileOrigin = new URL(file, window.location.href).origin;
1898
1899 if (fileOrigin !== viewerOrigin) {
1900 throw new Error("file origin does not match viewer's");
1901 }
1902 } catch (ex) {
1903 PDFViewerApplication.l10n.get("loading_error").then(msg => {
1904 PDFViewerApplication._documentError(msg, {
1905 message: ex?.message
1906 });
1907 });
1908 throw ex;
1909 }
1910 };
1911}
1912
1913async function loadFakeWorker() {
1914 _pdf.GlobalWorkerOptions.workerSrc ||= _app_options.AppOptions.get("workerSrc");
1915 await (0, _pdf.loadScript)(_pdf.PDFWorker.workerSrc);
1916}
1917
1918async function loadPDFBug(self) {
1919 const {
1920 debuggerScriptPath
1921 } = self.appConfig;
1922 const {
1923 PDFBug
1924 } = await import(debuggerScriptPath);
1925 self._PDFBug = PDFBug;
1926}
1927
1928function reportPageStatsPDFBug({
1929 pageNumber
1930}) {
1931 if (!globalThis.Stats?.enabled) {
1932 return;
1933 }
1934
1935 const pageView = PDFViewerApplication.pdfViewer.getPageView(pageNumber - 1);
1936 globalThis.Stats.add(pageNumber, pageView?.pdfPage?.stats);
1937}
1938
1939function webViewerInitialized() {
1940 const {
1941 appConfig,
1942 eventBus
1943 } = PDFViewerApplication;
1944 let file;
1945 const queryString = document.location.search.substring(1);
1946 const params = (0, _ui_utils.parseQueryString)(queryString);
1947 file = params.get("file") ?? _app_options.AppOptions.get("defaultUrl");
1948 validateFileURL(file);
1949 const fileInput = appConfig.openFileInput;
1950 fileInput.value = null;
1951 fileInput.addEventListener("change", function (evt) {
1952 const {
1953 files
1954 } = evt.target;
1955
1956 if (!files || files.length === 0) {
1957 return;
1958 }
1959
1960 eventBus.dispatch("fileinputchange", {
1961 source: this,
1962 fileInput: evt.target
1963 });
1964 });
1965 appConfig.mainContainer.addEventListener("dragover", function (evt) {
1966 evt.preventDefault();
1967 evt.dataTransfer.dropEffect = evt.dataTransfer.effectAllowed === "copy" ? "copy" : "move";
1968 });
1969 appConfig.mainContainer.addEventListener("drop", function (evt) {
1970 evt.preventDefault();
1971 const {
1972 files
1973 } = evt.dataTransfer;
1974
1975 if (!files || files.length === 0) {
1976 return;
1977 }
1978
1979 eventBus.dispatch("fileinputchange", {
1980 source: this,
1981 fileInput: evt.dataTransfer
1982 });
1983 });
1984
1985 if (!PDFViewerApplication.supportsDocumentFonts) {
1986 _app_options.AppOptions.set("disableFontFace", true);
1987
1988 PDFViewerApplication.l10n.get("web_fonts_disabled").then(msg => {
1989 console.warn(msg);
1990 });
1991 }
1992
1993 if (!PDFViewerApplication.supportsPrinting) {
1994 appConfig.toolbar.print.classList.add("hidden");
1995 appConfig.secondaryToolbar.printButton.classList.add("hidden");
1996 }
1997
1998 if (!PDFViewerApplication.supportsFullscreen) {
1999 appConfig.toolbar.presentationModeButton.classList.add("hidden");
2000 appConfig.secondaryToolbar.presentationModeButton.classList.add("hidden");
2001 }
2002
2003 if (PDFViewerApplication.supportsIntegratedFind) {
2004 appConfig.toolbar.viewFind.classList.add("hidden");
2005 }
2006
2007 appConfig.mainContainer.addEventListener("transitionend", function (evt) {
2008 if (evt.target === this) {
2009 eventBus.dispatch("resize", {
2010 source: this
2011 });
2012 }
2013 }, true);
2014
2015 try {
2016 if (file) {
2017 PDFViewerApplication.open(file);
2018 } else {
2019 PDFViewerApplication._hideViewBookmark();
2020 }
2021 } catch (reason) {
2022 PDFViewerApplication.l10n.get("loading_error").then(msg => {
2023 PDFViewerApplication._documentError(msg, reason);
2024 });
2025 }
2026}
2027
2028function webViewerPageRendered({
2029 pageNumber,
2030 error
2031}) {
2032 if (pageNumber === PDFViewerApplication.page) {
2033 PDFViewerApplication.toolbar.updateLoadingIndicatorState(false);
2034 }
2035
2036 if (PDFViewerApplication.pdfSidebar.visibleView === _ui_utils.SidebarView.THUMBS) {
2037 const pageView = PDFViewerApplication.pdfViewer.getPageView(pageNumber - 1);
2038 const thumbnailView = PDFViewerApplication.pdfThumbnailViewer.getThumbnail(pageNumber - 1);
2039
2040 if (pageView && thumbnailView) {
2041 thumbnailView.setImage(pageView);
2042 }
2043 }
2044
2045 if (error) {
2046 PDFViewerApplication.l10n.get("rendering_error").then(msg => {
2047 PDFViewerApplication._otherError(msg, error);
2048 });
2049 }
2050
2051 PDFViewerApplication._reportDocumentStatsTelemetry();
2052}
2053
2054function webViewerPageMode({
2055 mode
2056}) {
2057 let view;
2058
2059 switch (mode) {
2060 case "thumbs":
2061 view = _ui_utils.SidebarView.THUMBS;
2062 break;
2063
2064 case "bookmarks":
2065 case "outline":
2066 view = _ui_utils.SidebarView.OUTLINE;
2067 break;
2068
2069 case "attachments":
2070 view = _ui_utils.SidebarView.ATTACHMENTS;
2071 break;
2072
2073 case "layers":
2074 view = _ui_utils.SidebarView.LAYERS;
2075 break;
2076
2077 case "none":
2078 view = _ui_utils.SidebarView.NONE;
2079 break;
2080
2081 default:
2082 console.error('Invalid "pagemode" hash parameter: ' + mode);
2083 return;
2084 }
2085
2086 PDFViewerApplication.pdfSidebar.switchView(view, true);
2087}
2088
2089function webViewerNamedAction(evt) {
2090 switch (evt.action) {
2091 case "GoToPage":
2092 PDFViewerApplication.appConfig.toolbar.pageNumber.select();
2093 break;
2094
2095 case "Find":
2096 if (!PDFViewerApplication.supportsIntegratedFind) {
2097 PDFViewerApplication.findBar.toggle();
2098 }
2099
2100 break;
2101
2102 case "Print":
2103 PDFViewerApplication.triggerPrinting();
2104 break;
2105
2106 case "SaveAs":
2107 PDFViewerApplication.downloadOrSave();
2108 break;
2109 }
2110}
2111
2112function webViewerPresentationModeChanged(evt) {
2113 PDFViewerApplication.pdfViewer.presentationModeState = evt.state;
2114}
2115
2116function webViewerSidebarViewChanged({
2117 view
2118}) {
2119 PDFViewerApplication.pdfRenderingQueue.isThumbnailViewEnabled = view === _ui_utils.SidebarView.THUMBS;
2120
2121 if (PDFViewerApplication.isInitialViewSet) {
2122 PDFViewerApplication.store?.set("sidebarView", view).catch(() => {});
2123 }
2124}
2125
2126function webViewerUpdateViewarea({
2127 location
2128}) {
2129 if (PDFViewerApplication.isInitialViewSet) {
2130 PDFViewerApplication.store?.setMultiple({
2131 page: location.pageNumber,
2132 zoom: location.scale,
2133 scrollLeft: location.left,
2134 scrollTop: location.top,
2135 rotation: location.rotation
2136 }).catch(() => {});
2137 }
2138
2139 const href = PDFViewerApplication.pdfLinkService.getAnchorUrl(location.pdfOpenParams);
2140 PDFViewerApplication.appConfig.toolbar.viewBookmark.href = href;
2141 PDFViewerApplication.appConfig.secondaryToolbar.viewBookmarkButton.href = href;
2142 const currentPage = PDFViewerApplication.pdfViewer.getPageView(PDFViewerApplication.page - 1);
2143 const loading = currentPage?.renderingState !== _ui_utils.RenderingStates.FINISHED;
2144 PDFViewerApplication.toolbar.updateLoadingIndicatorState(loading);
2145}
2146
2147function webViewerScrollModeChanged(evt) {
2148 if (PDFViewerApplication.isInitialViewSet) {
2149 PDFViewerApplication.store?.set("scrollMode", evt.mode).catch(() => {});
2150 }
2151}
2152
2153function webViewerSpreadModeChanged(evt) {
2154 if (PDFViewerApplication.isInitialViewSet) {
2155 PDFViewerApplication.store?.set("spreadMode", evt.mode).catch(() => {});
2156 }
2157}
2158
2159function webViewerResize() {
2160 const {
2161 pdfDocument,
2162 pdfViewer
2163 } = PDFViewerApplication;
2164 pdfViewer.updateContainerHeightCss();
2165
2166 if (!pdfDocument) {
2167 return;
2168 }
2169
2170 const currentScaleValue = pdfViewer.currentScaleValue;
2171
2172 if (currentScaleValue === "auto" || currentScaleValue === "page-fit" || currentScaleValue === "page-width") {
2173 pdfViewer.currentScaleValue = currentScaleValue;
2174 }
2175
2176 pdfViewer.update();
2177}
2178
2179function webViewerHashchange(evt) {
2180 const hash = evt.hash;
2181
2182 if (!hash) {
2183 return;
2184 }
2185
2186 if (!PDFViewerApplication.isInitialViewSet) {
2187 PDFViewerApplication.initialBookmark = hash;
2188 } else if (!PDFViewerApplication.pdfHistory?.popStateInProgress) {
2189 PDFViewerApplication.pdfLinkService.setHash(hash);
2190 }
2191}
2192
2193{
2194 var webViewerFileInputChange = function (evt) {
2195 if (PDFViewerApplication.pdfViewer?.isInPresentationMode) {
2196 return;
2197 }
2198
2199 const file = evt.fileInput.files[0];
2200 let url = URL.createObjectURL(file);
2201
2202 if (file.name) {
2203 url = {
2204 url,
2205 originalUrl: file.name
2206 };
2207 }
2208
2209 PDFViewerApplication.open(url);
2210 };
2211
2212 var webViewerOpenFile = function (evt) {
2213 const fileInput = PDFViewerApplication.appConfig.openFileInput;
2214 fileInput.click();
2215 };
2216}
2217
2218function webViewerPresentationMode() {
2219 PDFViewerApplication.requestPresentationMode();
2220}
2221
2222function webViewerSwitchAnnotationEditorMode(evt) {
2223 PDFViewerApplication.pdfViewer.annotationEditorMode = evt.mode;
2224}
2225
2226function webViewerSwitchAnnotationEditorParams(evt) {
2227 PDFViewerApplication.pdfViewer.annotationEditorParams = evt;
2228}
2229
2230function webViewerPrint() {
2231 PDFViewerApplication.triggerPrinting();
2232}
2233
2234function webViewerDownload() {
2235 PDFViewerApplication.downloadOrSave();
2236}
2237
2238function webViewerFirstPage() {
2239 if (PDFViewerApplication.pdfDocument) {
2240 PDFViewerApplication.page = 1;
2241 }
2242}
2243
2244function webViewerLastPage() {
2245 if (PDFViewerApplication.pdfDocument) {
2246 PDFViewerApplication.page = PDFViewerApplication.pagesCount;
2247 }
2248}
2249
2250function webViewerNextPage() {
2251 PDFViewerApplication.pdfViewer.nextPage();
2252}
2253
2254function webViewerPreviousPage() {
2255 PDFViewerApplication.pdfViewer.previousPage();
2256}
2257
2258function webViewerZoomIn() {
2259 PDFViewerApplication.zoomIn();
2260}
2261
2262function webViewerZoomOut() {
2263 PDFViewerApplication.zoomOut();
2264}
2265
2266function webViewerZoomReset() {
2267 PDFViewerApplication.zoomReset();
2268}
2269
2270function webViewerPageNumberChanged(evt) {
2271 const pdfViewer = PDFViewerApplication.pdfViewer;
2272
2273 if (evt.value !== "") {
2274 PDFViewerApplication.pdfLinkService.goToPage(evt.value);
2275 }
2276
2277 if (evt.value !== pdfViewer.currentPageNumber.toString() && evt.value !== pdfViewer.currentPageLabel) {
2278 PDFViewerApplication.toolbar.setPageNumber(pdfViewer.currentPageNumber, pdfViewer.currentPageLabel);
2279 }
2280}
2281
2282function webViewerScaleChanged(evt) {
2283 PDFViewerApplication.pdfViewer.currentScaleValue = evt.value;
2284}
2285
2286function webViewerRotateCw() {
2287 PDFViewerApplication.rotatePages(90);
2288}
2289
2290function webViewerRotateCcw() {
2291 PDFViewerApplication.rotatePages(-90);
2292}
2293
2294function webViewerOptionalContentConfig(evt) {
2295 PDFViewerApplication.pdfViewer.optionalContentConfigPromise = evt.promise;
2296}
2297
2298function webViewerSwitchScrollMode(evt) {
2299 PDFViewerApplication.pdfViewer.scrollMode = evt.mode;
2300}
2301
2302function webViewerSwitchSpreadMode(evt) {
2303 PDFViewerApplication.pdfViewer.spreadMode = evt.mode;
2304}
2305
2306function webViewerDocumentProperties() {
2307 PDFViewerApplication.pdfDocumentProperties.open();
2308}
2309
2310function webViewerFindFromUrlHash(evt) {
2311 PDFViewerApplication.eventBus.dispatch("find", {
2312 source: evt.source,
2313 type: "",
2314 query: evt.query,
2315 phraseSearch: evt.phraseSearch,
2316 caseSensitive: false,
2317 entireWord: false,
2318 highlightAll: true,
2319 findPrevious: false,
2320 matchDiacritics: true
2321 });
2322}
2323
2324function webViewerUpdateFindMatchesCount({
2325 matchesCount
2326}) {
2327 if (PDFViewerApplication.supportsIntegratedFind) {
2328 PDFViewerApplication.externalServices.updateFindMatchesCount(matchesCount);
2329 } else {
2330 PDFViewerApplication.findBar.updateResultsCount(matchesCount);
2331 }
2332}
2333
2334function webViewerUpdateFindControlState({
2335 state,
2336 previous,
2337 matchesCount,
2338 rawQuery
2339}) {
2340 if (PDFViewerApplication.supportsIntegratedFind) {
2341 PDFViewerApplication.externalServices.updateFindControlState({
2342 result: state,
2343 findPrevious: previous,
2344 matchesCount,
2345 rawQuery
2346 });
2347 } else {
2348 PDFViewerApplication.findBar.updateUIState(state, previous, matchesCount);
2349 }
2350}
2351
2352function webViewerScaleChanging(evt) {
2353 PDFViewerApplication.toolbar.setPageScale(evt.presetValue, evt.scale);
2354 PDFViewerApplication.pdfViewer.update();
2355}
2356
2357function webViewerRotationChanging(evt) {
2358 PDFViewerApplication.pdfThumbnailViewer.pagesRotation = evt.pagesRotation;
2359 PDFViewerApplication.forceRendering();
2360 PDFViewerApplication.pdfViewer.currentPageNumber = evt.pageNumber;
2361}
2362
2363function webViewerPageChanging({
2364 pageNumber,
2365 pageLabel
2366}) {
2367 PDFViewerApplication.toolbar.setPageNumber(pageNumber, pageLabel);
2368 PDFViewerApplication.secondaryToolbar.setPageNumber(pageNumber);
2369
2370 if (PDFViewerApplication.pdfSidebar.visibleView === _ui_utils.SidebarView.THUMBS) {
2371 PDFViewerApplication.pdfThumbnailViewer.scrollThumbnailIntoView(pageNumber);
2372 }
2373}
2374
2375function webViewerVisibilityChange(evt) {
2376 if (document.visibilityState === "visible") {
2377 setZoomDisabledTimeout();
2378 }
2379}
2380
2381let zoomDisabledTimeout = null;
2382
2383function setZoomDisabledTimeout() {
2384 if (zoomDisabledTimeout) {
2385 clearTimeout(zoomDisabledTimeout);
2386 }
2387
2388 zoomDisabledTimeout = setTimeout(function () {
2389 zoomDisabledTimeout = null;
2390 }, WHEEL_ZOOM_DISABLED_TIMEOUT);
2391}
2392
2393function webViewerWheel(evt) {
2394 const {
2395 pdfViewer,
2396 supportedMouseWheelZoomModifierKeys
2397 } = PDFViewerApplication;
2398
2399 if (pdfViewer.isInPresentationMode) {
2400 return;
2401 }
2402
2403 if (evt.ctrlKey && supportedMouseWheelZoomModifierKeys.ctrlKey || evt.metaKey && supportedMouseWheelZoomModifierKeys.metaKey) {
2404 evt.preventDefault();
2405
2406 if (zoomDisabledTimeout || document.visibilityState === "hidden") {
2407 return;
2408 }
2409
2410 const deltaMode = evt.deltaMode;
2411 const delta = (0, _ui_utils.normalizeWheelEventDirection)(evt);
2412 const previousScale = pdfViewer.currentScale;
2413 let ticks = 0;
2414
2415 if (deltaMode === WheelEvent.DOM_DELTA_LINE || deltaMode === WheelEvent.DOM_DELTA_PAGE) {
2416 if (Math.abs(delta) >= 1) {
2417 ticks = Math.sign(delta);
2418 } else {
2419 ticks = PDFViewerApplication.accumulateWheelTicks(delta);
2420 }
2421 } else {
2422 const PIXELS_PER_LINE_SCALE = 30;
2423 ticks = PDFViewerApplication.accumulateWheelTicks(delta / PIXELS_PER_LINE_SCALE);
2424 }
2425
2426 if (ticks < 0) {
2427 PDFViewerApplication.zoomOut(-ticks);
2428 } else if (ticks > 0) {
2429 PDFViewerApplication.zoomIn(ticks);
2430 }
2431
2432 const currentScale = pdfViewer.currentScale;
2433
2434 if (previousScale !== currentScale) {
2435 const scaleCorrectionFactor = currentScale / previousScale - 1;
2436 const rect = pdfViewer.container.getBoundingClientRect();
2437 const dx = evt.clientX - rect.left;
2438 const dy = evt.clientY - rect.top;
2439 pdfViewer.container.scrollLeft += dx * scaleCorrectionFactor;
2440 pdfViewer.container.scrollTop += dy * scaleCorrectionFactor;
2441 }
2442 } else {
2443 setZoomDisabledTimeout();
2444 }
2445}
2446
2447function webViewerTouchStart(evt) {
2448 if (evt.touches.length > 1) {
2449 evt.preventDefault();
2450 }
2451}
2452
2453function webViewerClick(evt) {
2454 if (!PDFViewerApplication.secondaryToolbar.isOpen) {
2455 return;
2456 }
2457
2458 const appConfig = PDFViewerApplication.appConfig;
2459
2460 if (PDFViewerApplication.pdfViewer.containsElement(evt.target) || appConfig.toolbar.container.contains(evt.target) && evt.target !== appConfig.secondaryToolbar.toggleButton) {
2461 PDFViewerApplication.secondaryToolbar.close();
2462 }
2463}
2464
2465function webViewerKeyDown(evt) {
2466 if (PDFViewerApplication.overlayManager.active) {
2467 return;
2468 }
2469
2470 const {
2471 eventBus,
2472 pdfViewer
2473 } = PDFViewerApplication;
2474 const isViewerInPresentationMode = pdfViewer.isInPresentationMode;
2475 let handled = false,
2476 ensureViewerFocused = false;
2477 const cmd = (evt.ctrlKey ? 1 : 0) | (evt.altKey ? 2 : 0) | (evt.shiftKey ? 4 : 0) | (evt.metaKey ? 8 : 0);
2478
2479 if (cmd === 1 || cmd === 8 || cmd === 5 || cmd === 12) {
2480 switch (evt.keyCode) {
2481 case 70:
2482 if (!PDFViewerApplication.supportsIntegratedFind && !evt.shiftKey) {
2483 PDFViewerApplication.findBar.open();
2484 handled = true;
2485 }
2486
2487 break;
2488
2489 case 71:
2490 if (!PDFViewerApplication.supportsIntegratedFind) {
2491 const {
2492 state
2493 } = PDFViewerApplication.findController;
2494
2495 if (state) {
2496 const eventState = Object.assign(Object.create(null), state, {
2497 source: window,
2498 type: "again",
2499 findPrevious: cmd === 5 || cmd === 12
2500 });
2501 eventBus.dispatch("find", eventState);
2502 }
2503
2504 handled = true;
2505 }
2506
2507 break;
2508
2509 case 61:
2510 case 107:
2511 case 187:
2512 case 171:
2513 if (!isViewerInPresentationMode) {
2514 PDFViewerApplication.zoomIn();
2515 }
2516
2517 handled = true;
2518 break;
2519
2520 case 173:
2521 case 109:
2522 case 189:
2523 if (!isViewerInPresentationMode) {
2524 PDFViewerApplication.zoomOut();
2525 }
2526
2527 handled = true;
2528 break;
2529
2530 case 48:
2531 case 96:
2532 if (!isViewerInPresentationMode) {
2533 setTimeout(function () {
2534 PDFViewerApplication.zoomReset();
2535 });
2536 handled = false;
2537 }
2538
2539 break;
2540
2541 case 38:
2542 if (isViewerInPresentationMode || PDFViewerApplication.page > 1) {
2543 PDFViewerApplication.page = 1;
2544 handled = true;
2545 ensureViewerFocused = true;
2546 }
2547
2548 break;
2549
2550 case 40:
2551 if (isViewerInPresentationMode || PDFViewerApplication.page < PDFViewerApplication.pagesCount) {
2552 PDFViewerApplication.page = PDFViewerApplication.pagesCount;
2553 handled = true;
2554 ensureViewerFocused = true;
2555 }
2556
2557 break;
2558 }
2559 }
2560
2561 if (cmd === 1 || cmd === 8) {
2562 switch (evt.keyCode) {
2563 case 83:
2564 eventBus.dispatch("download", {
2565 source: window
2566 });
2567 handled = true;
2568 break;
2569
2570 case 79:
2571 {
2572 eventBus.dispatch("openfile", {
2573 source: window
2574 });
2575 handled = true;
2576 }
2577 break;
2578 }
2579 }
2580
2581 if (cmd === 3 || cmd === 10) {
2582 switch (evt.keyCode) {
2583 case 80:
2584 PDFViewerApplication.requestPresentationMode();
2585 handled = true;
2586 break;
2587
2588 case 71:
2589 PDFViewerApplication.appConfig.toolbar.pageNumber.select();
2590 handled = true;
2591 break;
2592 }
2593 }
2594
2595 if (handled) {
2596 if (ensureViewerFocused && !isViewerInPresentationMode) {
2597 pdfViewer.focus();
2598 }
2599
2600 evt.preventDefault();
2601 return;
2602 }
2603
2604 const curElement = (0, _ui_utils.getActiveOrFocusedElement)();
2605 const curElementTagName = curElement?.tagName.toUpperCase();
2606
2607 if (curElementTagName === "INPUT" || curElementTagName === "TEXTAREA" || curElementTagName === "SELECT" || curElement?.isContentEditable) {
2608 if (evt.keyCode !== 27) {
2609 return;
2610 }
2611 }
2612
2613 if (cmd === 0) {
2614 let turnPage = 0,
2615 turnOnlyIfPageFit = false;
2616
2617 switch (evt.keyCode) {
2618 case 38:
2619 case 33:
2620 if (pdfViewer.isVerticalScrollbarEnabled) {
2621 turnOnlyIfPageFit = true;
2622 }
2623
2624 turnPage = -1;
2625 break;
2626
2627 case 8:
2628 if (!isViewerInPresentationMode) {
2629 turnOnlyIfPageFit = true;
2630 }
2631
2632 turnPage = -1;
2633 break;
2634
2635 case 37:
2636 if (pdfViewer.isHorizontalScrollbarEnabled) {
2637 turnOnlyIfPageFit = true;
2638 }
2639
2640 case 75:
2641 case 80:
2642 turnPage = -1;
2643 break;
2644
2645 case 27:
2646 if (PDFViewerApplication.secondaryToolbar.isOpen) {
2647 PDFViewerApplication.secondaryToolbar.close();
2648 handled = true;
2649 }
2650
2651 if (!PDFViewerApplication.supportsIntegratedFind && PDFViewerApplication.findBar.opened) {
2652 PDFViewerApplication.findBar.close();
2653 handled = true;
2654 }
2655
2656 break;
2657
2658 case 40:
2659 case 34:
2660 if (pdfViewer.isVerticalScrollbarEnabled) {
2661 turnOnlyIfPageFit = true;
2662 }
2663
2664 turnPage = 1;
2665 break;
2666
2667 case 13:
2668 case 32:
2669 if (!isViewerInPresentationMode) {
2670 turnOnlyIfPageFit = true;
2671 }
2672
2673 turnPage = 1;
2674 break;
2675
2676 case 39:
2677 if (pdfViewer.isHorizontalScrollbarEnabled) {
2678 turnOnlyIfPageFit = true;
2679 }
2680
2681 case 74:
2682 case 78:
2683 turnPage = 1;
2684 break;
2685
2686 case 36:
2687 if (isViewerInPresentationMode || PDFViewerApplication.page > 1) {
2688 PDFViewerApplication.page = 1;
2689 handled = true;
2690 ensureViewerFocused = true;
2691 }
2692
2693 break;
2694
2695 case 35:
2696 if (isViewerInPresentationMode || PDFViewerApplication.page < PDFViewerApplication.pagesCount) {
2697 PDFViewerApplication.page = PDFViewerApplication.pagesCount;
2698 handled = true;
2699 ensureViewerFocused = true;
2700 }
2701
2702 break;
2703
2704 case 83:
2705 PDFViewerApplication.pdfCursorTools.switchTool(_pdf_cursor_tools.CursorTool.SELECT);
2706 break;
2707
2708 case 72:
2709 PDFViewerApplication.pdfCursorTools.switchTool(_pdf_cursor_tools.CursorTool.HAND);
2710 break;
2711
2712 case 82:
2713 PDFViewerApplication.rotatePages(90);
2714 break;
2715
2716 case 115:
2717 PDFViewerApplication.pdfSidebar.toggle();
2718 break;
2719 }
2720
2721 if (turnPage !== 0 && (!turnOnlyIfPageFit || pdfViewer.currentScaleValue === "page-fit")) {
2722 if (turnPage > 0) {
2723 pdfViewer.nextPage();
2724 } else {
2725 pdfViewer.previousPage();
2726 }
2727
2728 handled = true;
2729 }
2730 }
2731
2732 if (cmd === 4) {
2733 switch (evt.keyCode) {
2734 case 13:
2735 case 32:
2736 if (!isViewerInPresentationMode && pdfViewer.currentScaleValue !== "page-fit") {
2737 break;
2738 }
2739
2740 pdfViewer.previousPage();
2741 handled = true;
2742 break;
2743
2744 case 82:
2745 PDFViewerApplication.rotatePages(-90);
2746 break;
2747 }
2748 }
2749
2750 if (!handled && !isViewerInPresentationMode) {
2751 if (evt.keyCode >= 33 && evt.keyCode <= 40 || evt.keyCode === 32 && curElementTagName !== "BUTTON") {
2752 ensureViewerFocused = true;
2753 }
2754 }
2755
2756 if (ensureViewerFocused && !pdfViewer.containsElement(curElement)) {
2757 pdfViewer.focus();
2758 }
2759
2760 if (handled) {
2761 evt.preventDefault();
2762 }
2763}
2764
2765function beforeUnload(evt) {
2766 evt.preventDefault();
2767 evt.returnValue = "";
2768 return false;
2769}
2770
2771function webViewerAnnotationEditorStatesChanged(data) {
2772 PDFViewerApplication.externalServices.updateEditorStates(data);
2773}
2774
2775const PDFPrintServiceFactory = {
2776 instance: {
2777 supportsPrinting: false,
2778
2779 createPrintService() {
2780 throw new Error("Not implemented: createPrintService");
2781 }
2782
2783 }
2784};
2785exports.PDFPrintServiceFactory = PDFPrintServiceFactory;
\No newline at end of file