viewer_copy.html 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086
  1. <!DOCTYPE html>
  2. <!--
  3. Copyright 2012 Mozilla Foundation
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.apache.org/licenses/LICENSE-2.0
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. Adobe CMap resources are covered by their own copyright but the same license:
  14. Copyright 1990-2015 Adobe Systems Incorporated.
  15. See https://github.com/adobe-type-tools/cmap-resources
  16. -->
  17. <html dir="ltr" mozdisallowselectionprint>
  18. <head>
  19. <meta charset="utf-8">
  20. <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  21. <meta name="google" content="notranslate">
  22. <title>PDF.js viewer</title>
  23. <!-- This snippet is used in production (included from viewer.html) -->
  24. <link rel="resource" type="application/l10n" href="locale/locale.json">
  25. <script src="../build/pdf.mjs" type="module"></script>
  26. <link rel="stylesheet" href="viewer.css">
  27. <script src="viewer.mjs" type="module"></script>
  28. <style>
  29. /* 模态窗口样式 */
  30. .modal {
  31. display: none; /* 默认隐藏 */
  32. position: fixed;
  33. z-index: 1002;
  34. left: 50%;
  35. top: 50%;
  36. transform: translate(-50%, -50%);
  37. width: 300px;
  38. background-color: white;
  39. border: 1px solid #ccc;
  40. border-radius: 5px;
  41. padding: 20px;
  42. box-shadow: 0 5px 15px rgba(0,0,0,0.3);
  43. }
  44. /* 遮罩层样式 */
  45. .modal-overlay {
  46. display: none; /* 默认隐藏 */
  47. position: fixed;
  48. top: 0;
  49. left: 0;
  50. width: 100%;
  51. height: 100%;
  52. background-color: rgba(0, 0, 0, 0.5);
  53. z-index: 1001;
  54. }
  55. /* 按钮样式 */
  56. .button {
  57. padding: 10px 20px;
  58. background-color: #007bff;
  59. color: white;
  60. border: none;
  61. border-radius: 5px;
  62. cursor: pointer;
  63. }
  64. .button-secondary {
  65. background-color: #6c757d;
  66. }
  67. .button-success {
  68. background-color: #28a745;
  69. }
  70. .button-danger {
  71. background-color: #dc3545;
  72. }
  73. </style>
  74. </head>
  75. <body tabindex="0">
  76. <!-- 上传按钮定位在页面底部 -->
  77. <button id="uploadButton" style="
  78. position: fixed;
  79. bottom: 20px;
  80. right: 20px;
  81. z-index: 1000;
  82. padding: 10px 20px;
  83. background-color: #007bff;
  84. color: white;
  85. border: none;
  86. border-radius: 5px;
  87. cursor: pointer;">
  88. 上传 PDF
  89. </button>
  90. <!-- <input type="file" id="pdfInput" accept="application/pdf" style="display: none;" />
  91. <div id="outerContainer"> -->
  92. <!-- 上传按钮和文件名输入 -->
  93. <!-- <div style="position: fixed; bottom: 20px; right: 20px; z-index: 1000;">
  94. <input type="text" id="customFileName" placeholder="输入保存的文件名(不含扩展名)"
  95. style="margin-bottom: 10px; padding: 5px; width: 250px;" />
  96. <button id="uploadButton" style="
  97. padding: 10px 20px;
  98. background-color: #007bff;
  99. color: white;
  100. border: none;
  101. border-radius: 5px;
  102. cursor: pointer;">
  103. 上传 PDF
  104. </button>
  105. </div> -->
  106. <!-- 隐藏的文件输入 -->
  107. <input type="file" id="pdfInput" accept="application/pdf" style="display: none;" />
  108. <!-- 模态窗口 -->
  109. <div id="filenameModal" class="modal">
  110. <h3>输入保存的文件名</h3>
  111. <input type="text" id="customFileName" placeholder="不含扩展名" style="width: 100%; padding: 5px; margin-top: 10px;" />
  112. <div style="margin-top: 20px; text-align: right;">
  113. <button id="cancelUpload" class="button button-secondary">取消</button>
  114. <button id="confirmUpload" class="button button-success" style="margin-left: 10px;">确认</button>
  115. </div>
  116. </div>
  117. <!-- 页面遮罩 -->
  118. <div id="modalOverlay" class="modal-overlay"></div>
  119. <!-- 打开目录按钮 -->
  120. <button id="openDirectoryButton" style="
  121. position: fixed;
  122. bottom: 20px;
  123. right: 120px; /* 与上传按钮的距离,可以根据需要调整 */
  124. z-index: 1000;
  125. padding: 10px 20px;
  126. background-color: #28a745;
  127. color: white;
  128. border: none;
  129. border-radius: 5px;
  130. cursor: pointer;">
  131. 打开目录
  132. </button>
  133. <!-- 目录弹出层 -->
  134. <div id="directoryModal" style="
  135. display: none;
  136. position: fixed;
  137. top: 50%;
  138. left: 50%;
  139. transform: translate(-50%, -50%);
  140. background-color: white;
  141. border: 1px solid #ccc;
  142. border-radius: 5px;
  143. padding: 20px;
  144. z-index: 1001;
  145. width: 80%;
  146. max-height: 80%;
  147. overflow-y: auto;">
  148. <h2>已上传的 PDF 文档</h2>
  149. <ul id="pdfList" style="list-style-type: none; padding: 0;"></ul>
  150. <button id="closeDirectoryButton" style="
  151. margin-top: 20px;
  152. padding: 10px 20px;
  153. background-color: #dc3545;
  154. color: white;
  155. border: none;
  156. border-radius: 5px;
  157. cursor: pointer;">
  158. 关闭
  159. </button>
  160. </div>
  161. <!-- 页面遮罩 -->
  162. <div id="modalOverlay" style="
  163. display: none;
  164. position: fixed;
  165. top: 0;
  166. left: 0;
  167. width: 100%;
  168. height: 100%;
  169. background-color: rgba(0, 0, 0, 0.5);
  170. z-index: 1000;"></div>
  171. <div id="sidebarContainer">
  172. <div id="toolbarSidebar" class="toolbarHorizontalGroup">
  173. <div id="toolbarSidebarLeft">
  174. <div id="sidebarViewButtons" class="toolbarHorizontalGroup toggled" role="radiogroup">
  175. <button id="viewThumbnail" class="toolbarButton toggled" type="button" title="Show Thumbnails" tabindex="0"
  176. data-l10n-id="pdfjs-thumbs-button" role="radio" aria-checked="true" aria-controls="thumbnailView">
  177. <span data-l10n-id="pdfjs-thumbs-button-label">Thumbnails</span>
  178. </button>
  179. <button id="viewOutline" class="toolbarButton" type="button"
  180. title="Show Document Outline (double-click to expand/collapse all items)" tabindex="0"
  181. data-l10n-id="pdfjs-document-outline-button" role="radio" aria-checked="false" aria-controls="outlineView">
  182. <span data-l10n-id="pdfjs-document-outline-button-label">Document Outline</span>
  183. </button>
  184. <button id="viewAttachments" class="toolbarButton" type="button" title="Show Attachments" tabindex="0"
  185. data-l10n-id="pdfjs-attachments-button" role="radio" aria-checked="false" aria-controls="attachmentsView">
  186. <span data-l10n-id="pdfjs-attachments-button-label">Attachments</span>
  187. </button>
  188. <button id="viewLayers" class="toolbarButton" type="button"
  189. title="Show Layers (double-click to reset all layers to the default state)" tabindex="0"
  190. data-l10n-id="pdfjs-layers-button" role="radio" aria-checked="false" aria-controls="layersView">
  191. <span data-l10n-id="pdfjs-layers-button-label">Layers</span>
  192. </button>
  193. </div>
  194. </div>
  195. <div id="toolbarSidebarRight">
  196. <div id="outlineOptionsContainer" class="toolbarHorizontalGroup">
  197. <div class="verticalToolbarSeparator"></div>
  198. <button id="currentOutlineItem" class="toolbarButton" type="button" disabled="disabled"
  199. title="Find Current Outline Item" tabindex="0" data-l10n-id="pdfjs-current-outline-item-button">
  200. <span data-l10n-id="pdfjs-current-outline-item-button-label">Current Outline Item</span>
  201. </button>
  202. </div>
  203. </div>
  204. </div>
  205. <div id="sidebarContent">
  206. <div id="thumbnailView">
  207. </div>
  208. <div id="outlineView" class="hidden">
  209. </div>
  210. <div id="attachmentsView" class="hidden">
  211. </div>
  212. <div id="layersView" class="hidden">
  213. </div>
  214. </div>
  215. <div id="sidebarResizer"></div>
  216. </div> <!-- sidebarContainer -->
  217. <div id="mainContainer">
  218. <div class="toolbar">
  219. <div id="toolbarContainer">
  220. <div id="toolbarViewer" class="toolbarHorizontalGroup">
  221. <div id="toolbarViewerLeft" class="toolbarHorizontalGroup">
  222. <button id="sidebarToggleButton" class="toolbarButton" type="button" title="Toggle Sidebar" tabindex="0"
  223. data-l10n-id="pdfjs-toggle-sidebar-button" aria-expanded="false" aria-haspopup="true"
  224. aria-controls="sidebarContainer">
  225. <span data-l10n-id="pdfjs-toggle-sidebar-button-label">Toggle Sidebar</span>
  226. </button>
  227. <div class="toolbarButtonSpacer"></div>
  228. <div class="toolbarButtonWithContainer">
  229. <button id="viewFindButton" class="toolbarButton" type="button" title="Find in Document" tabindex="0"
  230. data-l10n-id="pdfjs-findbar-button" aria-expanded="false" aria-controls="findbar">
  231. <span data-l10n-id="pdfjs-findbar-button-label">Find</span>
  232. </button>
  233. <div class="hidden doorHanger toolbarHorizontalGroup" id="findbar">
  234. <div id="findInputContainer" class="toolbarHorizontalGroup">
  235. <span class="loadingInput end toolbarHorizontalGroup">
  236. <input id="findInput" class="toolbarField" title="Find" placeholder="Find in document…" tabindex="0"
  237. data-l10n-id="pdfjs-find-input" aria-invalid="false">
  238. </span>
  239. <div class="toolbarHorizontalGroup">
  240. <button id="findPreviousButton" class="toolbarButton" type="button"
  241. title="Find the previous occurrence of the phrase" tabindex="0"
  242. data-l10n-id="pdfjs-find-previous-button">
  243. <span data-l10n-id="pdfjs-find-previous-button-label">Previous</span>
  244. </button>
  245. <div class="splitToolbarButtonSeparator"></div>
  246. <button id="findNextButton" class="toolbarButton" type="button"
  247. title="Find the next occurrence of the phrase" tabindex="0" data-l10n-id="pdfjs-find-next-button">
  248. <span data-l10n-id="pdfjs-find-next-button-label">Next</span>
  249. </button>
  250. </div>
  251. </div>
  252. <div id="findbarOptionsOneContainer" class="toolbarHorizontalGroup">
  253. <div class="toggleButton toolbarLabel">
  254. <input type="checkbox" id="findHighlightAll" tabindex="0" />
  255. <label for="findHighlightAll" data-l10n-id="pdfjs-find-highlight-checkbox">Highlight All</label>
  256. </div>
  257. <div class="toggleButton toolbarLabel">
  258. <input type="checkbox" id="findMatchCase" tabindex="0" />
  259. <label for="findMatchCase" data-l10n-id="pdfjs-find-match-case-checkbox-label">Match Case</label>
  260. </div>
  261. </div>
  262. <div id="findbarOptionsTwoContainer" class="toolbarHorizontalGroup">
  263. <div class="toggleButton toolbarLabel">
  264. <input type="checkbox" id="findMatchDiacritics" tabindex="0" />
  265. <label for="findMatchDiacritics" data-l10n-id="pdfjs-find-match-diacritics-checkbox-label">Match
  266. Diacritics</label>
  267. </div>
  268. <div class="toggleButton toolbarLabel">
  269. <input type="checkbox" id="findEntireWord" tabindex="0" />
  270. <label for="findEntireWord" data-l10n-id="pdfjs-find-entire-word-checkbox-label">Whole
  271. Words</label>
  272. </div>
  273. </div>
  274. <div id="findbarMessageContainer" class="toolbarHorizontalGroup" aria-live="polite">
  275. <span id="findResultsCount" class="toolbarLabel"></span>
  276. <span id="findMsg" class="toolbarLabel"></span>
  277. </div>
  278. </div> <!-- findbar -->
  279. </div>
  280. <div class="toolbarHorizontalGroup hiddenSmallView">
  281. <button class="toolbarButton" title="Previous Page" type="button" id="previous" tabindex="0"
  282. data-l10n-id="pdfjs-previous-button">
  283. <span data-l10n-id="pdfjs-previous-button-label">Previous</span>
  284. </button>
  285. <div class="splitToolbarButtonSeparator"></div>
  286. <button class="toolbarButton" type="button" title="Next Page" id="next" tabindex="0"
  287. data-l10n-id="pdfjs-next-button">
  288. <span data-l10n-id="pdfjs-next-button-label">Next</span>
  289. </button>
  290. </div>
  291. <div class="toolbarHorizontalGroup">
  292. <span class="loadingInput start toolbarHorizontalGroup">
  293. <input type="number" id="pageNumber" class="toolbarField" title="Page" value="1" min="1" tabindex="0"
  294. data-l10n-id="pdfjs-page-input" autocomplete="off">
  295. </span>
  296. <span id="numPages" class="toolbarLabel"></span>
  297. </div>
  298. </div>
  299. <div id="toolbarViewerMiddle" class="toolbarHorizontalGroup">
  300. <div class="toolbarHorizontalGroup">
  301. <button id="zoomOutButton" class="toolbarButton" type="button" title="Zoom Out" tabindex="0"
  302. data-l10n-id="pdfjs-zoom-out-button">
  303. <span data-l10n-id="pdfjs-zoom-out-button-label">Zoom Out</span>
  304. </button>
  305. <div class="splitToolbarButtonSeparator"></div>
  306. <button id="zoomInButton" class="toolbarButton" type="button" title="Zoom In" tabindex="0"
  307. data-l10n-id="pdfjs-zoom-in-button">
  308. <span data-l10n-id="pdfjs-zoom-in-button-label">Zoom In</span>
  309. </button>
  310. </div>
  311. <span id="scaleSelectContainer" class="dropdownToolbarButton">
  312. <select id="scaleSelect" title="Zoom" tabindex="0" data-l10n-id="pdfjs-zoom-select">
  313. <option id="pageAutoOption" title="" value="auto" selected="selected"
  314. data-l10n-id="pdfjs-page-scale-auto">Automatic Zoom</option>
  315. <option id="pageActualOption" title="" value="page-actual" data-l10n-id="pdfjs-page-scale-actual">
  316. Actual Size</option>
  317. <option id="pageFitOption" title="" value="page-fit" data-l10n-id="pdfjs-page-scale-fit">Page Fit
  318. </option>
  319. <option id="pageWidthOption" title="" value="page-width" data-l10n-id="pdfjs-page-scale-width">Page
  320. Width</option>
  321. <option id="customScaleOption" title="" value="custom" disabled="disabled" hidden="true"
  322. data-l10n-id="pdfjs-page-scale-percent" data-l10n-args='{ "scale": 0 }'>0%</option>
  323. <option title="" value="0.5" data-l10n-id="pdfjs-page-scale-percent" data-l10n-args='{ "scale": 50 }'>
  324. 50%</option>
  325. <option title="" value="0.75" data-l10n-id="pdfjs-page-scale-percent" data-l10n-args='{ "scale": 75 }'>
  326. 75%</option>
  327. <option title="" value="1" data-l10n-id="pdfjs-page-scale-percent" data-l10n-args='{ "scale": 100 }'>
  328. 100%</option>
  329. <option title="" value="1.25" data-l10n-id="pdfjs-page-scale-percent" data-l10n-args='{ "scale": 125 }'>
  330. 125%</option>
  331. <option title="" value="1.5" data-l10n-id="pdfjs-page-scale-percent" data-l10n-args='{ "scale": 150 }'>
  332. 150%</option>
  333. <option title="" value="2" data-l10n-id="pdfjs-page-scale-percent" data-l10n-args='{ "scale": 200 }'>
  334. 200%</option>
  335. <option title="" value="3" data-l10n-id="pdfjs-page-scale-percent" data-l10n-args='{ "scale": 300 }'>
  336. 300%</option>
  337. <option title="" value="4" data-l10n-id="pdfjs-page-scale-percent" data-l10n-args='{ "scale": 400 }'>
  338. 400%</option>
  339. </select>
  340. </span>
  341. </div>
  342. <div id="toolbarViewerRight" class="toolbarHorizontalGroup">
  343. <div id="editorModeButtons" class="toolbarHorizontalGroup" role="radiogroup">
  344. <div id="editorHighlight" class="toolbarButtonWithContainer">
  345. <button id="editorHighlightButton" class="toolbarButton" type="button" disabled="disabled"
  346. title="Highlight" role="radio" aria-expanded="false" aria-haspopup="true"
  347. aria-controls="editorHighlightParamsToolbar" tabindex="0"
  348. data-l10n-id="pdfjs-editor-highlight-button">
  349. <span data-l10n-id="pdfjs-editor-highlight-button-label">Highlight</span>
  350. </button>
  351. <div class="editorParamsToolbar hidden doorHangerRight" id="editorHighlightParamsToolbar">
  352. <div id="highlightParamsToolbarContainer" class="editorParamsToolbarContainer">
  353. <div id="editorHighlightColorPicker" class="colorPicker">
  354. <span id="highlightColorPickerLabel" class="editorParamsLabel"
  355. data-l10n-id="pdfjs-editor-highlight-colorpicker-label">Highlight color</span>
  356. </div>
  357. <div id="editorHighlightThickness">
  358. <label for="editorFreeHighlightThickness" class="editorParamsLabel"
  359. data-l10n-id="pdfjs-editor-free-highlight-thickness-input">Thickness</label>
  360. <div class="thicknessPicker">
  361. <input type="range" id="editorFreeHighlightThickness" class="editorParamsSlider"
  362. data-l10n-id="pdfjs-editor-free-highlight-thickness-title" value="12" min="8" max="24"
  363. step="1" tabindex="0">
  364. </div>
  365. </div>
  366. <div id="editorHighlightVisibility">
  367. <div class="divider"></div>
  368. <div class="toggler">
  369. <label for="editorHighlightShowAll" class="editorParamsLabel"
  370. data-l10n-id="pdfjs-editor-highlight-show-all-button-label">Show all</label>
  371. <button id="editorHighlightShowAll" class="toggle-button" type="button"
  372. data-l10n-id="pdfjs-editor-highlight-show-all-button" aria-pressed="true"
  373. tabindex="0"></button>
  374. </div>
  375. </div>
  376. </div>
  377. </div>
  378. </div>
  379. <div id="editorFreeText" class="toolbarButtonWithContainer">
  380. <button id="editorFreeTextButton" class="toolbarButton" type="button" disabled="disabled" title="Text"
  381. role="radio" aria-expanded="false" aria-haspopup="true" aria-controls="editorFreeTextParamsToolbar"
  382. tabindex="0" data-l10n-id="pdfjs-editor-free-text-button">
  383. <span data-l10n-id="pdfjs-editor-free-text-button-label">Text</span>
  384. </button>
  385. <div class="editorParamsToolbar hidden doorHangerRight" id="editorFreeTextParamsToolbar">
  386. <div class="editorParamsToolbarContainer">
  387. <div class="editorParamsSetter">
  388. <label for="editorFreeTextColor" class="editorParamsLabel"
  389. data-l10n-id="pdfjs-editor-free-text-color-input">Color</label>
  390. <input type="color" id="editorFreeTextColor" class="editorParamsColor" tabindex="0">
  391. </div>
  392. <div class="editorParamsSetter">
  393. <label for="editorFreeTextFontSize" class="editorParamsLabel"
  394. data-l10n-id="pdfjs-editor-free-text-size-input">Size</label>
  395. <input type="range" id="editorFreeTextFontSize" class="editorParamsSlider" value="10" min="5"
  396. max="100" step="1" tabindex="0">
  397. </div>
  398. </div>
  399. </div>
  400. </div>
  401. <div id="editorInk" class="toolbarButtonWithContainer">
  402. <button id="editorInkButton" class="toolbarButton" type="button" disabled="disabled" title="Draw"
  403. role="radio" aria-expanded="false" aria-haspopup="true" aria-controls="editorInkParamsToolbar"
  404. tabindex="0" data-l10n-id="pdfjs-editor-ink-button">
  405. <span data-l10n-id="pdfjs-editor-ink-button-label">Draw</span>
  406. </button>
  407. <div class="editorParamsToolbar hidden doorHangerRight" id="editorInkParamsToolbar">
  408. <div class="editorParamsToolbarContainer">
  409. <div class="editorParamsSetter">
  410. <label for="editorInkColor" class="editorParamsLabel"
  411. data-l10n-id="pdfjs-editor-ink-color-input">Color</label>
  412. <input type="color" id="editorInkColor" class="editorParamsColor" tabindex="0">
  413. </div>
  414. <div class="editorParamsSetter">
  415. <label for="editorInkThickness" class="editorParamsLabel"
  416. data-l10n-id="pdfjs-editor-ink-thickness-input">Thickness</label>
  417. <input type="range" id="editorInkThickness" class="editorParamsSlider" value="1" min="1" max="20"
  418. step="1" tabindex="0">
  419. </div>
  420. <div class="editorParamsSetter">
  421. <label for="editorInkOpacity" class="editorParamsLabel"
  422. data-l10n-id="pdfjs-editor-ink-opacity-input">Opacity</label>
  423. <input type="range" id="editorInkOpacity" class="editorParamsSlider" value="100" min="1" max="100"
  424. step="1" tabindex="0">
  425. </div>
  426. </div>
  427. </div>
  428. </div>
  429. <div id="editorStamp" class="toolbarButtonWithContainer">
  430. <button id="editorStampButton" class="toolbarButton" type="button" disabled="disabled"
  431. title="Add or edit images" role="radio" aria-expanded="false" aria-haspopup="true"
  432. aria-controls="editorStampParamsToolbar" tabindex="0" data-l10n-id="pdfjs-editor-stamp-button">
  433. <span data-l10n-id="pdfjs-editor-stamp-button-label">Add or edit images</span>
  434. </button>
  435. <div class="editorParamsToolbar hidden doorHangerRight menu" id="editorStampParamsToolbar">
  436. <div class="menuContainer">
  437. <button id="editorStampAddImage" class="toolbarButton labeled" type="button" title="Add image"
  438. tabindex="0" data-l10n-id="pdfjs-editor-stamp-add-image-button">
  439. <span class="editorParamsLabel" data-l10n-id="pdfjs-editor-stamp-add-image-button-label">Add
  440. image</span>
  441. </button>
  442. </div>
  443. </div>
  444. </div>
  445. </div>
  446. <div id="editorModeSeparator" class="verticalToolbarSeparator"></div>
  447. <div class="toolbarHorizontalGroup hiddenMediumView">
  448. <button id="printButton" class="toolbarButton" type="button" title="Print" tabindex="0"
  449. data-l10n-id="pdfjs-print-button">
  450. <span data-l10n-id="pdfjs-print-button-label">Print</span>
  451. </button>
  452. <button id="downloadButton" class="toolbarButton" type="button" title="Save" tabindex="0"
  453. data-l10n-id="pdfjs-save-button">
  454. <span data-l10n-id="pdfjs-save-button-label">Save</span>
  455. </button>
  456. </div>
  457. <div class="verticalToolbarSeparator hiddenMediumView"></div>
  458. <div id="secondaryToolbarToggle" class="toolbarButtonWithContainer">
  459. <button id="secondaryToolbarToggleButton" class="toolbarButton" type="button" title="Tools" tabindex="0"
  460. data-l10n-id="pdfjs-tools-button" aria-expanded="false" aria-haspopup="true"
  461. aria-controls="secondaryToolbar">
  462. <span data-l10n-id="pdfjs-tools-button-label">Tools</span>
  463. </button>
  464. <div id="secondaryToolbar" class="hidden doorHangerRight menu">
  465. <div id="secondaryToolbarButtonContainer" class="menuContainer">
  466. <button id="secondaryOpenFile" class="toolbarButton labeled" type="button" title="Open File"
  467. tabindex="0" data-l10n-id="pdfjs-open-file-button">
  468. <span data-l10n-id="pdfjs-open-file-button-label">Open</span>
  469. </button>
  470. <div class="visibleMediumView">
  471. <button id="secondaryPrint" class="toolbarButton labeled" type="button" title="Print" tabindex="0"
  472. data-l10n-id="pdfjs-print-button">
  473. <span data-l10n-id="pdfjs-print-button-label">Print</span>
  474. </button>
  475. <button id="secondaryDownload" class="toolbarButton labeled" type="button" title="Save" tabindex="0"
  476. data-l10n-id="pdfjs-save-button">
  477. <span data-l10n-id="pdfjs-save-button-label">Save</span>
  478. </button>
  479. </div>
  480. <div class="horizontalToolbarSeparator"></div>
  481. <button id="presentationMode" class="toolbarButton labeled" type="button"
  482. title="Switch to Presentation Mode" tabindex="0" data-l10n-id="pdfjs-presentation-mode-button">
  483. <span data-l10n-id="pdfjs-presentation-mode-button-label">Presentation Mode</span>
  484. </button>
  485. <a href="#" id="viewBookmark" class="toolbarButton labeled"
  486. title="Current Page (View URL from Current Page)" tabindex="0" data-l10n-id="pdfjs-bookmark-button">
  487. <span data-l10n-id="pdfjs-bookmark-button-label">Current Page</span>
  488. </a>
  489. <div id="viewBookmarkSeparator" class="horizontalToolbarSeparator"></div>
  490. <button id="firstPage" class="toolbarButton labeled" type="button" title="Go to First Page"
  491. tabindex="0" data-l10n-id="pdfjs-first-page-button">
  492. <span data-l10n-id="pdfjs-first-page-button-label">Go to First Page</span>
  493. </button>
  494. <button id="lastPage" class="toolbarButton labeled" type="button" title="Go to Last Page" tabindex="0"
  495. data-l10n-id="pdfjs-last-page-button">
  496. <span data-l10n-id="pdfjs-last-page-button-label">Go to Last Page</span>
  497. </button>
  498. <div class="horizontalToolbarSeparator"></div>
  499. <button id="pageRotateCw" class="toolbarButton labeled" type="button" title="Rotate Clockwise"
  500. tabindex="0" data-l10n-id="pdfjs-page-rotate-cw-button">
  501. <span data-l10n-id="pdfjs-page-rotate-cw-button-label">Rotate Clockwise</span>
  502. </button>
  503. <button id="pageRotateCcw" class="toolbarButton labeled" type="button" title="Rotate Counterclockwise"
  504. tabindex="0" data-l10n-id="pdfjs-page-rotate-ccw-button">
  505. <span data-l10n-id="pdfjs-page-rotate-ccw-button-label">Rotate Counterclockwise</span>
  506. </button>
  507. <div class="horizontalToolbarSeparator"></div>
  508. <div id="cursorToolButtons" role="radiogroup">
  509. <button id="cursorSelectTool" class="toolbarButton labeled toggled" type="button"
  510. title="Enable Text Selection Tool" tabindex="0"
  511. data-l10n-id="pdfjs-cursor-text-select-tool-button" role="radio" aria-checked="true">
  512. <span data-l10n-id="pdfjs-cursor-text-select-tool-button-label">Text Selection Tool</span>
  513. </button>
  514. <button id="cursorHandTool" class="toolbarButton labeled" type="button" title="Enable Hand Tool"
  515. tabindex="0" data-l10n-id="pdfjs-cursor-hand-tool-button" role="radio" aria-checked="false">
  516. <span data-l10n-id="pdfjs-cursor-hand-tool-button-label">Hand Tool</span>
  517. </button>
  518. </div>
  519. <div class="horizontalToolbarSeparator"></div>
  520. <div id="scrollModeButtons" role="radiogroup">
  521. <button id="scrollPage" class="toolbarButton labeled" type="button" title="Use Page Scrolling"
  522. tabindex="0" data-l10n-id="pdfjs-scroll-page-button" role="radio" aria-checked="false">
  523. <span data-l10n-id="pdfjs-scroll-page-button-label">Page Scrolling</span>
  524. </button>
  525. <button id="scrollVertical" class="toolbarButton labeled toggled" type="button"
  526. title="Use Vertical Scrolling" tabindex="0" data-l10n-id="pdfjs-scroll-vertical-button"
  527. role="radio" aria-checked="true">
  528. <span data-l10n-id="pdfjs-scroll-vertical-button-label">Vertical Scrolling</span>
  529. </button>
  530. <button id="scrollHorizontal" class="toolbarButton labeled" type="button"
  531. title="Use Horizontal Scrolling" tabindex="0" data-l10n-id="pdfjs-scroll-horizontal-button"
  532. role="radio" aria-checked="false">
  533. <span data-l10n-id="pdfjs-scroll-horizontal-button-label">Horizontal Scrolling</span>
  534. </button>
  535. <button id="scrollWrapped" class="toolbarButton labeled" type="button" title="Use Wrapped Scrolling"
  536. tabindex="0" data-l10n-id="pdfjs-scroll-wrapped-button" role="radio" aria-checked="false">
  537. <span data-l10n-id="pdfjs-scroll-wrapped-button-label">Wrapped Scrolling</span>
  538. </button>
  539. </div>
  540. <div class="horizontalToolbarSeparator"></div>
  541. <div id="spreadModeButtons" role="radiogroup">
  542. <button id="spreadNone" class="toolbarButton labeled toggled" type="button"
  543. title="Do not join page spreads" tabindex="0" data-l10n-id="pdfjs-spread-none-button" role="radio"
  544. aria-checked="true">
  545. <span data-l10n-id="pdfjs-spread-none-button-label">No Spreads</span>
  546. </button>
  547. <button id="spreadOdd" class="toolbarButton labeled" type="button"
  548. title="Join page spreads starting with odd-numbered pages" tabindex="0"
  549. data-l10n-id="pdfjs-spread-odd-button" role="radio" aria-checked="false">
  550. <span data-l10n-id="pdfjs-spread-odd-button-label">Odd Spreads</span>
  551. </button>
  552. <button id="spreadEven" class="toolbarButton labeled" type="button"
  553. title="Join page spreads starting with even-numbered pages" tabindex="0"
  554. data-l10n-id="pdfjs-spread-even-button" role="radio" aria-checked="false">
  555. <span data-l10n-id="pdfjs-spread-even-button-label">Even Spreads</span>
  556. </button>
  557. </div>
  558. <div id="imageAltTextSettingsSeparator" class="horizontalToolbarSeparator hidden"></div>
  559. <button id="imageAltTextSettings" type="button" class="toolbarButton labeled hidden"
  560. title="Image alt text settings" tabindex="0" data-l10n-id="pdfjs-image-alt-text-settings-button"
  561. aria-controls="altTextSettingsDialog">
  562. <span data-l10n-id="pdfjs-image-alt-text-settings-button-label">Image alt text settings</span>
  563. </button>
  564. <div class="horizontalToolbarSeparator"></div>
  565. <button id="documentProperties" class="toolbarButton labeled" type="button"
  566. title="Document Properties…" tabindex="0" data-l10n-id="pdfjs-document-properties-button"
  567. aria-controls="documentPropertiesDialog">
  568. <span data-l10n-id="pdfjs-document-properties-button-label">Document Properties…</span>
  569. </button>
  570. </div>
  571. </div> <!-- secondaryToolbar -->
  572. </div>
  573. </div>
  574. </div>
  575. <div id="loadingBar">
  576. <div class="progress">
  577. <div class="glimmer">
  578. </div>
  579. </div>
  580. </div>
  581. </div>
  582. </div>
  583. <div id="viewerContainer" tabindex="0">
  584. <div id="viewer" class="pdfViewer"></div>
  585. </div>
  586. </div> <!-- mainContainer -->
  587. <div id="dialogContainer">
  588. <dialog id="passwordDialog">
  589. <div class="row">
  590. <label for="password" id="passwordText" data-l10n-id="pdfjs-password-label">Enter the password to open this
  591. PDF file:</label>
  592. </div>
  593. <div class="row">
  594. <input type="password" id="password" class="toolbarField">
  595. </div>
  596. <div class="buttonRow">
  597. <button id="passwordCancel" class="dialogButton" type="button"><span
  598. data-l10n-id="pdfjs-password-cancel-button">Cancel</span></button>
  599. <button id="passwordSubmit" class="dialogButton" type="button"><span
  600. data-l10n-id="pdfjs-password-ok-button">OK</span></button>
  601. </div>
  602. </dialog>
  603. <dialog id="documentPropertiesDialog">
  604. <div class="row">
  605. <span id="fileNameLabel" data-l10n-id="pdfjs-document-properties-file-name">File name:</span>
  606. <p id="fileNameField" aria-labelledby="fileNameLabel">-</p>
  607. </div>
  608. <div class="row">
  609. <span id="fileSizeLabel" data-l10n-id="pdfjs-document-properties-file-size">File size:</span>
  610. <p id="fileSizeField" aria-labelledby="fileSizeLabel">-</p>
  611. </div>
  612. <div class="separator"></div>
  613. <div class="row">
  614. <span id="titleLabel" data-l10n-id="pdfjs-document-properties-title">Title:</span>
  615. <p id="titleField" aria-labelledby="titleLabel">-</p>
  616. </div>
  617. <div class="row">
  618. <span id="authorLabel" data-l10n-id="pdfjs-document-properties-author">Author:</span>
  619. <p id="authorField" aria-labelledby="authorLabel">-</p>
  620. </div>
  621. <div class="row">
  622. <span id="subjectLabel" data-l10n-id="pdfjs-document-properties-subject">Subject:</span>
  623. <p id="subjectField" aria-labelledby="subjectLabel">-</p>
  624. </div>
  625. <div class="row">
  626. <span id="keywordsLabel" data-l10n-id="pdfjs-document-properties-keywords">Keywords:</span>
  627. <p id="keywordsField" aria-labelledby="keywordsLabel">-</p>
  628. </div>
  629. <div class="row">
  630. <span id="creationDateLabel" data-l10n-id="pdfjs-document-properties-creation-date">Creation Date:</span>
  631. <p id="creationDateField" aria-labelledby="creationDateLabel">-</p>
  632. </div>
  633. <div class="row">
  634. <span id="modificationDateLabel" data-l10n-id="pdfjs-document-properties-modification-date">Modification
  635. Date:</span>
  636. <p id="modificationDateField" aria-labelledby="modificationDateLabel">-</p>
  637. </div>
  638. <div class="row">
  639. <span id="creatorLabel" data-l10n-id="pdfjs-document-properties-creator">Creator:</span>
  640. <p id="creatorField" aria-labelledby="creatorLabel">-</p>
  641. </div>
  642. <div class="separator"></div>
  643. <div class="row">
  644. <span id="producerLabel" data-l10n-id="pdfjs-document-properties-producer">PDF Producer:</span>
  645. <p id="producerField" aria-labelledby="producerLabel">-</p>
  646. </div>
  647. <div class="row">
  648. <span id="versionLabel" data-l10n-id="pdfjs-document-properties-version">PDF Version:</span>
  649. <p id="versionField" aria-labelledby="versionLabel">-</p>
  650. </div>
  651. <div class="row">
  652. <span id="pageCountLabel" data-l10n-id="pdfjs-document-properties-page-count">Page Count:</span>
  653. <p id="pageCountField" aria-labelledby="pageCountLabel">-</p>
  654. </div>
  655. <div class="row">
  656. <span id="pageSizeLabel" data-l10n-id="pdfjs-document-properties-page-size">Page Size:</span>
  657. <p id="pageSizeField" aria-labelledby="pageSizeLabel">-</p>
  658. </div>
  659. <div class="separator"></div>
  660. <div class="row">
  661. <span id="linearizedLabel" data-l10n-id="pdfjs-document-properties-linearized">Fast Web View:</span>
  662. <p id="linearizedField" aria-labelledby="linearizedLabel">-</p>
  663. </div>
  664. <div class="buttonRow">
  665. <button id="documentPropertiesClose" class="dialogButton" type="button"><span
  666. data-l10n-id="pdfjs-document-properties-close-button">Close</span></button>
  667. </div>
  668. </dialog>
  669. <dialog class="dialog altText" id="altTextDialog" aria-labelledby="dialogLabel"
  670. aria-describedby="dialogDescription">
  671. <div id="altTextContainer" class="mainContainer">
  672. <div id="overallDescription">
  673. <span id="dialogLabel" data-l10n-id="pdfjs-editor-alt-text-dialog-label" class="title">Choose an
  674. option</span>
  675. <span id="dialogDescription" data-l10n-id="pdfjs-editor-alt-text-dialog-description">
  676. Alt text (alternative text) helps when people can’t see the image or when it doesn’t load.
  677. </span>
  678. </div>
  679. <div id="addDescription">
  680. <div class="radio">
  681. <div class="radioButton">
  682. <input type="radio" id="descriptionButton" name="altTextOption" tabindex="0"
  683. aria-describedby="descriptionAreaLabel" checked>
  684. <label for="descriptionButton" data-l10n-id="pdfjs-editor-alt-text-add-description-label">Add a
  685. description</label>
  686. </div>
  687. <div class="radioLabel">
  688. <span id="descriptionAreaLabel" data-l10n-id="pdfjs-editor-alt-text-add-description-description">
  689. Aim for 1-2 sentences that describe the subject, setting, or actions.
  690. </span>
  691. </div>
  692. </div>
  693. <div class="descriptionArea">
  694. <textarea id="descriptionTextarea"
  695. placeholder="For example, “A young man sits down at a table to eat a meal”"
  696. aria-labelledby="descriptionAreaLabel" data-l10n-id="pdfjs-editor-alt-text-textarea"
  697. tabindex="0"></textarea>
  698. </div>
  699. </div>
  700. <div id="markAsDecorative">
  701. <div class="radio">
  702. <div class="radioButton">
  703. <input type="radio" id="decorativeButton" name="altTextOption" aria-describedby="decorativeLabel">
  704. <label for="decorativeButton" data-l10n-id="pdfjs-editor-alt-text-mark-decorative-label">Mark as
  705. decorative</label>
  706. </div>
  707. <div class="radioLabel">
  708. <span id="decorativeLabel" data-l10n-id="pdfjs-editor-alt-text-mark-decorative-description">
  709. This is used for ornamental images, like borders or watermarks.
  710. </span>
  711. </div>
  712. </div>
  713. </div>
  714. <div id="buttons">
  715. <button id="altTextCancel" class="secondaryButton" type="button" tabindex="0"><span
  716. data-l10n-id="pdfjs-editor-alt-text-cancel-button">Cancel</span></button>
  717. <button id="altTextSave" class="primaryButton" type="button" tabindex="0"><span
  718. data-l10n-id="pdfjs-editor-alt-text-save-button">Save</span></button>
  719. </div>
  720. </div>
  721. </dialog>
  722. <dialog class="dialog newAltText" id="newAltTextDialog" aria-labelledby="newAltTextTitle"
  723. aria-describedby="newAltTextDescription" tabindex="0">
  724. <div id="newAltTextContainer" class="mainContainer">
  725. <div class="title">
  726. <span id="newAltTextTitle" data-l10n-id="pdfjs-editor-new-alt-text-dialog-edit-label" role="sectionhead"
  727. tabindex="0">Edit alt text (image description)</span>
  728. </div>
  729. <div id="mainContent">
  730. <div id="descriptionAndSettings">
  731. <div id="descriptionInstruction">
  732. <div id="newAltTextDescriptionContainer">
  733. <div class="altTextSpinner" role="status" aria-live="polite"></div>
  734. <textarea id="newAltTextDescriptionTextarea" placeholder="Write your description here…"
  735. aria-labelledby="descriptionAreaLabel" data-l10n-id="pdfjs-editor-new-alt-text-textarea"
  736. tabindex="0"></textarea>
  737. </div>
  738. <span id="newAltTextDescription" role="note" data-l10n-id="pdfjs-editor-new-alt-text-description">Short
  739. description for people who can’t see the image or when the image doesn’t load.</span>
  740. <div id="newAltTextDisclaimer" role="note">
  741. <div><span data-l10n-id="pdfjs-editor-new-alt-text-disclaimer1">This alt text was created
  742. automatically and may be inaccurate.</span> <a
  743. href="https://support.mozilla.org/en-US/kb/pdf-alt-text" target="_blank" rel="noopener noreferrer"
  744. id="newAltTextLearnMore" data-l10n-id="pdfjs-editor-new-alt-text-disclaimer-learn-more-url"
  745. tabindex="0">Learn more</a></div>
  746. </div>
  747. </div>
  748. <div id="newAltTextCreateAutomatically" class="toggler">
  749. <button id="newAltTextCreateAutomaticallyButton" class="toggle-button" type="button" aria-pressed="true"
  750. tabindex="0"></button>
  751. <label for="newAltTextCreateAutomaticallyButton" class="togglerLabel"
  752. data-l10n-id="pdfjs-editor-new-alt-text-create-automatically-button-label">Create alt text
  753. automatically</label>
  754. </div>
  755. <div id="newAltTextDownloadModel" class="hidden">
  756. <span id="newAltTextDownloadModelDescription"
  757. data-l10n-id="pdfjs-editor-new-alt-text-ai-model-downloading-progress" aria-valuemin="0"
  758. data-l10n-args='{ "totalSize": 0, "downloadedSize": 0 }'>Downloading alt text AI model (0 of 0
  759. MB)</span>
  760. </div>
  761. </div>
  762. <div id="newAltTextImagePreview"></div>
  763. </div>
  764. <div id="newAltTextError" class="messageBar">
  765. <div>
  766. <div>
  767. <span class="title" data-l10n-id="pdfjs-editor-new-alt-text-error-title">Couldn’t create alt text
  768. automatically</span>
  769. <span class="description" data-l10n-id="pdfjs-editor-new-alt-text-error-description">Please write your
  770. own alt text or try again later.</span>
  771. </div>
  772. <button id="newAltTextCloseButton" class="closeButton" type="button" tabindex="0" title="Close"><span
  773. data-l10n-id="pdfjs-editor-new-alt-text-error-close-button">Close</span></button>
  774. </div>
  775. </div>
  776. <div id="newAltTextButtons" class="dialogButtonsGroup">
  777. <button id="newAltTextCancel" type="button" class="secondaryButton hidden" tabindex="0"><span
  778. data-l10n-id="pdfjs-editor-alt-text-cancel-button">Cancel</span></button>
  779. <button id="newAltTextNotNow" type="button" class="secondaryButton" tabindex="0"><span
  780. data-l10n-id="pdfjs-editor-new-alt-text-not-now-button">Not now</span></button>
  781. <button id="newAltTextSave" type="button" class="primaryButton" tabindex="0"><span
  782. data-l10n-id="pdfjs-editor-alt-text-save-button">Save</span></button>
  783. </div>
  784. </div>
  785. </dialog>
  786. <dialog class="dialog" id="altTextSettingsDialog" aria-labelledby="altTextSettingsTitle">
  787. <div id="altTextSettingsContainer" class="mainContainer">
  788. <div class="title">
  789. <span id="altTextSettingsTitle" data-l10n-id="pdfjs-editor-alt-text-settings-dialog-label" role="sectionhead"
  790. tabindex="0" class="title">Image alt text settings</span>
  791. </div>
  792. <div id="automaticAltText">
  793. <span data-l10n-id="pdfjs-editor-alt-text-settings-automatic-title">Automatic alt text</span>
  794. <div id="automaticSettings">
  795. <div id="createModelSetting">
  796. <div class="toggler">
  797. <button id="createModelButton" type="button" class="toggle-button" aria-pressed="true"
  798. tabindex="0"></button>
  799. <label for="createModelButton" class="togglerLabel"
  800. data-l10n-id="pdfjs-editor-alt-text-settings-create-model-button-label">Create alt text
  801. automatically</label>
  802. </div>
  803. <div id="createModelDescription" class="description">
  804. <span data-l10n-id="pdfjs-editor-alt-text-settings-create-model-description">Suggests descriptions to
  805. help people who can’t see the image or when the image doesn’t load.</span> <a
  806. href="https://support.mozilla.org/en-US/kb/pdf-alt-text" target="_blank" rel="noopener noreferrer"
  807. id="altTextSettingsLearnMore" data-l10n-id="pdfjs-editor-new-alt-text-disclaimer-learn-more-url"
  808. tabindex="0">Learn more</a>
  809. </div>
  810. </div>
  811. <div id="aiModelSettings">
  812. <div>
  813. <span data-l10n-id="pdfjs-editor-alt-text-settings-download-model-label"
  814. data-l10n-args='{ "totalSize": 180 }'>Alt text AI model (180MB)</span>
  815. <div id="aiModelDescription" class="description">
  816. <span data-l10n-id="pdfjs-editor-alt-text-settings-ai-model-description">Runs locally on your device
  817. so your data stays private. Required for automatic alt text.</span>
  818. </div>
  819. </div>
  820. <button id="deleteModelButton" type="button" class="secondaryButton" tabindex="0"><span
  821. data-l10n-id="pdfjs-editor-alt-text-settings-delete-model-button">Delete</span></button>
  822. <button id="downloadModelButton" type="button" class="secondaryButton" tabindex="0"><span
  823. data-l10n-id="pdfjs-editor-alt-text-settings-download-model-button">Download</span></button>
  824. </div>
  825. </div>
  826. </div>
  827. <div class="dialogSeparator"></div>
  828. <div id="altTextEditor">
  829. <span data-l10n-id="pdfjs-editor-alt-text-settings-editor-title">Alt text editor</span>
  830. <div id="showAltTextEditor">
  831. <div class="toggler">
  832. <button id="showAltTextDialogButton" type="button" class="toggle-button" aria-pressed="true"
  833. tabindex="0"></button>
  834. <label for="showAltTextDialogButton" class="togglerLabel"
  835. data-l10n-id="pdfjs-editor-alt-text-settings-show-dialog-button-label">Show alt text editor right away
  836. when adding an image</label>
  837. </div>
  838. <div id="showAltTextDialogDescription" class="description">
  839. <span data-l10n-id="pdfjs-editor-alt-text-settings-show-dialog-description">Helps you make sure all your
  840. images have alt text.</span>
  841. </div>
  842. </div>
  843. </div>
  844. <div id="buttons" class="dialogButtonsGroup">
  845. <button id="altTextSettingsCloseButton" type="button" class="primaryButton" tabindex="0"><span
  846. data-l10n-id="pdfjs-editor-alt-text-settings-close-button">Close</span></button>
  847. </div>
  848. </div>
  849. </dialog>
  850. <dialog id="printServiceDialog" style="min-width: 200px;">
  851. <div class="row">
  852. <span data-l10n-id="pdfjs-print-progress-message">Preparing document for printing…</span>
  853. </div>
  854. <div class="row">
  855. <progress value="0" max="100"></progress>
  856. <span data-l10n-id="pdfjs-print-progress-percent" data-l10n-args='{ "progress": 0 }'
  857. class="relative-progress">0%</span>
  858. </div>
  859. <div class="buttonRow">
  860. <button id="printCancel" class="dialogButton" type="button"><span
  861. data-l10n-id="pdfjs-print-progress-close-button">Cancel</span></button>
  862. </div>
  863. </dialog>
  864. </div> <!-- dialogContainer -->
  865. </div> <!-- outerContainer -->
  866. <div id="printContainer"></div>
  867. <!-- <script>
  868. document.getElementById('uploadButton').addEventListener('click', function() {
  869. // 触发隐藏的文件输入
  870. document.getElementById('pdfInput').click();
  871. });
  872. document.getElementById('pdfInput').addEventListener('change', function(event) {
  873. const file = event.target.files[0];
  874. if (file && file.type === 'application/pdf') {
  875. const formData = new FormData();
  876. formData.append('file', file);
  877. // 调用 FastAPI 上传接口
  878. fetch('http://106.14.113.12:8005/upload-pdf', { // 根据实际部署情况调整URL
  879. method: 'POST',
  880. body: formData
  881. })
  882. .then(response => response.json())
  883. .then(data => {
  884. if (data.success) {
  885. const uploadedUrl = data.url;
  886. // 加载上传后的 PDF
  887. PDFViewerApplication.open(uploadedUrl);
  888. } else {
  889. alert('上传失败: ' + data.error);
  890. }
  891. })
  892. .catch(error => {
  893. console.error('Error:', error);
  894. alert('上传过程中发生错误');
  895. });
  896. } else {
  897. alert('请选择一个 PDF 文件');
  898. }
  899. });
  900. </script> -->
  901. <script>
  902. document.getElementById('uploadButton').addEventListener('click', function () {
  903. const customFileName = document.getElementById('customFileName').value.trim();
  904. if (customFileName === "") {
  905. alert('请输入保存的文件名');
  906. return;
  907. }
  908. // 检查文件名是否包含非法字符
  909. const invalidChars = /[\\/:"*?<>|]+/;
  910. if (invalidChars.test(customFileName)) {
  911. alert('文件名包含非法字符:\\ / : " * ? < > |');
  912. return;
  913. }
  914. // 触发隐藏的文件输入
  915. document.getElementById('pdfInput').click();
  916. });
  917. document.getElementById('pdfInput').addEventListener('change', function (event) {
  918. const file = event.target.files[0];
  919. const customFileName = document.getElementById('customFileName').value.trim();
  920. if (file && file.type === 'application/pdf') {
  921. const formData = new FormData();
  922. formData.append('file', file);
  923. formData.append('custom_name', customFileName); // 添加自定义文件名
  924. // 调用 FastAPI 上传接口
  925. fetch('http://106.14.113.12:8005/upload-pdf', { // 根据实际部署情况调整URL
  926. method: 'POST',
  927. body: formData
  928. })
  929. .then(response => response.json())
  930. .then(data => {
  931. if (data.success) {
  932. const uploadedFilePath = data.file_path; // 假设后端返回的是文件相对路径
  933. // 构建重定向的URL
  934. const redirectUrl = `http://106.14.113.12:8005/static/web/viewer.html?file=${uploadedFilePath}`;
  935. // 执行页面跳转
  936. window.location.href = redirectUrl;
  937. } else {
  938. alert('上传失败: ' + data.error);
  939. }
  940. })
  941. .catch(error => {
  942. console.error('Error:', error);
  943. alert('上传过程中发生错误');
  944. });
  945. } else {
  946. alert('请选择一个 PDF 文件');
  947. }
  948. });
  949. // 处理“打开目录”按钮点击事件
  950. document.getElementById('openDirectoryButton').addEventListener('click', function () {
  951. // 显示遮罩和弹出层
  952. document.getElementById('modalOverlay').style.display = 'block';
  953. document.getElementById('directoryModal').style.display = 'block';
  954. // 清空现有的列表
  955. const pdfList = document.getElementById('pdfList');
  956. pdfList.innerHTML = '';
  957. // 调用 FastAPI 获取文件列表
  958. fetch('http://106.14.113.12:8005/list-pdfs') // 根据实际部署情况调整URL
  959. .then(response => response.json())
  960. .then(data => {
  961. if (data.success) {
  962. const files = data.files;
  963. if (files.length === 0) {
  964. const listItem = document.createElement('li');
  965. listItem.textContent = '没有已上传的 PDF 文档。';
  966. pdfList.appendChild(listItem);
  967. } else {
  968. files.forEach(file => {
  969. const listItem = document.createElement('li');
  970. listItem.style.marginBottom = '10px';
  971. const link = document.createElement('a');
  972. link.href = `viewer.html?file=${file.url}`; // 确保 URL 正确
  973. link.textContent = file.name;
  974. // link.target = '_blank'; // 在新标签页中打开
  975. //在当前页打开
  976. link.addEventListener('click', function (event) {
  977. event.preventDefault(); // 防止默认的跳转行为
  978. const fileUrl = link.getAttribute('href');
  979. // const redirectUrl = `viewer.html?file=${fileUrl}`;
  980. const redirectUrl = `${fileUrl}`;
  981. window.location.href = redirectUrl; // 在当前页面跳转
  982. });
  983. listItem.appendChild(link);
  984. pdfList.appendChild(listItem);
  985. });
  986. }
  987. } else {
  988. alert('无法获取文件列表: ' + data.error);
  989. }
  990. })
  991. .catch(error => {
  992. console.error('Error:', error);
  993. alert('获取文件列表时发生错误');
  994. });
  995. });
  996. // 处理“关闭”按钮点击事件
  997. document.getElementById('closeDirectoryButton').addEventListener('click', function () {
  998. document.getElementById('modalOverlay').style.display = 'none';
  999. document.getElementById('directoryModal').style.display = 'none';
  1000. });
  1001. // 处理点击遮罩关闭弹出层
  1002. document.getElementById('modalOverlay').addEventListener('click', function () {
  1003. document.getElementById('modalOverlay').style.display = 'none';
  1004. document.getElementById('directoryModal').style.display = 'none';
  1005. });
  1006. </script>
  1007. </body>
  1008. </html>