viewer.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /* Copyright 2016 Mozilla Foundation
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. import { RenderingStates, ScrollMode, SpreadMode } from "./ui_utils.js";
  16. import { AppOptions } from "./app_options.js";
  17. import { LinkTarget } from "./pdf_link_service.js";
  18. import { PDFViewerApplication } from "./app.js";
  19. /* eslint-disable-next-line no-unused-vars */
  20. const pdfjsVersion =
  21. typeof PDFJSDev !== "undefined" ? PDFJSDev.eval("BUNDLE_VERSION") : void 0;
  22. /* eslint-disable-next-line no-unused-vars */
  23. const pdfjsBuild =
  24. typeof PDFJSDev !== "undefined" ? PDFJSDev.eval("BUNDLE_BUILD") : void 0;
  25. const AppConstants =
  26. typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")
  27. ? { LinkTarget, RenderingStates, ScrollMode, SpreadMode }
  28. : null;
  29. window.PDFViewerApplication = PDFViewerApplication;
  30. window.PDFViewerApplicationConstants = AppConstants;
  31. window.PDFViewerApplicationOptions = AppOptions;
  32. if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("CHROME")) {
  33. (function rewriteUrlClosure() {
  34. // Run this code outside DOMContentLoaded to make sure that the URL
  35. // is rewritten as soon as possible.
  36. const queryString = document.location.search.slice(1);
  37. const m = /(^|&)file=([^&]*)/.exec(queryString);
  38. const defaultUrl = m ? decodeURIComponent(m[2]) : "";
  39. // Example: chrome-extension://.../http://example.com/file.pdf
  40. const humanReadableUrl = "/" + defaultUrl + location.hash;
  41. history.replaceState(history.state, "", humanReadableUrl);
  42. if (top === window) {
  43. // eslint-disable-next-line no-undef
  44. chrome.runtime.sendMessage("showPageAction");
  45. }
  46. AppOptions.set("defaultUrl", defaultUrl);
  47. })();
  48. }
  49. if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
  50. require("./firefoxcom.js");
  51. require("./firefox_print_service.js");
  52. }
  53. if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("GENERIC")) {
  54. require("./genericcom.js");
  55. }
  56. if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("CHROME")) {
  57. require("./chromecom.js");
  58. }
  59. if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("CHROME || GENERIC")) {
  60. require("./pdf_print_service.js");
  61. }
  62. function getViewerConfiguration() {
  63. return {
  64. appContainer: document.body,
  65. mainContainer: document.getElementById("viewerContainer"),
  66. viewerContainer: document.getElementById("viewer"),
  67. toolbar: {
  68. container: document.getElementById("toolbarViewer"),
  69. numPages: document.getElementById("numPages"),
  70. pageNumber: document.getElementById("pageNumber"),
  71. scaleSelect: document.getElementById("scaleSelect"),
  72. customScaleOption: document.getElementById("customScaleOption"),
  73. previous: document.getElementById("previous"),
  74. next: document.getElementById("next"),
  75. zoomIn: document.getElementById("zoomIn"),
  76. zoomOut: document.getElementById("zoomOut"),
  77. viewFind: document.getElementById("viewFind"),
  78. openFile:
  79. typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")
  80. ? document.getElementById("openFile")
  81. : null,
  82. print: document.getElementById("print"),
  83. editorFreeTextButton: document.getElementById("editorFreeText"),
  84. editorFreeTextParamsToolbar: document.getElementById(
  85. "editorFreeTextParamsToolbar"
  86. ),
  87. editorInkButton: document.getElementById("editorInk"),
  88. editorInkParamsToolbar: document.getElementById("editorInkParamsToolbar"),
  89. download: document.getElementById("download"),
  90. },
  91. secondaryToolbar: {
  92. toolbar: document.getElementById("secondaryToolbar"),
  93. toggleButton: document.getElementById("secondaryToolbarToggle"),
  94. presentationModeButton: document.getElementById("presentationMode"),
  95. openFileButton:
  96. typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")
  97. ? document.getElementById("secondaryOpenFile")
  98. : null,
  99. printButton: document.getElementById("secondaryPrint"),
  100. downloadButton: document.getElementById("secondaryDownload"),
  101. viewBookmarkButton: document.getElementById("viewBookmark"),
  102. firstPageButton: document.getElementById("firstPage"),
  103. lastPageButton: document.getElementById("lastPage"),
  104. pageRotateCwButton: document.getElementById("pageRotateCw"),
  105. pageRotateCcwButton: document.getElementById("pageRotateCcw"),
  106. cursorSelectToolButton: document.getElementById("cursorSelectTool"),
  107. cursorHandToolButton: document.getElementById("cursorHandTool"),
  108. scrollPageButton: document.getElementById("scrollPage"),
  109. scrollVerticalButton: document.getElementById("scrollVertical"),
  110. scrollHorizontalButton: document.getElementById("scrollHorizontal"),
  111. scrollWrappedButton: document.getElementById("scrollWrapped"),
  112. spreadNoneButton: document.getElementById("spreadNone"),
  113. spreadOddButton: document.getElementById("spreadOdd"),
  114. spreadEvenButton: document.getElementById("spreadEven"),
  115. documentPropertiesButton: document.getElementById("documentProperties"),
  116. },
  117. sidebar: {
  118. // Divs (and sidebar button)
  119. outerContainer: document.getElementById("outerContainer"),
  120. sidebarContainer: document.getElementById("sidebarContainer"),
  121. toggleButton: document.getElementById("sidebarToggle"),
  122. // Buttons
  123. thumbnailButton: document.getElementById("viewThumbnail"),
  124. outlineButton: document.getElementById("viewOutline"),
  125. attachmentsButton: document.getElementById("viewAttachments"),
  126. layersButton: document.getElementById("viewLayers"),
  127. // Views
  128. thumbnailView: document.getElementById("thumbnailView"),
  129. outlineView: document.getElementById("outlineView"),
  130. attachmentsView: document.getElementById("attachmentsView"),
  131. layersView: document.getElementById("layersView"),
  132. // View-specific options
  133. outlineOptionsContainer: document.getElementById(
  134. "outlineOptionsContainer"
  135. ),
  136. currentOutlineItemButton: document.getElementById("currentOutlineItem"),
  137. },
  138. sidebarResizer: {
  139. outerContainer: document.getElementById("outerContainer"),
  140. resizer: document.getElementById("sidebarResizer"),
  141. },
  142. findBar: {
  143. bar: document.getElementById("findbar"),
  144. toggleButton: document.getElementById("viewFind"),
  145. findField: document.getElementById("findInput"),
  146. highlightAllCheckbox: document.getElementById("findHighlightAll"),
  147. caseSensitiveCheckbox: document.getElementById("findMatchCase"),
  148. matchDiacriticsCheckbox: document.getElementById("findMatchDiacritics"),
  149. entireWordCheckbox: document.getElementById("findEntireWord"),
  150. findMsg: document.getElementById("findMsg"),
  151. findResultsCount: document.getElementById("findResultsCount"),
  152. findPreviousButton: document.getElementById("findPrevious"),
  153. findNextButton: document.getElementById("findNext"),
  154. },
  155. passwordOverlay: {
  156. dialog: document.getElementById("passwordDialog"),
  157. label: document.getElementById("passwordText"),
  158. input: document.getElementById("password"),
  159. submitButton: document.getElementById("passwordSubmit"),
  160. cancelButton: document.getElementById("passwordCancel"),
  161. },
  162. documentProperties: {
  163. dialog: document.getElementById("documentPropertiesDialog"),
  164. closeButton: document.getElementById("documentPropertiesClose"),
  165. fields: {
  166. fileName: document.getElementById("fileNameField"),
  167. fileSize: document.getElementById("fileSizeField"),
  168. title: document.getElementById("titleField"),
  169. author: document.getElementById("authorField"),
  170. subject: document.getElementById("subjectField"),
  171. keywords: document.getElementById("keywordsField"),
  172. creationDate: document.getElementById("creationDateField"),
  173. modificationDate: document.getElementById("modificationDateField"),
  174. creator: document.getElementById("creatorField"),
  175. producer: document.getElementById("producerField"),
  176. version: document.getElementById("versionField"),
  177. pageCount: document.getElementById("pageCountField"),
  178. pageSize: document.getElementById("pageSizeField"),
  179. linearized: document.getElementById("linearizedField"),
  180. },
  181. },
  182. annotationEditorParams: {
  183. editorFreeTextFontSize: document.getElementById("editorFreeTextFontSize"),
  184. editorFreeTextColor: document.getElementById("editorFreeTextColor"),
  185. editorInkColor: document.getElementById("editorInkColor"),
  186. editorInkThickness: document.getElementById("editorInkThickness"),
  187. editorInkOpacity: document.getElementById("editorInkOpacity"),
  188. },
  189. printContainer: document.getElementById("printContainer"),
  190. openFileInput:
  191. typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")
  192. ? document.getElementById("fileInput")
  193. : null,
  194. debuggerScriptPath: "./debugger.js",
  195. };
  196. }
  197. function webViewerLoad() {
  198. const config = getViewerConfiguration();
  199. if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("PRODUCTION")) {
  200. if (window.chrome) {
  201. const link = document.createElement("link");
  202. link.rel = "stylesheet";
  203. link.href = "../build/dev-css/viewer.css";
  204. document.head.append(link);
  205. }
  206. Promise.all([
  207. import("pdfjs-web/genericcom.js"),
  208. import("pdfjs-web/pdf_print_service.js"),
  209. ]).then(function ([genericCom, pdfPrintService]) {
  210. PDFViewerApplication.run(config);
  211. });
  212. } else {
  213. if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("GENERIC")) {
  214. // Give custom implementations of the default viewer a simpler way to
  215. // set various `AppOptions`, by dispatching an event once all viewer
  216. // files are loaded but *before* the viewer initialization has run.
  217. const event = document.createEvent("CustomEvent");
  218. event.initCustomEvent("webviewerloaded", true, true, {
  219. source: window,
  220. });
  221. try {
  222. // Attempt to dispatch the event at the embedding `document`,
  223. // in order to support cases where the viewer is embedded in
  224. // a *dynamically* created <iframe> element.
  225. parent.document.dispatchEvent(event);
  226. } catch (ex) {
  227. // The viewer could be in e.g. a cross-origin <iframe> element,
  228. // fallback to dispatching the event at the current `document`.
  229. console.error(`webviewerloaded: ${ex}`);
  230. document.dispatchEvent(event);
  231. }
  232. }
  233. PDFViewerApplication.run(config);
  234. }
  235. }
  236. // Block the "load" event until all pages are loaded, to ensure that printing
  237. // works in Firefox; see https://bugzilla.mozilla.org/show_bug.cgi?id=1618553
  238. document.blockUnblockOnload?.(true);
  239. if (
  240. document.readyState === "interactive" ||
  241. document.readyState === "complete"
  242. ) {
  243. webViewerLoad();
  244. } else {
  245. document.addEventListener("DOMContentLoaded", webViewerLoad, true);
  246. }
  247. export {
  248. PDFViewerApplication,
  249. AppConstants as PDFViewerApplicationConstants,
  250. AppOptions as PDFViewerApplicationOptions,
  251. };