@embedpdf/viewer-chrome 3.0.0-next.15 → 3.0.0-next.16
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.
- package/dist/{annotation-fonts-BqoLZ4Mp.js → annotation-fonts-DWjVOTP0.js} +2 -2
- package/dist/{annotation-fonts-BqoLZ4Mp.js.map → annotation-fonts-DWjVOTP0.js.map} +1 -1
- package/dist/{annotation-fonts-Dt0IQXhz.cjs → annotation-fonts-dpfVkhnq.cjs} +2 -2
- package/dist/{annotation-fonts-Dt0IQXhz.cjs.map → annotation-fonts-dpfVkhnq.cjs.map} +1 -1
- package/dist/{annotation-style-Bzvvp8-N.cjs → annotation-style-B3XKAyZ-.cjs} +3 -3
- package/dist/{annotation-style-Bzvvp8-N.cjs.map → annotation-style-B3XKAyZ-.cjs.map} +1 -1
- package/dist/{annotation-style--rPIZsuP.js → annotation-style-CXF3X47Z.js} +3 -3
- package/dist/{annotation-style--rPIZsuP.js.map → annotation-style-CXF3X47Z.js.map} +1 -1
- package/dist/{ar-DnEj5vbP.cjs → ar-B132r9bo.cjs} +93 -1
- package/dist/ar-B132r9bo.cjs.map +1 -0
- package/dist/{ar-D9XKAmDx.js → ar-BLWFJoA_.js} +93 -1
- package/dist/ar-BLWFJoA_.js.map +1 -0
- package/dist/attachments-panel-Cxln8xos.cjs +217 -0
- package/dist/attachments-panel-Cxln8xos.cjs.map +1 -0
- package/dist/attachments-panel-H1ucRbwo.js +217 -0
- package/dist/attachments-panel-H1ucRbwo.js.map +1 -0
- package/dist/chrome.cjs +21 -0
- package/dist/chrome.cjs.map +1 -1
- package/dist/chrome.js +21 -0
- package/dist/chrome.js.map +1 -1
- package/dist/{commands-BmgxhJ8B.js → commands-BkgLP3Om.js} +418 -23
- package/dist/commands-BkgLP3Om.js.map +1 -0
- package/dist/{commands-CYt4SFUX.cjs → commands-DL1gjZt7.cjs} +433 -20
- package/dist/commands-DL1gjZt7.cjs.map +1 -0
- package/dist/commands.cjs +2 -1
- package/dist/commands.d.cts +3 -1
- package/dist/commands.d.ts +3 -1
- package/dist/commands.js +2 -2
- package/dist/{comments-panel-pEcQg4Vs.cjs → comments-panel-BsnWedTh.cjs} +2 -2
- package/dist/{comments-panel-pEcQg4Vs.cjs.map → comments-panel-BsnWedTh.cjs.map} +1 -1
- package/dist/{comments-panel-MUVgLCBI.js → comments-panel-D7Eadws9.js} +2 -2
- package/dist/{comments-panel-MUVgLCBI.js.map → comments-panel-D7Eadws9.js.map} +1 -1
- package/dist/{de-Dv6zvbnd.cjs → de-7_MvFWzN.cjs} +93 -1
- package/dist/de-7_MvFWzN.cjs.map +1 -0
- package/dist/{de-Bdr4aWzm.js → de-BUhwc9-x.js} +93 -1
- package/dist/de-BUhwc9-x.js.map +1 -0
- package/dist/{dialog-B5GBisKv.js → dialog-BIb373cg.js} +3 -3
- package/dist/dialog-BIb373cg.js.map +1 -0
- package/dist/{dialog-t8F13BL_.cjs → dialog-CngKTnAM.cjs} +3 -3
- package/dist/dialog-CngKTnAM.cjs.map +1 -0
- package/dist/{es-BP09DR9w.cjs → es-DgYj-1L3.cjs} +93 -1
- package/dist/es-DgYj-1L3.cjs.map +1 -0
- package/dist/{es-BSXz5tBv.js → es-DoXTqFoO.js} +93 -1
- package/dist/es-DoXTqFoO.js.map +1 -0
- package/dist/{form-design-panel-vWWU9uB-.js → form-design-panel-CgV_5YWC.js} +3 -3
- package/dist/{form-design-panel-vWWU9uB-.js.map → form-design-panel-CgV_5YWC.js.map} +1 -1
- package/dist/{form-design-panel-B5MXTZ96.cjs → form-design-panel-D0FdmWXW.cjs} +3 -3
- package/dist/{form-design-panel-B5MXTZ96.cjs.map → form-design-panel-D0FdmWXW.cjs.map} +1 -1
- package/dist/{fr-Ckn3K9v1.js → fr-B-8NDhBA.js} +93 -1
- package/dist/fr-B-8NDhBA.js.map +1 -0
- package/dist/{fr-BBQQn7tJ.cjs → fr-C856dmQJ.cjs} +93 -1
- package/dist/fr-C856dmQJ.cjs.map +1 -0
- package/dist/{he-DRsG7bH7.cjs → he-BFTeNc4t.cjs} +93 -1
- package/dist/he-BFTeNc4t.cjs.map +1 -0
- package/dist/{he-wdGU5PkU.js → he-Dlh0fNXM.js} +93 -1
- package/dist/he-Dlh0fNXM.js.map +1 -0
- package/dist/{icons-x0Tc05bs.cjs → icons-1UfLUZ_y.cjs} +20 -1
- package/dist/icons-1UfLUZ_y.cjs.map +1 -0
- package/dist/{icons-BrK5iVL8.js → icons-7dB0Y1ct.js} +20 -1
- package/dist/icons-7dB0Y1ct.js.map +1 -0
- package/dist/index.cjs +740 -171
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -2
- package/dist/index.d.ts +16 -2
- package/dist/index.js +727 -170
- package/dist/index.js.map +1 -1
- package/dist/{it-BuP4o0xQ.cjs → it-Bef-2Yxq.cjs} +93 -1
- package/dist/it-Bef-2Yxq.cjs.map +1 -0
- package/dist/{it-Us-VmvIu.js → it-BkirG7ol.js} +93 -1
- package/dist/it-BkirG7ol.js.map +1 -0
- package/dist/{ja-Cizj0-5O.js → ja-CGEjCE-s.js} +93 -1
- package/dist/ja-CGEjCE-s.js.map +1 -0
- package/dist/{ja-DovEd6ts.cjs → ja-DNw2zqSD.cjs} +93 -1
- package/dist/ja-DNw2zqSD.cjs.map +1 -0
- package/dist/{ko-DlrXliE1.js → ko-CTkl5vMh.js} +93 -1
- package/dist/ko-CTkl5vMh.js.map +1 -0
- package/dist/{ko-B-qJEol2.cjs → ko-YHzeBqP6.cjs} +93 -1
- package/dist/ko-YHzeBqP6.cjs.map +1 -0
- package/dist/{link-editor-CSjqPnj1.cjs → link-editor-CAS7MZM2.cjs} +2 -2
- package/dist/{link-editor-CSjqPnj1.cjs.map → link-editor-CAS7MZM2.cjs.map} +1 -1
- package/dist/{link-editor-SxM1nnJU.js → link-editor-CkwtqRvb.js} +2 -2
- package/dist/{link-editor-SxM1nnJU.js.map → link-editor-CkwtqRvb.js.map} +1 -1
- package/dist/{measurement-Bs61XWbJ.js → measurement-CQdbnIrn.js} +2 -2
- package/dist/{measurement-Bs61XWbJ.js.map → measurement-CQdbnIrn.js.map} +1 -1
- package/dist/{measurement-CcCsHPOX.cjs → measurement-Cxv1Ahxx.cjs} +2 -2
- package/dist/{measurement-CcCsHPOX.cjs.map → measurement-Cxv1Ahxx.cjs.map} +1 -1
- package/dist/{nl-D3KZDDiJ.cjs → nl-BjkbaLq3.cjs} +93 -1
- package/dist/nl-BjkbaLq3.cjs.map +1 -0
- package/dist/{nl-0aF7M_0h.js → nl-Dya4sR8_.js} +93 -1
- package/dist/nl-Dya4sR8_.js.map +1 -0
- package/dist/outline-panel-BpGtBdj0.cjs +707 -0
- package/dist/outline-panel-BpGtBdj0.cjs.map +1 -0
- package/dist/outline-panel-DO5_REYw.js +707 -0
- package/dist/outline-panel-DO5_REYw.js.map +1 -0
- package/dist/outline-properties-BCa2cc0t.js +330 -0
- package/dist/outline-properties-BCa2cc0t.js.map +1 -0
- package/dist/outline-properties-DT3FIxCw.cjs +330 -0
- package/dist/outline-properties-DT3FIxCw.cjs.map +1 -0
- package/dist/{pl-DSFhAUqx.cjs → pl-CKKdVnpZ.cjs} +93 -1
- package/dist/pl-CKKdVnpZ.cjs.map +1 -0
- package/dist/{pl-BW--AaCI.js → pl-DA9b5NVg.js} +93 -1
- package/dist/pl-DA9b5NVg.js.map +1 -0
- package/dist/print-dialog-BqIrHCBh.cjs +276 -0
- package/dist/print-dialog-BqIrHCBh.cjs.map +1 -0
- package/dist/print-dialog-DvcI2m2_.js +276 -0
- package/dist/print-dialog-DvcI2m2_.js.map +1 -0
- package/dist/{pt-C5S-8MC5.cjs → pt-DLcszlzi.cjs} +93 -1
- package/dist/pt-DLcszlzi.cjs.map +1 -0
- package/dist/{pt-DIhpU5pT.js → pt-Nm8yyjbX.js} +93 -1
- package/dist/pt-Nm8yyjbX.js.map +1 -0
- package/dist/{redact-confirm-CX_SY2ZN.cjs → redact-confirm-C6EiK8yN.cjs} +2 -2
- package/dist/{redact-confirm-CX_SY2ZN.cjs.map → redact-confirm-C6EiK8yN.cjs.map} +1 -1
- package/dist/{redact-confirm-B6j36TPw.js → redact-confirm-CKuv9iN_.js} +2 -2
- package/dist/{redact-confirm-B6j36TPw.js.map → redact-confirm-CKuv9iN_.js.map} +1 -1
- package/dist/{redaction-panel-IJDshSJI.js → redaction-panel-CgNZ-pQk.js} +2 -2
- package/dist/{redaction-panel-IJDshSJI.js.map → redaction-panel-CgNZ-pQk.js.map} +1 -1
- package/dist/{redaction-panel-BmoIl-Ll.cjs → redaction-panel-ZhX0dlMi.cjs} +2 -2
- package/dist/{redaction-panel-BmoIl-Ll.cjs.map → redaction-panel-ZhX0dlMi.cjs.map} +1 -1
- package/dist/{search-panel-HfIhJm1M.js → search-panel-BE4xzWlm.js} +4 -4
- package/dist/{search-panel-HfIhJm1M.js.map → search-panel-BE4xzWlm.js.map} +1 -1
- package/dist/{search-panel-s9IoiOtv.cjs → search-panel-wcbTNG1z.cjs} +4 -4
- package/dist/{search-panel-s9IoiOtv.cjs.map → search-panel-wcbTNG1z.cjs.map} +1 -1
- package/dist/{sheet-BDsa_Sup.cjs → sheet-DTBFiwde.cjs} +30 -11
- package/dist/sheet-DTBFiwde.cjs.map +1 -0
- package/dist/{sheet-R6XDgyEf.js → sheet-DyjKfAq0.js} +25 -12
- package/dist/sheet-DyjKfAq0.js.map +1 -0
- package/dist/{sign-dialog-CgnR7akj.cjs → sign-dialog-D5WGx-Yn.cjs} +2 -2
- package/dist/{sign-dialog-CgnR7akj.cjs.map → sign-dialog-D5WGx-Yn.cjs.map} +1 -1
- package/dist/{sign-dialog-GDqCoQhA.js → sign-dialog-DerNe8qT.js} +2 -2
- package/dist/{sign-dialog-GDqCoQhA.js.map → sign-dialog-DerNe8qT.js.map} +1 -1
- package/dist/{signature-inspector-DyO313Qf.cjs → signature-inspector-Bz6TAfZM.cjs} +4 -10
- package/dist/signature-inspector-Bz6TAfZM.cjs.map +1 -0
- package/dist/{signature-inspector-okFz8do6.js → signature-inspector-CsGr9EBk.js} +4 -10
- package/dist/signature-inspector-CsGr9EBk.js.map +1 -0
- package/dist/{signature-maker-BoYa8vgA.cjs → signature-maker-D_YfBXLn.cjs} +3 -3
- package/dist/{signature-maker-BoYa8vgA.cjs.map → signature-maker-D_YfBXLn.cjs.map} +1 -1
- package/dist/{signature-maker-BhCmYyHD.js → signature-maker-Dnth4rV4.js} +3 -3
- package/dist/{signature-maker-BhCmYyHD.js.map → signature-maker-Dnth4rV4.js.map} +1 -1
- package/dist/{signatures-panel-B56PC6d9.cjs → signatures-panel-Ci_LaI1C.cjs} +4 -10
- package/dist/signatures-panel-Ci_LaI1C.cjs.map +1 -0
- package/dist/{signatures-panel-CgnFfhFm.js → signatures-panel-DZ9ywrjz.js} +4 -10
- package/dist/signatures-panel-DZ9ywrjz.js.map +1 -0
- package/dist/{stamps-panel-CDO0FPyK.js → stamps-panel-BrczStaz.js} +4 -10
- package/dist/stamps-panel-BrczStaz.js.map +1 -0
- package/dist/{stamps-panel-B9NYGayn.cjs → stamps-panel-Cv9nJBwx.cjs} +4 -10
- package/dist/stamps-panel-Cv9nJBwx.cjs.map +1 -0
- package/dist/theme-Be0OZokZ.js +97 -0
- package/dist/theme-Be0OZokZ.js.map +1 -0
- package/dist/theme-FR26JI3r.cjs +126 -0
- package/dist/theme-FR26JI3r.cjs.map +1 -0
- package/dist/{toolbar-z9od3tKl.js → toolbar-DF361xWY.js} +7 -6
- package/dist/toolbar-DF361xWY.js.map +1 -0
- package/dist/{toolbar-CJu2wKTU.cjs → toolbar-ddvpsvTb.cjs} +7 -6
- package/dist/toolbar-ddvpsvTb.cjs.map +1 -0
- package/dist/{zh-cn-CxkUUBct.js → zh-cn-BMPPkLpL.js} +93 -1
- package/dist/zh-cn-BMPPkLpL.js.map +1 -0
- package/dist/{zh-cn-3tmMeHqv.cjs → zh-cn-CZOO3p4H.cjs} +93 -1
- package/dist/zh-cn-CZOO3p4H.cjs.map +1 -0
- package/package.json +4 -4
- package/src/styles.css +8 -0
- package/dist/ar-D9XKAmDx.js.map +0 -1
- package/dist/ar-DnEj5vbP.cjs.map +0 -1
- package/dist/commands-BmgxhJ8B.js.map +0 -1
- package/dist/commands-CYt4SFUX.cjs.map +0 -1
- package/dist/de-Bdr4aWzm.js.map +0 -1
- package/dist/de-Dv6zvbnd.cjs.map +0 -1
- package/dist/dialog-B5GBisKv.js.map +0 -1
- package/dist/dialog-t8F13BL_.cjs.map +0 -1
- package/dist/es-BP09DR9w.cjs.map +0 -1
- package/dist/es-BSXz5tBv.js.map +0 -1
- package/dist/fr-BBQQn7tJ.cjs.map +0 -1
- package/dist/fr-Ckn3K9v1.js.map +0 -1
- package/dist/he-DRsG7bH7.cjs.map +0 -1
- package/dist/he-wdGU5PkU.js.map +0 -1
- package/dist/icons-BrK5iVL8.js.map +0 -1
- package/dist/icons-x0Tc05bs.cjs.map +0 -1
- package/dist/it-BuP4o0xQ.cjs.map +0 -1
- package/dist/it-Us-VmvIu.js.map +0 -1
- package/dist/ja-Cizj0-5O.js.map +0 -1
- package/dist/ja-DovEd6ts.cjs.map +0 -1
- package/dist/ko-B-qJEol2.cjs.map +0 -1
- package/dist/ko-DlrXliE1.js.map +0 -1
- package/dist/nl-0aF7M_0h.js.map +0 -1
- package/dist/nl-D3KZDDiJ.cjs.map +0 -1
- package/dist/pl-BW--AaCI.js.map +0 -1
- package/dist/pl-DSFhAUqx.cjs.map +0 -1
- package/dist/pt-C5S-8MC5.cjs.map +0 -1
- package/dist/pt-DIhpU5pT.js.map +0 -1
- package/dist/sheet-BDsa_Sup.cjs.map +0 -1
- package/dist/sheet-R6XDgyEf.js.map +0 -1
- package/dist/signature-inspector-DyO313Qf.cjs.map +0 -1
- package/dist/signature-inspector-okFz8do6.js.map +0 -1
- package/dist/signatures-panel-B56PC6d9.cjs.map +0 -1
- package/dist/signatures-panel-CgnFfhFm.js.map +0 -1
- package/dist/stamps-panel-B9NYGayn.cjs.map +0 -1
- package/dist/stamps-panel-CDO0FPyK.js.map +0 -1
- package/dist/toolbar-CJu2wKTU.cjs.map +0 -1
- package/dist/toolbar-z9od3tKl.js.map +0 -1
- package/dist/zh-cn-3tmMeHqv.cjs.map +0 -1
- package/dist/zh-cn-CxkUUBct.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
import { a as DEFAULT_ENV, b as resolveViewerCommands, c as stripOf, d as useLayoutEnv, f as useLayoutOption, h as useResolvedLayout, i as iconPathsOf, m as usePanelResize, n as Icon, o as ResolvedLayoutProvider, r as hasIcon, s as ViewerConfigProvider, t as ICON_PATHS, u as useCustomIcons, v as useStripSchema, y as useViewerCommands } from "./icons-
|
|
1
|
+
import { _ as mayCarryPdf, b as openModeSurfaceOf, c as TOOL_ICONS, f as toolCommandsFor, g as isPdfFile, h as OPEN_COMMAND_ID, l as defaultCommands, p as OUTLINE_PROPERTIES_DIALOG, r as GO_TO_PAGE_DIALOG, s as SHORTCUTS_DIALOG, v as modeCommandsFor, x as sameModeSpecs, y as modeSpecsOf } from "./commands-BkgLP3Om.js";
|
|
2
|
+
import { a as DEFAULT_ENV, b as resolveViewerCommands, c as stripOf, d as useLayoutEnv, f as useLayoutOption, h as useResolvedLayout, i as iconPathsOf, m as usePanelResize, n as Icon, o as ResolvedLayoutProvider, r as hasIcon, s as ViewerConfigProvider, t as ICON_PATHS, u as useCustomIcons, v as useStripSchema, y as useViewerCommands } from "./icons-7dB0Y1ct.js";
|
|
3
3
|
import { defaultLayout } from "./chrome.js";
|
|
4
|
-
import { a as MenuAnchor, c as SlottedEdgesProvider, d as TOOLBAR_ITEM_CONTEXT_ATTRIBUTES, f as BarEdgeProvider, g as sameByHand, h as disabledSettingsOf, i as buttonPart, l as createSlottedEdges, m as byHandSettingsOf, n as CommandButton, o as MenuItem, p as bothAllow, r as buttonClass, s as MenuPopover, t as AppToolbar, u as useSlottedEdges } from "./toolbar-
|
|
5
|
-
import {
|
|
4
|
+
import { a as MenuAnchor, c as SlottedEdgesProvider, d as TOOLBAR_ITEM_CONTEXT_ATTRIBUTES, f as BarEdgeProvider, g as sameByHand, h as disabledSettingsOf, i as buttonPart, l as createSlottedEdges, m as byHandSettingsOf, n as CommandButton, o as MenuItem, p as bothAllow, r as buttonClass, s as MenuPopover, t as AppToolbar, u as useSlottedEdges } from "./toolbar-DF361xWY.js";
|
|
5
|
+
import { i as themeTokenCss, n as ThemeProvider, r as themeConfigOf, t as THEME_TOKENS } from "./theme-Be0OZokZ.js";
|
|
6
|
+
import { a as FOCUS_ROOT_ATTRIBUTE, d as safeAreaPaddingOf, f as sameScreenEdges, i as useCloseOnPick, l as holdFocus, m as windowSizeOf, n as SCRIM_CLASS, p as screenEdgesOf, r as Sheet, t as CloseOnPickProvider, u as NO_SCREEN_EDGES } from "./sheet-DyjKfAq0.js";
|
|
6
7
|
import { t as StampLibraryStore } from "./stamp-store-WuF-L3Jj.js";
|
|
7
|
-
import { t as AnnotationFontsProvider } from "./annotation-fonts-
|
|
8
|
-
import { t as Dialog } from "./dialog-
|
|
9
|
-
import { Fragment, Suspense,
|
|
10
|
-
import { DocumentGate, DocumentsToken, DocumentsToken as DocumentsToken$1, PluginError, Viewer, createCapabilityToken, isReadMember, mergeSettings, useDocument, useDocumentId, useDocuments, useDocumentsState, useKernel, useKernelValue, useOptionalCapability, useOptionalSelector } from "@embedpdf/react/runtime";
|
|
8
|
+
import { t as AnnotationFontsProvider } from "./annotation-fonts-DWjVOTP0.js";
|
|
9
|
+
import { t as Dialog } from "./dialog-BIb373cg.js";
|
|
10
|
+
import { Fragment, Suspense, lazy, useCallback, useEffect, useId, useLayoutEffect, useMemo, useReducer, useRef, useState, useSyncExternalStore } from "react";
|
|
11
|
+
import { DocumentGate, DocumentsToken, DocumentsToken as DocumentsToken$1, PluginError, Viewer, createCapabilityToken, isReadMember, mergeSettings, toPageRef, useDocument, useDocumentId, useDocuments, useDocumentsState, useKernel, useKernelValue, useOptionalCapability, useOptionalSelector, usePageList } from "@embedpdf/react/runtime";
|
|
11
12
|
import { Scrollbar, Stage, StageToken, StageToken as StageToken$1, stagePlugin, useStage, useStageState } from "@embedpdf/react/stage";
|
|
12
13
|
import { RenderLayer, RenderToken, RenderToken as RenderToken$1, renderPlugin } from "@embedpdf/react/render";
|
|
13
|
-
import { PageEditToken, PageEditToken as PageEditToken$1, pageEditPlugin } from "@embedpdf/react/page-edit";
|
|
14
|
+
import { PageEditToken, PageEditToken as PageEditToken$1, pageEditPlugin, usePageEdit, usePageEditState } from "@embedpdf/react/page-edit";
|
|
14
15
|
import { MetadataToken, MetadataToken as MetadataToken$1, metadataPlugin } from "@embedpdf/react/metadata";
|
|
16
|
+
import { OutlineToken, OutlineToken as OutlineToken$1, outlinePlugin, useOutlineState } from "@embedpdf/react/outline";
|
|
17
|
+
import { AttachmentToken, AttachmentToken as AttachmentToken$1, attachmentPlugin, useAttachmentState } from "@embedpdf/react/attachment";
|
|
15
18
|
import { InteractionToken, InteractionToken as InteractionToken$1, feedbackPlugin, interactionPlugin, useInteractionState, useToolCursor, vibrationFeedback } from "@embedpdf/react/interaction";
|
|
16
19
|
import { SelectionClipboard, SelectionHandles, SelectionLayer, SelectionMenu, SelectionToken, SelectionToken as SelectionToken$1, selectionPlugin } from "@embedpdf/react/selection";
|
|
17
20
|
import { AnnotationLayer, AnnotationMenu, AnnotationRotationBadge, AnnotationToken, AnnotationToken as AnnotationToken$1, annotationPlugin, useAnnotation, useAnnotationDefaults, useAnnotationState, useFilePickerProvider } from "@embedpdf/react/annotation";
|
|
@@ -149,6 +152,7 @@ const en = {
|
|
|
149
152
|
note: "Comment",
|
|
150
153
|
link: "Link",
|
|
151
154
|
gotoLink: "Go to link",
|
|
155
|
+
saveFile: "Save file",
|
|
152
156
|
removeLink: "Remove link",
|
|
153
157
|
delete: "Delete",
|
|
154
158
|
group: "Group",
|
|
@@ -205,12 +209,44 @@ const en = {
|
|
|
205
209
|
"annotations-create": "Adding annotations isn't allowed",
|
|
206
210
|
"doc-annotate-modify": "Changing annotations isn't allowed",
|
|
207
211
|
"doc-annotate-read": "Viewing annotations isn't allowed",
|
|
212
|
+
"doc-attachments-modify": "Adding files isn’t allowed",
|
|
208
213
|
"doc-download": "Downloading isn't allowed",
|
|
209
214
|
"doc-forms-modify": "Editing form fields isn't allowed",
|
|
215
|
+
"doc-outline-modify": "Changing the outline isn’t allowed",
|
|
216
|
+
"doc-pages-assemble": "Changing pages isn’t allowed",
|
|
210
217
|
"doc-print": "Printing isn't allowed",
|
|
211
218
|
"doc-text-copy": "Copying isn't allowed",
|
|
212
219
|
"doc-text-search": "Searching isn't allowed"
|
|
213
220
|
},
|
|
221
|
+
attachment: {
|
|
222
|
+
add: "Add file",
|
|
223
|
+
save: "Save",
|
|
224
|
+
goTo: "Go to page",
|
|
225
|
+
delete: "Delete",
|
|
226
|
+
more: "More options"
|
|
227
|
+
},
|
|
228
|
+
outline: {
|
|
229
|
+
add: "Add item",
|
|
230
|
+
addChild: "Add child item",
|
|
231
|
+
rename: "Rename",
|
|
232
|
+
setDestination: "Set destination to current view",
|
|
233
|
+
properties: "Properties…",
|
|
234
|
+
delete: "Delete",
|
|
235
|
+
expandAll: "Expand all",
|
|
236
|
+
collapseAll: "Collapse all",
|
|
237
|
+
more: "More options"
|
|
238
|
+
},
|
|
239
|
+
pages: {
|
|
240
|
+
rotateClockwise: "Rotate Page Clockwise",
|
|
241
|
+
rotateCounterclockwise: "Rotate Page Counter-Clockwise",
|
|
242
|
+
delete: "Delete Pages",
|
|
243
|
+
duplicate: "Duplicate Pages",
|
|
244
|
+
insertBlank: "Insert Blank Page",
|
|
245
|
+
insertFile: "Insert from File…",
|
|
246
|
+
extract: "Extract Pages",
|
|
247
|
+
selectAll: "Select All Pages",
|
|
248
|
+
more: "Page Options"
|
|
249
|
+
},
|
|
214
250
|
turnedOff: "{label} isn't available"
|
|
215
251
|
},
|
|
216
252
|
passwordPrompt: {
|
|
@@ -263,6 +299,25 @@ const en = {
|
|
|
263
299
|
other: "Other"
|
|
264
300
|
},
|
|
265
301
|
goToPage: { go: "Go" },
|
|
302
|
+
print: {
|
|
303
|
+
title: "Print",
|
|
304
|
+
pages: "Pages",
|
|
305
|
+
allPages: "All pages",
|
|
306
|
+
currentPage: "Current page",
|
|
307
|
+
range: "Custom",
|
|
308
|
+
rangeLabel: "Pages to print",
|
|
309
|
+
rangePlaceholder: "e.g. 1-3, 5",
|
|
310
|
+
rangeInvalid: "Use page numbers from 1 to {total}, such as 1-3, 5",
|
|
311
|
+
annotations: "Print annotations",
|
|
312
|
+
preparing: "Preparing…",
|
|
313
|
+
preparingPage: "Preparing page {page} of {total}…",
|
|
314
|
+
ready: "Ready to print.",
|
|
315
|
+
images: "Pages print as images at {dpi} DPI.",
|
|
316
|
+
lowResolution: "This document allows only low-resolution printing ({dpi} DPI).",
|
|
317
|
+
failed: "The printout couldn’t be prepared.",
|
|
318
|
+
cancel: "Cancel",
|
|
319
|
+
print: "Print"
|
|
320
|
+
},
|
|
266
321
|
panels: {
|
|
267
322
|
thumbnails: "Thumbnails",
|
|
268
323
|
outline: "Outline",
|
|
@@ -458,6 +513,46 @@ const en = {
|
|
|
458
513
|
noRotate: "Stays upright when the page rotates",
|
|
459
514
|
invisible: "Legacy: hide unknown subtypes"
|
|
460
515
|
},
|
|
516
|
+
attachments: {
|
|
517
|
+
loading: "Loading attachments…",
|
|
518
|
+
failed: "The attachments couldn’t be read.",
|
|
519
|
+
empty: "This document has no attached files",
|
|
520
|
+
drop: "Drop files to attach them",
|
|
521
|
+
dropHint: "Or drop files here",
|
|
522
|
+
adding: "Adding…",
|
|
523
|
+
onPage: "Page {page}",
|
|
524
|
+
count: "{count} file",
|
|
525
|
+
countPlural: "{count} files"
|
|
526
|
+
},
|
|
527
|
+
outline: {
|
|
528
|
+
filter: "Filter outline",
|
|
529
|
+
loading: "Loading outline…",
|
|
530
|
+
failed: "The outline couldn’t be read.",
|
|
531
|
+
empty: "This document has no outline",
|
|
532
|
+
noMatches: "No items match",
|
|
533
|
+
incomplete: "Part of the outline couldn’t be read.",
|
|
534
|
+
untitled: "Untitled",
|
|
535
|
+
properties: {
|
|
536
|
+
title: "Item properties",
|
|
537
|
+
name: "Title",
|
|
538
|
+
color: "Color",
|
|
539
|
+
noColor: "None",
|
|
540
|
+
customColor: "Custom color",
|
|
541
|
+
bold: "Bold",
|
|
542
|
+
italic: "Italic",
|
|
543
|
+
open: "Expanded when the document opens",
|
|
544
|
+
target: "Destination",
|
|
545
|
+
targetNone: "None",
|
|
546
|
+
targetView: "Current view",
|
|
547
|
+
targetNamed: "Page action",
|
|
548
|
+
targetKept: "Kept as it is",
|
|
549
|
+
keptNote: "This item runs a script or opens another file. It can’t be changed here.",
|
|
550
|
+
fit: "Fit",
|
|
551
|
+
fitKept: "As it is",
|
|
552
|
+
save: "Save",
|
|
553
|
+
cancel: "Cancel"
|
|
554
|
+
}
|
|
555
|
+
},
|
|
461
556
|
linkEditor: {
|
|
462
557
|
toUrl: "Link to a URL",
|
|
463
558
|
url: "URL",
|
|
@@ -620,18 +715,18 @@ const en = {
|
|
|
620
715
|
*/
|
|
621
716
|
/** The viewer's languages besides English, by code. */
|
|
622
717
|
const LOCALE_LOADERS = {
|
|
623
|
-
de: () => import("./de-
|
|
624
|
-
fr: () => import("./fr-
|
|
625
|
-
es: () => import("./es-
|
|
626
|
-
it: () => import("./it-
|
|
627
|
-
nl: () => import("./nl-
|
|
628
|
-
pt: () => import("./pt-
|
|
629
|
-
pl: () => import("./pl-
|
|
630
|
-
ja: () => import("./ja-
|
|
631
|
-
"zh-CN": () => import("./zh-cn-
|
|
632
|
-
ko: () => import("./ko-
|
|
633
|
-
ar: () => import("./ar-
|
|
634
|
-
he: () => import("./he-
|
|
718
|
+
de: () => import("./de-BUhwc9-x.js").then((module) => module.de),
|
|
719
|
+
fr: () => import("./fr-B-8NDhBA.js").then((module) => module.fr),
|
|
720
|
+
es: () => import("./es-DoXTqFoO.js").then((module) => module.es),
|
|
721
|
+
it: () => import("./it-BkirG7ol.js").then((module) => module.it),
|
|
722
|
+
nl: () => import("./nl-Dya4sR8_.js").then((module) => module.nl),
|
|
723
|
+
pt: () => import("./pt-Nm8yyjbX.js").then((module) => module.pt),
|
|
724
|
+
pl: () => import("./pl-DA9b5NVg.js").then((module) => module.pl),
|
|
725
|
+
ja: () => import("./ja-CGEjCE-s.js").then((module) => module.ja),
|
|
726
|
+
"zh-CN": () => import("./zh-cn-BMPPkLpL.js").then((module) => module.zhCN),
|
|
727
|
+
ko: () => import("./ko-CTkl5vMh.js").then((module) => module.ko),
|
|
728
|
+
ar: () => import("./ar-BLWFJoA_.js").then((module) => module.ar),
|
|
729
|
+
he: () => import("./he-Dlh0fNXM.js").then((module) => module.he)
|
|
635
730
|
};
|
|
636
731
|
/**
|
|
637
732
|
* The language a `locale` value shows, among `codes`: the browser's languages for `'auto'`,
|
|
@@ -769,6 +864,8 @@ const VIEWER_PLUGINS = {
|
|
|
769
864
|
signature: SignatureToken$1,
|
|
770
865
|
pageEdit: PageEditToken$1,
|
|
771
866
|
metadata: MetadataToken$1,
|
|
867
|
+
outline: OutlineToken$1,
|
|
868
|
+
attachment: AttachmentToken$1,
|
|
772
869
|
actions: ActionsToken$1,
|
|
773
870
|
documents: DocumentsToken$1,
|
|
774
871
|
interaction: InteractionToken$1,
|
|
@@ -958,6 +1055,8 @@ const WITHOUT_SETTINGS = /* @__PURE__ */ new Set([
|
|
|
958
1055
|
"link",
|
|
959
1056
|
"pageEdit",
|
|
960
1057
|
"metadata",
|
|
1058
|
+
"outline",
|
|
1059
|
+
"attachment",
|
|
961
1060
|
"documents",
|
|
962
1061
|
"shell"
|
|
963
1062
|
]);
|
|
@@ -1014,92 +1113,6 @@ function settingsOver(viewerSettings, settings) {
|
|
|
1014
1113
|
return mergeSettings(viewerSettings, settings);
|
|
1015
1114
|
}
|
|
1016
1115
|
//#endregion
|
|
1017
|
-
//#region src/ui/theme.tsx
|
|
1018
|
-
/**
|
|
1019
|
-
* Light/dark theme — one class, and the CSS variables in styles.css do the
|
|
1020
|
-
* rest (both toolbars, sidebars, popovers, and the canvas re-theme from it).
|
|
1021
|
-
* The mode follows the embedder's `theme` preference while the viewer runs;
|
|
1022
|
-
* `'system'` follows the OS setting, and switches when the user changes it.
|
|
1023
|
-
* The class lands on <html> by default; a delivery that must not touch the
|
|
1024
|
-
* page (the <embedpdf-viewer> shadow root) passes `target` and the class stays
|
|
1025
|
-
* inside its own subtree. The theme's tokens are CSS variables too: a delivery
|
|
1026
|
-
* applies {@link themeTokenCss} on the viewer's root.
|
|
1027
|
-
*/
|
|
1028
|
-
/**
|
|
1029
|
-
* The viewer's look, by name: each is the CSS variable `--epdf-<name>`, which the chrome's
|
|
1030
|
-
* stylesheet declares with a default for each mode and mixes every other shade from.
|
|
1031
|
-
*/
|
|
1032
|
-
const THEME_TOKENS = [
|
|
1033
|
-
"accent",
|
|
1034
|
-
"background",
|
|
1035
|
-
"surface",
|
|
1036
|
-
"surface-raised",
|
|
1037
|
-
"text",
|
|
1038
|
-
"text-muted",
|
|
1039
|
-
"border",
|
|
1040
|
-
"hover",
|
|
1041
|
-
"canvas",
|
|
1042
|
-
"radius",
|
|
1043
|
-
"font"
|
|
1044
|
-
];
|
|
1045
|
-
/** Normalize the shorthand — deliveries use this to read one shape. */
|
|
1046
|
-
const themeConfigOf = (theme) => typeof theme === "string" ? { preference: theme } : theme ?? {};
|
|
1047
|
-
const isThemeToken = (name) => THEME_TOKENS.includes(name);
|
|
1048
|
-
/** The declarations of `tokens` that are tokens with a CSS value; each other entry warns. */
|
|
1049
|
-
function tokenDeclarations(tokens) {
|
|
1050
|
-
return Object.entries(tokens).filter(([name, value]) => {
|
|
1051
|
-
if (value === void 0) return false;
|
|
1052
|
-
if (!isThemeToken(name)) {
|
|
1053
|
-
console.warn(`[embedpdf] theme: "${name}" isn't a token, ignored`);
|
|
1054
|
-
return false;
|
|
1055
|
-
}
|
|
1056
|
-
if (typeof value !== "string" || /[{};]/.test(value)) {
|
|
1057
|
-
console.warn(`[embedpdf] theme: ignoring the invalid value of "${name}"`);
|
|
1058
|
-
return false;
|
|
1059
|
-
}
|
|
1060
|
-
return true;
|
|
1061
|
-
}).map(([name, value]) => `--epdf-${name}:var(--embedpdf-host-${name},${value});`).join("");
|
|
1062
|
-
}
|
|
1063
|
-
/**
|
|
1064
|
-
* The CSS that applies a theme's tokens on the viewer's root (`root`, a selector), for a sheet
|
|
1065
|
-
* after the chrome's: its tokens win over the defaults in both modes by coming later, and its
|
|
1066
|
-
* dark ones win in dark by naming the class too. A value is a default only: the page's own
|
|
1067
|
-
* `--epdf-*` variable still wins, read on the host as the chrome's stylesheet does. Empty when
|
|
1068
|
-
* the theme sets no token.
|
|
1069
|
-
*/
|
|
1070
|
-
function themeTokenCss(theme, root) {
|
|
1071
|
-
const { accent, tokens, dark } = themeConfigOf(theme);
|
|
1072
|
-
const both = tokenDeclarations({
|
|
1073
|
-
...accent === void 0 ? null : { accent },
|
|
1074
|
-
...tokens
|
|
1075
|
-
});
|
|
1076
|
-
const darkOnly = dark ? tokenDeclarations(dark) : "";
|
|
1077
|
-
return (both ? `${root}{${both}}` : "") + (darkOnly ? `${root}.dark{${darkOnly}}` : "");
|
|
1078
|
-
}
|
|
1079
|
-
const ThemeCtx = createContext(null);
|
|
1080
|
-
const DARK_QUERY = "(prefers-color-scheme: dark)";
|
|
1081
|
-
const systemMode = () => typeof window !== "undefined" && window.matchMedia?.(DARK_QUERY).matches ? "dark" : "light";
|
|
1082
|
-
function ThemeProvider({ children, preference = "system", target }) {
|
|
1083
|
-
const [system, setSystem] = useState(systemMode);
|
|
1084
|
-
useEffect(() => {
|
|
1085
|
-
if (preference !== "system" || typeof window === "undefined" || !window.matchMedia) return;
|
|
1086
|
-
const query = window.matchMedia(DARK_QUERY);
|
|
1087
|
-
const follow = () => setSystem(query.matches ? "dark" : "light");
|
|
1088
|
-
follow();
|
|
1089
|
-
query.addEventListener("change", follow);
|
|
1090
|
-
return () => query.removeEventListener("change", follow);
|
|
1091
|
-
}, [preference]);
|
|
1092
|
-
const mode = preference === "system" ? system : preference;
|
|
1093
|
-
useLayoutEffect(() => {
|
|
1094
|
-
(target ?? document.documentElement).classList.toggle("dark", mode === "dark");
|
|
1095
|
-
}, [mode, target]);
|
|
1096
|
-
const value = useMemo(() => ({ mode }), [mode]);
|
|
1097
|
-
return /* @__PURE__ */ jsx(ThemeCtx.Provider, {
|
|
1098
|
-
value,
|
|
1099
|
-
children
|
|
1100
|
-
});
|
|
1101
|
-
}
|
|
1102
|
-
//#endregion
|
|
1103
1116
|
//#region src/config/panels.ts
|
|
1104
1117
|
/**
|
|
1105
1118
|
* The panels a layout brings, as commands. Every panel gets `panel:<id>`, which
|
|
@@ -1119,6 +1132,12 @@ const panelSideOf = (panel) => panel.side === "start" ? "start" : "end";
|
|
|
1119
1132
|
function panelsOnSide(data, side) {
|
|
1120
1133
|
return Object.entries(data.panels ?? {}).filter(([, panel]) => isPanel(panel) && panelSideOf(panel) === side).map(([id]) => id);
|
|
1121
1134
|
}
|
|
1135
|
+
/**
|
|
1136
|
+
* Whether a list panel has a job: its list holds entries, or the session may add some (the
|
|
1137
|
+
* right, and `adding`, the feature that turns adding off, on). A document without an outline
|
|
1138
|
+
* shows no outline button to a session that can't add items; the same for attachments.
|
|
1139
|
+
*/
|
|
1140
|
+
const hasJob = (commandContext, entries, mayAdd, adding) => entries > 0 || mayAdd && !(commandContext.tryGet(CommandsToken$1)?.isCategoryDisabled(adding) ?? false);
|
|
1122
1141
|
/** The search panel's id in the layout. */
|
|
1123
1142
|
const SEARCH_PANEL = "search";
|
|
1124
1143
|
/** Searching, which the search panel and Find need: without it every query is refused. */
|
|
@@ -1145,11 +1164,17 @@ const BUILT_IN_PANELS = /* @__PURE__ */ new Map([
|
|
|
1145
1164
|
["thumbnails", { categories: ["thumbnails"] }],
|
|
1146
1165
|
["outline", {
|
|
1147
1166
|
categories: ["outline"],
|
|
1148
|
-
visible: () =>
|
|
1167
|
+
visible: (commandContext) => {
|
|
1168
|
+
const outline = commandContext.tryGet(OutlineToken$1);
|
|
1169
|
+
return outline != null && hasJob(commandContext, outline.list().length, outline.canEdit(), "outline.editing");
|
|
1170
|
+
}
|
|
1149
1171
|
}],
|
|
1150
1172
|
["attachments", {
|
|
1151
1173
|
categories: ["attachments"],
|
|
1152
|
-
visible: () =>
|
|
1174
|
+
visible: (commandContext) => {
|
|
1175
|
+
const attachment = commandContext.tryGet(AttachmentToken$1);
|
|
1176
|
+
return attachment != null && hasJob(commandContext, attachment.list().length, attachment.canAdd(), "attachments.adding");
|
|
1177
|
+
}
|
|
1153
1178
|
}],
|
|
1154
1179
|
[SEARCH_PANEL, {
|
|
1155
1180
|
...SEARCHES,
|
|
@@ -1816,7 +1841,7 @@ function StripBar({ view, label }) {
|
|
|
1816
1841
|
* groups vanish, null when nothing applies. Mounted in the Stage `overlay`
|
|
1817
1842
|
* slot. The pixels are the shared <StripBar>.
|
|
1818
1843
|
*/
|
|
1819
|
-
const LinkEditorCard = lazyComponent(() => import("./link-editor-
|
|
1844
|
+
const LinkEditorCard = lazyComponent(() => import("./link-editor-CkwtqRvb.js").then((ui) => ui.LinkEditorCard));
|
|
1820
1845
|
function AnnotationStrip() {
|
|
1821
1846
|
const t = useT();
|
|
1822
1847
|
const view = useStripView(useStripSchema("annotation"));
|
|
@@ -2516,6 +2541,551 @@ function PanelRow({ panel, current, onPicked }) {
|
|
|
2516
2541
|
});
|
|
2517
2542
|
}
|
|
2518
2543
|
//#endregion
|
|
2544
|
+
//#region src/ui/thumbnail-drop.ts
|
|
2545
|
+
/** How thick the drop line is drawn, in px. */
|
|
2546
|
+
const LINE = 2;
|
|
2547
|
+
/** How many thumbnails share the first row on screen: 1 for a single column. */
|
|
2548
|
+
function columnsOf(boxes) {
|
|
2549
|
+
const first = boxes[0];
|
|
2550
|
+
if (!first) return 1;
|
|
2551
|
+
return Math.max(1, boxes.filter((box) => Math.abs(box.y - first.y) < 1).length);
|
|
2552
|
+
}
|
|
2553
|
+
/** How far a point is from a box: 0 inside it. */
|
|
2554
|
+
function distance(box, x, y) {
|
|
2555
|
+
const dx = Math.max(box.x - x, 0, x - (box.x + box.width));
|
|
2556
|
+
const dy = Math.max(box.y - y, 0, y - (box.y + box.height));
|
|
2557
|
+
return Math.hypot(dx, dy);
|
|
2558
|
+
}
|
|
2559
|
+
/**
|
|
2560
|
+
* The order of the document's pages once `moving` go to `position`, together in the order they
|
|
2561
|
+
* have now: what a reorder answers.
|
|
2562
|
+
*/
|
|
2563
|
+
function orderAfter(order, moving, position) {
|
|
2564
|
+
const staying = order.filter((page) => !moving.has(page));
|
|
2565
|
+
const anchor = "before" in position ? position.before : position.after;
|
|
2566
|
+
const at = staying.indexOf(anchor) + ("after" in position ? 1 : 0);
|
|
2567
|
+
const moved = order.filter((page) => moving.has(page));
|
|
2568
|
+
return [
|
|
2569
|
+
...staying.slice(0, at),
|
|
2570
|
+
...moved,
|
|
2571
|
+
...staying.slice(at)
|
|
2572
|
+
];
|
|
2573
|
+
}
|
|
2574
|
+
/**
|
|
2575
|
+
* Where pages dropped at `point` land, or `null` when nothing would change: over a page that
|
|
2576
|
+
* moves, or in the place the pages already are. `order` is every page of the document in display
|
|
2577
|
+
* order; `moving` the pages dragged, empty for files dropped from outside.
|
|
2578
|
+
*/
|
|
2579
|
+
function thumbDropAt(boxes, point, spacing, order, moving) {
|
|
2580
|
+
let nearest = null;
|
|
2581
|
+
for (const box of boxes) if (!nearest || distance(box, point.x, point.y) < distance(nearest, point.x, point.y)) nearest = box;
|
|
2582
|
+
if (!nearest || moving.has(nearest.page)) return null;
|
|
2583
|
+
const across = columnsOf(boxes) > 1;
|
|
2584
|
+
const before = across ? point.x < nearest.x + nearest.width / 2 : point.y < nearest.y + nearest.height / 2;
|
|
2585
|
+
const position = before ? { before: nearest.page } : { after: nearest.page };
|
|
2586
|
+
if (moving.size > 0) {
|
|
2587
|
+
if (orderAfter(order, moving, position).every((page, i) => page === order[i])) return null;
|
|
2588
|
+
}
|
|
2589
|
+
const half = spacing.gap / 2;
|
|
2590
|
+
return {
|
|
2591
|
+
position,
|
|
2592
|
+
line: across ? {
|
|
2593
|
+
x: (before ? nearest.x - half : nearest.x + nearest.width + half) - LINE / 2,
|
|
2594
|
+
y: nearest.y,
|
|
2595
|
+
width: LINE,
|
|
2596
|
+
height: nearest.height
|
|
2597
|
+
} : {
|
|
2598
|
+
x: nearest.x,
|
|
2599
|
+
y: (before ? nearest.y - half : nearest.y + nearest.height + spacing.band + half) - LINE / 2,
|
|
2600
|
+
width: nearest.width,
|
|
2601
|
+
height: LINE
|
|
2602
|
+
}
|
|
2603
|
+
};
|
|
2604
|
+
}
|
|
2605
|
+
/**
|
|
2606
|
+
* The page a move of one slot puts the selection next to, keys up or down: past the nearest page
|
|
2607
|
+
* that isn't selected, on that side. `null` at the start or the end.
|
|
2608
|
+
*/
|
|
2609
|
+
function slotMove(order, selected, direction) {
|
|
2610
|
+
const indexes = order.flatMap((page, i) => selected.has(page) ? [i] : []);
|
|
2611
|
+
if (indexes.length === 0) return null;
|
|
2612
|
+
if (direction < 0) {
|
|
2613
|
+
for (let i = indexes[0] - 1; i >= 0; i -= 1) if (!selected.has(order[i])) return { before: order[i] };
|
|
2614
|
+
return null;
|
|
2615
|
+
}
|
|
2616
|
+
for (let i = indexes[indexes.length - 1] + 1; i < order.length; i += 1) if (!selected.has(order[i])) return { after: order[i] };
|
|
2617
|
+
return null;
|
|
2618
|
+
}
|
|
2619
|
+
//#endregion
|
|
2620
|
+
//#region src/ui/thumbnail-list.tsx
|
|
2621
|
+
/**
|
|
2622
|
+
* The thumbnails panel: the same document through the thumbnail Stage lens (a fixed-zoom grid
|
|
2623
|
+
* that wraps into as many columns as the panel's width fits; see the viewer's `thumbnails`
|
|
2624
|
+
* plugin). A click goes to the page, and the panel follows the main view.
|
|
2625
|
+
*
|
|
2626
|
+
* A session that may change the pages (`page:insert-blank` shows and is enabled, the outline
|
|
2627
|
+
* panel's rule) organizes them here too:
|
|
2628
|
+
* - a click selects the page, Ctrl/Cmd+click adds or removes one, Shift+click selects a range;
|
|
2629
|
+
* - each page has a menu: its button, a right-click, or a long press;
|
|
2630
|
+
* - dragging moves the selection if the page is in it, else that page, with a line where they
|
|
2631
|
+
* land; a pen or a finger holds the page first, so a swipe still scrolls;
|
|
2632
|
+
* - PDFs dropped between pages are inserted there, not opened as a tab;
|
|
2633
|
+
* - the header has insert, rotate, delete, the selection's menu, and undo and redo;
|
|
2634
|
+
* - the list is one tab stop: arrows go through the pages, Shift extends, Space adds or removes,
|
|
2635
|
+
* Alt+arrows move the selection one place, Delete deletes and Ctrl/Cmd+A selects every page.
|
|
2636
|
+
*/
|
|
2637
|
+
/** How far the pointer moves before a press on a page becomes a drag, in px (the outline's). */
|
|
2638
|
+
const DRAG_SLOP_PX = 4;
|
|
2639
|
+
/** How long a pen or a finger holds a page before it drags it, or opens its menu, in ms. */
|
|
2640
|
+
const HOLD_MS = 450;
|
|
2641
|
+
/** Within this many px of the list's top or bottom, a drag scrolls the list. */
|
|
2642
|
+
const EDGE_PX = 28;
|
|
2643
|
+
/** The lens's spacing when its settings don't say it in px. */
|
|
2644
|
+
const DEFAULT_GAP_PX = 16;
|
|
2645
|
+
/** The header's commands: insert and rotate, delete, the menu of the rest, then the history. */
|
|
2646
|
+
const HEADER_EDITS = [
|
|
2647
|
+
"page:insert-blank",
|
|
2648
|
+
"page:rotate-counterclockwise",
|
|
2649
|
+
"page:rotate-clockwise",
|
|
2650
|
+
"page:delete",
|
|
2651
|
+
"menu:page"
|
|
2652
|
+
];
|
|
2653
|
+
const HEADER_HISTORY = ["history:undo", "history:redo"];
|
|
2654
|
+
/** The thumbnails on screen, as boxes in the lens's viewport. */
|
|
2655
|
+
function boxesOf(thumbs) {
|
|
2656
|
+
return thumbs.listVisiblePages().map((page) => ({
|
|
2657
|
+
page: page.ref.objectNumber,
|
|
2658
|
+
x: page.screenX,
|
|
2659
|
+
y: page.screenY,
|
|
2660
|
+
width: page.transform.viewWidth,
|
|
2661
|
+
height: page.transform.viewHeight
|
|
2662
|
+
}));
|
|
2663
|
+
}
|
|
2664
|
+
const positionOf = (position) => "before" in position ? { before: toPageRef(position.before) } : { after: toPageRef(position.after) };
|
|
2665
|
+
function ThumbnailList() {
|
|
2666
|
+
const t = useT();
|
|
2667
|
+
const idPrefix = useId();
|
|
2668
|
+
const main = useStage();
|
|
2669
|
+
const thumbs = useStage(ThumbsStageToken);
|
|
2670
|
+
const currentPage = useStageState((state) => state.currentPageIndex);
|
|
2671
|
+
const pages = usePageList();
|
|
2672
|
+
const pageEdit = usePageEdit();
|
|
2673
|
+
const selected = usePageEditState((state) => state.selected);
|
|
2674
|
+
const commands = useCommands();
|
|
2675
|
+
const insertFile = useCommand("page:insert-file");
|
|
2676
|
+
const insertBlank = useCommand("page:insert-blank");
|
|
2677
|
+
const editable = insertBlank.visible && insertBlank.enabled;
|
|
2678
|
+
const closeOnPick = useCloseOnPick();
|
|
2679
|
+
const host = useRef(null);
|
|
2680
|
+
const [focusedPage, setFocusedPage] = useState(null);
|
|
2681
|
+
const [anchorPage, setAnchorPage] = useState(null);
|
|
2682
|
+
const [listFocused, setListFocused] = useState(false);
|
|
2683
|
+
const [drag, setDrag] = useState(null);
|
|
2684
|
+
const dragRef = useRef(null);
|
|
2685
|
+
dragRef.current = drag;
|
|
2686
|
+
const [fileDrop, setFileDrop] = useState(null);
|
|
2687
|
+
const holdTimer = useRef(null);
|
|
2688
|
+
const suppressClick = useRef(false);
|
|
2689
|
+
const order = pages.map((page) => page.ref.objectNumber);
|
|
2690
|
+
const indexOf = (page) => page === null ? -1 : order.indexOf(page);
|
|
2691
|
+
const selectedPages = new Set(selected.map((ref) => ref.objectNumber));
|
|
2692
|
+
const focusedIndex = indexOf(focusedPage) >= 0 ? indexOf(focusedPage) : currentPage;
|
|
2693
|
+
useEffect(() => thumbs.reveal(currentPage), [currentPage, thumbs]);
|
|
2694
|
+
const laidOut = useStageState((state) => state.pageCount, ThumbsStageToken);
|
|
2695
|
+
const lastSelected = selected[selected.length - 1]?.objectNumber ?? null;
|
|
2696
|
+
const lastSelectedIndex = lastSelected === null ? -1 : order.indexOf(lastSelected);
|
|
2697
|
+
useEffect(() => {
|
|
2698
|
+
if (lastSelectedIndex >= 0 && lastSelectedIndex < laidOut) thumbs.reveal(lastSelectedIndex);
|
|
2699
|
+
}, [
|
|
2700
|
+
lastSelectedIndex,
|
|
2701
|
+
laidOut,
|
|
2702
|
+
thumbs
|
|
2703
|
+
]);
|
|
2704
|
+
const spacing = () => {
|
|
2705
|
+
const { gap, pageFrame } = thumbs.getSettings();
|
|
2706
|
+
return {
|
|
2707
|
+
gap: typeof gap === "object" && gap !== null && "px" in gap ? gap.px : DEFAULT_GAP_PX,
|
|
2708
|
+
band: pageFrame.bottom
|
|
2709
|
+
};
|
|
2710
|
+
};
|
|
2711
|
+
/** A pointer's place in the lens's viewport. */
|
|
2712
|
+
const pointOf = (clientX, clientY) => {
|
|
2713
|
+
const box = host.current?.getBoundingClientRect();
|
|
2714
|
+
return box ? {
|
|
2715
|
+
x: clientX - box.left,
|
|
2716
|
+
y: clientY - box.top
|
|
2717
|
+
} : null;
|
|
2718
|
+
};
|
|
2719
|
+
const dropAt = (clientX, clientY, moving) => {
|
|
2720
|
+
const point = pointOf(clientX, clientY);
|
|
2721
|
+
return point ? thumbDropAt(boxesOf(thumbs), point, spacing(), order, moving) : null;
|
|
2722
|
+
};
|
|
2723
|
+
const go = (index) => {
|
|
2724
|
+
main.goToPage(index);
|
|
2725
|
+
closeOnPick();
|
|
2726
|
+
};
|
|
2727
|
+
const select = (refs) => pageEdit.select(refs);
|
|
2728
|
+
const onPageClick = (ref, index, event) => {
|
|
2729
|
+
if (suppressClick.current) {
|
|
2730
|
+
suppressClick.current = false;
|
|
2731
|
+
return;
|
|
2732
|
+
}
|
|
2733
|
+
const page = ref.objectNumber;
|
|
2734
|
+
setFocusedPage(page);
|
|
2735
|
+
if (editable && (event.metaKey || event.ctrlKey)) {
|
|
2736
|
+
select(selectedPages.has(page) ? selected.filter((each) => each.objectNumber !== page) : [...selected, ref]);
|
|
2737
|
+
setAnchorPage(page);
|
|
2738
|
+
return;
|
|
2739
|
+
}
|
|
2740
|
+
if (editable && event.shiftKey && indexOf(anchorPage) >= 0) {
|
|
2741
|
+
const from = indexOf(anchorPage);
|
|
2742
|
+
const [low, high] = from < index ? [from, index] : [index, from];
|
|
2743
|
+
select(pages.slice(low, high + 1).map((each) => each.ref));
|
|
2744
|
+
return;
|
|
2745
|
+
}
|
|
2746
|
+
setAnchorPage(page);
|
|
2747
|
+
if (editable) select([ref]);
|
|
2748
|
+
go(index);
|
|
2749
|
+
};
|
|
2750
|
+
/** A page's menu is about to open: an unselected page becomes the selection. */
|
|
2751
|
+
const onMenu = (ref) => {
|
|
2752
|
+
setFocusedPage(ref.objectNumber);
|
|
2753
|
+
if (!selectedPages.has(ref.objectNumber)) select([ref]);
|
|
2754
|
+
};
|
|
2755
|
+
const openMenuOf = (page) => host.current?.querySelector(`[data-epdf-page-menu="${page}"] button`)?.click();
|
|
2756
|
+
const stopHold = () => {
|
|
2757
|
+
if (holdTimer.current !== null) clearTimeout(holdTimer.current);
|
|
2758
|
+
holdTimer.current = null;
|
|
2759
|
+
};
|
|
2760
|
+
const onPagePointerDown = (ref, event) => {
|
|
2761
|
+
if (!editable || event.button !== 0) return;
|
|
2762
|
+
if (event.target.closest("[data-epdf-page-menu]")) return;
|
|
2763
|
+
const page = ref.objectNumber;
|
|
2764
|
+
const moving = selectedPages.has(page) ? selectedPages : /* @__PURE__ */ new Set([page]);
|
|
2765
|
+
setDrag({
|
|
2766
|
+
pointerId: event.pointerId,
|
|
2767
|
+
startX: event.clientX,
|
|
2768
|
+
startY: event.clientY,
|
|
2769
|
+
page,
|
|
2770
|
+
moving,
|
|
2771
|
+
held: false,
|
|
2772
|
+
active: false,
|
|
2773
|
+
drop: null
|
|
2774
|
+
});
|
|
2775
|
+
if (event.pointerType !== "mouse") holdTimer.current = setTimeout(() => {
|
|
2776
|
+
const current = dragRef.current;
|
|
2777
|
+
if (current && !current.active) setDrag({
|
|
2778
|
+
...current,
|
|
2779
|
+
held: true
|
|
2780
|
+
});
|
|
2781
|
+
}, HOLD_MS);
|
|
2782
|
+
};
|
|
2783
|
+
const dragging = drag?.active === true;
|
|
2784
|
+
const pressed = drag !== null;
|
|
2785
|
+
useEffect(() => {
|
|
2786
|
+
if (!pressed) return void 0;
|
|
2787
|
+
const move = (event) => {
|
|
2788
|
+
const current = dragRef.current;
|
|
2789
|
+
if (!current || event.pointerId !== current.pointerId) return;
|
|
2790
|
+
if (!current.active) {
|
|
2791
|
+
if (Math.hypot(event.clientX - current.startX, event.clientY - current.startY) <= DRAG_SLOP_PX) return;
|
|
2792
|
+
if (event.pointerType !== "mouse" && !current.held) {
|
|
2793
|
+
stopHold();
|
|
2794
|
+
setDrag(null);
|
|
2795
|
+
return;
|
|
2796
|
+
}
|
|
2797
|
+
}
|
|
2798
|
+
const box = host.current?.getBoundingClientRect();
|
|
2799
|
+
if (box && event.clientY < box.top + EDGE_PX) thumbs.scrollBy({ top: -8 });
|
|
2800
|
+
else if (box && event.clientY > box.bottom - EDGE_PX) thumbs.scrollBy({ top: 8 });
|
|
2801
|
+
setDrag({
|
|
2802
|
+
...current,
|
|
2803
|
+
active: true,
|
|
2804
|
+
drop: dropAt(event.clientX, event.clientY, current.moving)
|
|
2805
|
+
});
|
|
2806
|
+
};
|
|
2807
|
+
const end = (event, commit) => {
|
|
2808
|
+
stopHold();
|
|
2809
|
+
const current = dragRef.current;
|
|
2810
|
+
if (!current || event.pointerId !== current.pointerId) return;
|
|
2811
|
+
setDrag(null);
|
|
2812
|
+
if (!current.active) {
|
|
2813
|
+
if (current.held && commit) {
|
|
2814
|
+
suppressClick.current = true;
|
|
2815
|
+
onMenu(toPageRef(current.page));
|
|
2816
|
+
openMenuOf(current.page);
|
|
2817
|
+
}
|
|
2818
|
+
return;
|
|
2819
|
+
}
|
|
2820
|
+
suppressClick.current = true;
|
|
2821
|
+
setTimeout(() => {
|
|
2822
|
+
suppressClick.current = false;
|
|
2823
|
+
}, 0);
|
|
2824
|
+
if (!commit || !current.drop) return;
|
|
2825
|
+
const moving = pages.filter((page) => current.moving.has(page.ref.objectNumber));
|
|
2826
|
+
pageEdit.reorder(moving.map((page) => page.ref), positionOf(current.drop.position)).catch(() => {});
|
|
2827
|
+
};
|
|
2828
|
+
const up = (event) => end(event, true);
|
|
2829
|
+
const cancel = (event) => end(event, false);
|
|
2830
|
+
window.addEventListener("pointermove", move);
|
|
2831
|
+
window.addEventListener("pointerup", up);
|
|
2832
|
+
window.addEventListener("pointercancel", cancel);
|
|
2833
|
+
return () => {
|
|
2834
|
+
window.removeEventListener("pointermove", move);
|
|
2835
|
+
window.removeEventListener("pointerup", up);
|
|
2836
|
+
window.removeEventListener("pointercancel", cancel);
|
|
2837
|
+
};
|
|
2838
|
+
});
|
|
2839
|
+
useEffect(() => {
|
|
2840
|
+
if (!dragging) return void 0;
|
|
2841
|
+
const prevent = (event) => event.preventDefault();
|
|
2842
|
+
document.addEventListener("touchmove", prevent, { passive: false });
|
|
2843
|
+
return () => document.removeEventListener("touchmove", prevent);
|
|
2844
|
+
}, [dragging]);
|
|
2845
|
+
useEffect(() => stopHold, []);
|
|
2846
|
+
const takesFiles = (event) => editable && insertFile.visible && insertFile.enabled && mayCarryPdf(event.dataTransfer);
|
|
2847
|
+
const onDragOver = (event) => {
|
|
2848
|
+
if (!takesFiles(event)) return;
|
|
2849
|
+
event.preventDefault();
|
|
2850
|
+
event.stopPropagation();
|
|
2851
|
+
event.dataTransfer.dropEffect = "copy";
|
|
2852
|
+
setFileDrop(dropAt(event.clientX, event.clientY, /* @__PURE__ */ new Set()));
|
|
2853
|
+
};
|
|
2854
|
+
const onDragLeave = (event) => {
|
|
2855
|
+
if (!takesFiles(event)) return;
|
|
2856
|
+
event.stopPropagation();
|
|
2857
|
+
const next = event.relatedTarget;
|
|
2858
|
+
if (!next || !host.current?.contains(next)) setFileDrop(null);
|
|
2859
|
+
};
|
|
2860
|
+
const onDrop = (event) => {
|
|
2861
|
+
if (!takesFiles(event)) return;
|
|
2862
|
+
event.preventDefault();
|
|
2863
|
+
event.stopPropagation();
|
|
2864
|
+
const drop = dropAt(event.clientX, event.clientY, /* @__PURE__ */ new Set());
|
|
2865
|
+
setFileDrop(null);
|
|
2866
|
+
const files = Array.from(event.dataTransfer.files).filter(isPdfFile);
|
|
2867
|
+
if (files.length === 0) return;
|
|
2868
|
+
const args = {
|
|
2869
|
+
files,
|
|
2870
|
+
...drop ? { position: positionOf(drop.position) } : {}
|
|
2871
|
+
};
|
|
2872
|
+
commands.execute("page:insert-file", { args }).catch(() => {});
|
|
2873
|
+
};
|
|
2874
|
+
const focusIndex = (index, extend) => {
|
|
2875
|
+
const page = pages[index];
|
|
2876
|
+
if (!page) return;
|
|
2877
|
+
setFocusedPage(page.ref.objectNumber);
|
|
2878
|
+
thumbs.reveal(index);
|
|
2879
|
+
if (!editable) {
|
|
2880
|
+
main.goToPage(index);
|
|
2881
|
+
return;
|
|
2882
|
+
}
|
|
2883
|
+
if (extend && indexOf(anchorPage) >= 0) {
|
|
2884
|
+
const from = indexOf(anchorPage);
|
|
2885
|
+
const [low, high] = from < index ? [from, index] : [index, from];
|
|
2886
|
+
select(pages.slice(low, high + 1).map((each) => each.ref));
|
|
2887
|
+
return;
|
|
2888
|
+
}
|
|
2889
|
+
setAnchorPage(page.ref.objectNumber);
|
|
2890
|
+
select([page.ref]);
|
|
2891
|
+
main.goToPage(index);
|
|
2892
|
+
};
|
|
2893
|
+
const onKeyDown = (event) => {
|
|
2894
|
+
if (event.target !== event.currentTarget || pages.length === 0) return;
|
|
2895
|
+
setListFocused(true);
|
|
2896
|
+
const columns = columnsOf(boxesOf(thumbs));
|
|
2897
|
+
const step = {
|
|
2898
|
+
ArrowLeft: -1,
|
|
2899
|
+
ArrowRight: 1,
|
|
2900
|
+
ArrowUp: -columns,
|
|
2901
|
+
ArrowDown: columns
|
|
2902
|
+
}[event.key];
|
|
2903
|
+
const mod = event.metaKey || event.ctrlKey;
|
|
2904
|
+
if (step !== void 0 && event.altKey && editable) {
|
|
2905
|
+
event.preventDefault();
|
|
2906
|
+
const position = slotMove(order, selectedPages, step < 0 ? -1 : 1);
|
|
2907
|
+
const moving = pages.filter((page) => selectedPages.has(page.ref.objectNumber));
|
|
2908
|
+
if (position && moving.length > 0) pageEdit.reorder(moving.map((page) => page.ref), positionOf(position)).catch(() => {});
|
|
2909
|
+
return;
|
|
2910
|
+
}
|
|
2911
|
+
if (step !== void 0) {
|
|
2912
|
+
event.preventDefault();
|
|
2913
|
+
focusIndex(Math.max(0, Math.min(pages.length - 1, focusedIndex + step)), event.shiftKey);
|
|
2914
|
+
return;
|
|
2915
|
+
}
|
|
2916
|
+
switch (event.key) {
|
|
2917
|
+
case "Home":
|
|
2918
|
+
case "End":
|
|
2919
|
+
event.preventDefault();
|
|
2920
|
+
focusIndex(event.key === "Home" ? 0 : pages.length - 1, event.shiftKey);
|
|
2921
|
+
return;
|
|
2922
|
+
case "Enter":
|
|
2923
|
+
event.preventDefault();
|
|
2924
|
+
go(focusedIndex);
|
|
2925
|
+
return;
|
|
2926
|
+
case " ": {
|
|
2927
|
+
if (!editable) return;
|
|
2928
|
+
event.preventDefault();
|
|
2929
|
+
const page = pages[focusedIndex];
|
|
2930
|
+
if (!page) return;
|
|
2931
|
+
const number = page.ref.objectNumber;
|
|
2932
|
+
setAnchorPage(number);
|
|
2933
|
+
select(selectedPages.has(number) ? selected.filter((each) => each.objectNumber !== number) : [...selected, page.ref]);
|
|
2934
|
+
return;
|
|
2935
|
+
}
|
|
2936
|
+
case "Delete":
|
|
2937
|
+
case "Backspace":
|
|
2938
|
+
if (!editable) return;
|
|
2939
|
+
event.preventDefault();
|
|
2940
|
+
commands.execute("page:delete").catch(() => {});
|
|
2941
|
+
return;
|
|
2942
|
+
case "a":
|
|
2943
|
+
case "A":
|
|
2944
|
+
if (!mod || !editable) return;
|
|
2945
|
+
event.preventDefault();
|
|
2946
|
+
commands.execute("page:select-all").catch(() => {});
|
|
2947
|
+
return;
|
|
2948
|
+
}
|
|
2949
|
+
};
|
|
2950
|
+
const focusedRef = pages[focusedIndex]?.ref ?? null;
|
|
2951
|
+
const shownDrop = dragging ? drag.drop : fileDrop;
|
|
2952
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
2953
|
+
className: "flex min-h-0 flex-1 flex-col",
|
|
2954
|
+
children: [editable && /* @__PURE__ */ jsx(PageHeader, {}), /* @__PURE__ */ jsx("div", {
|
|
2955
|
+
ref: host,
|
|
2956
|
+
role: "listbox",
|
|
2957
|
+
"aria-label": t("panels.thumbnails"),
|
|
2958
|
+
"aria-multiselectable": editable || void 0,
|
|
2959
|
+
tabIndex: 0,
|
|
2960
|
+
"aria-activedescendant": listFocused && focusedRef ? `${idPrefix}-${focusedRef.objectNumber}` : void 0,
|
|
2961
|
+
onKeyDown,
|
|
2962
|
+
onFocus: (event) => event.target === event.currentTarget && setListFocused(event.currentTarget.matches(":focus-visible")),
|
|
2963
|
+
onBlur: (event) => event.target === event.currentTarget && setListFocused(false),
|
|
2964
|
+
onDragEnter: onDragOver,
|
|
2965
|
+
onDragOver,
|
|
2966
|
+
onDragLeave,
|
|
2967
|
+
onDrop,
|
|
2968
|
+
className: "focus-visible:ring-accent relative flex min-h-0 flex-1 flex-col outline-none focus-visible:ring-2 focus-visible:ring-inset",
|
|
2969
|
+
children: /* @__PURE__ */ jsx(Stage, {
|
|
2970
|
+
token: ThumbsStageToken,
|
|
2971
|
+
className: "flex-1",
|
|
2972
|
+
style: { position: "relative" },
|
|
2973
|
+
overlay: shownDrop ? /* @__PURE__ */ jsx("div", {
|
|
2974
|
+
"aria-hidden": true,
|
|
2975
|
+
className: "bg-accent pointer-events-none absolute rounded-full",
|
|
2976
|
+
style: {
|
|
2977
|
+
left: shownDrop.line.x,
|
|
2978
|
+
top: shownDrop.line.y,
|
|
2979
|
+
width: shownDrop.line.width,
|
|
2980
|
+
height: shownDrop.line.height
|
|
2981
|
+
}
|
|
2982
|
+
}) : null,
|
|
2983
|
+
pageChrome: (page) => {
|
|
2984
|
+
const number = page.ref.objectNumber;
|
|
2985
|
+
const isSelected = editable && selectedPages.has(number);
|
|
2986
|
+
const isCurrent = page.pageIndex === currentPage;
|
|
2987
|
+
const isFocused = listFocused && focusedRef?.objectNumber === number;
|
|
2988
|
+
const isMoving = dragging && drag.moving.has(number);
|
|
2989
|
+
const label = t("thumbnails.page", { params: { page: page.pageIndex + 1 } });
|
|
2990
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
2991
|
+
className: "group",
|
|
2992
|
+
style: {
|
|
2993
|
+
position: "absolute",
|
|
2994
|
+
inset: 0
|
|
2995
|
+
},
|
|
2996
|
+
children: [
|
|
2997
|
+
/* @__PURE__ */ jsx("button", {
|
|
2998
|
+
type: "button",
|
|
2999
|
+
id: `${idPrefix}-${number}`,
|
|
3000
|
+
role: "option",
|
|
3001
|
+
"aria-selected": editable ? isSelected : isCurrent,
|
|
3002
|
+
"aria-current": isCurrent ? "page" : void 0,
|
|
3003
|
+
"aria-label": label,
|
|
3004
|
+
tabIndex: -1,
|
|
3005
|
+
title: label,
|
|
3006
|
+
onClick: (event) => onPageClick(page.ref, page.pageIndex, event),
|
|
3007
|
+
onPointerDown: (event) => onPagePointerDown(page.ref, event),
|
|
3008
|
+
onContextMenu: (event) => {
|
|
3009
|
+
if (!editable) return;
|
|
3010
|
+
event.preventDefault();
|
|
3011
|
+
onMenu(page.ref);
|
|
3012
|
+
openMenuOf(number);
|
|
3013
|
+
},
|
|
3014
|
+
className: `box-border cursor-pointer touch-manipulation rounded ${isSelected || isCurrent ? "border-accent border-2" : "border-border-subtle border"} ${isCurrent ? "ring-accent-light ring-2" : ""} ${isSelected ? "bg-accent/10" : ""} ${isFocused ? "outline-accent outline outline-2 outline-offset-2" : ""} ${isMoving ? "bg-surface/60" : ""}`,
|
|
3015
|
+
style: {
|
|
3016
|
+
position: "absolute",
|
|
3017
|
+
top: page.frame.top,
|
|
3018
|
+
left: page.frame.left,
|
|
3019
|
+
right: page.frame.right,
|
|
3020
|
+
bottom: page.frame.bottom
|
|
3021
|
+
}
|
|
3022
|
+
}),
|
|
3023
|
+
editable && /* @__PURE__ */ jsx("span", {
|
|
3024
|
+
"data-epdf-page-menu": number,
|
|
3025
|
+
onClick: (event) => event.stopPropagation(),
|
|
3026
|
+
onPointerDownCapture: () => onMenu(page.ref),
|
|
3027
|
+
className: `bg-elevated absolute rounded shadow-sm ${isSelected || isFocused ? "" : "opacity-0 focus-within:opacity-100 group-hover:opacity-100"}`,
|
|
3028
|
+
style: {
|
|
3029
|
+
top: page.frame.top + 4,
|
|
3030
|
+
right: page.frame.right + 4
|
|
3031
|
+
},
|
|
3032
|
+
children: /* @__PURE__ */ jsx(PageMenuButton, {})
|
|
3033
|
+
}),
|
|
3034
|
+
/* @__PURE__ */ jsx("div", {
|
|
3035
|
+
style: {
|
|
3036
|
+
position: "absolute",
|
|
3037
|
+
bottom: 0,
|
|
3038
|
+
left: 0,
|
|
3039
|
+
right: 0,
|
|
3040
|
+
height: page.frame.bottom,
|
|
3041
|
+
display: "flex",
|
|
3042
|
+
alignItems: "center",
|
|
3043
|
+
justifyContent: "center",
|
|
3044
|
+
fontSize: 11,
|
|
3045
|
+
color: "var(--epdf-text-muted)",
|
|
3046
|
+
pointerEvents: "none"
|
|
3047
|
+
},
|
|
3048
|
+
children: page.pageIndex + 1
|
|
3049
|
+
})
|
|
3050
|
+
]
|
|
3051
|
+
});
|
|
3052
|
+
},
|
|
3053
|
+
children: () => /* @__PURE__ */ jsx(RenderLayer, {})
|
|
3054
|
+
})
|
|
3055
|
+
})]
|
|
3056
|
+
});
|
|
3057
|
+
}
|
|
3058
|
+
/** A page's menu button: the page commands for the selected pages. */
|
|
3059
|
+
function PageMenuButton() {
|
|
3060
|
+
const more = useCommand("menu:page");
|
|
3061
|
+
if (!more.visible) return null;
|
|
3062
|
+
return /* @__PURE__ */ jsx(CommandButton, {
|
|
3063
|
+
cmd: more,
|
|
3064
|
+
variant: "icon",
|
|
3065
|
+
run: () => void more.run()
|
|
3066
|
+
});
|
|
3067
|
+
}
|
|
3068
|
+
/** The header over the thumbnails while the pages can be changed: the edits, then the history. */
|
|
3069
|
+
function PageHeader() {
|
|
3070
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
3071
|
+
className: "border-border-subtle flex items-center gap-1 border-b p-2",
|
|
3072
|
+
children: [
|
|
3073
|
+
HEADER_EDITS.map((id) => /* @__PURE__ */ jsx(HeaderButton, { id }, id)),
|
|
3074
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1" }),
|
|
3075
|
+
HEADER_HISTORY.map((id) => /* @__PURE__ */ jsx(HeaderButton, { id }, id))
|
|
3076
|
+
]
|
|
3077
|
+
});
|
|
3078
|
+
}
|
|
3079
|
+
function HeaderButton({ id }) {
|
|
3080
|
+
const command = useCommand(id);
|
|
3081
|
+
if (!command.visible) return null;
|
|
3082
|
+
return /* @__PURE__ */ jsx(CommandButton, {
|
|
3083
|
+
cmd: command,
|
|
3084
|
+
variant: "icon",
|
|
3085
|
+
run: () => void command.run()
|
|
3086
|
+
});
|
|
3087
|
+
}
|
|
3088
|
+
//#endregion
|
|
2519
3089
|
//#region src/ui/panels.tsx
|
|
2520
3090
|
/**
|
|
2521
3091
|
* The layout's panels, drawn: on each side of the pages, the panel open on
|
|
@@ -2531,19 +3101,29 @@ function PanelRow({ panel, current, onPicked }) {
|
|
|
2531
3101
|
* A panel whose button no longer shows (its feature turned off, or not
|
|
2532
3102
|
* allowed) closes.
|
|
2533
3103
|
*/
|
|
2534
|
-
const SearchPanel = lazyComponent(() => import("./search-panel-
|
|
2535
|
-
const CommentsPanel = lazyComponent(() => import("./comments-panel-
|
|
2536
|
-
const MeasurementSection = lazyComponent(() => import("./measurement-
|
|
2537
|
-
const AnnotationStylePanel = lazyComponent(() => import("./annotation-style
|
|
2538
|
-
const StampsPanel = lazyComponent(() => import("./stamps-panel-
|
|
2539
|
-
const SignaturesPanel = lazyComponent(() => import("./signatures-panel-
|
|
2540
|
-
const RedactionPanel = lazyComponent(() => import("./redaction-panel-
|
|
2541
|
-
const
|
|
3104
|
+
const SearchPanel = lazyComponent(() => import("./search-panel-BE4xzWlm.js").then((ui) => ui.SearchPanel));
|
|
3105
|
+
const CommentsPanel = lazyComponent(() => import("./comments-panel-D7Eadws9.js").then((ui) => ui.CommentsPanel));
|
|
3106
|
+
const MeasurementSection = lazyComponent(() => import("./measurement-CQdbnIrn.js").then((ui) => ui.MeasurementSection));
|
|
3107
|
+
const AnnotationStylePanel = lazyComponent(() => import("./annotation-style-CXF3X47Z.js").then((ui) => ui.AnnotationStylePanel));
|
|
3108
|
+
const StampsPanel = lazyComponent(() => import("./stamps-panel-BrczStaz.js").then((ui) => ui.StampsPanel));
|
|
3109
|
+
const SignaturesPanel = lazyComponent(() => import("./signatures-panel-DZ9ywrjz.js").then((ui) => ui.SignaturesPanel));
|
|
3110
|
+
const RedactionPanel = lazyComponent(() => import("./redaction-panel-CgNZ-pQk.js").then((ui) => ui.RedactionPanel));
|
|
3111
|
+
const OutlinePanel = lazyComponent(() => import("./outline-panel-DO5_REYw.js").then((ui) => ui.OutlinePanel));
|
|
3112
|
+
const AttachmentsPanel = lazyComponent(() => import("./attachments-panel-H1ucRbwo.js").then((ui) => ui.AttachmentsPanel));
|
|
3113
|
+
const FormDesignPanel = lazyComponent(() => import("./form-design-panel-CgV_5YWC.js").then((ui) => ui.FormDesignPanel));
|
|
2542
3114
|
const BUILT_IN_CONTENT = /* @__PURE__ */ new Map([
|
|
2543
3115
|
["thumbnails", {
|
|
2544
3116
|
draw: () => /* @__PURE__ */ jsx(ThumbnailList, {}),
|
|
2545
3117
|
list: true
|
|
2546
3118
|
}],
|
|
3119
|
+
["outline", {
|
|
3120
|
+
draw: (documentId) => /* @__PURE__ */ jsx(OutlinePanel, {}, documentId ?? "none"),
|
|
3121
|
+
list: true
|
|
3122
|
+
}],
|
|
3123
|
+
["attachments", {
|
|
3124
|
+
draw: (documentId) => /* @__PURE__ */ jsx(AttachmentsPanel, {}, documentId ?? "none"),
|
|
3125
|
+
list: true
|
|
3126
|
+
}],
|
|
2547
3127
|
["search", {
|
|
2548
3128
|
draw: (documentId) => /* @__PURE__ */ jsx(SearchPanel, {}, documentId ?? "none"),
|
|
2549
3129
|
list: true
|
|
@@ -2624,51 +3204,6 @@ function OpenPanel({ id, side, siblings }) {
|
|
|
2624
3204
|
})
|
|
2625
3205
|
});
|
|
2626
3206
|
}
|
|
2627
|
-
function ThumbnailList() {
|
|
2628
|
-
const t = useT();
|
|
2629
|
-
const main = useStage();
|
|
2630
|
-
const thumbs = useStage(ThumbsStageToken);
|
|
2631
|
-
const currentPage = useStageState((state) => state.currentPageIndex);
|
|
2632
|
-
const closeOnPick = useCloseOnPick();
|
|
2633
|
-
useEffect(() => thumbs.reveal(currentPage), [currentPage, thumbs]);
|
|
2634
|
-
return /* @__PURE__ */ jsx(Stage, {
|
|
2635
|
-
token: ThumbsStageToken,
|
|
2636
|
-
className: "flex-1",
|
|
2637
|
-
style: { position: "relative" },
|
|
2638
|
-
pageChrome: (page) => /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("button", {
|
|
2639
|
-
type: "button",
|
|
2640
|
-
onClick: () => {
|
|
2641
|
-
main.goToPage(page.pageIndex);
|
|
2642
|
-
closeOnPick();
|
|
2643
|
-
},
|
|
2644
|
-
title: t("thumbnails.page", { params: { page: page.pageIndex + 1 } }),
|
|
2645
|
-
className: `box-border cursor-pointer rounded ${page.pageIndex === currentPage ? "border-accent ring-accent-light border-2 ring-2" : "border-border-subtle border"}`,
|
|
2646
|
-
style: {
|
|
2647
|
-
position: "absolute",
|
|
2648
|
-
top: page.frame.top,
|
|
2649
|
-
left: page.frame.left,
|
|
2650
|
-
right: page.frame.right,
|
|
2651
|
-
bottom: page.frame.bottom
|
|
2652
|
-
}
|
|
2653
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
2654
|
-
style: {
|
|
2655
|
-
position: "absolute",
|
|
2656
|
-
bottom: 0,
|
|
2657
|
-
left: 0,
|
|
2658
|
-
right: 0,
|
|
2659
|
-
height: page.frame.bottom,
|
|
2660
|
-
display: "flex",
|
|
2661
|
-
alignItems: "center",
|
|
2662
|
-
justifyContent: "center",
|
|
2663
|
-
fontSize: 11,
|
|
2664
|
-
color: "var(--epdf-text-muted)",
|
|
2665
|
-
pointerEvents: "none"
|
|
2666
|
-
},
|
|
2667
|
-
children: page.pageIndex + 1
|
|
2668
|
-
})] }),
|
|
2669
|
-
children: () => /* @__PURE__ */ jsx(RenderLayer, {})
|
|
2670
|
-
});
|
|
2671
|
-
}
|
|
2672
3207
|
//#endregion
|
|
2673
3208
|
//#region src/ui/placed-components.tsx
|
|
2674
3209
|
/**
|
|
@@ -2991,7 +3526,8 @@ const GROUPS = [
|
|
|
2991
3526
|
"selection",
|
|
2992
3527
|
"annotation",
|
|
2993
3528
|
"redaction",
|
|
2994
|
-
"measurement"
|
|
3529
|
+
"measurement",
|
|
3530
|
+
"outline"
|
|
2995
3531
|
]
|
|
2996
3532
|
}
|
|
2997
3533
|
];
|
|
@@ -3081,6 +3617,18 @@ function ShortcutsList({ onClose }) {
|
|
|
3081
3617
|
});
|
|
3082
3618
|
}
|
|
3083
3619
|
//#endregion
|
|
3620
|
+
//#region src/ui/sidebar-reads.tsx
|
|
3621
|
+
/**
|
|
3622
|
+
* Once a document shows: read its outline and its attachments, so their panels' buttons know
|
|
3623
|
+
* whether the panels have a job (`config/panels.ts`). Reading a plugin's state is what reads it;
|
|
3624
|
+
* a viewer without the plugin reads nothing. Mounted once per document view; renders nothing.
|
|
3625
|
+
*/
|
|
3626
|
+
function SidebarReads() {
|
|
3627
|
+
useOutlineState((state) => state.status);
|
|
3628
|
+
useAttachmentState((state) => state.status);
|
|
3629
|
+
return null;
|
|
3630
|
+
}
|
|
3631
|
+
//#endregion
|
|
3084
3632
|
//#region src/ui/signature-bridge.tsx
|
|
3085
3633
|
/**
|
|
3086
3634
|
* The signature plugin's UI intents → shell surfaces. The plugin owns the
|
|
@@ -3408,11 +3956,15 @@ const useCalibrating = () => useMeasurementState((state) => state.calibrationReq
|
|
|
3408
3956
|
const useSignDialogOpen = () => useSurface("signature-sign").isOpen;
|
|
3409
3957
|
const useSignatureMakerOpen = () => useSurface("signature-maker").isOpen;
|
|
3410
3958
|
const useSignatureInspectorOpen = () => useSurface("signature-inspector").isOpen;
|
|
3411
|
-
const
|
|
3412
|
-
const
|
|
3413
|
-
const
|
|
3414
|
-
const
|
|
3415
|
-
const
|
|
3959
|
+
const usePrintDialogOpen = () => useSurface("print").isOpen;
|
|
3960
|
+
const RedactConfirmModal = lazyComponent(() => import("./redact-confirm-CKuv9iN_.js").then((ui) => ui.RedactConfirmModal), { shownWhile: useRedactConfirmOpen });
|
|
3961
|
+
const CalibrationDialog = lazyComponent(() => import("./measurement-CQdbnIrn.js").then((ui) => ui.CalibrationDialog), { shownWhile: useCalibrating });
|
|
3962
|
+
const SignDialog = lazyComponent(() => import("./sign-dialog-DerNe8qT.js").then((ui) => ui.SignDialog), { shownWhile: useSignDialogOpen });
|
|
3963
|
+
const SignatureMakerModal = lazyComponent(() => import("./signature-maker-Dnth4rV4.js").then((ui) => ui.SignatureMakerModal), { shownWhile: useSignatureMakerOpen });
|
|
3964
|
+
const SignatureInspector = lazyComponent(() => import("./signature-inspector-CsGr9EBk.js").then((ui) => ui.SignatureInspector), { shownWhile: useSignatureInspectorOpen });
|
|
3965
|
+
const PrintDialog = lazyComponent(() => import("./print-dialog-DvcI2m2_.js").then((ui) => ui.PrintDialog), { shownWhile: usePrintDialogOpen });
|
|
3966
|
+
const useOutlinePropertiesOpen = () => useSurface(OUTLINE_PROPERTIES_DIALOG).isOpen;
|
|
3967
|
+
const OutlinePropertiesDialog = lazyComponent(() => import("./outline-properties-BCa2cc0t.js").then((ui) => ui.OutlinePropertiesDialog), { shownWhile: useOutlinePropertiesOpen });
|
|
3416
3968
|
/** The document tabs, as the layout says: always, while more than one document is open, or never. */
|
|
3417
3969
|
function DocumentTabs() {
|
|
3418
3970
|
const visibility = tabsOf(useResolvedLayout().data);
|
|
@@ -3537,8 +4089,11 @@ function Shell({ components }) {
|
|
|
3537
4089
|
/* @__PURE__ */ jsx(RedactConfirmModal, {}),
|
|
3538
4090
|
/* @__PURE__ */ jsx(CalibrationDialog, {}),
|
|
3539
4091
|
/* @__PURE__ */ jsx(GoToPageDialog, {}),
|
|
4092
|
+
/* @__PURE__ */ jsx(PrintDialog, {}),
|
|
4093
|
+
/* @__PURE__ */ jsx(OutlinePropertiesDialog, {}),
|
|
3540
4094
|
/* @__PURE__ */ jsx(ShortcutsSheet, {}),
|
|
3541
4095
|
/* @__PURE__ */ jsx(SignatureBridge, {}),
|
|
4096
|
+
/* @__PURE__ */ jsx(SidebarReads, {}),
|
|
3542
4097
|
/* @__PURE__ */ jsx(FeaturePrefetch, {}),
|
|
3543
4098
|
/* @__PURE__ */ jsx(SignDialog, {}),
|
|
3544
4099
|
/* @__PURE__ */ jsx(SignatureMakerModal, {})
|
|
@@ -3716,6 +4271,8 @@ function FullViewer({ engine, initialDocuments, fallback, commands, icons, strin
|
|
|
3716
4271
|
renderPlugin(settings.render),
|
|
3717
4272
|
pageEditPlugin(),
|
|
3718
4273
|
metadataPlugin(),
|
|
4274
|
+
outlinePlugin(),
|
|
4275
|
+
attachmentPlugin(),
|
|
3719
4276
|
interactionPlugin(settings.interaction),
|
|
3720
4277
|
feedbackPlugin({ provider: vibrationFeedback }),
|
|
3721
4278
|
selectionPlugin(settings.selection),
|
|
@@ -3826,6 +4383,6 @@ function FullViewer({ engine, initialDocuments, fallback, commands, icons, strin
|
|
|
3826
4383
|
});
|
|
3827
4384
|
}
|
|
3828
4385
|
//#endregion
|
|
3829
|
-
export { ActionsToken, AnnotationToken, CommandsToken, DocumentsToken, FormToken, FullViewer, I18nToken, InteractionToken, LinkToken, MeasurementToken, MetadataToken, PageEditToken, RedactionToken, RenderToken, SearchToken, SelectionToken, ShellToken, SignatureToken, StageToken, StampToken, THEME_TOKENS, TOOLBAR_ITEM_CONTEXT_ATTRIBUTES, VIEWER_PLUGINS, createLayout, createPlacedComponents, createTestSigner, createViewer, defaultCommands, ICON_PATHS as defaultIcons, defaultLayout, indexedDbKeyStore, memoryKeyStore, personalSigner, remoteSigner, themeConfigOf, themeTokenCss, webCryptoSigner };
|
|
4386
|
+
export { ActionsToken, AnnotationToken, AttachmentToken, CommandsToken, DocumentsToken, FormToken, FullViewer, I18nToken, InteractionToken, LinkToken, MeasurementToken, MetadataToken, OutlineToken, PageEditToken, RedactionToken, RenderToken, SearchToken, SelectionToken, ShellToken, SignatureToken, StageToken, StampToken, THEME_TOKENS, TOOLBAR_ITEM_CONTEXT_ATTRIBUTES, VIEWER_PLUGINS, createLayout, createPlacedComponents, createTestSigner, createViewer, defaultCommands, ICON_PATHS as defaultIcons, defaultLayout, indexedDbKeyStore, memoryKeyStore, personalSigner, remoteSigner, themeConfigOf, themeTokenCss, webCryptoSigner };
|
|
3830
4387
|
|
|
3831
4388
|
//# sourceMappingURL=index.js.map
|