@a3s-lab/office 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (463) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +470 -0
  3. package/THIRD_PARTY_NOTICES.md +33 -0
  4. package/dist/0~1403.js +245 -0
  5. package/dist/0~152.js +94 -0
  6. package/dist/0~3539.js +1856 -0
  7. package/dist/0~3557.js +179 -0
  8. package/dist/0~3635.js +302 -0
  9. package/dist/0~4595.js +1162 -0
  10. package/dist/0~5050.js +308 -0
  11. package/dist/0~6552.js +787 -0
  12. package/dist/0~7048.js +2110 -0
  13. package/dist/0~7614.js +1037 -0
  14. package/dist/0~8155.js +299 -0
  15. package/dist/0~9445.js +283 -0
  16. package/dist/0~9512.js +743 -0
  17. package/dist/0~document-editor.js +10967 -0
  18. package/dist/0~markdown-editor.js +2260 -0
  19. package/dist/0~pdf-viewer.js +2156 -0
  20. package/dist/0~presentation-editor.js +8359 -0
  21. package/dist/0~rslib-runtime.js +27 -0
  22. package/dist/0~spreadsheet-editor.js +10388 -0
  23. package/dist/0~use-office-draft.js +46 -0
  24. package/dist/0~work-document-extensions.js +2470 -0
  25. package/dist/0~work-document-links.js +14 -0
  26. package/dist/0~work-document-model-codec.js +42 -0
  27. package/dist/0~work-document-page-color.js +11 -0
  28. package/dist/0~work-document-paragraph-formatting.js +425 -0
  29. package/dist/0~work-docx-bibliography.js +347 -0
  30. package/dist/0~work-docx-export.js +1151 -0
  31. package/dist/0~work-docx-import.js +3116 -0
  32. package/dist/0~work-docx-page-color.js +42 -0
  33. package/dist/0~work-office-diagnostics.js +1377 -0
  34. package/dist/0~work-pptx-export.js +1009 -0
  35. package/dist/0~work-pptx-import.js +1138 -0
  36. package/dist/0~work-presentation-charts.js +442 -0
  37. package/dist/0~work-presentation-transition.js +38 -0
  38. package/dist/0~work-presentation-visual-scale.js +38 -0
  39. package/dist/0~work-spreadsheet-formula-support.js +9 -0
  40. package/dist/1134.js +445 -0
  41. package/dist/4104.js +5786 -0
  42. package/dist/432.js +211 -0
  43. package/dist/4704.js +1364 -0
  44. package/dist/6489.js +182 -0
  45. package/dist/8715.js +3959 -0
  46. package/dist/8728.js +723 -0
  47. package/dist/9356.js +10 -0
  48. package/dist/core.d.ts +15 -0
  49. package/dist/core.js +4 -0
  50. package/dist/index.d.ts +2 -0
  51. package/dist/index.js +5 -0
  52. package/dist/internal/design-system/primitives/button/button.d.ts +9 -0
  53. package/dist/internal/design-system/primitives/button/icon-button.d.ts +7 -0
  54. package/dist/internal/design-system/primitives/dialog/dialog.d.ts +12 -0
  55. package/dist/internal/design-system/primitives/feedback/collection-state.d.ts +9 -0
  56. package/dist/internal/design-system/primitives/feedback/inline-notice.d.ts +10 -0
  57. package/dist/internal/design-system/primitives/feedback/state-view.d.ts +13 -0
  58. package/dist/internal/design-system/primitives/form/field.d.ts +19 -0
  59. package/dist/internal/design-system/primitives/index.d.ts +14 -0
  60. package/dist/internal/design-system/primitives/layout/split-handle.d.ts +17 -0
  61. package/dist/internal/design-system/primitives/navigation/segmented-control.d.ts +19 -0
  62. package/dist/internal/design-system/primitives/navigation/tab-navigation.d.ts +13 -0
  63. package/dist/internal/design-system/primitives/navigation/tabs.d.ts +21 -0
  64. package/dist/internal/design-system/primitives/overlay/dialog-focus-scope.d.ts +17 -0
  65. package/dist/internal/design-system/primitives/overlay/popover.d.ts +34 -0
  66. package/dist/internal/design-system/primitives/overlay/portal-root.d.ts +1 -0
  67. package/dist/internal/design-system/primitives/status/status-badge.d.ts +6 -0
  68. package/dist/internal/features/work/components/work-document-pages.d.ts +4 -0
  69. package/dist/internal/features/work/components/work-editor-agent-menus.d.ts +12 -0
  70. package/dist/internal/features/work/components/work-editor-loading-state.d.ts +3 -0
  71. package/dist/internal/features/work/editors/document-changes-panel.d.ts +9 -0
  72. package/dist/internal/features/work/editors/document-citation-source-form.d.ts +33 -0
  73. package/dist/internal/features/work/editors/document-citations-panel.d.ts +8 -0
  74. package/dist/internal/features/work/editors/document-columns-panel.d.ts +5 -0
  75. package/dist/internal/features/work/editors/document-comment-composer.d.ts +13 -0
  76. package/dist/internal/features/work/editors/document-comments-panel.d.ts +17 -0
  77. package/dist/internal/features/work/editors/document-editor-focus.d.ts +1 -0
  78. package/dist/internal/features/work/editors/document-editor-pagination.d.ts +3 -0
  79. package/dist/internal/features/work/editors/document-editor-support.d.ts +34 -0
  80. package/dist/internal/features/work/editors/document-editor.d.ts +20 -0
  81. package/dist/internal/features/work/editors/document-find-highlight.d.ts +8 -0
  82. package/dist/internal/features/work/editors/document-find-replace-panel.d.ts +10 -0
  83. package/dist/internal/features/work/editors/document-formatting-options.d.ts +113 -0
  84. package/dist/internal/features/work/editors/document-home-ribbon.d.ts +9 -0
  85. package/dist/internal/features/work/editors/document-layout-panel.d.ts +10 -0
  86. package/dist/internal/features/work/editors/document-list-gallery.d.ts +4 -0
  87. package/dist/internal/features/work/editors/document-navigation-panel.d.ts +9 -0
  88. package/dist/internal/features/work/editors/document-page-chrome-editor.d.ts +39 -0
  89. package/dist/internal/features/work/editors/document-page-chrome-panel.d.ts +5 -0
  90. package/dist/internal/features/work/editors/document-page-chrome-ribbon.d.ts +10 -0
  91. package/dist/internal/features/work/editors/document-page-navigation.d.ts +14 -0
  92. package/dist/internal/features/work/editors/document-page-stack.d.ts +8 -0
  93. package/dist/internal/features/work/editors/document-pagination-popover.d.ts +4 -0
  94. package/dist/internal/features/work/editors/document-paragraph-spacing-popover.d.ts +4 -0
  95. package/dist/internal/features/work/editors/document-picture-ribbon.d.ts +4 -0
  96. package/dist/internal/features/work/editors/document-ruler-tab-stops.d.ts +12 -0
  97. package/dist/internal/features/work/editors/document-ruler.d.ts +15 -0
  98. package/dist/internal/features/work/editors/document-selection-context-menu.d.ts +22 -0
  99. package/dist/internal/features/work/editors/document-selection-toolbar.d.ts +8 -0
  100. package/dist/internal/features/work/editors/document-status-bar.d.ts +19 -0
  101. package/dist/internal/features/work/editors/document-style-gallery.d.ts +4 -0
  102. package/dist/internal/features/work/editors/document-table-insert-popover.d.ts +4 -0
  103. package/dist/internal/features/work/editors/document-table-ribbon.d.ts +7 -0
  104. package/dist/internal/features/work/editors/document-task-pane.d.ts +11 -0
  105. package/dist/internal/features/work/editors/document-toolbar.d.ts +100 -0
  106. package/dist/internal/features/work/editors/document-vertical-ruler.d.ts +6 -0
  107. package/dist/internal/features/work/editors/markdown-editor-focus.d.ts +2 -0
  108. package/dist/internal/features/work/editors/markdown-editor.d.ts +16 -0
  109. package/dist/internal/features/work/editors/markdown-insert-dialog.d.ts +19 -0
  110. package/dist/internal/features/work/editors/markdown-selection-context-menu.d.ts +14 -0
  111. package/dist/internal/features/work/editors/markdown-source-commands.d.ts +41 -0
  112. package/dist/internal/features/work/editors/markdown-status.d.ts +7 -0
  113. package/dist/internal/features/work/editors/markdown-toolbar.d.ts +22 -0
  114. package/dist/internal/features/work/editors/markdown-workspace.d.ts +26 -0
  115. package/dist/internal/features/work/editors/office-checkbox.d.ts +9 -0
  116. package/dist/internal/features/work/editors/office-color-picker.d.ts +11 -0
  117. package/dist/internal/features/work/editors/office-controls.d.ts +7 -0
  118. package/dist/internal/features/work/editors/office-dialog.d.ts +35 -0
  119. package/dist/internal/features/work/editors/office-editor-extension.d.ts +86 -0
  120. package/dist/internal/features/work/editors/office-file-data.d.ts +1 -0
  121. package/dist/internal/features/work/editors/office-font-families.d.ts +187 -0
  122. package/dist/internal/features/work/editors/office-menu-keyboard.d.ts +2 -0
  123. package/dist/internal/features/work/editors/office-number-field.d.ts +21 -0
  124. package/dist/internal/features/work/editors/office-number-normalization.d.ts +9 -0
  125. package/dist/internal/features/work/editors/office-select.d.ts +19 -0
  126. package/dist/internal/features/work/editors/office-shortcuts.d.ts +1 -0
  127. package/dist/internal/features/work/editors/office-slider.d.ts +10 -0
  128. package/dist/internal/features/work/editors/office-table-dimensions.d.ts +4 -0
  129. package/dist/internal/features/work/editors/office-table-insert-popover.d.ts +7 -0
  130. package/dist/internal/features/work/editors/office-task-pane.d.ts +7 -0
  131. package/dist/internal/features/work/editors/office-text-field.d.ts +20 -0
  132. package/dist/internal/features/work/editors/office-tiptap-extensions.d.ts +2 -0
  133. package/dist/internal/features/work/editors/pdf-annotation-controller.d.ts +23 -0
  134. package/dist/internal/features/work/editors/pdf-editor-extensions.d.ts +36 -0
  135. package/dist/internal/features/work/editors/pdf-thumbnail-rail.d.ts +26 -0
  136. package/dist/internal/features/work/editors/pdf-toolbar.d.ts +23 -0
  137. package/dist/internal/features/work/editors/pdf-viewer-controller.d.ts +48 -0
  138. package/dist/internal/features/work/editors/pdf-viewer.d.ts +11 -0
  139. package/dist/internal/features/work/editors/presentation-arrangement-controller.d.ts +19 -0
  140. package/dist/internal/features/work/editors/presentation-chart-analysis-canvas.d.ts +21 -0
  141. package/dist/internal/features/work/editors/presentation-chart-axis-canvas.d.ts +33 -0
  142. package/dist/internal/features/work/editors/presentation-chart-axis-editor.d.ts +5 -0
  143. package/dist/internal/features/work/editors/presentation-chart-canvas.d.ts +5 -0
  144. package/dist/internal/features/work/editors/presentation-chart-cartesian-canvas.d.ts +3 -0
  145. package/dist/internal/features/work/editors/presentation-chart-data-label-editor.d.ts +6 -0
  146. package/dist/internal/features/work/editors/presentation-chart-data-labels.d.ts +26 -0
  147. package/dist/internal/features/work/editors/presentation-chart-layout-editor.d.ts +5 -0
  148. package/dist/internal/features/work/editors/presentation-chart-legend-canvas.d.ts +15 -0
  149. package/dist/internal/features/work/editors/presentation-chart-panel.d.ts +7 -0
  150. package/dist/internal/features/work/editors/presentation-chart-series-analysis-editor.d.ts +6 -0
  151. package/dist/internal/features/work/editors/presentation-chart-series-canvas.d.ts +15 -0
  152. package/dist/internal/features/work/editors/presentation-command-controller.d.ts +3 -0
  153. package/dist/internal/features/work/editors/presentation-command-types.d.ts +206 -0
  154. package/dist/internal/features/work/editors/presentation-comments-panel.d.ts +9 -0
  155. package/dist/internal/features/work/editors/presentation-context-menu.d.ts +11 -0
  156. package/dist/internal/features/work/editors/presentation-design-panel.d.ts +13 -0
  157. package/dist/internal/features/work/editors/presentation-editor-focus.d.ts +12 -0
  158. package/dist/internal/features/work/editors/presentation-editor-operations.d.ts +10 -0
  159. package/dist/internal/features/work/editors/presentation-editor-types.d.ts +22 -0
  160. package/dist/internal/features/work/editors/presentation-editor.d.ts +3 -0
  161. package/dist/internal/features/work/editors/presentation-keyboard-extension.d.ts +3 -0
  162. package/dist/internal/features/work/editors/presentation-player.d.ts +7 -0
  163. package/dist/internal/features/work/editors/presentation-presenter-view.d.ts +15 -0
  164. package/dist/internal/features/work/editors/presentation-selection.d.ts +21 -0
  165. package/dist/internal/features/work/editors/presentation-slide-canvas.d.ts +26 -0
  166. package/dist/internal/features/work/editors/presentation-slide-thumbnail.d.ts +18 -0
  167. package/dist/internal/features/work/editors/presentation-status-bar.d.ts +10 -0
  168. package/dist/internal/features/work/editors/presentation-text-editor.d.ts +22 -0
  169. package/dist/internal/features/work/editors/presentation-text-formatting.d.ts +3 -0
  170. package/dist/internal/features/work/editors/presentation-thumbnail-rail.d.ts +20 -0
  171. package/dist/internal/features/work/editors/presentation-toolbar.d.ts +19 -0
  172. package/dist/internal/features/work/editors/presentation-transition-panel.d.ts +9 -0
  173. package/dist/internal/features/work/editors/presentation-workspace.d.ts +38 -0
  174. package/dist/internal/features/work/editors/spreadsheet-calculation-model.d.ts +8 -0
  175. package/dist/internal/features/work/editors/spreadsheet-calculation-projection.d.ts +32 -0
  176. package/dist/internal/features/work/editors/spreadsheet-chart-axis-editor.d.ts +9 -0
  177. package/dist/internal/features/work/editors/spreadsheet-chart-draft.d.ts +17 -0
  178. package/dist/internal/features/work/editors/spreadsheet-chart-layout-editor.d.ts +13 -0
  179. package/dist/internal/features/work/editors/spreadsheet-chart-panel.d.ts +10 -0
  180. package/dist/internal/features/work/editors/spreadsheet-chart-series-style-editor.d.ts +9 -0
  181. package/dist/internal/features/work/editors/spreadsheet-clipboard-shortcuts.d.ts +9 -0
  182. package/dist/internal/features/work/editors/spreadsheet-command-controller.d.ts +121 -0
  183. package/dist/internal/features/work/editors/spreadsheet-conditional-comparison-fields.d.ts +7 -0
  184. package/dist/internal/features/work/editors/spreadsheet-conditional-format-model.d.ts +72 -0
  185. package/dist/internal/features/work/editors/spreadsheet-conditional-format-panel.d.ts +7 -0
  186. package/dist/internal/features/work/editors/spreadsheet-conditional-threshold-fields.d.ts +10 -0
  187. package/dist/internal/features/work/editors/spreadsheet-context-menu.d.ts +36 -0
  188. package/dist/internal/features/work/editors/spreadsheet-data-label-editor.d.ts +9 -0
  189. package/dist/internal/features/work/editors/spreadsheet-editor-ribbon.d.ts +46 -0
  190. package/dist/internal/features/work/editors/spreadsheet-editor-support.d.ts +31 -0
  191. package/dist/internal/features/work/editors/spreadsheet-editor.d.ts +16 -0
  192. package/dist/internal/features/work/editors/spreadsheet-error-bar-editor.d.ts +10 -0
  193. package/dist/internal/features/work/editors/spreadsheet-find-bar.d.ts +8 -0
  194. package/dist/internal/features/work/editors/spreadsheet-find.d.ts +9 -0
  195. package/dist/internal/features/work/editors/spreadsheet-formula-panel.d.ts +10 -0
  196. package/dist/internal/features/work/editors/spreadsheet-header-footer-fields.d.ts +5 -0
  197. package/dist/internal/features/work/editors/spreadsheet-keyboard-navigation.d.ts +18 -0
  198. package/dist/internal/features/work/editors/spreadsheet-number-format.d.ts +11 -0
  199. package/dist/internal/features/work/editors/spreadsheet-pivot-panel.d.ts +10 -0
  200. package/dist/internal/features/work/editors/spreadsheet-print-settings-panel.d.ts +6 -0
  201. package/dist/internal/features/work/editors/spreadsheet-protection-panel.d.ts +7 -0
  202. package/dist/internal/features/work/editors/spreadsheet-sheet-bar.d.ts +17 -0
  203. package/dist/internal/features/work/editors/spreadsheet-sheet-model.d.ts +13 -0
  204. package/dist/internal/features/work/editors/spreadsheet-trendline-editor.d.ts +8 -0
  205. package/dist/internal/features/work/editors/spreadsheet-workbook-panel.d.ts +16 -0
  206. package/dist/internal/features/work/editors/use-document-comments.d.ts +26 -0
  207. package/dist/internal/features/work/editors/use-document-insert-commands.d.ts +19 -0
  208. package/dist/internal/features/work/editors/use-document-layout-fonts.d.ts +2 -0
  209. package/dist/internal/features/work/editors/use-document-page-chrome.d.ts +33 -0
  210. package/dist/internal/features/work/editors/use-document-pagination.d.ts +46 -0
  211. package/dist/internal/features/work/editors/use-markdown-source-history.d.ts +16 -0
  212. package/dist/internal/features/work/editors/use-office-draft.d.ts +10 -0
  213. package/dist/internal/features/work/editors/use-office-editor-keyboard-shortcuts.d.ts +9 -0
  214. package/dist/internal/features/work/editors/use-office-editor-runtime.d.ts +6 -0
  215. package/dist/internal/features/work/editors/use-office-editor-wheel-zoom.d.ts +19 -0
  216. package/dist/internal/features/work/editors/use-office-history.d.ts +10 -0
  217. package/dist/internal/features/work/editors/use-presentation-clipboard.d.ts +22 -0
  218. package/dist/internal/features/work/editors/use-presentation-design-commands.d.ts +33 -0
  219. package/dist/internal/features/work/editors/use-presentation-element-commands.d.ts +29 -0
  220. package/dist/internal/features/work/editors/use-presentation-geometry.d.ts +17 -0
  221. package/dist/internal/features/work/editors/use-presentation-history.d.ts +12 -0
  222. package/dist/internal/features/work/editors/use-presentation-review-commands.d.ts +22 -0
  223. package/dist/internal/features/work/editors/use-presentation-selection.d.ts +11 -0
  224. package/dist/internal/features/work/editors/use-presentation-slide-commands.d.ts +18 -0
  225. package/dist/internal/features/work/editors/use-presentation-thumbnail-visibility.d.ts +4 -0
  226. package/dist/internal/features/work/editors/use-presentation-thumbnail-window.d.ts +17 -0
  227. package/dist/internal/features/work/editors/use-presentation-transform.d.ts +53 -0
  228. package/dist/internal/features/work/editors/use-spreadsheet-calculation.d.ts +17 -0
  229. package/dist/internal/features/work/editors/use-spreadsheet-workbook-sync.d.ts +10 -0
  230. package/dist/internal/features/work/editors/work-office-chrome.d.ts +61 -0
  231. package/dist/internal/features/work/editors/work-office-ribbon-overflow.d.ts +18 -0
  232. package/dist/internal/features/work/work-agent-proposal-apply.d.ts +8 -0
  233. package/dist/internal/features/work/work-agent-proposal.d.ts +55 -0
  234. package/dist/internal/features/work/work-agent-request.d.ts +6 -0
  235. package/dist/internal/features/work/work-chart-series-analysis-context.d.ts +3 -0
  236. package/dist/internal/features/work/work-document-caption-nodes.d.ts +13 -0
  237. package/dist/internal/features/work/work-document-captions.d.ts +14 -0
  238. package/dist/internal/features/work/work-document-changes.d.ts +35 -0
  239. package/dist/internal/features/work/work-document-character-formatting.d.ts +13 -0
  240. package/dist/internal/features/work/work-document-citation-nodes.d.ts +25 -0
  241. package/dist/internal/features/work/work-document-citations.d.ts +21 -0
  242. package/dist/internal/features/work/work-document-columns.d.ts +15 -0
  243. package/dist/internal/features/work/work-document-comments.d.ts +48 -0
  244. package/dist/internal/features/work/work-document-extensions.d.ts +11 -0
  245. package/dist/internal/features/work/work-document-field-node.d.ts +12 -0
  246. package/dist/internal/features/work/work-document-fields.d.ts +15 -0
  247. package/dist/internal/features/work/work-document-file-io.d.ts +4 -0
  248. package/dist/internal/features/work/work-document-fonts.d.ts +16 -0
  249. package/dist/internal/features/work/work-document-image-layout.d.ts +29 -0
  250. package/dist/internal/features/work/work-document-incremental-layout.d.ts +17 -0
  251. package/dist/internal/features/work/work-document-layout.d.ts +5 -0
  252. package/dist/internal/features/work/work-document-line-measurement.d.ts +24 -0
  253. package/dist/internal/features/work/work-document-links.d.ts +2 -0
  254. package/dist/internal/features/work/work-document-lists.d.ts +25 -0
  255. package/dist/internal/features/work/work-document-model-codec.d.ts +3 -0
  256. package/dist/internal/features/work/work-document-model.d.ts +12 -0
  257. package/dist/internal/features/work/work-document-note-nodes.d.ts +11 -0
  258. package/dist/internal/features/work/work-document-notes.d.ts +18 -0
  259. package/dist/internal/features/work/work-document-outline.d.ts +14 -0
  260. package/dist/internal/features/work/work-document-page-break.d.ts +2 -0
  261. package/dist/internal/features/work/work-document-page-chrome-commands.d.ts +15 -0
  262. package/dist/internal/features/work/work-document-page-chrome.d.ts +19 -0
  263. package/dist/internal/features/work/work-document-page-color.d.ts +3 -0
  264. package/dist/internal/features/work/work-document-pages.d.ts +19 -0
  265. package/dist/internal/features/work/work-document-pagination-decorations.d.ts +3 -0
  266. package/dist/internal/features/work/work-document-pagination-dom.d.ts +35 -0
  267. package/dist/internal/features/work/work-document-pagination-measurement.d.ts +9 -0
  268. package/dist/internal/features/work/work-document-pagination-types.d.ts +88 -0
  269. package/dist/internal/features/work/work-document-pagination.d.ts +17 -0
  270. package/dist/internal/features/work/work-document-paragraph-formatting.d.ts +61 -0
  271. package/dist/internal/features/work/work-document-search.d.ts +11 -0
  272. package/dist/internal/features/work/work-document-section-editor.d.ts +20 -0
  273. package/dist/internal/features/work/work-document-section-node.d.ts +13 -0
  274. package/dist/internal/features/work/work-document-section.d.ts +34 -0
  275. package/dist/internal/features/work/work-document-selection-menu.d.ts +54 -0
  276. package/dist/internal/features/work/work-document-tab-node.d.ts +6 -0
  277. package/dist/internal/features/work/work-document-tab-stops.d.ts +29 -0
  278. package/dist/internal/features/work/work-document-table-cell-formatting.d.ts +46 -0
  279. package/dist/internal/features/work/work-document-table-commands.d.ts +17 -0
  280. package/dist/internal/features/work/work-document-table-pagination.d.ts +5 -0
  281. package/dist/internal/features/work/work-document-table-row.d.ts +37 -0
  282. package/dist/internal/features/work/work-document-table-sizing.d.ts +27 -0
  283. package/dist/internal/features/work/work-document-text-layout.d.ts +14 -0
  284. package/dist/internal/features/work/work-docx-bibliography.d.ts +12 -0
  285. package/dist/internal/features/work/work-docx-caption-diagnostics.d.ts +6 -0
  286. package/dist/internal/features/work/work-docx-caption-export.d.ts +4 -0
  287. package/dist/internal/features/work/work-docx-caption-fields.d.ts +5 -0
  288. package/dist/internal/features/work/work-docx-caption-import.d.ts +20 -0
  289. package/dist/internal/features/work/work-docx-change-import.d.ts +12 -0
  290. package/dist/internal/features/work/work-docx-citation-diagnostics.d.ts +3 -0
  291. package/dist/internal/features/work/work-docx-citation-export.d.ts +3 -0
  292. package/dist/internal/features/work/work-docx-citation-import.d.ts +23 -0
  293. package/dist/internal/features/work/work-docx-column-export.d.ts +14 -0
  294. package/dist/internal/features/work/work-docx-column-import.d.ts +2 -0
  295. package/dist/internal/features/work/work-docx-comment-import.d.ts +14 -0
  296. package/dist/internal/features/work/work-docx-export-formatting.d.ts +30 -0
  297. package/dist/internal/features/work/work-docx-export-image.d.ts +2 -0
  298. package/dist/internal/features/work/work-docx-export.d.ts +2 -0
  299. package/dist/internal/features/work/work-docx-field-export.d.ts +2 -0
  300. package/dist/internal/features/work/work-docx-field-import.d.ts +16 -0
  301. package/dist/internal/features/work/work-docx-field-instructions.d.ts +8 -0
  302. package/dist/internal/features/work/work-docx-image-layout-import.d.ts +12 -0
  303. package/dist/internal/features/work/work-docx-import.d.ts +50 -0
  304. package/dist/internal/features/work/work-docx-list-import.d.ts +14 -0
  305. package/dist/internal/features/work/work-docx-note-diagnostics.d.ts +3 -0
  306. package/dist/internal/features/work/work-docx-note-import.d.ts +3 -0
  307. package/dist/internal/features/work/work-docx-page-chrome-diagnostics.d.ts +3 -0
  308. package/dist/internal/features/work/work-docx-page-chrome-import.d.ts +11 -0
  309. package/dist/internal/features/work/work-docx-page-color.d.ts +2 -0
  310. package/dist/internal/features/work/work-docx-paragraph-alignment-import.d.ts +12 -0
  311. package/dist/internal/features/work/work-docx-paragraph-direction-import.d.ts +12 -0
  312. package/dist/internal/features/work/work-docx-paragraph-indent-import.d.ts +12 -0
  313. package/dist/internal/features/work/work-docx-paragraph-pagination-import.d.ts +12 -0
  314. package/dist/internal/features/work/work-docx-paragraph-spacing-import.d.ts +12 -0
  315. package/dist/internal/features/work/work-docx-paragraph-styles.d.ts +18 -0
  316. package/dist/internal/features/work/work-docx-run-formatting-import.d.ts +19 -0
  317. package/dist/internal/features/work/work-docx-tab-stop-import.d.ts +13 -0
  318. package/dist/internal/features/work/work-docx-table-cell-export.d.ts +4 -0
  319. package/dist/internal/features/work/work-docx-table-cell-import.d.ts +16 -0
  320. package/dist/internal/features/work/work-docx-table-row-import.d.ts +13 -0
  321. package/dist/internal/features/work/work-docx-table-sizing-export.d.ts +8 -0
  322. package/dist/internal/features/work/work-docx-table-sizing-import.d.ts +12 -0
  323. package/dist/internal/features/work/work-docx-theme.d.ts +9 -0
  324. package/dist/internal/features/work/work-file-data.d.ts +1 -0
  325. package/dist/internal/features/work/work-file-download.d.ts +3 -0
  326. package/dist/internal/features/work/work-file-io.d.ts +8 -0
  327. package/dist/internal/features/work/work-markdown-extensions.d.ts +19 -0
  328. package/dist/internal/features/work/work-markdown-file-io.d.ts +3 -0
  329. package/dist/internal/features/work/work-markdown-selection-menu.d.ts +57 -0
  330. package/dist/internal/features/work/work-office-diagnostics.d.ts +9 -0
  331. package/dist/internal/features/work/work-ooxml-package.d.ts +28 -0
  332. package/dist/internal/features/work/work-pdf-export.d.ts +23 -0
  333. package/dist/internal/features/work/work-pptx-chart-axes.d.ts +3 -0
  334. package/dist/internal/features/work/work-pptx-chart-axis-diagnostics.d.ts +5 -0
  335. package/dist/internal/features/work/work-pptx-chart-data-labels.d.ts +12 -0
  336. package/dist/internal/features/work/work-pptx-chart-import.d.ts +11 -0
  337. package/dist/internal/features/work/work-pptx-chart-layout-style.d.ts +15 -0
  338. package/dist/internal/features/work/work-pptx-chart-series-analysis.d.ts +13 -0
  339. package/dist/internal/features/work/work-pptx-chart-xy.d.ts +3 -0
  340. package/dist/internal/features/work/work-pptx-comments.d.ts +17 -0
  341. package/dist/internal/features/work/work-pptx-export.d.ts +4 -0
  342. package/dist/internal/features/work/work-pptx-groups.d.ts +19 -0
  343. package/dist/internal/features/work/work-pptx-import.d.ts +6 -0
  344. package/dist/internal/features/work/work-pptx-layout-export.d.ts +13 -0
  345. package/dist/internal/features/work/work-pptx-layout-import.d.ts +30 -0
  346. package/dist/internal/features/work/work-pptx-style.d.ts +13 -0
  347. package/dist/internal/features/work/work-pptx-transition.d.ts +13 -0
  348. package/dist/internal/features/work/work-presentation-agent-context.d.ts +6 -0
  349. package/dist/internal/features/work/work-presentation-chart-axes.d.ts +14 -0
  350. package/dist/internal/features/work/work-presentation-charts.d.ts +37 -0
  351. package/dist/internal/features/work/work-presentation-clipboard.d.ts +26 -0
  352. package/dist/internal/features/work/work-presentation-file-io.d.ts +15 -0
  353. package/dist/internal/features/work/work-presentation-groups.d.ts +17 -0
  354. package/dist/internal/features/work/work-presentation-layouts.d.ts +13 -0
  355. package/dist/internal/features/work/work-presentation-transition.d.ts +4 -0
  356. package/dist/internal/features/work/work-presentation-visual-scale.d.ts +2 -0
  357. package/dist/internal/features/work/work-repository.d.ts +4 -0
  358. package/dist/internal/features/work/work-spreadsheet-agent-context.d.ts +15 -0
  359. package/dist/internal/features/work/work-spreadsheet-chart-axis.d.ts +42 -0
  360. package/dist/internal/features/work/work-spreadsheet-chart-layout.d.ts +29 -0
  361. package/dist/internal/features/work/work-spreadsheet-chart-legend-svg.d.ts +18 -0
  362. package/dist/internal/features/work/work-spreadsheet-chart-series-layout.d.ts +24 -0
  363. package/dist/internal/features/work/work-spreadsheet-chart-series-style.d.ts +29 -0
  364. package/dist/internal/features/work/work-spreadsheet-chart-svg-utils.d.ts +7 -0
  365. package/dist/internal/features/work/work-spreadsheet-chart-svg.d.ts +3 -0
  366. package/dist/internal/features/work/work-spreadsheet-chart-types.d.ts +147 -0
  367. package/dist/internal/features/work/work-spreadsheet-chart-validation.d.ts +2 -0
  368. package/dist/internal/features/work/work-spreadsheet-charts.d.ts +17 -0
  369. package/dist/internal/features/work/work-spreadsheet-combination-chart-svg.d.ts +9 -0
  370. package/dist/internal/features/work/work-spreadsheet-comments.d.ts +7 -0
  371. package/dist/internal/features/work/work-spreadsheet-conditional-canvas.d.ts +5 -0
  372. package/dist/internal/features/work/work-spreadsheet-conditional-colors.d.ts +9 -0
  373. package/dist/internal/features/work/work-spreadsheet-conditional-comparisons.d.ts +4 -0
  374. package/dist/internal/features/work/work-spreadsheet-conditional-data-bar.d.ts +8 -0
  375. package/dist/internal/features/work/work-spreadsheet-conditional-format.d.ts +10 -0
  376. package/dist/internal/features/work/work-spreadsheet-conditional-icons.d.ts +107 -0
  377. package/dist/internal/features/work/work-spreadsheet-conditional-values.d.ts +19 -0
  378. package/dist/internal/features/work/work-spreadsheet-data-label-svg.d.ts +27 -0
  379. package/dist/internal/features/work/work-spreadsheet-error-bar-svg.d.ts +5 -0
  380. package/dist/internal/features/work/work-spreadsheet-error-bars.d.ts +8 -0
  381. package/dist/internal/features/work/work-spreadsheet-formula-analysis.d.ts +30 -0
  382. package/dist/internal/features/work/work-spreadsheet-formula-support.d.ts +1 -0
  383. package/dist/internal/features/work/work-spreadsheet-formulas.d.ts +19 -0
  384. package/dist/internal/features/work/work-spreadsheet-header-footer.d.ts +14 -0
  385. package/dist/internal/features/work/work-spreadsheet-line-chart-svg.d.ts +10 -0
  386. package/dist/internal/features/work/work-spreadsheet-page-breaks.d.ts +4 -0
  387. package/dist/internal/features/work/work-spreadsheet-page-setup.d.ts +26 -0
  388. package/dist/internal/features/work/work-spreadsheet-pivot-engine.d.ts +21 -0
  389. package/dist/internal/features/work/work-spreadsheet-pivot-values.d.ts +7 -0
  390. package/dist/internal/features/work/work-spreadsheet-pivots.d.ts +27 -0
  391. package/dist/internal/features/work/work-spreadsheet-protection.d.ts +55 -0
  392. package/dist/internal/features/work/work-spreadsheet-ranges.d.ts +25 -0
  393. package/dist/internal/features/work/work-spreadsheet-trendline-svg.d.ts +9 -0
  394. package/dist/internal/features/work/work-spreadsheet-trendlines.d.ts +11 -0
  395. package/dist/internal/features/work/work-spreadsheet-xy-chart-axes-svg.d.ts +10 -0
  396. package/dist/internal/features/work/work-templates.d.ts +4 -0
  397. package/dist/internal/features/work/work-types.d.ts +513 -0
  398. package/dist/internal/features/work/work-xlsx-chart-axes.d.ts +4 -0
  399. package/dist/internal/features/work/work-xlsx-chart-diagnostics.d.ts +3 -0
  400. package/dist/internal/features/work/work-xlsx-chart-layout.d.ts +16 -0
  401. package/dist/internal/features/work/work-xlsx-chart-series-style.d.ts +6 -0
  402. package/dist/internal/features/work/work-xlsx-chart-values.d.ts +10 -0
  403. package/dist/internal/features/work/work-xlsx-charts.d.ts +32 -0
  404. package/dist/internal/features/work/work-xlsx-conditional-format-diagnostics.d.ts +6 -0
  405. package/dist/internal/features/work/work-xlsx-conditional-format-write.d.ts +11 -0
  406. package/dist/internal/features/work/work-xlsx-conditional-format.d.ts +29 -0
  407. package/dist/internal/features/work/work-xlsx-defined-names.d.ts +4 -0
  408. package/dist/internal/features/work/work-xlsx-drawing-geometry.d.ts +27 -0
  409. package/dist/internal/features/work/work-xlsx-formula-diagnostics.d.ts +3 -0
  410. package/dist/internal/features/work/work-xlsx-formulas.d.ts +40 -0
  411. package/dist/internal/features/work/work-xlsx-header-footer.d.ts +12 -0
  412. package/dist/internal/features/work/work-xlsx-images.d.ts +17 -0
  413. package/dist/internal/features/work/work-xlsx-interop.d.ts +39 -0
  414. package/dist/internal/features/work/work-xlsx-page-breaks.d.ts +7 -0
  415. package/dist/internal/features/work/work-xlsx-page-setup-diagnostics.d.ts +2 -0
  416. package/dist/internal/features/work/work-xlsx-page-setup.d.ts +5 -0
  417. package/dist/internal/features/work/work-xlsx-pivot-diagnostics.d.ts +3 -0
  418. package/dist/internal/features/work/work-xlsx-pivot-xml.d.ts +9 -0
  419. package/dist/internal/features/work/work-xlsx-pivots.d.ts +32 -0
  420. package/dist/internal/features/work/work-xlsx-protection.d.ts +24 -0
  421. package/dist/internal/features/workspace/components/workspace-context-menu.d.ts +29 -0
  422. package/dist/internal/features/workspace/components/workspace-text-control-selection.d.ts +7 -0
  423. package/dist/internal/kernel/office-kernel-client-types.d.ts +40 -0
  424. package/dist/internal/kernel/office-kernel-client.d.ts +4 -0
  425. package/dist/internal/kernel/office-kernel-fallback.d.ts +2 -0
  426. package/dist/internal/kernel/office-kernel-presentation-fallback.d.ts +2 -0
  427. package/dist/internal/kernel/office-kernel-protocol.d.ts +229 -0
  428. package/dist/internal/kernel/office-kernel-spreadsheet-fallback-formula.d.ts +3 -0
  429. package/dist/internal/kernel/office-kernel-spreadsheet-fallback-validation.d.ts +5 -0
  430. package/dist/internal/kernel/office-kernel-spreadsheet-fallback-value.d.ts +6 -0
  431. package/dist/internal/kernel/office-kernel-spreadsheet-fallback.d.ts +2 -0
  432. package/dist/internal/kernel/office-kernel-spreadsheet-protocol.d.ts +112 -0
  433. package/dist/internal/kernel/office-kernel-spreadsheet-session-fallback.d.ts +8 -0
  434. package/dist/internal/kernel/office-kernel-text-fallback.d.ts +10 -0
  435. package/dist/internal/kernel/office-kernel-version.d.ts +1 -0
  436. package/dist/internal/kernel/office-kernel.worker.d.ts +1 -0
  437. package/dist/internal/keyboard-shortcuts.d.ts +2 -0
  438. package/dist/internal/state/app-state.d.ts +8 -0
  439. package/dist/noto-naskh-arabic-regular.ttf +0 -0
  440. package/dist/noto-naskh-arabic.LICENSE.txt +94 -0
  441. package/dist/noto-sans-hans-regular.otf +0 -0
  442. package/dist/noto-sans-hans.LICENSE.txt +94 -0
  443. package/dist/noto-sans-hebrew-regular.ttf +0 -0
  444. package/dist/noto-sans-hebrew.LICENSE.txt +94 -0
  445. package/dist/noto-sans-regular.ttf +0 -0
  446. package/dist/noto-sans.LICENSE.txt +94 -0
  447. package/dist/office-kernel.wasm +0 -0
  448. package/dist/office-kernel.worker.js +14605 -0
  449. package/dist/office-surface.d.ts +10 -0
  450. package/dist/pdfium.LICENSE.txt +196 -0
  451. package/dist/pdfium.wasm +0 -0
  452. package/dist/pptxgen.LICENSE.txt +21 -0
  453. package/dist/pptxgen.bundle.js +11244 -0
  454. package/dist/react.d.ts +51 -0
  455. package/dist/react.js +1 -0
  456. package/dist/styles.css +17435 -0
  457. package/dist/styles.js +0 -0
  458. package/dist/vue.d.ts +282 -0
  459. package/dist/vue.js +231 -0
  460. package/dist/web-component.d.ts +98 -0
  461. package/dist/web-component.js +335 -0
  462. package/docs/browser-editor-architecture.md +947 -0
  463. package/package.json +165 -0
