kviewer 0.2.0 → 0.2.2
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/README.md +47 -0
- package/dist/module.d.mts +8 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +25 -3
- package/dist/runtime/annotation/engine/canvas-resolution.d.ts +7 -0
- package/dist/runtime/annotation/engine/canvas-resolution.js +21 -0
- package/dist/runtime/annotation/engine/editor/editor.d.ts +5 -0
- package/dist/runtime/annotation/engine/editor/editor.js +14 -0
- package/dist/runtime/annotation/engine/editor/selector.d.ts +13 -1
- package/dist/runtime/annotation/engine/editor/selector.js +60 -8
- package/dist/runtime/annotation/engine/painter.d.ts +31 -0
- package/dist/runtime/annotation/engine/painter.js +88 -2
- package/dist/runtime/annotation/engine/store.js +3 -0
- package/dist/runtime/annotation/engine/tools/arrow.js +0 -1
- package/dist/runtime/annotation/engine/tools/circle.js +0 -2
- package/dist/runtime/annotation/engine/tools/free-highlight.js +0 -2
- package/dist/runtime/annotation/engine/tools/freehand.js +0 -2
- package/dist/runtime/annotation/engine/tools/rectangle.js +0 -2
- package/dist/runtime/annotation/engine/types.d.ts +5 -0
- package/dist/runtime/annotation/font-style.d.ts +15 -0
- package/dist/runtime/annotation/font-style.js +19 -0
- package/dist/runtime/annotation/parsers/extractCheckboxStyles.d.ts +8 -0
- package/dist/runtime/annotation/parsers/extractCheckboxStyles.js +24 -1
- package/dist/runtime/annotation/pdf-export/annotation-flags.d.ts +8 -0
- package/dist/runtime/annotation/pdf-export/annotation-flags.js +5 -0
- package/dist/runtime/annotation/pdf-export/export-form-fields.js +3 -1
- package/dist/runtime/annotation/pdf-export/export.js +13 -1
- package/dist/runtime/annotation/pdf-export/parse_circle.js +3 -0
- package/dist/runtime/annotation/pdf-export/parse_freetext.js +31 -19
- package/dist/runtime/annotation/pdf-export/parse_highlight.js +3 -0
- package/dist/runtime/annotation/pdf-export/parse_ink.js +5 -1
- package/dist/runtime/annotation/pdf-export/parse_line.js +5 -1
- package/dist/runtime/annotation/pdf-export/parse_polyline.js +5 -1
- package/dist/runtime/annotation/pdf-export/parse_square.js +3 -0
- package/dist/runtime/annotation/pdf-export/parse_stamp.js +4 -2
- package/dist/runtime/annotation/pdf-export/parse_strikeout.js +3 -0
- package/dist/runtime/annotation/pdf-export/parse_text.js +3 -0
- package/dist/runtime/annotation/pdf-export/parse_underline.js +3 -0
- package/dist/runtime/annotation/pdf-export/unicode-font.d.ts +5 -0
- package/dist/runtime/annotation/pdf-export/unicode-font.js +31 -0
- package/dist/runtime/annotation/pdf-export/winansi.d.ts +17 -0
- package/dist/runtime/annotation/pdf-export/winansi.js +77 -0
- package/dist/runtime/annotation/pdf-import/decode_circle.js +0 -1
- package/dist/runtime/annotation/pdf-import/decode_ink.js +0 -1
- package/dist/runtime/annotation/pdf-import/decode_line.js +0 -1
- package/dist/runtime/annotation/pdf-import/decode_square.js +0 -1
- package/dist/runtime/annotation/pdf-import/extract_stamp_appearance.d.ts +12 -0
- package/dist/runtime/annotation/pdf-import/extract_stamp_appearance.js +17 -4
- package/dist/runtime/annotation/pdf-import/types.d.ts +2 -0
- package/dist/runtime/assets/fonts/LICENSE-LiberationSans +102 -0
- package/dist/runtime/assets/fonts/LiberationSans-Regular.ttf +0 -0
- package/dist/runtime/assets/kviewer.css +1 -1
- package/dist/runtime/components/AnnotationToolbar.vue +6 -4
- package/dist/runtime/components/PdfPage.d.vue.ts +16 -0
- package/dist/runtime/components/PdfPage.vue +170 -9
- package/dist/runtime/components/PdfPage.vue.d.ts +16 -0
- package/dist/runtime/components/PerfHud.d.vue.ts +3 -0
- package/dist/runtime/components/PerfHud.vue +97 -0
- package/dist/runtime/components/PerfHud.vue.d.ts +3 -0
- package/dist/runtime/components/ToolButton.vue +4 -1
- package/dist/runtime/components/Viewer.d.vue.ts +37 -2
- package/dist/runtime/components/Viewer.vue +208 -13
- package/dist/runtime/components/Viewer.vue.d.ts +37 -2
- package/dist/runtime/components/ViewerBar.d.vue.ts +21 -1
- package/dist/runtime/components/ViewerBar.vue +183 -101
- package/dist/runtime/components/ViewerBar.vue.d.ts +21 -1
- package/dist/runtime/components/ViewerTabs.d.vue.ts +10 -2
- package/dist/runtime/components/ViewerTabs.vue +13 -2
- package/dist/runtime/components/ViewerTabs.vue.d.ts +10 -2
- package/dist/runtime/components/form-fields/FormDropdown.vue +50 -19
- package/dist/runtime/components/form-fields/FormSignatureField.vue +4 -2
- package/dist/runtime/components/form-fields/FormTextField.vue +7 -18
- package/dist/runtime/components/modals/FreeTextModal.vue +6 -4
- package/dist/runtime/components/modals/SignatureDrawModal.vue +6 -4
- package/dist/runtime/components/panels/PlacedFieldSidebar.vue +67 -50
- package/dist/runtime/components/panels/SignaturePicker.vue +6 -4
- package/dist/runtime/components/panels/StampPicker.vue +3 -1
- package/dist/runtime/components/tools/AnnotationToolButton.d.vue.ts +10 -0
- package/dist/runtime/components/tools/AnnotationToolButton.vue +33 -0
- package/dist/runtime/components/tools/AnnotationToolButton.vue.d.ts +10 -0
- package/dist/runtime/components/tools/MarqueeTool.vue +3 -1
- package/dist/runtime/components/tools/PageSettings.vue +13 -11
- package/dist/runtime/components/tools/SearchTool.vue +12 -10
- package/dist/runtime/components/tools/ToolProperties.vue +7 -5
- package/dist/runtime/components/tools/ToolbarMenu.d.vue.ts +9 -0
- package/dist/runtime/components/tools/ToolbarMenu.vue +79 -0
- package/dist/runtime/components/tools/ToolbarMenu.vue.d.ts +9 -0
- package/dist/runtime/components/tools/ZoomControls.vue +17 -9
- package/dist/runtime/composables/canvas-limits.d.ts +22 -0
- package/dist/runtime/composables/canvas-limits.js +10 -0
- package/dist/runtime/composables/useFormFields.d.ts +6 -0
- package/dist/runtime/composables/useFormFields.js +28 -0
- package/dist/runtime/composables/useInertiaPanzoom.d.ts +10 -0
- package/dist/runtime/composables/useInertiaPanzoom.js +57 -10
- package/dist/runtime/composables/useKviewerI18n.d.ts +18 -0
- package/dist/runtime/composables/useKviewerI18n.js +29 -0
- package/dist/runtime/composables/usePageVirtualization.d.ts +11 -0
- package/dist/runtime/composables/usePageVirtualization.js +40 -0
- package/dist/runtime/composables/useScriptingManager.d.ts +8 -4
- package/dist/runtime/composables/useScriptingManager.js +2 -0
- package/dist/runtime/composables/useViewerState.d.ts +4 -0
- package/dist/runtime/composables/useViewerState.js +8 -0
- package/dist/runtime/embed/bridge-client.d.ts +9 -1
- package/dist/runtime/embed/bridge-client.js +13 -0
- package/dist/runtime/embed/bridge-host.d.ts +3 -0
- package/dist/runtime/embed/bridge-host.js +30 -8
- package/dist/runtime/embed/protocol.d.ts +21 -0
- package/dist/runtime/i18n/messages.d.ts +252 -0
- package/dist/runtime/i18n/messages.js +249 -0
- package/dist/runtime/public-types.d.ts +2 -0
- package/dist/runtime/toolbar-tools.d.ts +54 -0
- package/dist/runtime/toolbar-tools.js +79 -0
- package/dist/types.d.mts +1 -1
- package/package.json +14 -31
|
@@ -5,6 +5,30 @@ export function createPageVirtualization() {
|
|
|
5
5
|
const pageMetas = shallowRef([]);
|
|
6
6
|
const currentPage = ref(1);
|
|
7
7
|
const visiblePages = shallowRef(/* @__PURE__ */ new Set());
|
|
8
|
+
const viewedPages = shallowRef(/* @__PURE__ */ new Set());
|
|
9
|
+
const allPagesRead = computed(() => {
|
|
10
|
+
const total = pageMetas.value.length;
|
|
11
|
+
return total > 0 && viewedPages.value.size >= total;
|
|
12
|
+
});
|
|
13
|
+
function markPageViewed(pageNumber) {
|
|
14
|
+
if (viewedPages.value.has(pageNumber)) return;
|
|
15
|
+
const next = new Set(viewedPages.value);
|
|
16
|
+
next.add(pageNumber);
|
|
17
|
+
viewedPages.value = next;
|
|
18
|
+
}
|
|
19
|
+
function markPagesViewed(pageNumbers) {
|
|
20
|
+
let next = null;
|
|
21
|
+
for (const n of pageNumbers) {
|
|
22
|
+
if (viewedPages.value.has(n) || next?.has(n)) continue;
|
|
23
|
+
if (!next) next = new Set(viewedPages.value);
|
|
24
|
+
next.add(n);
|
|
25
|
+
}
|
|
26
|
+
if (next) viewedPages.value = next;
|
|
27
|
+
}
|
|
28
|
+
function resetViewedPages() {
|
|
29
|
+
if (viewedPages.value.size === 0) return;
|
|
30
|
+
viewedPages.value = /* @__PURE__ */ new Set();
|
|
31
|
+
}
|
|
8
32
|
let observer = null;
|
|
9
33
|
let scrollRoot = null;
|
|
10
34
|
let scrollListener = null;
|
|
@@ -88,12 +112,19 @@ export function createPageVirtualization() {
|
|
|
88
112
|
if (bestPage !== currentPage.value) {
|
|
89
113
|
currentPage.value = bestPage;
|
|
90
114
|
}
|
|
115
|
+
const viewportBottom = rootTop + scrollRoot.clientHeight;
|
|
116
|
+
const reached = [];
|
|
117
|
+
for (const [pageNum, el] of pageToElement) {
|
|
118
|
+
if (el.offsetTop < viewportBottom) reached.push(pageNum);
|
|
119
|
+
}
|
|
120
|
+
markPagesViewed(reached);
|
|
91
121
|
}
|
|
92
122
|
function scrollToPage(pageNumber) {
|
|
93
123
|
const element = pageToElement.get(pageNumber);
|
|
94
124
|
if (element && scrollRoot) {
|
|
95
125
|
element.scrollIntoView({ block: "start", behavior: "instant" });
|
|
96
126
|
currentPage.value = pageNumber;
|
|
127
|
+
markPageViewed(pageNumber);
|
|
97
128
|
}
|
|
98
129
|
}
|
|
99
130
|
function getPageElement(pageNumber) {
|
|
@@ -103,8 +134,10 @@ export function createPageVirtualization() {
|
|
|
103
134
|
if (!scrollRoot) return;
|
|
104
135
|
const rootRect = scrollRoot.getBoundingClientRect();
|
|
105
136
|
const rootMid = rootRect.top + rootRect.height / 2;
|
|
137
|
+
const rootBottom = rootRect.top + rootRect.height;
|
|
106
138
|
let bestPage = currentPage.value;
|
|
107
139
|
let bestDist = Infinity;
|
|
140
|
+
const reached = [];
|
|
108
141
|
for (const [pageNum, el] of pageToElement) {
|
|
109
142
|
const rect = el.getBoundingClientRect();
|
|
110
143
|
const dist = rootMid < rect.top ? rect.top - rootMid : rootMid > rect.bottom ? rootMid - rect.bottom : 0;
|
|
@@ -112,7 +145,9 @@ export function createPageVirtualization() {
|
|
|
112
145
|
bestDist = dist;
|
|
113
146
|
bestPage = pageNum;
|
|
114
147
|
}
|
|
148
|
+
if (rect.top < rootBottom) reached.push(pageNum);
|
|
115
149
|
}
|
|
150
|
+
markPagesViewed(reached);
|
|
116
151
|
if (bestPage !== currentPage.value) {
|
|
117
152
|
currentPage.value = bestPage;
|
|
118
153
|
}
|
|
@@ -221,6 +256,7 @@ export function createPageVirtualization() {
|
|
|
221
256
|
elementToPage.clear();
|
|
222
257
|
pageToElement.clear();
|
|
223
258
|
visiblePages.value = /* @__PURE__ */ new Set();
|
|
259
|
+
viewedPages.value = /* @__PURE__ */ new Set();
|
|
224
260
|
pageMetas.value = [];
|
|
225
261
|
scrollRoot = null;
|
|
226
262
|
}
|
|
@@ -228,6 +264,10 @@ export function createPageVirtualization() {
|
|
|
228
264
|
pageMetas,
|
|
229
265
|
currentPage,
|
|
230
266
|
renderedPages,
|
|
267
|
+
viewedPages,
|
|
268
|
+
allPagesRead,
|
|
269
|
+
markPageViewed,
|
|
270
|
+
resetViewedPages,
|
|
231
271
|
isPageRendered,
|
|
232
272
|
observePage,
|
|
233
273
|
unobservePage,
|
|
@@ -2,7 +2,9 @@ import type { PDFDocumentProxy, PDFPageProxy } from 'pdfjs-dist';
|
|
|
2
2
|
import type { Ref } from 'vue';
|
|
3
3
|
/** Minimal viewer surface PDFScriptingManager calls into. The official
|
|
4
4
|
* PDFViewer is large; we mock the slice the manager actually touches
|
|
5
|
-
* (verified
|
|
5
|
+
* (verified against the `PDFScriptingManager` class in
|
|
6
|
+
* pdfjs-dist/web/pdf_viewer.mjs — `setDocument`, `#dispatchPageOpen`,
|
|
7
|
+
* and the `updatefromsandbox` handler). */
|
|
6
8
|
export interface ScriptingViewerAdapter {
|
|
7
9
|
currentPageNumber: number;
|
|
8
10
|
pagesCount: number;
|
|
@@ -39,7 +41,8 @@ export interface ScriptingManager {
|
|
|
39
41
|
/** Pump a user-interaction event into the sandbox for a given field. */
|
|
40
42
|
dispatchFieldEvent: (fieldId: string, name: 'Action' | 'Validate' | 'Focus' | 'Blur' | 'Mouse Up' | 'Mouse Down' | 'Mouse Enter' | 'Mouse Exit' | 'Keystroke', value: string | boolean | string[], extra?: Record<string, unknown>) => void;
|
|
41
43
|
/** Notify the sandbox that a page finished rendering, so any deferred
|
|
42
|
-
* PageOpen action can fire (
|
|
44
|
+
* PageOpen action can fire (the manager's `updatefromsandbox` /
|
|
45
|
+
* pagerendered handling in pdf_viewer.mjs). */
|
|
43
46
|
notifyPageRendered: (pageNumber: number) => void;
|
|
44
47
|
/** Bind a document to the sandbox. Safe to call repeatedly — pass
|
|
45
48
|
* null to detach (e.g. before swapping documents). */
|
|
@@ -53,8 +56,9 @@ export interface ScriptingManager {
|
|
|
53
56
|
/** Construct the scripting manager. ONE instance per `<Viewer>` lifetime —
|
|
54
57
|
* reuse `setDocument(null)` then `setDocument(newDoc)` across document
|
|
55
58
|
* swaps. PDFScriptingManagerComponents attaches a window-level
|
|
56
|
-
* `updatefromsandbox` listener in its constructor (
|
|
57
|
-
* with no removal path; constructing it
|
|
59
|
+
* `updatefromsandbox` listener in its constructor (when no
|
|
60
|
+
* `externalServices` is supplied) with no removal path; constructing it
|
|
61
|
+
* per-document would leak. */
|
|
58
62
|
export declare function createScriptingManager(deps: ScriptingManagerDeps): Promise<ScriptingManager>;
|
|
59
63
|
/** Cast helper used by the bridge — keeps the eventBus access narrowly
|
|
60
64
|
* typed without exporting an extra interface. */
|
|
@@ -18,6 +18,7 @@ export async function createScriptingManager(deps) {
|
|
|
18
18
|
};
|
|
19
19
|
window.addEventListener("updatefromsandbox", onSandboxWindowEvent);
|
|
20
20
|
const sandboxBundleSrc = new URL("/_kviewer/pdfjs/pdf.sandbox.mjs", window.location.origin).href;
|
|
21
|
+
const wasmUrl = new URL("/_kviewer/wasm/", window.location.origin).href;
|
|
21
22
|
const adapter = {
|
|
22
23
|
get currentPageNumber() {
|
|
23
24
|
return deps.viewerState.currentPage.value;
|
|
@@ -70,6 +71,7 @@ export async function createScriptingManager(deps) {
|
|
|
70
71
|
const manager = new PDFScriptingManager({
|
|
71
72
|
eventBus,
|
|
72
73
|
sandboxBundleSrc,
|
|
74
|
+
wasmUrl,
|
|
73
75
|
// Required: PDFScriptingManager passes the result into the sandbox's
|
|
74
76
|
// docInfo. The official viewer assembles a rich metadata blob; we
|
|
75
77
|
// provide the minimum the sandbox needs to boot. Fields are read by
|
|
@@ -65,6 +65,10 @@ export interface ViewerStateProvider {
|
|
|
65
65
|
state: ViewerState;
|
|
66
66
|
setScrollToPageFn: (fn: (pageNumber: number) => void) => void;
|
|
67
67
|
setDownloadPdfFn: (fn: () => Promise<void>) => void;
|
|
68
|
+
/** Register how custom-scale changes are applied. The Viewer registers a
|
|
69
|
+
* position-preserving commit (zoom about the viewport centre); without
|
|
70
|
+
* one, setScale falls back to a plain scale write. */
|
|
71
|
+
setApplyScaleFn: (fn: (value: number) => void) => void;
|
|
68
72
|
}
|
|
69
73
|
export declare function provideViewerState(): ViewerStateProvider;
|
|
70
74
|
export declare function useViewerState(): ViewerState;
|
|
@@ -41,7 +41,12 @@ export function provideViewerState() {
|
|
|
41
41
|
function setFitMode(mode) {
|
|
42
42
|
fitMode.value = mode;
|
|
43
43
|
}
|
|
44
|
+
let _applyScaleFn = null;
|
|
44
45
|
function setScale(value) {
|
|
46
|
+
if (_applyScaleFn) {
|
|
47
|
+
_applyScaleFn(value);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
45
50
|
fitMode.value = "custom";
|
|
46
51
|
scale.value = value;
|
|
47
52
|
}
|
|
@@ -212,6 +217,9 @@ export function provideViewerState() {
|
|
|
212
217
|
},
|
|
213
218
|
setDownloadPdfFn(fn) {
|
|
214
219
|
_downloadPdfFn = fn;
|
|
220
|
+
},
|
|
221
|
+
setApplyScaleFn(fn) {
|
|
222
|
+
_applyScaleFn = fn;
|
|
215
223
|
}
|
|
216
224
|
};
|
|
217
225
|
}
|
|
@@ -20,7 +20,8 @@ type EventHandler<E extends EventName> = (payload: EventPayloads[E]) => void;
|
|
|
20
20
|
* Parent-page client that drives a `<KViewer>` instance running inside
|
|
21
21
|
* an iframe. Wraps `postMessage` into a Promise-based RPC mirroring the
|
|
22
22
|
* viewer's exposed methods, and surfaces iframe-emitted events
|
|
23
|
-
* (`ready`, `formEditMode-changed`
|
|
23
|
+
* (`ready`, `formEditMode-changed`, `viewedPages-changed`, `all-pages-read`)
|
|
24
|
+
* via `on()`.
|
|
24
25
|
*/
|
|
25
26
|
export declare class KViewerEmbedClient {
|
|
26
27
|
private readonly iframe;
|
|
@@ -52,6 +53,13 @@ export declare class KViewerEmbedClient {
|
|
|
52
53
|
getFormEditMode(): Promise<boolean>;
|
|
53
54
|
setFormEditMode(enabled: boolean): Promise<void>;
|
|
54
55
|
toggleFormEditMode(): Promise<boolean>;
|
|
56
|
+
/** True once the user has viewed every page. For a push-style signal,
|
|
57
|
+
* subscribe via `on('all-pages-read', …)` / `on('viewedPages-changed', …)`. */
|
|
58
|
+
allPagesRead(): Promise<boolean>;
|
|
59
|
+
/** Page numbers viewed so far, ascending. */
|
|
60
|
+
getViewedPages(): Promise<number[]>;
|
|
61
|
+
/** Clear viewed-page tracking, e.g. to restart a signing session. */
|
|
62
|
+
resetViewedPages(): Promise<void>;
|
|
55
63
|
private call;
|
|
56
64
|
private handleMessage;
|
|
57
65
|
}
|
|
@@ -87,6 +87,19 @@ export class KViewerEmbedClient {
|
|
|
87
87
|
toggleFormEditMode() {
|
|
88
88
|
return this.call("toggleFormEditMode");
|
|
89
89
|
}
|
|
90
|
+
/** True once the user has viewed every page. For a push-style signal,
|
|
91
|
+
* subscribe via `on('all-pages-read', …)` / `on('viewedPages-changed', …)`. */
|
|
92
|
+
allPagesRead() {
|
|
93
|
+
return this.call("allPagesRead");
|
|
94
|
+
}
|
|
95
|
+
/** Page numbers viewed so far, ascending. */
|
|
96
|
+
getViewedPages() {
|
|
97
|
+
return this.call("getViewedPages");
|
|
98
|
+
}
|
|
99
|
+
/** Clear viewed-page tracking, e.g. to restart a signing session. */
|
|
100
|
+
resetViewedPages() {
|
|
101
|
+
return this.call("resetViewedPages");
|
|
102
|
+
}
|
|
90
103
|
// ── internals ──────────────────────────────────────────────────────────
|
|
91
104
|
call(method, ...args) {
|
|
92
105
|
if (this.disposed) {
|
|
@@ -26,6 +26,9 @@ export interface KViewerApi {
|
|
|
26
26
|
formEditMode: Ref<boolean>;
|
|
27
27
|
setFormEditMode: (enabled: boolean) => void;
|
|
28
28
|
toggleFormEditMode: () => boolean;
|
|
29
|
+
allPagesRead: () => boolean;
|
|
30
|
+
getViewedPages: () => number[];
|
|
31
|
+
resetViewedPages: () => void;
|
|
29
32
|
}
|
|
30
33
|
export interface KViewerEmbedBridgeOptions {
|
|
31
34
|
/**
|
|
@@ -75,6 +75,13 @@ export function useKViewerEmbedBridge(viewerRef, options) {
|
|
|
75
75
|
}
|
|
76
76
|
case "toggleFormEditMode":
|
|
77
77
|
return viewer.toggleFormEditMode();
|
|
78
|
+
case "allPagesRead":
|
|
79
|
+
return viewer.allPagesRead();
|
|
80
|
+
case "getViewedPages":
|
|
81
|
+
return viewer.getViewedPages();
|
|
82
|
+
case "resetViewedPages":
|
|
83
|
+
viewer.resetViewedPages();
|
|
84
|
+
return void 0;
|
|
78
85
|
default:
|
|
79
86
|
throw new Error(`Unknown KViewer embed method: ${req.method}`);
|
|
80
87
|
}
|
|
@@ -110,17 +117,32 @@ export function useKViewerEmbedBridge(viewerRef, options) {
|
|
|
110
117
|
target.postMessage(reply, event.origin === "" ? options.parentOrigin : event.origin);
|
|
111
118
|
}
|
|
112
119
|
win.addEventListener("message", handleMessage);
|
|
113
|
-
let
|
|
120
|
+
let stopViewerStateWatches = [];
|
|
114
121
|
const stopViewerWatch = watch(
|
|
115
122
|
viewerRef,
|
|
116
123
|
(viewer) => {
|
|
117
|
-
|
|
118
|
-
|
|
124
|
+
for (const stop of stopViewerStateWatches) stop();
|
|
125
|
+
stopViewerStateWatches = [];
|
|
119
126
|
if (!viewer) return;
|
|
120
127
|
postEvent("ready", { protocolVersion: KVIEWER_EMBED_PROTOCOL_VERSION });
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
128
|
+
stopViewerStateWatches.push(
|
|
129
|
+
watch(
|
|
130
|
+
viewer.formEditMode,
|
|
131
|
+
(enabled) => postEvent("formEditMode-changed", { enabled })
|
|
132
|
+
),
|
|
133
|
+
// Read-tracking. The getters touch the viewer's reactive viewed-pages
|
|
134
|
+
// state, so watch re-runs them whenever a page is viewed or tracking
|
|
135
|
+
// is reset.
|
|
136
|
+
watch(
|
|
137
|
+
() => viewer.allPagesRead(),
|
|
138
|
+
(read, prev) => {
|
|
139
|
+
if (read && !prev) postEvent("all-pages-read", {});
|
|
140
|
+
}
|
|
141
|
+
),
|
|
142
|
+
watch(
|
|
143
|
+
() => viewer.getViewedPages(),
|
|
144
|
+
(pages) => postEvent("viewedPages-changed", { pages, allRead: viewer.allPagesRead() })
|
|
145
|
+
)
|
|
124
146
|
);
|
|
125
147
|
},
|
|
126
148
|
{ immediate: true }
|
|
@@ -128,8 +150,8 @@ export function useKViewerEmbedBridge(viewerRef, options) {
|
|
|
128
150
|
function unmount() {
|
|
129
151
|
win.removeEventListener("message", handleMessage);
|
|
130
152
|
stopViewerWatch();
|
|
131
|
-
|
|
132
|
-
|
|
153
|
+
for (const stop of stopViewerStateWatches) stop();
|
|
154
|
+
stopViewerStateWatches = [];
|
|
133
155
|
}
|
|
134
156
|
onScopeDispose(unmount);
|
|
135
157
|
return { unmount };
|
|
@@ -59,6 +59,18 @@ export interface MethodSignatures {
|
|
|
59
59
|
args: [];
|
|
60
60
|
result: boolean;
|
|
61
61
|
};
|
|
62
|
+
allPagesRead: {
|
|
63
|
+
args: [];
|
|
64
|
+
result: boolean;
|
|
65
|
+
};
|
|
66
|
+
getViewedPages: {
|
|
67
|
+
args: [];
|
|
68
|
+
result: number[];
|
|
69
|
+
};
|
|
70
|
+
resetViewedPages: {
|
|
71
|
+
args: [];
|
|
72
|
+
result: undefined;
|
|
73
|
+
};
|
|
62
74
|
}
|
|
63
75
|
export type MethodName = keyof MethodSignatures;
|
|
64
76
|
export interface RequestMessage<M extends MethodName = MethodName> {
|
|
@@ -91,6 +103,15 @@ export interface EventPayloads {
|
|
|
91
103
|
'formEditMode-changed': {
|
|
92
104
|
enabled: boolean;
|
|
93
105
|
};
|
|
106
|
+
/** The set of viewed pages changed. `allRead` is true once every page has
|
|
107
|
+
* been viewed. */
|
|
108
|
+
'viewedPages-changed': {
|
|
109
|
+
pages: number[];
|
|
110
|
+
allRead: boolean;
|
|
111
|
+
};
|
|
112
|
+
/** Fires once when the final unseen page is viewed. Re-arms after
|
|
113
|
+
* `resetViewedPages()` or a new document. */
|
|
114
|
+
'all-pages-read': Record<string, never>;
|
|
94
115
|
}
|
|
95
116
|
export type EventName = keyof EventPayloads;
|
|
96
117
|
export interface EventMessage<E extends EventName = EventName> {
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in UI message catalog.
|
|
3
|
+
*
|
|
4
|
+
* kviewer is consumed both as a Nuxt module (wrench) and through the
|
|
5
|
+
* iframe embed bridge by non-Nuxt hosts (esign/React), so it cannot
|
|
6
|
+
* depend on a host i18n library. The catalog is intentionally tiny:
|
|
7
|
+
* locale comes from the Viewer `locale` prop (or the module option),
|
|
8
|
+
* and hosts may override individual strings via the `messages` prop.
|
|
9
|
+
*/
|
|
10
|
+
export declare const messages: {
|
|
11
|
+
readonly en: {
|
|
12
|
+
readonly cancel: "Cancel";
|
|
13
|
+
readonly ok: "OK";
|
|
14
|
+
readonly save: "Save";
|
|
15
|
+
readonly clear: "Clear";
|
|
16
|
+
readonly delete: "Delete";
|
|
17
|
+
readonly download: "Download";
|
|
18
|
+
readonly search: "Search";
|
|
19
|
+
readonly marqueeSelect: "Marquee select";
|
|
20
|
+
readonly eraser: "Eraser";
|
|
21
|
+
readonly color: "Color";
|
|
22
|
+
readonly editText: "Edit text";
|
|
23
|
+
readonly strokeWidth: "Stroke width";
|
|
24
|
+
readonly decreaseStrokeWidth: "Decrease stroke width";
|
|
25
|
+
readonly increaseStrokeWidth: "Increase stroke width";
|
|
26
|
+
readonly noProperties: "No properties";
|
|
27
|
+
readonly detectFormFields: "Detect form fields";
|
|
28
|
+
readonly disableFormFieldDetection: "Disable form field detection";
|
|
29
|
+
readonly fitWidth: "Fit width";
|
|
30
|
+
readonly fitPage: "Fit page";
|
|
31
|
+
readonly stamp: "Stamp";
|
|
32
|
+
readonly signature: "Signature";
|
|
33
|
+
readonly searchPlaceholder: "Find in document...";
|
|
34
|
+
readonly previousMatch: "Previous match";
|
|
35
|
+
readonly nextMatch: "Next match";
|
|
36
|
+
readonly matchCase: "Match case";
|
|
37
|
+
readonly wholeWord: "Whole word";
|
|
38
|
+
readonly highlightAll: "Highlight all";
|
|
39
|
+
readonly closeSearch: "Close search";
|
|
40
|
+
readonly noResults: "No results";
|
|
41
|
+
readonly typeToSearch: "Type to search";
|
|
42
|
+
readonly freeText: "Free text";
|
|
43
|
+
readonly startTyping: "Start typing...";
|
|
44
|
+
readonly drawSignature: "Draw signature";
|
|
45
|
+
readonly noSavedSignatures: "No saved signatures";
|
|
46
|
+
readonly addSignature: "Add signature";
|
|
47
|
+
readonly selectedCount: "{count} selected";
|
|
48
|
+
readonly pageTransition: "Page transition";
|
|
49
|
+
readonly continuous: "Continuous";
|
|
50
|
+
readonly pageByPage: "Page by page";
|
|
51
|
+
readonly rotate: "Rotate";
|
|
52
|
+
readonly rotateClockwise: "Clockwise";
|
|
53
|
+
readonly rotateCounterclockwise: "Counterclockwise";
|
|
54
|
+
readonly layout: "Layout";
|
|
55
|
+
readonly singlePage: "Single page";
|
|
56
|
+
readonly twoPages: "Two pages";
|
|
57
|
+
readonly stylusMode: "Stylus mode";
|
|
58
|
+
readonly fullscreen: "Fullscreen";
|
|
59
|
+
readonly fieldProperties: "Field properties";
|
|
60
|
+
readonly fieldName: "Field name";
|
|
61
|
+
readonly fieldNameHint: "Shared names group radio buttons and bind multiple widgets to the same value.";
|
|
62
|
+
readonly required: "Required";
|
|
63
|
+
readonly readOnly: "Read-only";
|
|
64
|
+
readonly multiLine: "Multi-line";
|
|
65
|
+
readonly maxLength: "Max length";
|
|
66
|
+
readonly noLimit: "No limit";
|
|
67
|
+
readonly style: "Style";
|
|
68
|
+
readonly checkboxStyleHint: "Glyph drawn when checked. Saved as /MK /CA on export.";
|
|
69
|
+
readonly options: "Options";
|
|
70
|
+
readonly optionLabelPlaceholder: "Label";
|
|
71
|
+
readonly addOption: "Add option";
|
|
72
|
+
readonly comboBox: "Combo box (collapsible)";
|
|
73
|
+
readonly allowCustomText: "Allow custom text";
|
|
74
|
+
readonly multiSelect: "Multi-select";
|
|
75
|
+
readonly promptText: "Prompt text";
|
|
76
|
+
readonly clickToSign: "Click to sign";
|
|
77
|
+
readonly promptTextHint: "Shown on the unsigned widget. Defaults to \"{default}\".";
|
|
78
|
+
readonly lockFieldsAfterSigning: "Lock fields after signing";
|
|
79
|
+
readonly lockFieldsHint: "Once this signature is filled, listed fields become read-only inside the viewer. Not preserved on PDF export.";
|
|
80
|
+
readonly lockNone: "None";
|
|
81
|
+
readonly lockAllOther: "All other fields";
|
|
82
|
+
readonly lockSelectedOnly: "Selected fields only";
|
|
83
|
+
readonly lockAllExceptSelected: "All except selected";
|
|
84
|
+
readonly lockTheseFields: "Lock these fields";
|
|
85
|
+
readonly lockAllFieldsExcept: "Lock all fields except";
|
|
86
|
+
readonly noOtherNamedFields: "No other named fields in the document.";
|
|
87
|
+
readonly group: "Group";
|
|
88
|
+
readonly newGroup: "+ New group";
|
|
89
|
+
readonly radioGroupHint: "Radios sharing a group act as one — picking one clears the others.";
|
|
90
|
+
readonly optionValue: "Option value";
|
|
91
|
+
readonly optionValueHint: "Value stored when this option is selected. Must be unique inside the group.";
|
|
92
|
+
readonly typeLabel: "Type";
|
|
93
|
+
readonly pageLabel: "Page";
|
|
94
|
+
readonly deleteField: "Delete field";
|
|
95
|
+
readonly selectFieldHint: "Select a placed field to edit its properties.";
|
|
96
|
+
readonly fieldTypeText: "Text field";
|
|
97
|
+
readonly fieldTypeCheckbox: "Checkbox";
|
|
98
|
+
readonly fieldTypeRadio: "Radio button";
|
|
99
|
+
readonly fieldTypeSignature: "Signature field";
|
|
100
|
+
readonly fieldTypeDropdown: "Dropdown";
|
|
101
|
+
readonly fieldTypeButton: "Button";
|
|
102
|
+
readonly fieldTypeGeneric: "Field";
|
|
103
|
+
readonly fieldOnPage: "{type} on page {page}";
|
|
104
|
+
readonly styleCheck: "Check";
|
|
105
|
+
readonly styleCross: "Cross";
|
|
106
|
+
readonly styleDiamond: "Diamond";
|
|
107
|
+
readonly styleCircle: "Circle";
|
|
108
|
+
readonly styleStar: "Star";
|
|
109
|
+
readonly styleSquare: "Square";
|
|
110
|
+
readonly toolSelect: "Select";
|
|
111
|
+
readonly toolHighlight: "Highlight";
|
|
112
|
+
readonly toolStrikeout: "Strike out";
|
|
113
|
+
readonly toolUnderline: "Underline";
|
|
114
|
+
readonly toolRectangle: "Rectangle";
|
|
115
|
+
readonly toolCircle: "Ellipse";
|
|
116
|
+
readonly toolNote: "Note";
|
|
117
|
+
readonly toolArrow: "Arrow";
|
|
118
|
+
readonly toolCloud: "Cloud";
|
|
119
|
+
readonly toolFreehand: "Pen";
|
|
120
|
+
readonly toolFreeHighlight: "Highlighter";
|
|
121
|
+
readonly toolFreeText: "Text";
|
|
122
|
+
readonly toolSignature: "Signature";
|
|
123
|
+
readonly toolStamp: "Stamp";
|
|
124
|
+
readonly toolFormText: "Text field";
|
|
125
|
+
readonly toolFormCheckbox: "Checkbox";
|
|
126
|
+
readonly toolFormSignature: "Signature field";
|
|
127
|
+
readonly toolFormRadio: "Radio button";
|
|
128
|
+
readonly toolEraser: "Eraser";
|
|
129
|
+
};
|
|
130
|
+
readonly de: {
|
|
131
|
+
readonly cancel: "Abbrechen";
|
|
132
|
+
readonly ok: "OK";
|
|
133
|
+
readonly save: "Speichern";
|
|
134
|
+
readonly clear: "Leeren";
|
|
135
|
+
readonly delete: "Löschen";
|
|
136
|
+
readonly download: "Herunterladen";
|
|
137
|
+
readonly search: "Suchen";
|
|
138
|
+
readonly marqueeSelect: "Mehrfachauswahl";
|
|
139
|
+
readonly eraser: "Radierer";
|
|
140
|
+
readonly color: "Farbe";
|
|
141
|
+
readonly editText: "Text bearbeiten";
|
|
142
|
+
readonly strokeWidth: "Linienstärke";
|
|
143
|
+
readonly decreaseStrokeWidth: "Linienstärke verringern";
|
|
144
|
+
readonly increaseStrokeWidth: "Linienstärke erhöhen";
|
|
145
|
+
readonly noProperties: "Keine Eigenschaften";
|
|
146
|
+
readonly detectFormFields: "Formularfelder erkennen";
|
|
147
|
+
readonly disableFormFieldDetection: "Formularfeld-Erkennung deaktivieren";
|
|
148
|
+
readonly fitWidth: "Seitenbreite";
|
|
149
|
+
readonly fitPage: "Ganze Seite";
|
|
150
|
+
readonly stamp: "Stempel";
|
|
151
|
+
readonly signature: "Unterschrift";
|
|
152
|
+
readonly searchPlaceholder: "Im Dokument suchen...";
|
|
153
|
+
readonly previousMatch: "Vorheriger Treffer";
|
|
154
|
+
readonly nextMatch: "Nächster Treffer";
|
|
155
|
+
readonly matchCase: "Groß-/Kleinschreibung";
|
|
156
|
+
readonly wholeWord: "Ganzes Wort";
|
|
157
|
+
readonly highlightAll: "Alle hervorheben";
|
|
158
|
+
readonly closeSearch: "Suche schließen";
|
|
159
|
+
readonly noResults: "Keine Treffer";
|
|
160
|
+
readonly typeToSearch: "Suchbegriff eingeben";
|
|
161
|
+
readonly freeText: "Freitext";
|
|
162
|
+
readonly startTyping: "Text eingeben...";
|
|
163
|
+
readonly drawSignature: "Unterschrift zeichnen";
|
|
164
|
+
readonly noSavedSignatures: "Keine gespeicherten Unterschriften";
|
|
165
|
+
readonly addSignature: "Unterschrift hinzufügen";
|
|
166
|
+
readonly selectedCount: "{count} ausgewählt";
|
|
167
|
+
readonly pageTransition: "Seitenübergang";
|
|
168
|
+
readonly continuous: "Fortlaufend";
|
|
169
|
+
readonly pageByPage: "Seite für Seite";
|
|
170
|
+
readonly rotate: "Drehen";
|
|
171
|
+
readonly rotateClockwise: "Im Uhrzeigersinn";
|
|
172
|
+
readonly rotateCounterclockwise: "Gegen den Uhrzeigersinn";
|
|
173
|
+
readonly layout: "Layout";
|
|
174
|
+
readonly singlePage: "Einseitig";
|
|
175
|
+
readonly twoPages: "Zweiseitig";
|
|
176
|
+
readonly stylusMode: "Stiftmodus";
|
|
177
|
+
readonly fullscreen: "Vollbildansicht";
|
|
178
|
+
readonly fieldProperties: "Feldeigenschaften";
|
|
179
|
+
readonly fieldName: "Feldname";
|
|
180
|
+
readonly fieldNameHint: "Gleiche Namen gruppieren Optionsfelder und verbinden mehrere Widgets mit demselben Wert.";
|
|
181
|
+
readonly required: "Pflichtfeld";
|
|
182
|
+
readonly readOnly: "Schreibgeschützt";
|
|
183
|
+
readonly multiLine: "Mehrzeilig";
|
|
184
|
+
readonly maxLength: "Maximale Länge";
|
|
185
|
+
readonly noLimit: "Kein Limit";
|
|
186
|
+
readonly style: "Stil";
|
|
187
|
+
readonly checkboxStyleHint: "Symbol im angekreuzten Zustand. Wird beim Export als /MK /CA gespeichert.";
|
|
188
|
+
readonly options: "Optionen";
|
|
189
|
+
readonly optionLabelPlaceholder: "Beschriftung";
|
|
190
|
+
readonly addOption: "Option hinzufügen";
|
|
191
|
+
readonly comboBox: "Kombinationsfeld (aufklappbar)";
|
|
192
|
+
readonly allowCustomText: "Eigenen Text erlauben";
|
|
193
|
+
readonly multiSelect: "Mehrfachauswahl";
|
|
194
|
+
readonly promptText: "Hinweistext";
|
|
195
|
+
readonly clickToSign: "Zum Unterschreiben klicken";
|
|
196
|
+
readonly promptTextHint: "Wird auf dem nicht unterschriebenen Feld angezeigt. Standard: \"{default}\".";
|
|
197
|
+
readonly lockFieldsAfterSigning: "Felder nach Unterschrift sperren";
|
|
198
|
+
readonly lockFieldsHint: "Sobald diese Unterschrift ausgefüllt ist, werden die gewählten Felder im Viewer schreibgeschützt. Wird beim PDF-Export nicht übernommen.";
|
|
199
|
+
readonly lockNone: "Keine";
|
|
200
|
+
readonly lockAllOther: "Alle anderen Felder";
|
|
201
|
+
readonly lockSelectedOnly: "Nur ausgewählte Felder";
|
|
202
|
+
readonly lockAllExceptSelected: "Alle außer ausgewählte";
|
|
203
|
+
readonly lockTheseFields: "Diese Felder sperren";
|
|
204
|
+
readonly lockAllFieldsExcept: "Alle Felder sperren außer";
|
|
205
|
+
readonly noOtherNamedFields: "Keine weiteren benannten Felder im Dokument.";
|
|
206
|
+
readonly group: "Gruppe";
|
|
207
|
+
readonly newGroup: "+ Neue Gruppe";
|
|
208
|
+
readonly radioGroupHint: "Optionsfelder derselben Gruppe wirken als eines — die Auswahl eines Feldes hebt die anderen auf.";
|
|
209
|
+
readonly optionValue: "Optionswert";
|
|
210
|
+
readonly optionValueHint: "Wert, der bei Auswahl dieser Option gespeichert wird. Muss innerhalb der Gruppe eindeutig sein.";
|
|
211
|
+
readonly typeLabel: "Typ";
|
|
212
|
+
readonly pageLabel: "Seite";
|
|
213
|
+
readonly deleteField: "Feld löschen";
|
|
214
|
+
readonly selectFieldHint: "Wählen Sie ein platziertes Feld aus, um seine Eigenschaften zu bearbeiten.";
|
|
215
|
+
readonly fieldTypeText: "Textfeld";
|
|
216
|
+
readonly fieldTypeCheckbox: "Kontrollkästchen";
|
|
217
|
+
readonly fieldTypeRadio: "Optionsfeld";
|
|
218
|
+
readonly fieldTypeSignature: "Unterschriftsfeld";
|
|
219
|
+
readonly fieldTypeDropdown: "Auswahlliste";
|
|
220
|
+
readonly fieldTypeButton: "Schaltfläche";
|
|
221
|
+
readonly fieldTypeGeneric: "Feld";
|
|
222
|
+
readonly fieldOnPage: "{type} auf Seite {page}";
|
|
223
|
+
readonly styleCheck: "Haken";
|
|
224
|
+
readonly styleCross: "Kreuz";
|
|
225
|
+
readonly styleDiamond: "Raute";
|
|
226
|
+
readonly styleCircle: "Kreis";
|
|
227
|
+
readonly styleStar: "Stern";
|
|
228
|
+
readonly styleSquare: "Quadrat";
|
|
229
|
+
readonly toolSelect: "Auswählen";
|
|
230
|
+
readonly toolHighlight: "Hervorheben";
|
|
231
|
+
readonly toolStrikeout: "Durchstreichen";
|
|
232
|
+
readonly toolUnderline: "Unterstreichen";
|
|
233
|
+
readonly toolRectangle: "Rechteck";
|
|
234
|
+
readonly toolCircle: "Ellipse";
|
|
235
|
+
readonly toolNote: "Notiz";
|
|
236
|
+
readonly toolArrow: "Pfeil";
|
|
237
|
+
readonly toolCloud: "Wolke";
|
|
238
|
+
readonly toolFreehand: "Stift";
|
|
239
|
+
readonly toolFreeHighlight: "Marker";
|
|
240
|
+
readonly toolFreeText: "Text";
|
|
241
|
+
readonly toolSignature: "Unterschrift";
|
|
242
|
+
readonly toolStamp: "Stempel";
|
|
243
|
+
readonly toolFormText: "Textfeld";
|
|
244
|
+
readonly toolFormCheckbox: "Kontrollkästchen";
|
|
245
|
+
readonly toolFormSignature: "Unterschriftsfeld";
|
|
246
|
+
readonly toolFormRadio: "Optionsfeld";
|
|
247
|
+
readonly toolEraser: "Radierer";
|
|
248
|
+
};
|
|
249
|
+
};
|
|
250
|
+
export type KviewerLocale = keyof typeof messages;
|
|
251
|
+
export type MessageKey = keyof typeof messages.en;
|
|
252
|
+
export declare const KVIEWER_LOCALES: KviewerLocale[];
|