@@ -0,0 +1,2156 @@
1
+ import { __webpack_require__ } from "./0~rslib-runtime.js";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { AnnotationPlugin, DocumentManagerPlugin, ExportPlugin, HistoryPlugin, PDFViewer, ScrollPlugin, SearchPlugin, ThumbnailPlugin, ZoomMode, ZoomPlugin } from "@embedpdf/react-pdf-viewer";
4
+ import { AlertCircle, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Ellipsis, GalleryVerticalEnd, Highlighter, Loader2, Minus, MousePointer2, MoveHorizontal, Pencil, Plus, Redo2, Save, Scan, Search, SlidersHorizontal, Strikethrough, Trash2, Type, Underline, Undo2, X } from "lucide-react";
5
+ import { useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
6
+ import { createOfficeEditorExtension, useOfficeEditorRuntime, useOfficeEditorKeyboardShortcuts } from "./0~3557.js";
7
+ import { isOfficeShortcutBlocked, OfficeColorPicker } from "./0~3635.js";
8
+ import { button_Button, moveOfficeMenuFocus, icon_button_IconButton, office_text_field_OfficeTextField, Popover, useDialogFocusScope, useOfficeEditorWheelZoom } from "./0~9512.js";
9
+ import { StateView } from "./432.js";
10
+ var pdf_viewer_namespaceObject = {};
11
+ __webpack_require__.r(pdf_viewer_namespaceObject);
12
+ __webpack_require__.d(pdf_viewer_namespaceObject, {
13
+ PdfViewer: ()=>PdfViewer,
14
+ a3sPdfUiSchema: ()=>a3sPdfUiSchema
15
+ });
16
+ const INITIAL_STATE = {
17
+ activeToolId: null,
18
+ annotationColor: '#ffd966',
19
+ annotationOpacity: 1,
20
+ annotationStrokeWidth: 6,
21
+ available: false,
22
+ availableToolIds: [],
23
+ hasPendingChanges: false,
24
+ selectedCount: 0,
25
+ supportsOpacity: false,
26
+ supportsStrokeWidth: false
27
+ };
28
+ function usePdfAnnotationController(registry) {
29
+ const capabilitiesRef = useRef(null);
30
+ const [state, setState] = useState(INITIAL_STATE);
31
+ useEffect(()=>{
32
+ let disposed = false;
33
+ const unsubscribe = [];
34
+ capabilitiesRef.current = null;
35
+ setState(INITIAL_STATE);
36
+ if (!registry) return;
37
+ registry.pluginsReady().then(()=>{
38
+ if (disposed) return;
39
+ const capabilities = {
40
+ annotation: registry.getPlugin(AnnotationPlugin.id)?.provides() ?? null,
41
+ documentManager: registry.getPlugin(DocumentManagerPlugin.id)?.provides() ?? null
42
+ };
43
+ capabilitiesRef.current = capabilities;
44
+ const sync = ()=>{
45
+ if (disposed) return;
46
+ const scope = activeAnnotationScope(capabilities);
47
+ const annotationState = safely(()=>scope?.getState());
48
+ const activeToolId = annotationState?.activeToolId ?? null;
49
+ const style = currentAnnotationStyle(capabilities, scope, activeToolId);
50
+ setState({
51
+ activeToolId,
52
+ annotationColor: currentAnnotationColor(capabilities, scope, activeToolId),
53
+ ...style,
54
+ available: Boolean(scope),
55
+ availableToolIds: availableAnnotationToolIds(capabilities),
56
+ hasPendingChanges: annotationState?.hasPendingChanges ?? false,
57
+ selectedCount: annotationState?.selectedUids.length ?? 0
58
+ });
59
+ };
60
+ subscribe(unsubscribe, capabilities.annotation?.onStateChange, sync);
61
+ subscribe(unsubscribe, capabilities.annotation?.onActiveToolChange, sync);
62
+ subscribe(unsubscribe, capabilities.documentManager?.onActiveDocumentChanged, sync);
63
+ subscribe(unsubscribe, capabilities.documentManager?.onDocumentOpened, sync);
64
+ subscribe(unsubscribe, capabilities.documentManager?.onDocumentClosed, sync);
65
+ sync();
66
+ }).catch(()=>{
67
+ if (!disposed) setState(INITIAL_STATE);
68
+ });
69
+ return ()=>{
70
+ disposed = true;
71
+ capabilitiesRef.current = null;
72
+ for (const stop of unsubscribe)stop();
73
+ };
74
+ }, [
75
+ registry
76
+ ]);
77
+ const selectTool = useCallback((toolId)=>{
78
+ const capabilities = capabilitiesRef.current;
79
+ const scope = activeAnnotationScope(capabilities);
80
+ if (!scope) return;
81
+ if (toolId && !capabilities?.annotation?.getTool(toolId)) return;
82
+ safely(()=>scope.setActiveTool(toolId));
83
+ }, []);
84
+ const deleteSelection = useCallback(()=>{
85
+ const scope = activeAnnotationScope(capabilitiesRef.current);
86
+ if (!scope) return;
87
+ const selected = new Set(scope.getSelectedAnnotationIds());
88
+ if (0 === selected.size) return;
89
+ const deletions = Object.entries(scope.getState().pages).flatMap(([pageIndex, annotationIds])=>annotationIds.filter((annotationId)=>selected.has(annotationId)).map((annotationId)=>({
90
+ pageIndex: Number(pageIndex),
91
+ id: annotationId
92
+ })));
93
+ if (deletions.length > 0) scope.deleteAnnotations(deletions);
94
+ }, []);
95
+ const setAnnotationColor = useCallback((color)=>{
96
+ const normalizedColor = normalizeAnnotationColor(color);
97
+ const capabilities = capabilitiesRef.current;
98
+ const scope = activeAnnotationScope(capabilities);
99
+ if (!normalizedColor || !capabilities?.annotation || !scope) return;
100
+ const activeToolId = scope.getState().activeToolId;
101
+ const patch = {
102
+ color: normalizedColor,
103
+ strokeColor: normalizedColor
104
+ };
105
+ if (activeToolId) capabilities.annotation.setToolDefaults(activeToolId, patch);
106
+ const selected = scope.getSelectedAnnotations();
107
+ if (selected.length) scope.updateAnnotations(selected.map(({ object })=>({
108
+ pageIndex: object.pageIndex,
109
+ id: object.id,
110
+ patch
111
+ })));
112
+ setState((current)=>({
113
+ ...current,
114
+ annotationColor: normalizedColor
115
+ }));
116
+ }, []);
117
+ const setAnnotationOpacity = useCallback((opacity)=>{
118
+ const normalizedOpacity = normalizeAnnotationOpacity(opacity);
119
+ if (null === normalizedOpacity || !applyAnnotationNumberStyle(capabilitiesRef.current, 'opacity', normalizedOpacity)) return;
120
+ setState((current)=>({
121
+ ...current,
122
+ annotationOpacity: normalizedOpacity
123
+ }));
124
+ }, []);
125
+ const setAnnotationStrokeWidth = useCallback((strokeWidth)=>{
126
+ const normalizedStrokeWidth = normalizeAnnotationStrokeWidth(strokeWidth);
127
+ if (null === normalizedStrokeWidth || !applyAnnotationNumberStyle(capabilitiesRef.current, 'strokeWidth', normalizedStrokeWidth)) return;
128
+ setState((current)=>({
129
+ ...current,
130
+ annotationStrokeWidth: normalizedStrokeWidth
131
+ }));
132
+ }, []);
133
+ return useMemo(()=>({
134
+ state,
135
+ deleteSelection,
136
+ setAnnotationColor,
137
+ setAnnotationOpacity,
138
+ setAnnotationStrokeWidth,
139
+ selectTool
140
+ }), [
141
+ deleteSelection,
142
+ setAnnotationColor,
143
+ setAnnotationOpacity,
144
+ setAnnotationStrokeWidth,
145
+ selectTool,
146
+ state
147
+ ]);
148
+ }
149
+ const PDF_ANNOTATION_TOOL_IDS = [
150
+ 'highlight',
151
+ 'underline',
152
+ 'strikeout',
153
+ 'ink',
154
+ 'freeText'
155
+ ];
156
+ function availableAnnotationToolIds(capabilities) {
157
+ return PDF_ANNOTATION_TOOL_IDS.filter((toolId)=>Boolean(safely(()=>capabilities.annotation?.getTool(toolId))));
158
+ }
159
+ function currentAnnotationStyle(capabilities, scope, activeToolId) {
160
+ const selectedObjects = safely(()=>scope?.getSelectedAnnotations().map(({ object })=>object)) ?? [];
161
+ const activeDefaults = activeToolId ? safely(()=>capabilities.annotation?.getTool(activeToolId)?.defaults) : null;
162
+ const opacitySource = selectedObjects.find((object)=>annotationRecordSupports(object, 'opacity')) ?? activeDefaults;
163
+ const strokeWidthSource = selectedObjects.find((object)=>annotationRecordSupports(object, 'strokeWidth')) ?? activeDefaults;
164
+ return {
165
+ annotationOpacity: annotationNumberFromRecord(opacitySource, 'opacity', normalizeAnnotationOpacity) ?? INITIAL_STATE.annotationOpacity,
166
+ annotationStrokeWidth: annotationNumberFromRecord(strokeWidthSource, 'strokeWidth', normalizeAnnotationStrokeWidth) ?? INITIAL_STATE.annotationStrokeWidth,
167
+ supportsOpacity: selectedObjects.some((object)=>annotationRecordSupports(object, 'opacity')) || annotationRecordSupports(activeDefaults, 'opacity'),
168
+ supportsStrokeWidth: selectedObjects.some((object)=>annotationRecordSupports(object, 'strokeWidth')) || annotationRecordSupports(activeDefaults, 'strokeWidth')
169
+ };
170
+ }
171
+ function applyAnnotationNumberStyle(capabilities, attribute, value) {
172
+ const scope = activeAnnotationScope(capabilities);
173
+ if (!capabilities?.annotation || !scope) return false;
174
+ const patch = {
175
+ [attribute]: value
176
+ };
177
+ const activeToolId = scope.getState().activeToolId;
178
+ const activeDefaults = activeToolId ? safely(()=>capabilities.annotation?.getTool(activeToolId)?.defaults) : null;
179
+ let applied = false;
180
+ if (activeToolId && annotationRecordSupports(activeDefaults, attribute)) {
181
+ capabilities.annotation.setToolDefaults(activeToolId, patch);
182
+ applied = true;
183
+ }
184
+ const selected = scope.getSelectedAnnotations().filter(({ object })=>annotationRecordSupports(object, attribute));
185
+ if (selected.length) {
186
+ scope.updateAnnotations(selected.map(({ object })=>({
187
+ pageIndex: object.pageIndex,
188
+ id: object.id,
189
+ patch
190
+ })));
191
+ applied = true;
192
+ }
193
+ return applied;
194
+ }
195
+ function currentAnnotationColor(capabilities, scope, activeToolId) {
196
+ const selectedObject = safely(()=>scope?.getSelectedAnnotations()[0]?.object);
197
+ const selectedColor = annotationColorFromRecord(selectedObject);
198
+ if (selectedColor) return selectedColor;
199
+ const activeTool = activeToolId ? safely(()=>capabilities.annotation?.getTool(activeToolId)) : null;
200
+ return annotationColorFromRecord(activeTool?.defaults) ?? INITIAL_STATE.annotationColor;
201
+ }
202
+ function annotationColorFromRecord(value) {
203
+ if (!value || 'object' != typeof value) return null;
204
+ const record = value;
205
+ return normalizeAnnotationColor(record.color ?? record.strokeColor);
206
+ }
207
+ function annotationNumberFromRecord(value, attribute, normalize) {
208
+ if (!annotationRecordSupports(value, attribute)) return null;
209
+ return normalize(value[attribute]);
210
+ }
211
+ function annotationRecordSupports(value, attribute) {
212
+ return Boolean(value && 'object' == typeof value && attribute in value);
213
+ }
214
+ function normalizeAnnotationColor(value) {
215
+ if ('string' != typeof value || !/^#[0-9a-f]{6}$/i.test(value.trim())) return null;
216
+ return value.trim().toLowerCase();
217
+ }
218
+ function normalizeAnnotationOpacity(value) {
219
+ return 'number' == typeof value && Number.isFinite(value) && value >= 0 && value <= 1 ? value : null;
220
+ }
221
+ function normalizeAnnotationStrokeWidth(value) {
222
+ return 'number' == typeof value && Number.isFinite(value) && value > 0 && value <= 24 ? value : null;
223
+ }
224
+ function activeAnnotationScope(capabilities) {
225
+ const documentId = safely(()=>capabilities?.documentManager?.getActiveDocumentId()) ?? null;
226
+ if (!documentId) return null;
227
+ return safely(()=>capabilities?.annotation?.forDocument(documentId)) ?? null;
228
+ }
229
+ function subscribe(unsubscribe, event, listener) {
230
+ if (!event) return;
231
+ const stop = safely(()=>event(()=>listener()));
232
+ if (stop) unsubscribe.push(stop);
233
+ }
234
+ function safely(action) {
235
+ try {
236
+ return action();
237
+ } catch {
238
+ return;
239
+ }
240
+ }
241
+ function createPdfEditorExtensions() {
242
+ return [
243
+ createOfficeEditorExtension({
244
+ name: 'pdfDocument',
245
+ addCommands: ()=>({
246
+ save: {
247
+ canExecute: canSave,
248
+ execute: ({ save })=>save.execute()
249
+ }
250
+ })
251
+ }),
252
+ createOfficeEditorExtension({
253
+ name: 'pdfHistory',
254
+ addCommands: ()=>({
255
+ redo: {
256
+ canExecute: ({ editable, viewer })=>editable && documentReady(viewer) && viewer.state.features.history && viewer.state.canRedo,
257
+ execute: ({ viewer })=>viewer.redo()
258
+ },
259
+ undo: {
260
+ canExecute: ({ editable, viewer })=>editable && documentReady(viewer) && viewer.state.features.history && viewer.state.canUndo,
261
+ execute: ({ viewer })=>viewer.undo()
262
+ }
263
+ })
264
+ }),
265
+ createOfficeEditorExtension({
266
+ name: 'pdfNavigation',
267
+ addCommands: ()=>({
268
+ goToPage: {
269
+ canExecute: ({ viewer }, page)=>canNavigate(viewer) && Number.isInteger(page) && page >= 1 && page <= viewer.state.totalPages,
270
+ execute: ({ viewer }, page)=>viewer.goToPage(page)
271
+ },
272
+ nextPage: {
273
+ canExecute: ({ viewer })=>canNavigate(viewer) && viewer.state.currentPage < viewer.state.totalPages,
274
+ execute: ({ viewer })=>viewer.nextPage()
275
+ },
276
+ previousPage: {
277
+ canExecute: ({ viewer })=>canNavigate(viewer) && viewer.state.currentPage > 1,
278
+ execute: ({ viewer })=>viewer.previousPage()
279
+ }
280
+ })
281
+ }),
282
+ createOfficeEditorExtension({
283
+ name: 'pdfSearch',
284
+ addCommands: ()=>({
285
+ clearSearch: {
286
+ canExecute: ({ viewer })=>canSearch(viewer),
287
+ execute: ({ viewer })=>viewer.clearSearch()
288
+ },
289
+ nextSearchResult: {
290
+ canExecute: ({ viewer })=>canNavigateSearchResults(viewer),
291
+ execute: ({ viewer })=>viewer.nextSearchResult()
292
+ },
293
+ previousSearchResult: {
294
+ canExecute: ({ viewer })=>canNavigateSearchResults(viewer),
295
+ execute: ({ viewer })=>viewer.previousSearchResult()
296
+ },
297
+ search: {
298
+ canExecute: ({ viewer })=>canSearch(viewer),
299
+ execute: ({ viewer }, query)=>viewer.search(query)
300
+ }
301
+ })
302
+ }),
303
+ createOfficeEditorExtension({
304
+ name: 'pdfZoom',
305
+ addCommands: ()=>({
306
+ fitPage: {
307
+ canExecute: ({ viewer })=>canZoom(viewer),
308
+ execute: ({ viewer })=>viewer.fitPage()
309
+ },
310
+ fitWidth: {
311
+ canExecute: ({ viewer })=>canZoom(viewer),
312
+ execute: ({ viewer })=>viewer.fitWidth()
313
+ },
314
+ zoomIn: {
315
+ canExecute: ({ viewer })=>canZoom(viewer),
316
+ execute: ({ viewer })=>viewer.zoomIn()
317
+ },
318
+ zoomOut: {
319
+ canExecute: ({ viewer })=>canZoom(viewer),
320
+ execute: ({ viewer })=>viewer.zoomOut()
321
+ }
322
+ })
323
+ }),
324
+ createOfficeEditorExtension({
325
+ name: 'pdfAnnotations',
326
+ addCommands: ()=>({
327
+ deleteAnnotationSelection: {
328
+ canExecute: ({ annotation, editable, viewer })=>editable && documentReady(viewer) && annotation.state.available && annotation.state.selectedCount > 0,
329
+ execute: ({ annotation })=>annotation.deleteSelection()
330
+ },
331
+ selectAnnotationTool: {
332
+ canExecute: ({ annotation, editable, viewer }, toolId)=>editable && documentReady(viewer) && annotation.state.available && (null === toolId || annotation.state.availableToolIds.includes(toolId)),
333
+ execute: ({ annotation }, toolId)=>annotation.selectTool(toolId)
334
+ },
335
+ setAnnotationColor: {
336
+ canExecute: ({ annotation, editable, viewer }, color)=>editable && documentReady(viewer) && annotation.state.available && (annotation.state.selectedCount > 0 || Boolean(annotation.state.activeToolId)) && /^#[0-9a-f]{6}$/i.test(color),
337
+ execute: ({ annotation }, color)=>annotation.setAnnotationColor(color)
338
+ },
339
+ setAnnotationOpacity: {
340
+ canExecute: ({ annotation, editable, viewer }, opacity)=>editable && documentReady(viewer) && annotation.state.available && annotation.state.supportsOpacity && Number.isFinite(opacity) && opacity >= 0 && opacity <= 1,
341
+ execute: ({ annotation }, opacity)=>annotation.setAnnotationOpacity(opacity)
342
+ },
343
+ setAnnotationStrokeWidth: {
344
+ canExecute: ({ annotation, editable, viewer }, strokeWidth)=>editable && documentReady(viewer) && annotation.state.available && annotation.state.supportsStrokeWidth && Number.isFinite(strokeWidth) && strokeWidth > 0 && strokeWidth <= 24,
345
+ execute: ({ annotation }, strokeWidth)=>annotation.setAnnotationStrokeWidth(strokeWidth)
346
+ }
347
+ })
348
+ }),
349
+ createOfficeEditorExtension({
350
+ name: 'pdfKeyboardShortcuts',
351
+ addKeyboardShortcuts: ()=>({
352
+ 'Mod-s': ({ can, commands }, event)=>runPdfShortcut(event, can.save, ()=>{
353
+ commands.save();
354
+ }),
355
+ 'Mod-z': ({ can, commands }, event)=>runPdfTextAwareShortcut(event, can.undo, commands.undo),
356
+ 'Mod-Shift-z': ({ can, commands }, event)=>runPdfTextAwareShortcut(event, can.redo, commands.redo),
357
+ 'Mod-y': ({ can, commands }, event)=>runPdfTextAwareShortcut(event, can.redo, commands.redo),
358
+ 'Mod-Equal': ({ can, commands }, event)=>runPdfShortcut(event, can.zoomIn, commands.zoomIn),
359
+ 'Mod-Shift-Plus': ({ can, commands }, event)=>runPdfShortcut(event, can.zoomIn, commands.zoomIn),
360
+ 'Mod-Minus': ({ can, commands }, event)=>runPdfShortcut(event, can.zoomOut, commands.zoomOut),
361
+ 'Mod-0': ({ can, commands }, event)=>runPdfShortcut(event, can.fitPage, commands.fitPage),
362
+ 'Mod-f': ({ can, context }, event)=>{
363
+ if (event.repeat || isOfficeShortcutBlocked(event.target) || !can.search('')) return false;
364
+ context.focusSearch();
365
+ return true;
366
+ },
367
+ Delete: ({ can, commands }, event)=>runPdfTextAwareShortcut(event, can.deleteAnnotationSelection, commands.deleteAnnotationSelection),
368
+ Backspace: ({ can, commands }, event)=>runPdfTextAwareShortcut(event, can.deleteAnnotationSelection, commands.deleteAnnotationSelection),
369
+ Escape: ({ can, commands, context }, event)=>{
370
+ if (event.repeat || isOfficeShortcutBlocked(event.target) || isPdfTextEditingTarget(event.target) || !context.annotation.state.activeToolId || !can.selectAnnotationTool(null)) return false;
371
+ commands.selectAnnotationTool(null);
372
+ return true;
373
+ }
374
+ })
375
+ })
376
+ ];
377
+ }
378
+ function runPdfShortcut(event, canExecute, execute) {
379
+ if (event.repeat || isOfficeShortcutBlocked(event.target) || !canExecute()) return false;
380
+ execute();
381
+ return true;
382
+ }
383
+ function runPdfTextAwareShortcut(event, canExecute, execute) {
384
+ if (isPdfTextEditingTarget(event.target)) return false;
385
+ return runPdfShortcut(event, canExecute, execute);
386
+ }
387
+ function isPdfTextEditingTarget(target) {
388
+ if (!(target instanceof HTMLElement)) return false;
389
+ return target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLSelectElement || target.isContentEditable || Boolean(target.closest('[contenteditable="true"]'));
390
+ }
391
+ function documentReady(viewer) {
392
+ return viewer.state.ready && viewer.state.documentOpen;
393
+ }
394
+ function canNavigateSearchResults(viewer) {
395
+ return canSearch(viewer) && !viewer.state.search.loading && !viewer.state.search.error && viewer.state.search.total > 0;
396
+ }
397
+ function canNavigate(viewer) {
398
+ return documentReady(viewer) && viewer.state.features.navigation;
399
+ }
400
+ function canSearch(viewer) {
401
+ return documentReady(viewer) && viewer.state.features.search;
402
+ }
403
+ function canZoom(viewer) {
404
+ return documentReady(viewer) && viewer.state.features.zoom;
405
+ }
406
+ function canSave({ editable, save, viewer }) {
407
+ return editable && save.enabled && documentReady(viewer) && viewer.state.features.export;
408
+ }
409
+ const PDF_THUMBNAIL_ITEM_HEIGHT = 190;
410
+ const PDF_THUMBNAIL_WINDOW_THRESHOLD = 48;
411
+ const PDF_THUMBNAIL_OVERSCAN = 5;
412
+ const PDF_THUMBNAIL_FALLBACK_VIEWPORT_HEIGHT = 720;
413
+ const PDF_THUMBNAIL_WINDOW_LIMIT = 32;
414
+ function PdfThumbnailRail({ currentPage, mobileCloseButtonRef, mobileNavigationId, mobileNavigationModal = false, registry, totalPages, onCloseMobileNavigation, onSelectPage }) {
415
+ const viewportRef = useRef(null);
416
+ const pendingKeyboardFocusPageRef = useRef(null);
417
+ const [anchorIndex, setAnchorIndex] = useState(()=>pdf_thumbnail_rail_pageIndex(currentPage, totalPages));
418
+ const [viewportHeight, setViewportHeight] = useState(PDF_THUMBNAIL_FALLBACK_VIEWPORT_HEIGHT);
419
+ const [itemHeight, setItemHeight] = useState(PDF_THUMBNAIL_ITEM_HEIGHT);
420
+ useEffect(()=>{
421
+ setAnchorIndex(pdf_thumbnail_rail_pageIndex(currentPage, totalPages));
422
+ }, [
423
+ currentPage,
424
+ totalPages
425
+ ]);
426
+ useLayoutEffect(()=>{
427
+ const viewport = viewportRef.current;
428
+ if (!viewport) return;
429
+ const update = ()=>{
430
+ if (viewport.clientHeight > 0) setViewportHeight(viewport.clientHeight);
431
+ };
432
+ update();
433
+ if ("u" < typeof ResizeObserver) return;
434
+ const observer = new ResizeObserver(update);
435
+ observer.observe(viewport);
436
+ return ()=>observer.disconnect();
437
+ }, []);
438
+ useLayoutEffect(()=>{
439
+ const viewport = viewportRef.current;
440
+ if (!viewport || currentPage < 1) return;
441
+ const index = pdf_thumbnail_rail_pageIndex(currentPage, totalPages);
442
+ const pageTop = index * itemHeight;
443
+ const pageBottom = pageTop + itemHeight;
444
+ const visibleTop = viewport.scrollTop;
445
+ const visibleBottom = visibleTop + viewportHeight;
446
+ if (pageTop >= visibleTop && pageBottom <= visibleBottom) return;
447
+ const top = Math.max(0, pageTop - (viewportHeight - itemHeight) / 2);
448
+ if ('function' == typeof viewport.scrollTo) viewport.scrollTo({
449
+ top,
450
+ behavior: 'smooth'
451
+ });
452
+ else viewport.scrollTop = top;
453
+ }, [
454
+ currentPage,
455
+ itemHeight,
456
+ totalPages,
457
+ viewportHeight
458
+ ]);
459
+ const range = useMemo(()=>calculatePdfThumbnailRange({
460
+ anchorIndex,
461
+ itemHeight,
462
+ totalPages,
463
+ viewportHeight
464
+ }), [
465
+ anchorIndex,
466
+ itemHeight,
467
+ totalPages,
468
+ viewportHeight
469
+ ]);
470
+ const pages = useMemo(()=>Array.from({
471
+ length: Math.max(0, range.end - range.start)
472
+ }, (_, index)=>range.start + index + 1), [
473
+ range.end,
474
+ range.start
475
+ ]);
476
+ useLayoutEffect(()=>{
477
+ const pendingPage = pendingKeyboardFocusPageRef.current;
478
+ if (null === pendingPage || currentPage !== pendingPage) return;
479
+ const thumbnail = viewportRef.current?.querySelector(`[data-pdf-page-index="${pendingPage - 1}"]`);
480
+ if (!thumbnail) return;
481
+ pendingKeyboardFocusPageRef.current = null;
482
+ thumbnail.focus({
483
+ preventScroll: true
484
+ });
485
+ }, [
486
+ currentPage,
487
+ range.end,
488
+ range.start
489
+ ]);
490
+ useLayoutEffect(()=>{
491
+ const viewport = viewportRef.current;
492
+ const thumbnail = viewport?.querySelector('[data-pdf-page-thumbnail]');
493
+ const list = viewport?.querySelector('.work-pdf-thumbnail-list');
494
+ if (!(thumbnail && list)) return;
495
+ const measure = ()=>{
496
+ const height = thumbnail.getBoundingClientRect().height;
497
+ const gap = Number.parseFloat(getComputedStyle(list).rowGap) || 0;
498
+ if (height > 0) setItemHeight(Math.round(height + gap));
499
+ };
500
+ measure();
501
+ if ("u" < typeof ResizeObserver) return;
502
+ const observer = new ResizeObserver(measure);
503
+ observer.observe(thumbnail);
504
+ return ()=>observer.disconnect();
505
+ }, [
506
+ range.end,
507
+ range.start
508
+ ]);
509
+ const topSpacerHeight = range.start * itemHeight;
510
+ const bottomSpacerHeight = Math.max(0, totalPages - range.end) * itemHeight;
511
+ const modalAttributes = mobileNavigationModal ? {
512
+ role: 'dialog',
513
+ 'aria-modal': true
514
+ } : {};
515
+ return /*#__PURE__*/ jsxs("aside", {
516
+ ...modalAttributes,
517
+ id: mobileNavigationId,
518
+ className: "work-pdf-thumbnail-rail",
519
+ "aria-label": "PDF 页面",
520
+ "data-pdf-page-count": totalPages,
521
+ "data-pdf-thumbnail-window-end": range.end,
522
+ "data-pdf-thumbnail-window-start": range.start,
523
+ "data-pdf-thumbnail-windowed": range.windowed ? 'true' : 'false',
524
+ children: [
525
+ /*#__PURE__*/ jsxs("header", {
526
+ className: "work-pdf-thumbnail-header",
527
+ children: [
528
+ /*#__PURE__*/ jsx("strong", {
529
+ children: "页面"
530
+ }),
531
+ /*#__PURE__*/ jsx("button", {
532
+ ref: mobileCloseButtonRef,
533
+ type: "button",
534
+ "aria-label": "关闭 PDF 页面导航",
535
+ onClick: onCloseMobileNavigation,
536
+ children: /*#__PURE__*/ jsx(X, {
537
+ size: 16
538
+ })
539
+ })
540
+ ]
541
+ }),
542
+ /*#__PURE__*/ jsx("nav", {
543
+ ref: viewportRef,
544
+ className: "work-pdf-thumbnail-viewport",
545
+ "aria-label": "PDF 页面缩略图",
546
+ onScroll: (event)=>{
547
+ setAnchorIndex(Math.floor(event.currentTarget.scrollTop / itemHeight));
548
+ },
549
+ children: /*#__PURE__*/ jsxs("div", {
550
+ className: "work-pdf-thumbnail-list",
551
+ children: [
552
+ /*#__PURE__*/ jsx(PdfThumbnailSpacer, {
553
+ height: topSpacerHeight,
554
+ position: "before"
555
+ }),
556
+ pages.map((page)=>/*#__PURE__*/ jsx(PdfPageThumbnail, {
557
+ current: page === currentPage,
558
+ page: page,
559
+ registry: registry,
560
+ totalPages: totalPages,
561
+ onSelectPage: onSelectPage,
562
+ onSelectPageFromKeyboard: (nextPage)=>{
563
+ if (!mobileNavigationModal) pendingKeyboardFocusPageRef.current = nextPage;
564
+ onSelectPage(nextPage);
565
+ }
566
+ }, page)),
567
+ /*#__PURE__*/ jsx(PdfThumbnailSpacer, {
568
+ height: bottomSpacerHeight,
569
+ position: "after"
570
+ })
571
+ ]
572
+ })
573
+ })
574
+ ]
575
+ });
576
+ }
577
+ function calculatePdfThumbnailRange({ anchorIndex, itemHeight = PDF_THUMBNAIL_ITEM_HEIGHT, totalPages, viewportHeight }) {
578
+ const pageCount = Math.max(0, Math.floor(totalPages));
579
+ if (pageCount <= PDF_THUMBNAIL_WINDOW_THRESHOLD) return {
580
+ end: pageCount,
581
+ start: 0,
582
+ windowed: false
583
+ };
584
+ const visibleCount = Math.max(1, Math.ceil(Math.max(1, viewportHeight) / Math.max(1, itemHeight)));
585
+ const windowCount = Math.min(PDF_THUMBNAIL_WINDOW_LIMIT, pageCount, visibleCount + 2 * PDF_THUMBNAIL_OVERSCAN);
586
+ const boundedAnchor = Math.min(pageCount - 1, Math.max(0, Math.floor(anchorIndex)));
587
+ const start = Math.min(pageCount - windowCount, Math.max(0, boundedAnchor - PDF_THUMBNAIL_OVERSCAN));
588
+ return {
589
+ end: start + windowCount,
590
+ start,
591
+ windowed: true
592
+ };
593
+ }
594
+ function PdfPageThumbnail({ current, page, registry, totalPages, onSelectPage, onSelectPageFromKeyboard }) {
595
+ const { sourceUrl, state } = usePdfThumbnailSource(registry, page);
596
+ return /*#__PURE__*/ jsxs("button", {
597
+ type: "button",
598
+ className: current ? 'active' : void 0,
599
+ "aria-current": current ? 'page' : void 0,
600
+ "aria-label": `第 ${page} 页`,
601
+ "data-pdf-page-thumbnail": true,
602
+ "data-pdf-page-index": page - 1,
603
+ onClick: ()=>onSelectPage(page),
604
+ onKeyDown: (event)=>{
605
+ const nextPage = pdfThumbnailKeyboardPage(event.key, page, totalPages);
606
+ if (null === nextPage) return;
607
+ event.preventDefault();
608
+ event.stopPropagation();
609
+ onSelectPageFromKeyboard(nextPage);
610
+ },
611
+ children: [
612
+ /*#__PURE__*/ jsx("span", {
613
+ className: "work-pdf-thumbnail-number",
614
+ "aria-hidden": "true",
615
+ children: page
616
+ }),
617
+ /*#__PURE__*/ jsx("span", {
618
+ className: "work-pdf-thumbnail-preview",
619
+ "data-pdf-thumbnail-state": state,
620
+ children: sourceUrl && /*#__PURE__*/ jsx("img", {
621
+ src: sourceUrl,
622
+ alt: "",
623
+ draggable: false
624
+ })
625
+ })
626
+ ]
627
+ });
628
+ }
629
+ function usePdfThumbnailSource(registry, page) {
630
+ const [sourceUrl, setSourceUrl] = useState(null);
631
+ const [state, setState] = useState('loading');
632
+ useEffect(()=>{
633
+ let disposed = false;
634
+ let objectUrl = null;
635
+ setSourceUrl(null);
636
+ setState('loading');
637
+ renderPdfThumbnail(registry, page).then((blob)=>{
638
+ objectUrl = URL.createObjectURL(blob);
639
+ if (disposed) return void URL.revokeObjectURL(objectUrl);
640
+ setSourceUrl(objectUrl);
641
+ setState('ready');
642
+ }).catch(()=>{
643
+ if (!disposed) setState('error');
644
+ });
645
+ return ()=>{
646
+ disposed = true;
647
+ if (objectUrl) URL.revokeObjectURL(objectUrl);
648
+ };
649
+ }, [
650
+ page,
651
+ registry
652
+ ]);
653
+ return {
654
+ sourceUrl,
655
+ state
656
+ };
657
+ }
658
+ async function renderPdfThumbnail(registry, page) {
659
+ await registry.pluginsReady();
660
+ const documentManager = registry.getPlugin(DocumentManagerPlugin.id)?.provides();
661
+ const thumbnail = registry.getPlugin(ThumbnailPlugin.id)?.provides();
662
+ const documentId = documentManager?.getActiveDocumentId();
663
+ if (!documentId || !thumbnail) throw new Error('PDF thumbnail rendering is unavailable.');
664
+ const devicePixelRatio = "u" < typeof window ? 1 : Math.min(2, Math.max(1, window.devicePixelRatio || 1));
665
+ return thumbnail.forDocument(documentId).renderThumb(page - 1, devicePixelRatio).toPromise();
666
+ }
667
+ function PdfThumbnailSpacer({ height, position }) {
668
+ if (height <= 0) return null;
669
+ return /*#__PURE__*/ jsx("span", {
670
+ "aria-hidden": "true",
671
+ className: "work-pdf-thumbnail-spacer",
672
+ "data-pdf-thumbnail-spacer": position,
673
+ style: {
674
+ height: `${height}px`
675
+ }
676
+ });
677
+ }
678
+ function pdf_thumbnail_rail_pageIndex(currentPage, totalPages) {
679
+ return Math.min(Math.max(0, Math.floor(totalPages) - 1), Math.max(0, Math.floor(currentPage) - 1));
680
+ }
681
+ function pdfThumbnailKeyboardPage(key, page, totalPages) {
682
+ if ('Home' === key) return 1;
683
+ if ('End' === key) return totalPages;
684
+ if ('ArrowUp' === key || 'ArrowLeft' === key) return Math.max(1, page - 1);
685
+ if ('ArrowDown' === key || 'ArrowRight' === key) return Math.min(totalPages, page + 1);
686
+ return null;
687
+ }
688
+ function StatusBadge({ tone = 'neutral', children, className = '' }) {
689
+ return /*#__PURE__*/ jsx("span", {
690
+ className: `ds-status-badge ${tone}${className ? ` ${className}` : ''}`,
691
+ children: children
692
+ });
693
+ }
694
+ const pdfKeyboardShortcuts = {
695
+ deleteAnnotation: 'Delete Backspace',
696
+ fitPage: 'Control+0 Meta+0',
697
+ redo: 'Control+Shift+Z Meta+Shift+Z Control+Y Meta+Y',
698
+ save: 'Control+S Meta+S',
699
+ search: 'Control+F Meta+F',
700
+ undo: 'Control+Z Meta+Z',
701
+ zoomIn: 'Control+= Meta+= Control+Shift++ Meta+Shift++',
702
+ zoomOut: 'Control+- Meta+-'
703
+ };
704
+ function PdfToolbar({ annotationState, can, commands, editable, pageNavigation, saveLabel, saveState, searchInputRef, state }) {
705
+ const [pageValue, setPageValue] = useState('');
706
+ const [searchValue, setSearchValue] = useState('');
707
+ const cancelPageBlurCommitRef = useRef(false);
708
+ useEffect(()=>{
709
+ setPageValue(state.currentPage > 0 ? String(state.currentPage) : '');
710
+ }, [
711
+ state.currentPage
712
+ ]);
713
+ useEffect(()=>{
714
+ setSearchValue(state.search.query);
715
+ }, [
716
+ state.search.query
717
+ ]);
718
+ const commitPage = ()=>{
719
+ const page = Number(pageValue);
720
+ if (can.goToPage(page)) return void commands.goToPage(page);
721
+ setPageValue(state.currentPage > 0 ? String(state.currentPage) : '');
722
+ };
723
+ const submitSearch = (event)=>{
724
+ event.preventDefault();
725
+ const query = searchValue.trim();
726
+ if (query && query === state.search.query) {
727
+ if (state.search.loading) return;
728
+ if (state.search.error) return void commands.search(query);
729
+ if (state.search.total > 0 && can.nextSearchResult()) commands.nextSearchResult();
730
+ return;
731
+ }
732
+ commands.search(query);
733
+ };
734
+ return /*#__PURE__*/ jsxs("header", {
735
+ className: "work-pdf-toolbar",
736
+ role: "toolbar",
737
+ "aria-label": "PDF 工具栏",
738
+ children: [
739
+ editable && /*#__PURE__*/ jsxs("div", {
740
+ className: "work-pdf-toolbar-group work-pdf-save",
741
+ children: [
742
+ /*#__PURE__*/ jsxs("output", {
743
+ "aria-label": "PDF 保存状态",
744
+ "aria-live": "polite",
745
+ children: [
746
+ 'saving' === saveState && /*#__PURE__*/ jsxs(StatusBadge, {
747
+ tone: "info",
748
+ children: [
749
+ /*#__PURE__*/ jsx(Loader2, {
750
+ className: "spin",
751
+ size: 12
752
+ }),
753
+ " 保存中"
754
+ ]
755
+ }),
756
+ 'saved' === saveState && /*#__PURE__*/ jsxs(StatusBadge, {
757
+ tone: "success",
758
+ children: [
759
+ /*#__PURE__*/ jsx(Check, {
760
+ size: 12
761
+ }),
762
+ " 已保存"
763
+ ]
764
+ }),
765
+ 'error' === saveState && /*#__PURE__*/ jsx(StatusBadge, {
766
+ tone: "danger",
767
+ children: "保存失败"
768
+ })
769
+ ]
770
+ }),
771
+ /*#__PURE__*/ jsxs(button_Button, {
772
+ tone: "secondary",
773
+ title: `${saveLabel}(Cmd/Ctrl+S)`,
774
+ "aria-keyshortcuts": pdfKeyboardShortcuts.save,
775
+ disabled: !can.save(),
776
+ onClick: ()=>void commands.save(),
777
+ children: [
778
+ /*#__PURE__*/ jsx(Save, {
779
+ size: 14
780
+ }),
781
+ saveLabel
782
+ ]
783
+ })
784
+ ]
785
+ }),
786
+ editable && /*#__PURE__*/ jsxs("div", {
787
+ className: "work-pdf-toolbar-group work-pdf-history",
788
+ children: [
789
+ /*#__PURE__*/ jsx(icon_button_IconButton, {
790
+ label: "撤销",
791
+ title: "撤销(Cmd/Ctrl+Z)",
792
+ "aria-keyshortcuts": pdfKeyboardShortcuts.undo,
793
+ disabled: !can.undo(),
794
+ onClick: commands.undo,
795
+ children: /*#__PURE__*/ jsx(Undo2, {
796
+ size: 15
797
+ })
798
+ }),
799
+ /*#__PURE__*/ jsx(icon_button_IconButton, {
800
+ label: "重做",
801
+ title: "重做(Cmd/Ctrl+Shift+Z 或 Cmd/Ctrl+Y)",
802
+ "aria-keyshortcuts": pdfKeyboardShortcuts.redo,
803
+ disabled: !can.redo(),
804
+ onClick: commands.redo,
805
+ children: /*#__PURE__*/ jsx(Redo2, {
806
+ size: 15
807
+ })
808
+ })
809
+ ]
810
+ }),
811
+ editable && /*#__PURE__*/ jsxs("fieldset", {
812
+ className: "work-pdf-toolbar-group work-pdf-annotation",
813
+ children: [
814
+ /*#__PURE__*/ jsx("legend", {
815
+ className: "sr-only",
816
+ children: "PDF 批注工具"
817
+ }),
818
+ /*#__PURE__*/ jsx(icon_button_IconButton, {
819
+ className: "work-pdf-annotation-selection",
820
+ label: "选择",
821
+ selected: null === annotationState.activeToolId,
822
+ disabled: !can.selectAnnotationTool(null),
823
+ onClick: ()=>commands.selectAnnotationTool(null),
824
+ children: /*#__PURE__*/ jsx(MousePointer2, {
825
+ size: 14
826
+ })
827
+ }),
828
+ /*#__PURE__*/ jsx(icon_button_IconButton, {
829
+ label: "高亮",
830
+ selected: 'highlight' === annotationState.activeToolId,
831
+ disabled: !can.selectAnnotationTool('highlight'),
832
+ onClick: ()=>commands.selectAnnotationTool('highlight'),
833
+ children: /*#__PURE__*/ jsx(Highlighter, {
834
+ size: 14
835
+ })
836
+ }),
837
+ /*#__PURE__*/ jsx(icon_button_IconButton, {
838
+ className: "work-pdf-annotation-optional",
839
+ label: "下划线批注",
840
+ selected: 'underline' === annotationState.activeToolId,
841
+ disabled: !can.selectAnnotationTool('underline'),
842
+ onClick: ()=>commands.selectAnnotationTool('underline'),
843
+ children: /*#__PURE__*/ jsx(Underline, {
844
+ size: 14
845
+ })
846
+ }),
847
+ /*#__PURE__*/ jsx(icon_button_IconButton, {
848
+ className: "work-pdf-annotation-optional",
849
+ label: "删除线批注",
850
+ selected: 'strikeout' === annotationState.activeToolId,
851
+ disabled: !can.selectAnnotationTool('strikeout'),
852
+ onClick: ()=>commands.selectAnnotationTool('strikeout'),
853
+ children: /*#__PURE__*/ jsx(Strikethrough, {
854
+ size: 14
855
+ })
856
+ }),
857
+ /*#__PURE__*/ jsx(icon_button_IconButton, {
858
+ className: "work-pdf-annotation-ink",
859
+ label: "画笔",
860
+ selected: 'ink' === annotationState.activeToolId,
861
+ disabled: !can.selectAnnotationTool('ink'),
862
+ onClick: ()=>commands.selectAnnotationTool('ink'),
863
+ children: /*#__PURE__*/ jsx(Pencil, {
864
+ size: 14
865
+ })
866
+ }),
867
+ /*#__PURE__*/ jsx(icon_button_IconButton, {
868
+ className: "work-pdf-annotation-optional",
869
+ label: "文字批注",
870
+ selected: 'freeText' === annotationState.activeToolId,
871
+ disabled: !can.selectAnnotationTool('freeText'),
872
+ onClick: ()=>commands.selectAnnotationTool('freeText'),
873
+ children: /*#__PURE__*/ jsx(Type, {
874
+ size: 14
875
+ })
876
+ }),
877
+ /*#__PURE__*/ jsx(OfficeColorPicker, {
878
+ ariaLabel: "批注颜色",
879
+ className: "work-pdf-annotation-color",
880
+ compact: true,
881
+ value: annotationState.annotationColor,
882
+ disabled: !can.setAnnotationColor(annotationState.annotationColor),
883
+ onValueChange: commands.setAnnotationColor
884
+ }),
885
+ /*#__PURE__*/ jsx(PdfAnnotationStyleControl, {
886
+ annotationState: annotationState,
887
+ can: can,
888
+ commands: commands
889
+ }),
890
+ /*#__PURE__*/ jsx(icon_button_IconButton, {
891
+ className: "work-pdf-annotation-delete",
892
+ label: "删除所选批注",
893
+ title: "删除所选批注(Delete / Backspace)",
894
+ "aria-keyshortcuts": pdfKeyboardShortcuts.deleteAnnotation,
895
+ disabled: !can.deleteAnnotationSelection(),
896
+ onClick: commands.deleteAnnotationSelection,
897
+ children: /*#__PURE__*/ jsx(Trash2, {
898
+ size: 14
899
+ })
900
+ })
901
+ ]
902
+ }),
903
+ /*#__PURE__*/ jsx(PdfToolbarOverflow, {
904
+ annotationState: annotationState,
905
+ can: can,
906
+ commands: commands,
907
+ editable: editable,
908
+ state: state
909
+ }),
910
+ /*#__PURE__*/ jsx("search", {
911
+ className: "work-pdf-search",
912
+ children: /*#__PURE__*/ jsxs("form", {
913
+ onSubmit: submitSearch,
914
+ children: [
915
+ /*#__PURE__*/ jsx(Search, {
916
+ size: 14,
917
+ "aria-hidden": "true"
918
+ }),
919
+ /*#__PURE__*/ jsx(office_text_field_OfficeTextField, {
920
+ ref: searchInputRef,
921
+ type: "search",
922
+ "aria-label": "在 PDF 中搜索",
923
+ "aria-keyshortcuts": pdfKeyboardShortcuts.search,
924
+ placeholder: "搜索",
925
+ value: searchValue,
926
+ disabled: !can.search(searchValue),
927
+ onChange: (event)=>setSearchValue(event.target.value),
928
+ onKeyDown: (event)=>{
929
+ if ('Escape' === event.key) {
930
+ event.preventDefault();
931
+ event.stopPropagation();
932
+ setSearchValue('');
933
+ commands.clearSearch();
934
+ } else if ('Enter' === event.key && event.shiftKey && searchValue.trim() === state.search.query) {
935
+ event.preventDefault();
936
+ event.stopPropagation();
937
+ if (!state.search.loading && !state.search.error && state.search.total > 0 && can.previousSearchResult()) commands.previousSearchResult();
938
+ }
939
+ }
940
+ }),
941
+ (searchValue || state.search.active) && /*#__PURE__*/ jsx(icon_button_IconButton, {
942
+ className: "work-pdf-search-clear",
943
+ label: "清除搜索",
944
+ onClick: ()=>{
945
+ setSearchValue('');
946
+ commands.clearSearch();
947
+ searchInputRef.current?.focus();
948
+ },
949
+ children: /*#__PURE__*/ jsx(X, {
950
+ size: 13
951
+ })
952
+ }),
953
+ /*#__PURE__*/ jsx("output", {
954
+ className: "work-pdf-search-state",
955
+ "aria-live": "polite",
956
+ children: searchStatus(state)
957
+ }),
958
+ /*#__PURE__*/ jsx(icon_button_IconButton, {
959
+ label: "上一个搜索结果",
960
+ disabled: !can.previousSearchResult(),
961
+ onClick: commands.previousSearchResult,
962
+ children: /*#__PURE__*/ jsx(ChevronUp, {
963
+ size: 14
964
+ })
965
+ }),
966
+ /*#__PURE__*/ jsx(icon_button_IconButton, {
967
+ label: "下一个搜索结果",
968
+ disabled: !can.nextSearchResult(),
969
+ onClick: commands.nextSearchResult,
970
+ children: /*#__PURE__*/ jsx(ChevronDown, {
971
+ size: 14
972
+ })
973
+ })
974
+ ]
975
+ })
976
+ }),
977
+ /*#__PURE__*/ jsxs("div", {
978
+ className: "work-pdf-toolbar-group work-pdf-page-controls",
979
+ children: [
980
+ pageNavigation && /*#__PURE__*/ jsxs(icon_button_IconButton, {
981
+ ref: pageNavigation.toggleRef,
982
+ className: "work-pdf-page-navigation-toggle",
983
+ label: "打开 PDF 页面导航",
984
+ tooltip: "页面缩略图",
985
+ "aria-controls": pageNavigation.controlsId,
986
+ "aria-expanded": pageNavigation.expanded,
987
+ onClick: pageNavigation.onOpen,
988
+ children: [
989
+ /*#__PURE__*/ jsx(GalleryVerticalEnd, {
990
+ size: 15
991
+ }),
992
+ /*#__PURE__*/ jsxs("span", {
993
+ className: "sr-only",
994
+ children: [
995
+ "第 ",
996
+ Math.max(1, state.currentPage),
997
+ " 页"
998
+ ]
999
+ })
1000
+ ]
1001
+ }),
1002
+ /*#__PURE__*/ jsx(icon_button_IconButton, {
1003
+ className: "work-pdf-page-step",
1004
+ label: "上一页",
1005
+ disabled: !can.previousPage(),
1006
+ onClick: commands.previousPage,
1007
+ children: /*#__PURE__*/ jsx(ChevronLeft, {
1008
+ size: 15
1009
+ })
1010
+ }),
1011
+ /*#__PURE__*/ jsx(office_text_field_OfficeTextField, {
1012
+ className: "work-pdf-page-field",
1013
+ "aria-label": "页码",
1014
+ inputMode: "numeric",
1015
+ value: pageValue,
1016
+ disabled: !can.goToPage(state.currentPage || 1),
1017
+ onBlur: ()=>{
1018
+ if (cancelPageBlurCommitRef.current) {
1019
+ cancelPageBlurCommitRef.current = false;
1020
+ return;
1021
+ }
1022
+ commitPage();
1023
+ },
1024
+ onFocus: ()=>{
1025
+ cancelPageBlurCommitRef.current = false;
1026
+ },
1027
+ onChange: (event)=>setPageValue(event.target.value.replace(/\D/g, '')),
1028
+ onKeyDown: (event)=>{
1029
+ if ('Enter' === event.key) {
1030
+ event.preventDefault();
1031
+ commitPage();
1032
+ event.currentTarget.select();
1033
+ } else if ('Escape' === event.key) {
1034
+ event.preventDefault();
1035
+ event.stopPropagation();
1036
+ cancelPageBlurCommitRef.current = true;
1037
+ setPageValue(String(state.currentPage));
1038
+ event.currentTarget.blur();
1039
+ }
1040
+ }
1041
+ }),
1042
+ /*#__PURE__*/ jsxs("span", {
1043
+ className: "work-pdf-page-total",
1044
+ children: [
1045
+ "/ ",
1046
+ state.totalPages || '—'
1047
+ ]
1048
+ }),
1049
+ /*#__PURE__*/ jsx(icon_button_IconButton, {
1050
+ className: "work-pdf-page-step",
1051
+ label: "下一页",
1052
+ disabled: !can.nextPage(),
1053
+ onClick: commands.nextPage,
1054
+ children: /*#__PURE__*/ jsx(ChevronRight, {
1055
+ size: 15
1056
+ })
1057
+ })
1058
+ ]
1059
+ }),
1060
+ /*#__PURE__*/ jsxs("div", {
1061
+ className: "work-pdf-toolbar-group work-pdf-zoom-controls",
1062
+ children: [
1063
+ /*#__PURE__*/ jsx(icon_button_IconButton, {
1064
+ label: "缩小",
1065
+ title: "缩小(Cmd/Ctrl+-)",
1066
+ "aria-keyshortcuts": pdfKeyboardShortcuts.zoomOut,
1067
+ disabled: !can.zoomOut(),
1068
+ onClick: commands.zoomOut,
1069
+ children: /*#__PURE__*/ jsx(Minus, {
1070
+ size: 14
1071
+ })
1072
+ }),
1073
+ /*#__PURE__*/ jsxs("output", {
1074
+ "aria-label": "PDF 缩放比例",
1075
+ children: [
1076
+ state.zoomPercent,
1077
+ "%"
1078
+ ]
1079
+ }),
1080
+ /*#__PURE__*/ jsx(icon_button_IconButton, {
1081
+ label: "放大",
1082
+ title: "放大(Cmd/Ctrl++)",
1083
+ "aria-keyshortcuts": pdfKeyboardShortcuts.zoomIn,
1084
+ disabled: !can.zoomIn(),
1085
+ onClick: commands.zoomIn,
1086
+ children: /*#__PURE__*/ jsx(Plus, {
1087
+ size: 14
1088
+ })
1089
+ }),
1090
+ /*#__PURE__*/ jsx("button", {
1091
+ type: "button",
1092
+ className: "work-pdf-fit-button",
1093
+ title: "整页(Cmd/Ctrl+0)",
1094
+ "aria-keyshortcuts": pdfKeyboardShortcuts.fitPage,
1095
+ "aria-pressed": 'fit-page' === state.zoomMode,
1096
+ disabled: !can.fitPage(),
1097
+ onClick: commands.fitPage,
1098
+ children: "整页"
1099
+ }),
1100
+ /*#__PURE__*/ jsx("button", {
1101
+ type: "button",
1102
+ className: "work-pdf-fit-button",
1103
+ "aria-pressed": 'fit-width' === state.zoomMode,
1104
+ disabled: !can.fitWidth(),
1105
+ onClick: commands.fitWidth,
1106
+ children: "页宽"
1107
+ })
1108
+ ]
1109
+ })
1110
+ ]
1111
+ });
1112
+ }
1113
+ const PDF_ANNOTATION_OPACITY_OPTIONS = [
1114
+ 0.25,
1115
+ 0.5,
1116
+ 0.75,
1117
+ 1
1118
+ ];
1119
+ const PDF_ANNOTATION_STROKE_WIDTH_OPTIONS = [
1120
+ 1,
1121
+ 2,
1122
+ 4,
1123
+ 6,
1124
+ 10
1125
+ ];
1126
+ function PdfAnnotationStyleControl({ annotationState, can, commands }) {
1127
+ const [open, setOpen] = useState(false);
1128
+ const panelRef = useRef(null);
1129
+ const opacityGroupName = useId();
1130
+ const strokeWidthGroupName = useId();
1131
+ const opacityPercent = Math.round(100 * annotationState.annotationOpacity);
1132
+ const disabled = !can.setAnnotationOpacity(annotationState.annotationOpacity) && !can.setAnnotationStrokeWidth(annotationState.annotationStrokeWidth);
1133
+ const title = annotationState.supportsStrokeWidth ? `批注样式(${opacityPercent}%,线宽 ${annotationState.annotationStrokeWidth})` : `批注样式(${opacityPercent}%)`;
1134
+ return /*#__PURE__*/ jsx(Popover, {
1135
+ label: "批注样式",
1136
+ panelLabel: "批注样式",
1137
+ panelRole: "dialog",
1138
+ placement: "bottom-end",
1139
+ portal: true,
1140
+ open: open,
1141
+ panelRef: panelRef,
1142
+ onOpenChange: (nextOpen)=>{
1143
+ setOpen(nextOpen);
1144
+ if (!nextOpen) return;
1145
+ requestAnimationFrame(()=>{
1146
+ const panel = panelRef.current;
1147
+ const target = panel?.querySelector('input[type="radio"]:checked:not(:disabled)') ?? panel?.querySelector('input[type="radio"]:not(:disabled)');
1148
+ target?.focus({
1149
+ preventScroll: true
1150
+ });
1151
+ });
1152
+ },
1153
+ disabled: disabled,
1154
+ className: "work-pdf-annotation-style",
1155
+ panelClassName: "work-pdf-annotation-style-panel",
1156
+ trigger: (triggerProps)=>/*#__PURE__*/ jsx("button", {
1157
+ ...triggerProps,
1158
+ className: "ds-icon-button",
1159
+ title: title,
1160
+ children: /*#__PURE__*/ jsx(SlidersHorizontal, {
1161
+ size: 14
1162
+ })
1163
+ }),
1164
+ children: /*#__PURE__*/ jsxs("div", {
1165
+ className: "work-pdf-annotation-style-content",
1166
+ children: [
1167
+ annotationState.supportsOpacity && /*#__PURE__*/ jsxs("fieldset", {
1168
+ className: "work-pdf-annotation-style-row",
1169
+ children: [
1170
+ /*#__PURE__*/ jsx("legend", {
1171
+ children: "透明度"
1172
+ }),
1173
+ /*#__PURE__*/ jsx("div", {
1174
+ className: "work-pdf-annotation-style-options",
1175
+ children: PDF_ANNOTATION_OPACITY_OPTIONS.map((opacity)=>{
1176
+ const label = `${Math.round(100 * opacity)}%`;
1177
+ return /*#__PURE__*/ jsxs("label", {
1178
+ children: [
1179
+ /*#__PURE__*/ jsx("input", {
1180
+ type: "radio",
1181
+ name: opacityGroupName,
1182
+ "aria-label": `透明度 ${label}`,
1183
+ checked: annotationState.annotationOpacity === opacity,
1184
+ disabled: !can.setAnnotationOpacity(opacity),
1185
+ onChange: ()=>commands.setAnnotationOpacity(opacity),
1186
+ onKeyDown: movePdfAnnotationStyleOption
1187
+ }),
1188
+ /*#__PURE__*/ jsx("span", {
1189
+ children: label
1190
+ })
1191
+ ]
1192
+ }, opacity);
1193
+ })
1194
+ })
1195
+ ]
1196
+ }),
1197
+ annotationState.supportsStrokeWidth && /*#__PURE__*/ jsxs("fieldset", {
1198
+ className: "work-pdf-annotation-style-row",
1199
+ children: [
1200
+ /*#__PURE__*/ jsx("legend", {
1201
+ children: "线宽"
1202
+ }),
1203
+ /*#__PURE__*/ jsx("div", {
1204
+ className: "work-pdf-annotation-style-options",
1205
+ children: PDF_ANNOTATION_STROKE_WIDTH_OPTIONS.map((strokeWidth)=>/*#__PURE__*/ jsxs("label", {
1206
+ children: [
1207
+ /*#__PURE__*/ jsx("input", {
1208
+ type: "radio",
1209
+ name: strokeWidthGroupName,
1210
+ "aria-label": `线宽 ${strokeWidth}`,
1211
+ checked: annotationState.annotationStrokeWidth === strokeWidth,
1212
+ disabled: !can.setAnnotationStrokeWidth(strokeWidth),
1213
+ onChange: ()=>commands.setAnnotationStrokeWidth(strokeWidth),
1214
+ onKeyDown: movePdfAnnotationStyleOption
1215
+ }),
1216
+ /*#__PURE__*/ jsx("span", {
1217
+ children: strokeWidth
1218
+ })
1219
+ ]
1220
+ }, strokeWidth))
1221
+ })
1222
+ ]
1223
+ })
1224
+ ]
1225
+ })
1226
+ });
1227
+ }
1228
+ function movePdfAnnotationStyleOption(event) {
1229
+ if (![
1230
+ 'ArrowDown',
1231
+ 'ArrowLeft',
1232
+ 'ArrowRight',
1233
+ 'ArrowUp',
1234
+ 'Home',
1235
+ 'End'
1236
+ ].includes(event.key)) return;
1237
+ const options = [
1238
+ ...event.currentTarget.closest('fieldset')?.querySelectorAll('input[type="radio"]:not(:disabled)') ?? []
1239
+ ];
1240
+ if (!options.length) return;
1241
+ event.preventDefault();
1242
+ const current = options.indexOf(event.currentTarget);
1243
+ const nextIndex = 'Home' === event.key ? 0 : 'End' === event.key ? options.length - 1 : 'ArrowDown' === event.key || 'ArrowRight' === event.key ? (current + 1 + options.length) % options.length : (current - 1 + options.length) % options.length;
1244
+ const next = options[nextIndex];
1245
+ next?.focus({
1246
+ preventScroll: true
1247
+ });
1248
+ next?.click();
1249
+ }
1250
+ function PdfToolbarOverflow({ annotationState, can, commands, editable, state }) {
1251
+ const hasOverflowTools = editable && annotationState.available || editable && state.features.history || state.features.navigation || state.features.search || state.features.zoom;
1252
+ return /*#__PURE__*/ jsx(Popover, {
1253
+ label: "更多 PDF 工具",
1254
+ panelLabel: "更多 PDF 工具",
1255
+ panelRole: "menu",
1256
+ placement: "bottom-end",
1257
+ portal: true,
1258
+ focusFirstOnOpen: true,
1259
+ onPanelKeyDown: moveOfficeMenuFocus,
1260
+ disabled: !hasOverflowTools,
1261
+ className: "work-pdf-overflow",
1262
+ panelClassName: "work-pdf-overflow-panel",
1263
+ trigger: (triggerProps)=>/*#__PURE__*/ jsx("button", {
1264
+ ...triggerProps,
1265
+ className: "ds-icon-button work-pdf-overflow-trigger",
1266
+ title: "更多 PDF 工具",
1267
+ children: /*#__PURE__*/ jsx(Ellipsis, {
1268
+ size: 16
1269
+ })
1270
+ }),
1271
+ children: (close)=>{
1272
+ const select = (command)=>{
1273
+ close();
1274
+ command();
1275
+ };
1276
+ return /*#__PURE__*/ jsxs(Fragment, {
1277
+ children: [
1278
+ editable && annotationState.available && /*#__PURE__*/ jsxs("fieldset", {
1279
+ className: "work-pdf-overflow-group",
1280
+ "aria-label": "批注工具",
1281
+ children: [
1282
+ /*#__PURE__*/ jsx(PdfOverflowAction, {
1283
+ label: "选择",
1284
+ active: null === annotationState.activeToolId,
1285
+ disabled: !can.selectAnnotationTool(null),
1286
+ onSelect: ()=>select(()=>commands.selectAnnotationTool(null)),
1287
+ children: /*#__PURE__*/ jsx(MousePointer2, {
1288
+ size: 15
1289
+ })
1290
+ }),
1291
+ /*#__PURE__*/ jsx(PdfOverflowAction, {
1292
+ label: "高亮",
1293
+ active: 'highlight' === annotationState.activeToolId,
1294
+ disabled: !can.selectAnnotationTool('highlight'),
1295
+ onSelect: ()=>select(()=>commands.selectAnnotationTool('highlight')),
1296
+ children: /*#__PURE__*/ jsx(Highlighter, {
1297
+ size: 15
1298
+ })
1299
+ }),
1300
+ /*#__PURE__*/ jsx(PdfOverflowAction, {
1301
+ label: "画笔",
1302
+ active: 'ink' === annotationState.activeToolId,
1303
+ disabled: !can.selectAnnotationTool('ink'),
1304
+ onSelect: ()=>select(()=>commands.selectAnnotationTool('ink')),
1305
+ children: /*#__PURE__*/ jsx(Pencil, {
1306
+ size: 15
1307
+ })
1308
+ }),
1309
+ /*#__PURE__*/ jsx(PdfOverflowAction, {
1310
+ label: "下划线批注",
1311
+ active: 'underline' === annotationState.activeToolId,
1312
+ disabled: !can.selectAnnotationTool('underline'),
1313
+ onSelect: ()=>select(()=>commands.selectAnnotationTool('underline')),
1314
+ children: /*#__PURE__*/ jsx(Underline, {
1315
+ size: 15
1316
+ })
1317
+ }),
1318
+ /*#__PURE__*/ jsx(PdfOverflowAction, {
1319
+ label: "删除线批注",
1320
+ active: 'strikeout' === annotationState.activeToolId,
1321
+ disabled: !can.selectAnnotationTool('strikeout'),
1322
+ onSelect: ()=>select(()=>commands.selectAnnotationTool('strikeout')),
1323
+ children: /*#__PURE__*/ jsx(Strikethrough, {
1324
+ size: 15
1325
+ })
1326
+ }),
1327
+ /*#__PURE__*/ jsx(PdfOverflowAction, {
1328
+ label: "文字批注",
1329
+ active: 'freeText' === annotationState.activeToolId,
1330
+ disabled: !can.selectAnnotationTool('freeText'),
1331
+ onSelect: ()=>select(()=>commands.selectAnnotationTool('freeText')),
1332
+ children: /*#__PURE__*/ jsx(Type, {
1333
+ size: 15
1334
+ })
1335
+ }),
1336
+ /*#__PURE__*/ jsx(PdfOverflowAction, {
1337
+ label: "删除所选批注",
1338
+ ariaKeyShortcuts: pdfKeyboardShortcuts.deleteAnnotation,
1339
+ disabled: !can.deleteAnnotationSelection(),
1340
+ onSelect: ()=>select(commands.deleteAnnotationSelection),
1341
+ children: /*#__PURE__*/ jsx(Trash2, {
1342
+ size: 15
1343
+ })
1344
+ })
1345
+ ]
1346
+ }),
1347
+ editable && annotationState.available && annotationState.supportsOpacity && /*#__PURE__*/ jsx("fieldset", {
1348
+ className: "work-pdf-overflow-group",
1349
+ "aria-label": "透明度",
1350
+ children: PDF_ANNOTATION_OPACITY_OPTIONS.map((opacity)=>{
1351
+ const label = `透明度 ${Math.round(100 * opacity)}%`;
1352
+ return /*#__PURE__*/ jsx(PdfOverflowAction, {
1353
+ label: label,
1354
+ active: annotationState.annotationOpacity === opacity,
1355
+ disabled: !can.setAnnotationOpacity(opacity),
1356
+ onSelect: ()=>select(()=>commands.setAnnotationOpacity(opacity)),
1357
+ children: /*#__PURE__*/ jsx(SlidersHorizontal, {
1358
+ size: 15
1359
+ })
1360
+ }, opacity);
1361
+ })
1362
+ }),
1363
+ editable && annotationState.available && annotationState.supportsStrokeWidth && /*#__PURE__*/ jsx("fieldset", {
1364
+ className: "work-pdf-overflow-group",
1365
+ "aria-label": "线宽",
1366
+ children: PDF_ANNOTATION_STROKE_WIDTH_OPTIONS.map((strokeWidth)=>/*#__PURE__*/ jsx(PdfOverflowAction, {
1367
+ label: `线宽 ${strokeWidth}`,
1368
+ active: annotationState.annotationStrokeWidth === strokeWidth,
1369
+ disabled: !can.setAnnotationStrokeWidth(strokeWidth),
1370
+ onSelect: ()=>select(()=>commands.setAnnotationStrokeWidth(strokeWidth)),
1371
+ children: /*#__PURE__*/ jsx(Pencil, {
1372
+ size: 15
1373
+ })
1374
+ }, strokeWidth))
1375
+ }),
1376
+ editable && state.features.history && /*#__PURE__*/ jsxs("fieldset", {
1377
+ className: "work-pdf-overflow-group",
1378
+ "aria-label": "历史记录",
1379
+ children: [
1380
+ /*#__PURE__*/ jsx(PdfOverflowAction, {
1381
+ label: "撤销",
1382
+ ariaKeyShortcuts: pdfKeyboardShortcuts.undo,
1383
+ disabled: !can.undo(),
1384
+ onSelect: ()=>select(commands.undo),
1385
+ children: /*#__PURE__*/ jsx(Undo2, {
1386
+ size: 15
1387
+ })
1388
+ }),
1389
+ /*#__PURE__*/ jsx(PdfOverflowAction, {
1390
+ label: "重做",
1391
+ ariaKeyShortcuts: pdfKeyboardShortcuts.redo,
1392
+ disabled: !can.redo(),
1393
+ onSelect: ()=>select(commands.redo),
1394
+ children: /*#__PURE__*/ jsx(Redo2, {
1395
+ size: 15
1396
+ })
1397
+ })
1398
+ ]
1399
+ }),
1400
+ state.features.navigation && /*#__PURE__*/ jsxs("fieldset", {
1401
+ className: "work-pdf-overflow-group",
1402
+ "aria-label": "翻页",
1403
+ children: [
1404
+ /*#__PURE__*/ jsx(PdfOverflowAction, {
1405
+ label: "上一页",
1406
+ disabled: !can.previousPage(),
1407
+ onSelect: ()=>select(commands.previousPage),
1408
+ children: /*#__PURE__*/ jsx(ChevronLeft, {
1409
+ size: 15
1410
+ })
1411
+ }),
1412
+ /*#__PURE__*/ jsx(PdfOverflowAction, {
1413
+ label: "下一页",
1414
+ disabled: !can.nextPage(),
1415
+ onSelect: ()=>select(commands.nextPage),
1416
+ children: /*#__PURE__*/ jsx(ChevronRight, {
1417
+ size: 15
1418
+ })
1419
+ })
1420
+ ]
1421
+ }),
1422
+ state.features.zoom && /*#__PURE__*/ jsxs("fieldset", {
1423
+ className: "work-pdf-overflow-group",
1424
+ "aria-label": "缩放",
1425
+ children: [
1426
+ /*#__PURE__*/ jsx(PdfOverflowAction, {
1427
+ label: "缩小",
1428
+ ariaKeyShortcuts: pdfKeyboardShortcuts.zoomOut,
1429
+ disabled: !can.zoomOut(),
1430
+ onSelect: ()=>select(commands.zoomOut),
1431
+ children: /*#__PURE__*/ jsx(Minus, {
1432
+ size: 15
1433
+ })
1434
+ }),
1435
+ /*#__PURE__*/ jsx(PdfOverflowAction, {
1436
+ label: "放大",
1437
+ ariaKeyShortcuts: pdfKeyboardShortcuts.zoomIn,
1438
+ disabled: !can.zoomIn(),
1439
+ onSelect: ()=>select(commands.zoomIn),
1440
+ children: /*#__PURE__*/ jsx(Plus, {
1441
+ size: 15
1442
+ })
1443
+ }),
1444
+ /*#__PURE__*/ jsx(PdfOverflowAction, {
1445
+ label: "整页",
1446
+ active: 'fit-page' === state.zoomMode,
1447
+ ariaKeyShortcuts: pdfKeyboardShortcuts.fitPage,
1448
+ disabled: !can.fitPage(),
1449
+ onSelect: ()=>select(commands.fitPage),
1450
+ children: /*#__PURE__*/ jsx(Scan, {
1451
+ size: 15
1452
+ })
1453
+ }),
1454
+ /*#__PURE__*/ jsx(PdfOverflowAction, {
1455
+ label: "页宽",
1456
+ active: 'fit-width' === state.zoomMode,
1457
+ disabled: !can.fitWidth(),
1458
+ onSelect: ()=>select(commands.fitWidth),
1459
+ children: /*#__PURE__*/ jsx(MoveHorizontal, {
1460
+ size: 15
1461
+ })
1462
+ })
1463
+ ]
1464
+ }),
1465
+ state.features.search && /*#__PURE__*/ jsxs("fieldset", {
1466
+ className: "work-pdf-overflow-group work-pdf-overflow-narrow",
1467
+ "aria-label": "搜索结果",
1468
+ children: [
1469
+ /*#__PURE__*/ jsx(PdfOverflowAction, {
1470
+ label: "上一个搜索结果",
1471
+ disabled: !can.previousSearchResult(),
1472
+ onSelect: ()=>select(commands.previousSearchResult),
1473
+ children: /*#__PURE__*/ jsx(ChevronUp, {
1474
+ size: 15
1475
+ })
1476
+ }),
1477
+ /*#__PURE__*/ jsx(PdfOverflowAction, {
1478
+ label: "下一个搜索结果",
1479
+ disabled: !can.nextSearchResult(),
1480
+ onSelect: ()=>select(commands.nextSearchResult),
1481
+ children: /*#__PURE__*/ jsx(ChevronDown, {
1482
+ size: 15
1483
+ })
1484
+ })
1485
+ ]
1486
+ })
1487
+ ]
1488
+ });
1489
+ }
1490
+ });
1491
+ }
1492
+ function PdfOverflowAction({ active, ariaKeyShortcuts, children, disabled, label, onSelect }) {
1493
+ const content = /*#__PURE__*/ jsxs(Fragment, {
1494
+ children: [
1495
+ /*#__PURE__*/ jsx("span", {
1496
+ "aria-hidden": "true",
1497
+ children: children
1498
+ }),
1499
+ /*#__PURE__*/ jsx("span", {
1500
+ children: label
1501
+ }),
1502
+ active && /*#__PURE__*/ jsx(Check, {
1503
+ size: 14,
1504
+ "aria-hidden": "true"
1505
+ })
1506
+ ]
1507
+ });
1508
+ if (void 0 !== active) return /*#__PURE__*/ jsx("button", {
1509
+ type: "button",
1510
+ role: "menuitemradio",
1511
+ "aria-checked": active,
1512
+ "aria-keyshortcuts": ariaKeyShortcuts,
1513
+ tabIndex: -1,
1514
+ "data-active": active ? 'true' : void 0,
1515
+ disabled: disabled,
1516
+ onClick: onSelect,
1517
+ children: content
1518
+ });
1519
+ return /*#__PURE__*/ jsx("button", {
1520
+ type: "button",
1521
+ role: "menuitem",
1522
+ "aria-keyshortcuts": ariaKeyShortcuts,
1523
+ tabIndex: -1,
1524
+ disabled: disabled,
1525
+ onClick: onSelect,
1526
+ children: content
1527
+ });
1528
+ }
1529
+ function searchStatus(state) {
1530
+ const { search } = state;
1531
+ if (search.loading) return '搜索中';
1532
+ if (search.error) return '失败';
1533
+ if (!search.query && !search.active) return '';
1534
+ if (0 === search.total) return '0 / 0';
1535
+ return `${search.activeResultIndex + 1} / ${search.total}`;
1536
+ }
1537
+ const EMPTY_FEATURES = {
1538
+ export: false,
1539
+ history: false,
1540
+ navigation: false,
1541
+ search: false,
1542
+ zoom: false
1543
+ };
1544
+ const EMPTY_SEARCH = {
1545
+ active: false,
1546
+ activeResultIndex: -1,
1547
+ error: false,
1548
+ loading: false,
1549
+ query: '',
1550
+ total: 0
1551
+ };
1552
+ const initialPdfViewerControllerState = {
1553
+ canRedo: false,
1554
+ canUndo: false,
1555
+ currentPage: 0,
1556
+ documentOpen: false,
1557
+ error: null,
1558
+ features: EMPTY_FEATURES,
1559
+ ready: false,
1560
+ search: EMPTY_SEARCH,
1561
+ totalPages: 0,
1562
+ zoomMode: null,
1563
+ zoomPercent: 100
1564
+ };
1565
+ function usePdfViewerController(registry) {
1566
+ const capabilitiesRef = useRef(null);
1567
+ const pendingPageRef = useRef(null);
1568
+ const [state, setState] = useState(initialPdfViewerControllerState);
1569
+ useEffect(()=>{
1570
+ let disposed = false;
1571
+ const unsubscribe = [];
1572
+ capabilitiesRef.current = null;
1573
+ pendingPageRef.current = null;
1574
+ setState(initialPdfViewerControllerState);
1575
+ if (!registry) return;
1576
+ registry.pluginsReady().then(()=>{
1577
+ if (disposed) return;
1578
+ const capabilities = readCapabilities(registry);
1579
+ capabilitiesRef.current = capabilities;
1580
+ const sync = ()=>{
1581
+ if (!disposed) setState(readControllerState(capabilities));
1582
+ };
1583
+ const syncDocument = ()=>{
1584
+ pendingPageRef.current = null;
1585
+ sync();
1586
+ };
1587
+ pdf_viewer_controller_subscribe(unsubscribe, capabilities.documentManager?.onActiveDocumentChanged, syncDocument);
1588
+ pdf_viewer_controller_subscribe(unsubscribe, capabilities.documentManager?.onDocumentOpened, syncDocument);
1589
+ pdf_viewer_controller_subscribe(unsubscribe, capabilities.documentManager?.onDocumentClosed, syncDocument);
1590
+ pdf_viewer_controller_subscribe(unsubscribe, capabilities.scroll?.onPageChange, sync);
1591
+ pdf_viewer_controller_subscribe(unsubscribe, capabilities.scroll?.onLayoutReady, sync);
1592
+ const stopPageChangeState = pdf_viewer_controller_safely(()=>capabilities.scroll?.onPageChangeState((event)=>{
1593
+ if (disposed || event.state.isChanging) return;
1594
+ const pendingPage = pendingPageRef.current;
1595
+ if (null === pendingPage) return;
1596
+ withActiveDocument(capabilities, ({ scroll }, documentId)=>{
1597
+ if (event.documentId !== documentId) return;
1598
+ const scope = scroll?.forDocument(documentId);
1599
+ if (scope) requestPdfPageNavigation(scope, pendingPage, pendingPageRef);
1600
+ });
1601
+ }));
1602
+ if (stopPageChangeState) unsubscribe.push(stopPageChangeState);
1603
+ pdf_viewer_controller_subscribe(unsubscribe, capabilities.zoom?.onStateChange, sync);
1604
+ pdf_viewer_controller_subscribe(unsubscribe, capabilities.search?.onStateChange, sync);
1605
+ pdf_viewer_controller_subscribe(unsubscribe, capabilities.history?.onHistoryChange, sync);
1606
+ sync();
1607
+ }).catch((error)=>{
1608
+ if (disposed) return;
1609
+ setState({
1610
+ ...initialPdfViewerControllerState,
1611
+ error: errorMessage(error)
1612
+ });
1613
+ });
1614
+ return ()=>{
1615
+ disposed = true;
1616
+ capabilitiesRef.current = null;
1617
+ pendingPageRef.current = null;
1618
+ for (const stop of unsubscribe)stop();
1619
+ };
1620
+ }, [
1621
+ registry
1622
+ ]);
1623
+ const previousPage = useCallback(()=>{
1624
+ withActiveDocument(capabilitiesRef.current, ({ scroll }, documentId)=>{
1625
+ scroll?.forDocument(documentId).scrollToPreviousPage('smooth');
1626
+ });
1627
+ }, []);
1628
+ const nextPage = useCallback(()=>{
1629
+ withActiveDocument(capabilitiesRef.current, ({ scroll }, documentId)=>{
1630
+ scroll?.forDocument(documentId).scrollToNextPage('smooth');
1631
+ });
1632
+ }, []);
1633
+ const goToPage = useCallback((page)=>{
1634
+ withActiveDocument(capabilitiesRef.current, ({ scroll }, documentId)=>{
1635
+ const scope = scroll?.forDocument(documentId);
1636
+ if (!scope) return;
1637
+ requestPdfPageNavigation(scope, page, pendingPageRef);
1638
+ });
1639
+ }, []);
1640
+ const zoomOut = useCallback(()=>{
1641
+ withActiveDocument(capabilitiesRef.current, ({ zoom }, documentId)=>{
1642
+ zoom?.forDocument(documentId).zoomOut();
1643
+ });
1644
+ }, []);
1645
+ const zoomIn = useCallback(()=>{
1646
+ withActiveDocument(capabilitiesRef.current, ({ zoom }, documentId)=>{
1647
+ zoom?.forDocument(documentId).zoomIn();
1648
+ });
1649
+ }, []);
1650
+ const fitPage = useCallback(()=>{
1651
+ withActiveDocument(capabilitiesRef.current, ({ zoom }, documentId)=>{
1652
+ zoom?.forDocument(documentId).requestZoom(ZoomMode.FitPage);
1653
+ });
1654
+ }, []);
1655
+ const fitWidth = useCallback(()=>{
1656
+ withActiveDocument(capabilitiesRef.current, ({ zoom }, documentId)=>{
1657
+ zoom?.forDocument(documentId).requestZoom(ZoomMode.FitWidth);
1658
+ });
1659
+ }, []);
1660
+ const search = useCallback((query)=>{
1661
+ const trimmedQuery = query.trim();
1662
+ withActiveDocument(capabilitiesRef.current, ({ search: searchCapability }, documentId)=>{
1663
+ const scope = searchCapability?.forDocument(documentId);
1664
+ if (!scope) return;
1665
+ if (!trimmedQuery) {
1666
+ scope.searchAllPages('');
1667
+ scope.stopSearch();
1668
+ setState((previous)=>({
1669
+ ...previous,
1670
+ search: EMPTY_SEARCH
1671
+ }));
1672
+ return;
1673
+ }
1674
+ setState((previous)=>({
1675
+ ...previous,
1676
+ search: {
1677
+ ...previous.search,
1678
+ error: false,
1679
+ loading: true,
1680
+ query: trimmedQuery
1681
+ }
1682
+ }));
1683
+ scope.searchAllPages(trimmedQuery).toPromise().catch(()=>{
1684
+ setState((previous)=>previous.search.query !== trimmedQuery ? previous : {
1685
+ ...previous,
1686
+ search: {
1687
+ ...previous.search,
1688
+ error: true,
1689
+ loading: false
1690
+ }
1691
+ });
1692
+ });
1693
+ });
1694
+ }, []);
1695
+ const clearSearch = useCallback(()=>{
1696
+ search('');
1697
+ }, [
1698
+ search
1699
+ ]);
1700
+ const previousSearchResult = useCallback(()=>{
1701
+ withActiveDocument(capabilitiesRef.current, ({ search: searchCapability }, documentId)=>{
1702
+ searchCapability?.forDocument(documentId).previousResult();
1703
+ });
1704
+ }, []);
1705
+ const nextSearchResult = useCallback(()=>{
1706
+ withActiveDocument(capabilitiesRef.current, ({ search: searchCapability }, documentId)=>{
1707
+ searchCapability?.forDocument(documentId).nextResult();
1708
+ });
1709
+ }, []);
1710
+ const undo = useCallback(()=>{
1711
+ withActiveDocument(capabilitiesRef.current, ({ history }, documentId)=>{
1712
+ history?.forDocument(documentId).undo();
1713
+ });
1714
+ }, []);
1715
+ const redo = useCallback(()=>{
1716
+ withActiveDocument(capabilitiesRef.current, ({ history }, documentId)=>{
1717
+ history?.forDocument(documentId).redo();
1718
+ });
1719
+ }, []);
1720
+ const saveAsCopy = useCallback(async ()=>{
1721
+ const capabilities = capabilitiesRef.current;
1722
+ const documentId = activeDocumentId(capabilities);
1723
+ if (!capabilities?.export || !documentId) throw new Error('PDF export is unavailable.');
1724
+ const buffer = await capabilities.export.forDocument(documentId).saveAsCopy().toPromise();
1725
+ return new Blob([
1726
+ buffer
1727
+ ], {
1728
+ type: 'application/pdf'
1729
+ });
1730
+ }, []);
1731
+ return useMemo(()=>({
1732
+ state,
1733
+ clearSearch,
1734
+ fitPage,
1735
+ fitWidth,
1736
+ goToPage,
1737
+ nextPage,
1738
+ nextSearchResult,
1739
+ previousPage,
1740
+ previousSearchResult,
1741
+ redo,
1742
+ saveAsCopy,
1743
+ search,
1744
+ undo,
1745
+ zoomIn,
1746
+ zoomOut
1747
+ }), [
1748
+ state,
1749
+ clearSearch,
1750
+ fitPage,
1751
+ fitWidth,
1752
+ goToPage,
1753
+ nextPage,
1754
+ nextSearchResult,
1755
+ previousPage,
1756
+ previousSearchResult,
1757
+ redo,
1758
+ saveAsCopy,
1759
+ search,
1760
+ undo,
1761
+ zoomIn,
1762
+ zoomOut
1763
+ ]);
1764
+ }
1765
+ function readCapabilities(registry) {
1766
+ return {
1767
+ documentManager: registry.getPlugin(DocumentManagerPlugin.id)?.provides() ?? null,
1768
+ export: registry.getPlugin(ExportPlugin.id)?.provides() ?? null,
1769
+ history: registry.getPlugin(HistoryPlugin.id)?.provides() ?? null,
1770
+ search: registry.getPlugin(SearchPlugin.id)?.provides() ?? null,
1771
+ scroll: registry.getPlugin(ScrollPlugin.id)?.provides() ?? null,
1772
+ zoom: registry.getPlugin(ZoomPlugin.id)?.provides() ?? null
1773
+ };
1774
+ }
1775
+ function readControllerState(capabilities) {
1776
+ const documentId = activeDocumentId(capabilities);
1777
+ const features = {
1778
+ export: Boolean(capabilities.export),
1779
+ history: Boolean(capabilities.history),
1780
+ navigation: Boolean(capabilities.scroll),
1781
+ search: Boolean(capabilities.search),
1782
+ zoom: Boolean(capabilities.zoom)
1783
+ };
1784
+ if (!documentId) return {
1785
+ ...initialPdfViewerControllerState,
1786
+ features,
1787
+ ready: true
1788
+ };
1789
+ const scroll = pdf_viewer_controller_safely(()=>capabilities.scroll?.forDocument(documentId));
1790
+ const zoom = pdf_viewer_controller_safely(()=>capabilities.zoom?.forDocument(documentId));
1791
+ const search = pdf_viewer_controller_safely(()=>capabilities.search?.forDocument(documentId));
1792
+ const history = pdf_viewer_controller_safely(()=>capabilities.history?.forDocument(documentId));
1793
+ const zoomState = pdf_viewer_controller_safely(()=>zoom?.getState());
1794
+ const searchState = pdf_viewer_controller_safely(()=>search?.getState());
1795
+ return {
1796
+ canRedo: pdf_viewer_controller_safely(()=>history?.canRedo()) ?? false,
1797
+ canUndo: pdf_viewer_controller_safely(()=>history?.canUndo()) ?? false,
1798
+ currentPage: pdf_viewer_controller_safely(()=>scroll?.getCurrentPage()) ?? 1,
1799
+ documentOpen: true,
1800
+ error: null,
1801
+ features,
1802
+ ready: true,
1803
+ search: searchState ? {
1804
+ active: searchState.active,
1805
+ activeResultIndex: searchState.activeResultIndex,
1806
+ error: false,
1807
+ loading: searchState.loading,
1808
+ query: searchState.query,
1809
+ total: searchState.total
1810
+ } : EMPTY_SEARCH,
1811
+ totalPages: pdf_viewer_controller_safely(()=>scroll?.getTotalPages()) ?? 0,
1812
+ zoomMode: 'string' == typeof zoomState?.zoomLevel ? zoomState.zoomLevel : null,
1813
+ zoomPercent: Math.round((zoomState?.currentZoomLevel ?? 1) * 100)
1814
+ };
1815
+ }
1816
+ function activeDocumentId(capabilities) {
1817
+ return pdf_viewer_controller_safely(()=>capabilities?.documentManager?.getActiveDocumentId()) ?? null;
1818
+ }
1819
+ function withActiveDocument(capabilities, action) {
1820
+ const documentId = activeDocumentId(capabilities);
1821
+ if (!capabilities || !documentId) return;
1822
+ pdf_viewer_controller_safely(()=>action(capabilities, documentId));
1823
+ }
1824
+ function requestPdfPageNavigation(scope, page, pendingPage) {
1825
+ const totalPages = scope.getTotalPages();
1826
+ if (totalPages < 1 || !Number.isFinite(page)) return;
1827
+ const nextPage = Math.min(totalPages, Math.max(1, Math.round(page)));
1828
+ const pageChangeInProgress = pdf_viewer_controller_safely(()=>scope.getPageChangeState().isChanging) ?? false;
1829
+ if (pageChangeInProgress) {
1830
+ pendingPage.current = nextPage;
1831
+ return;
1832
+ }
1833
+ pendingPage.current = null;
1834
+ scope.scrollToPage({
1835
+ pageNumber: nextPage,
1836
+ behavior: 'auto'
1837
+ });
1838
+ }
1839
+ function pdf_viewer_controller_subscribe(unsubscribe, event, listener) {
1840
+ if (!event) return;
1841
+ const stop = pdf_viewer_controller_safely(()=>event(()=>listener()));
1842
+ if (stop) unsubscribe.push(stop);
1843
+ }
1844
+ function pdf_viewer_controller_safely(read) {
1845
+ try {
1846
+ return read();
1847
+ } catch {
1848
+ return;
1849
+ }
1850
+ }
1851
+ function errorMessage(error) {
1852
+ return error instanceof Error && error.message ? error.message : 'PDF viewer initialization failed.';
1853
+ }
1854
+ const PDFIUM_WASM_PATH = '/vendor/embedpdf/pdfium.wasm';
1855
+ const PDF_VIEWER_READY_TIMEOUT_MS = 45000;
1856
+ const PDF_MOBILE_PAGE_NAVIGATION_QUERY = '(max-width: 640px)';
1857
+ const a3sPdfUiSchema = {
1858
+ id: 'a3s-office-pdf',
1859
+ version: '1',
1860
+ toolbars: {},
1861
+ menus: {},
1862
+ sidebars: {},
1863
+ modals: {},
1864
+ overlays: {},
1865
+ selectionMenus: {}
1866
+ };
1867
+ function PdfViewer({ fileName = 'document.pdf', loadSource, onSave, saveLabel = '保存', sourceKey, wasmUrl }) {
1868
+ const [sourceUrl, setSourceUrl] = useState(null);
1869
+ const [loadError, setLoadError] = useState(null);
1870
+ const [saveState, setSaveState] = useState('idle');
1871
+ const [retryCount, setRetryCount] = useState(0);
1872
+ const [registry, setRegistry] = useState(null);
1873
+ const [mobilePageNavigationOpen, setMobilePageNavigationOpen] = useState(false);
1874
+ const pdfRootRef = useRef(null);
1875
+ const searchInputRef = useRef(null);
1876
+ const mobilePageNavigationId = useId();
1877
+ const mobilePageNavigationToggleRef = useRef(null);
1878
+ const mobilePageNavigationCloseRef = useRef(null);
1879
+ const controller = usePdfViewerController(registry);
1880
+ const annotation = usePdfAnnotationController(registry);
1881
+ const viewerReady = controller.state.ready && controller.state.documentOpen;
1882
+ const mobilePageNavigationModal = usePdfMobilePageNavigationModal();
1883
+ const mobilePageNavigationModalOpen = mobilePageNavigationOpen && mobilePageNavigationModal;
1884
+ const closeMobilePageNavigation = useCallback(()=>{
1885
+ setMobilePageNavigationOpen(false);
1886
+ }, []);
1887
+ useDialogFocusScope({
1888
+ active: mobilePageNavigationModalOpen,
1889
+ onEscape: closeMobilePageNavigation,
1890
+ initialFocus: ()=>mobilePageNavigationCloseRef.current,
1891
+ getActiveScope: ()=>document.getElementById(mobilePageNavigationId),
1892
+ getIsolationExceptions: ()=>[
1893
+ document.querySelector('.work-pdf-page-navigation-backdrop')
1894
+ ],
1895
+ restoreFocusTarget: ()=>mobilePageNavigationModal ? mobilePageNavigationToggleRef.current : document.getElementById(mobilePageNavigationId)?.querySelector('[data-pdf-page-thumbnail][aria-current="page"]') ?? null
1896
+ });
1897
+ useEffect(()=>{
1898
+ let disposed = false;
1899
+ let objectUrl = null;
1900
+ setRegistry(null);
1901
+ setSaveState('idle');
1902
+ setSourceUrl(null);
1903
+ setLoadError(null);
1904
+ setMobilePageNavigationOpen(false);
1905
+ loadSource().then((source)=>{
1906
+ if (disposed) return;
1907
+ objectUrl = URL.createObjectURL('application/pdf' === source.type ? source : new Blob([
1908
+ source
1909
+ ], {
1910
+ type: 'application/pdf'
1911
+ }));
1912
+ setSourceUrl(objectUrl);
1913
+ }).catch((error)=>{
1914
+ if (!disposed) setLoadError(pdfErrorMessage(error));
1915
+ });
1916
+ return ()=>{
1917
+ disposed = true;
1918
+ if (objectUrl) URL.revokeObjectURL(objectUrl);
1919
+ };
1920
+ }, [
1921
+ loadSource,
1922
+ retryCount,
1923
+ sourceKey
1924
+ ]);
1925
+ useEffect(()=>{
1926
+ if (controller.state.error) setLoadError(controller.state.error);
1927
+ }, [
1928
+ controller.state.error
1929
+ ]);
1930
+ useEffect(()=>{
1931
+ if (!sourceUrl || viewerReady || loadError) return;
1932
+ const timeout = window.setTimeout(()=>{
1933
+ setRegistry(null);
1934
+ setLoadError('PDF viewer initialization timed out.');
1935
+ }, PDF_VIEWER_READY_TIMEOUT_MS);
1936
+ return ()=>window.clearTimeout(timeout);
1937
+ }, [
1938
+ loadError,
1939
+ sourceUrl,
1940
+ viewerReady
1941
+ ]);
1942
+ const savePdf = useCallback(async ()=>{
1943
+ if (!onSave || 'saving' === saveState) return;
1944
+ setSaveState('saving');
1945
+ try {
1946
+ const saved = await onSave(await controller.saveAsCopy());
1947
+ setSaveState(saved ? 'saved' : 'error');
1948
+ } catch {
1949
+ setSaveState('error');
1950
+ }
1951
+ }, [
1952
+ controller,
1953
+ onSave,
1954
+ saveState
1955
+ ]);
1956
+ const pdfExtensions = useMemo(createPdfEditorExtensions, []);
1957
+ const pdfEditor = useOfficeEditorRuntime({
1958
+ annotation,
1959
+ editable: Boolean(onSave),
1960
+ focusSearch: ()=>{
1961
+ searchInputRef.current?.focus();
1962
+ searchInputRef.current?.select();
1963
+ },
1964
+ save: {
1965
+ enabled: Boolean(onSave) && 'saving' !== saveState,
1966
+ execute: savePdf
1967
+ },
1968
+ viewer: controller
1969
+ }, pdfExtensions);
1970
+ const pdfCommands = pdfEditor.commands;
1971
+ useOfficeEditorKeyboardShortcuts(pdfEditor, {
1972
+ capture: true,
1973
+ enabled: Boolean(sourceUrl),
1974
+ scopeRef: pdfRootRef
1975
+ });
1976
+ useOfficeEditorWheelZoom({
1977
+ enabled: Boolean(sourceUrl),
1978
+ scopeRef: pdfRootRef,
1979
+ onZoomIn: pdfCommands.zoomIn,
1980
+ onZoomOut: pdfCommands.zoomOut
1981
+ });
1982
+ if (loadError) return /*#__PURE__*/ jsx(StateView, {
1983
+ className: "work-pdf-state",
1984
+ tone: "danger",
1985
+ role: "alert",
1986
+ icon: /*#__PURE__*/ jsx(AlertCircle, {
1987
+ size: 24
1988
+ }),
1989
+ title: "无法打开 PDF",
1990
+ description: "请重试。",
1991
+ descriptionTitle: loadError,
1992
+ actions: /*#__PURE__*/ jsx(button_Button, {
1993
+ onClick: ()=>setRetryCount((value)=>value + 1),
1994
+ children: "重试"
1995
+ })
1996
+ });
1997
+ if (!sourceUrl) return /*#__PURE__*/ jsx(StateView, {
1998
+ className: "work-pdf-state",
1999
+ role: "status",
2000
+ icon: /*#__PURE__*/ jsx(Loader2, {
2001
+ className: "spin",
2002
+ size: 22
2003
+ }),
2004
+ title: "正在加载 PDF…"
2005
+ });
2006
+ return /*#__PURE__*/ jsxs("section", {
2007
+ ref: pdfRootRef,
2008
+ className: "work-pdf-viewer",
2009
+ "aria-label": `PDF 编辑器:${fileName}`,
2010
+ children: [
2011
+ /*#__PURE__*/ jsx(PdfToolbar, {
2012
+ annotationState: annotation.state,
2013
+ can: pdfEditor.can(),
2014
+ commands: pdfCommands,
2015
+ editable: Boolean(onSave),
2016
+ pageNavigation: viewerReady && registry && controller.state.totalPages > 0 ? {
2017
+ controlsId: mobilePageNavigationId,
2018
+ expanded: mobilePageNavigationOpen,
2019
+ onOpen: ()=>setMobilePageNavigationOpen(true),
2020
+ toggleRef: mobilePageNavigationToggleRef
2021
+ } : void 0,
2022
+ searchInputRef: searchInputRef,
2023
+ saveLabel: saveLabel,
2024
+ saveState: saveState,
2025
+ state: controller.state
2026
+ }),
2027
+ /*#__PURE__*/ jsxs("div", {
2028
+ className: "work-pdf-workspace",
2029
+ "data-mobile-page-navigation": mobilePageNavigationOpen ? 'open' : 'closed',
2030
+ children: [
2031
+ viewerReady && registry && controller.state.totalPages > 0 && /*#__PURE__*/ jsx(PdfThumbnailRail, {
2032
+ currentPage: controller.state.currentPage,
2033
+ mobileCloseButtonRef: mobilePageNavigationCloseRef,
2034
+ mobileNavigationId: mobilePageNavigationId,
2035
+ mobileNavigationModal: mobilePageNavigationModalOpen,
2036
+ registry: registry,
2037
+ totalPages: controller.state.totalPages,
2038
+ onCloseMobileNavigation: closeMobilePageNavigation,
2039
+ onSelectPage: (page)=>{
2040
+ controller.goToPage(page);
2041
+ if (mobilePageNavigationModalOpen) closeMobilePageNavigation();
2042
+ }
2043
+ }),
2044
+ mobilePageNavigationModalOpen && /*#__PURE__*/ jsx("button", {
2045
+ type: "button",
2046
+ className: "work-pdf-page-navigation-backdrop",
2047
+ "aria-label": "关闭 PDF 页面导航遮罩",
2048
+ tabIndex: -1,
2049
+ onClick: closeMobilePageNavigation
2050
+ }),
2051
+ /*#__PURE__*/ jsxs("div", {
2052
+ className: "work-pdf-embed",
2053
+ "aria-busy": !viewerReady,
2054
+ "data-ready": viewerReady || void 0,
2055
+ children: [
2056
+ /*#__PURE__*/ jsx(PDFViewer, {
2057
+ className: "work-pdf-native-viewer",
2058
+ style: {
2059
+ width: '100%',
2060
+ height: '100%'
2061
+ },
2062
+ config: {
2063
+ src: sourceUrl,
2064
+ wasmUrl: wasmUrl ?? new URL(PDFIUM_WASM_PATH, window.location.href).href,
2065
+ tabBar: 'never',
2066
+ theme: {
2067
+ preference: 'system',
2068
+ light: {
2069
+ accent: {
2070
+ primary: '#2867d8'
2071
+ }
2072
+ },
2073
+ dark: {
2074
+ accent: {
2075
+ primary: '#7da7ff'
2076
+ }
2077
+ }
2078
+ },
2079
+ i18n: {
2080
+ defaultLocale: 'zh-CN'
2081
+ },
2082
+ ui: {
2083
+ schema: a3sPdfUiSchema
2084
+ },
2085
+ thumbnails: {
2086
+ autoScroll: false,
2087
+ buffer: 4,
2088
+ gap: 10,
2089
+ imagePadding: 0,
2090
+ labelHeight: 0,
2091
+ paddingY: 0,
2092
+ width: 132
2093
+ },
2094
+ annotations: {
2095
+ annotationAuthor: 'A3S Office 用户',
2096
+ autoCommit: true
2097
+ },
2098
+ export: {
2099
+ defaultFileName: fileName
2100
+ },
2101
+ fonts: {
2102
+ ui: null,
2103
+ signature: null
2104
+ },
2105
+ disabledCategories: onSave ? void 0 : [
2106
+ 'annotation',
2107
+ 'redaction',
2108
+ 'form',
2109
+ 'history'
2110
+ ]
2111
+ },
2112
+ onReady: setRegistry
2113
+ }, sourceUrl),
2114
+ !viewerReady && /*#__PURE__*/ jsxs("div", {
2115
+ className: "work-pdf-loading",
2116
+ role: "status",
2117
+ children: [
2118
+ /*#__PURE__*/ jsx(Loader2, {
2119
+ className: "spin",
2120
+ size: 18
2121
+ }),
2122
+ "正在打开…"
2123
+ ]
2124
+ })
2125
+ ]
2126
+ })
2127
+ ]
2128
+ })
2129
+ ]
2130
+ });
2131
+ }
2132
+ function pdfErrorMessage(error) {
2133
+ if (error instanceof Error && error.message) return error.message;
2134
+ return 'Unable to read this PDF file.';
2135
+ }
2136
+ function usePdfMobilePageNavigationModal() {
2137
+ const [matches, setMatches] = useState(()=>pdfMediaQueryMatches(PDF_MOBILE_PAGE_NAVIGATION_QUERY));
2138
+ useEffect(()=>{
2139
+ if ("u" < typeof window || 'function' != typeof window.matchMedia) return;
2140
+ const mediaQuery = window.matchMedia(PDF_MOBILE_PAGE_NAVIGATION_QUERY);
2141
+ const update = ()=>setMatches(mediaQuery.matches);
2142
+ update();
2143
+ if ('function' == typeof mediaQuery.addEventListener) {
2144
+ mediaQuery.addEventListener('change', update);
2145
+ return ()=>mediaQuery.removeEventListener('change', update);
2146
+ }
2147
+ mediaQuery.addListener(update);
2148
+ return ()=>mediaQuery.removeListener(update);
2149
+ }, []);
2150
+ return matches;
2151
+ }
2152
+ function pdfMediaQueryMatches(query) {
2153
+ if ("u" < typeof window || 'function' != typeof window.matchMedia) return true;
2154
+ return window.matchMedia(query).matches;
2155
+ }
2156
+ export { pdf_viewer_namespaceObject };