@embedpdf/engine-core 3.0.0-next.13 → 3.0.0-next.15
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/AnnotationList-CkijRHet.d.cts +27163 -0
- package/dist/AnnotationList-CkijRHet.d.ts +27163 -0
- package/dist/Change-CKoxfTNY.js +889 -0
- package/dist/Change-CKoxfTNY.js.map +1 -0
- package/dist/Change-CjImsrN0.cjs +1020 -0
- package/dist/Change-CjImsrN0.cjs.map +1 -0
- package/dist/DocumentRenderService-BfFdFSwI.cjs +120 -0
- package/dist/DocumentRenderService-BfFdFSwI.cjs.map +1 -0
- package/dist/DocumentRenderService-DV3J9lMz.js +85 -0
- package/dist/DocumentRenderService-DV3J9lMz.js.map +1 -0
- package/dist/{DocumentSecurityService-_JRjqvoI.d.ts → DocumentSecurityService-CU1M6Q7m.d.ts} +100 -112
- package/dist/{DocumentSecurityService-ClTZc0zO.d.cts → DocumentSecurityService-e6vp2de8.d.cts} +100 -112
- package/dist/LocalDocumentHandle-D02FMm-Z.cjs +53 -0
- package/dist/LocalDocumentHandle-D02FMm-Z.cjs.map +1 -0
- package/dist/LocalDocumentHandle-DAPdaOt_.js +30 -0
- package/dist/LocalDocumentHandle-DAPdaOt_.js.map +1 -0
- package/dist/LocalEngine-DFoBm4B3.d.cts +1565 -0
- package/dist/LocalEngine-DPriFujS.d.ts +1565 -0
- package/dist/PageInsertBlankInput-CXHAM7l6.cjs +17 -0
- package/dist/PageInsertBlankInput-CXHAM7l6.cjs.map +1 -0
- package/dist/PageInsertBlankInput-DhVYVJ_S.js +12 -0
- package/dist/PageInsertBlankInput-DhVYVJ_S.js.map +1 -0
- package/dist/authority-B3BklsB4.js +2239 -0
- package/dist/authority-B3BklsB4.js.map +1 -0
- package/dist/authority-DLMNR7ff.cjs +2676 -0
- package/dist/authority-DLMNR7ff.cjs.map +1 -0
- package/dist/builders-CNj0POeY.js +161 -0
- package/dist/builders-CNj0POeY.js.map +1 -0
- package/dist/builders-Cgdp_YCn.cjs +184 -0
- package/dist/builders-Cgdp_YCn.cjs.map +1 -0
- package/dist/calibrate-7T3fnP8-.js +2404 -0
- package/dist/calibrate-7T3fnP8-.js.map +1 -0
- package/dist/calibrate-DJBXnhLE.cjs +2919 -0
- package/dist/calibrate-DJBXnhLE.cjs.map +1 -0
- package/dist/charmap-Cprti1ta.js +239 -0
- package/dist/charmap-Cprti1ta.js.map +1 -0
- package/dist/charmap-aYlefQP9.cjs +304 -0
- package/dist/charmap-aYlefQP9.cjs.map +1 -0
- package/dist/conformance.cjs +16753 -5247
- package/dist/conformance.cjs.map +1 -1
- package/dist/conformance.d.cts +928 -165
- package/dist/conformance.d.ts +928 -165
- package/dist/conformance.js +16731 -5268
- package/dist/conformance.js.map +1 -1
- package/dist/format-Bp3QFSH1.cjs +574 -0
- package/dist/format-Bp3QFSH1.cjs.map +1 -0
- package/dist/format-Dgg428Kb.js +461 -0
- package/dist/format-Dgg428Kb.js.map +1 -0
- package/dist/index.cjs +330 -103
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +14 -5
- package/dist/pageRefs-B3ur7Ckm.cjs +51 -0
- package/dist/pageRefs-B3ur7Ckm.cjs.map +1 -0
- package/dist/pageRefs-DkbuxSCV.js +40 -0
- package/dist/pageRefs-DkbuxSCV.js.map +1 -0
- package/dist/public.cjs +57 -0
- package/dist/public.d.cts +5 -0
- package/dist/public.d.ts +5 -0
- package/dist/public.js +9 -0
- package/dist/resolveAnnotationDraft-7Ke4nV7F.cjs +3646 -0
- package/dist/resolveAnnotationDraft-7Ke4nV7F.cjs.map +1 -0
- package/dist/resolveAnnotationDraft-CUpf0SMh.js +3167 -0
- package/dist/resolveAnnotationDraft-CUpf0SMh.js.map +1 -0
- package/dist/{resolver-inAVzsWt.js → resolver-CzxmD9Ck.js} +294 -144
- package/dist/resolver-CzxmD9Ck.js.map +1 -0
- package/dist/{resolver-CYVNV4hn.cjs → resolver-D2OCtE8F.cjs} +347 -143
- package/dist/resolver-D2OCtE8F.cjs.map +1 -0
- package/dist/runtime-Cl0v56mm.d.ts +2032 -0
- package/dist/runtime-p1WDzDo4.d.cts +2032 -0
- package/dist/runtime.cjs +733 -284
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.d.cts +5 -1348
- package/dist/runtime.d.ts +5 -1348
- package/dist/runtime.js +396 -179
- package/dist/runtime.js.map +1 -1
- package/dist/schema-C-gU4vj7.cjs +3034 -0
- package/dist/schema-C-gU4vj7.cjs.map +1 -0
- package/dist/schema-DzlUNk38.js +2081 -0
- package/dist/schema-DzlUNk38.js.map +1 -0
- package/dist/schemas-Berf1swF.cjs +2481 -0
- package/dist/schemas-Berf1swF.cjs.map +1 -0
- package/dist/schemas-D6xOGjqg.js +1654 -0
- package/dist/schemas-D6xOGjqg.js.map +1 -0
- package/dist/subtype-CG4WpIRj.js +129 -0
- package/dist/subtype-CG4WpIRj.js.map +1 -0
- package/dist/subtype-aDt5TFmK.cjs +158 -0
- package/dist/subtype-aDt5TFmK.cjs.map +1 -0
- package/dist/validation.cjs +578 -0
- package/dist/validation.cjs.map +1 -0
- package/dist/validation.d.cts +174 -0
- package/dist/validation.d.ts +174 -0
- package/dist/validation.js +571 -0
- package/dist/validation.js.map +1 -0
- package/dist/value-BFS1R8ek.cjs +435 -0
- package/dist/value-BFS1R8ek.cjs.map +1 -0
- package/dist/value-Dhc8eYcx.js +340 -0
- package/dist/value-Dhc8eYcx.js.map +1 -0
- package/dist/viewport-BJW13EGZ.js +540 -0
- package/dist/viewport-BJW13EGZ.js.map +1 -0
- package/dist/viewport-DlL5Bxbg.cjs +671 -0
- package/dist/viewport-DlL5Bxbg.cjs.map +1 -0
- package/dist/wire.cjs +1056 -379
- package/dist/wire.cjs.map +1 -1
- package/dist/wire.d.cts +15069 -725
- package/dist/wire.d.ts +15069 -725
- package/dist/wire.js +825 -239
- package/dist/wire.js.map +1 -1
- package/package.json +10 -1
- package/dist/AbortError-Cq2igpZ6.cjs +0 -38
- package/dist/AbortError-Cq2igpZ6.cjs.map +0 -1
- package/dist/AbortError-DHqPBnYc.js +0 -27
- package/dist/AbortError-DHqPBnYc.js.map +0 -1
- package/dist/AnnotationListSnapshot-D3mFut1e.d.cts +0 -6871
- package/dist/AnnotationListSnapshot-D3mFut1e.d.ts +0 -6871
- package/dist/Engine-Bx0NOfmd.d.cts +0 -1264
- package/dist/Engine-DxtpCYcP.d.ts +0 -1264
- package/dist/PageInsertBlankInput-CqXBmFhN.cjs +0 -449
- package/dist/PageInsertBlankInput-CqXBmFhN.cjs.map +0 -1
- package/dist/PageInsertBlankInput-cHq9-i-z.js +0 -378
- package/dist/PageInsertBlankInput-cHq9-i-z.js.map +0 -1
- package/dist/builders-Bqm8yTpi.cjs +0 -3564
- package/dist/builders-Bqm8yTpi.cjs.map +0 -1
- package/dist/builders-Dqo2X-dt.js +0 -3121
- package/dist/builders-Dqo2X-dt.js.map +0 -1
- package/dist/fold-2V29cxCV.cjs +0 -447
- package/dist/fold-2V29cxCV.cjs.map +0 -1
- package/dist/fold-CdEJTBTn.js +0 -334
- package/dist/fold-CdEJTBTn.js.map +0 -1
- package/dist/resolver-CYVNV4hn.cjs.map +0 -1
- package/dist/resolver-inAVzsWt.js.map +0 -1
- package/dist/schemas-BLARNCgx.js +0 -3113
- package/dist/schemas-BLARNCgx.js.map +0 -1
- package/dist/schemas-DIqFMmrC.cjs +0 -4468
- package/dist/schemas-DIqFMmrC.cjs.map +0 -1
|
@@ -0,0 +1,889 @@
|
|
|
1
|
+
import { a as formWidget, h as EngineError, y as EngineErrorCode } from "./format-Dgg428Kb.js";
|
|
2
|
+
import { dt as hasAnnotationResources, f as applyAnnotationPatch, ft as resolveAnnotationResources, lt as annotationResourceBuffers, pt as withFileFromResource, u as annotationOfDraft } from "./calibrate-7T3fnP8-.js";
|
|
3
|
+
//#region src/mutation/AttachmentMutationResults.ts
|
|
4
|
+
/**
|
|
5
|
+
* What a delete removed, as its `attachments.deleted` event names it for
|
|
6
|
+
* listeners that didn't make the call.
|
|
7
|
+
*/
|
|
8
|
+
function deletedAttachmentOf(result) {
|
|
9
|
+
return result.meta.changed[0] ?? null;
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/forms/write.ts
|
|
13
|
+
/** The shapes each family takes, for the message when a value doesn't fit. */
|
|
14
|
+
const TAKES = {
|
|
15
|
+
text: "{ value }",
|
|
16
|
+
checkbox: "{ checked } or { value }",
|
|
17
|
+
radio: "{ value }",
|
|
18
|
+
combobox: "{ value }",
|
|
19
|
+
listbox: "{ selectedValues }"
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* The write `value` makes for `field`, checked before anything is written:
|
|
23
|
+
* the shape must be one the family takes, a toggle's value must be the
|
|
24
|
+
* export value of one of its widgets (a radio group that must keep a choice
|
|
25
|
+
* can't be cleared), and a choice must be option values (free text for a
|
|
26
|
+
* dropdown that allows editing). `InvalidArg` otherwise.
|
|
27
|
+
*/
|
|
28
|
+
function fieldValueWriteOf(field, value) {
|
|
29
|
+
switch (field.family) {
|
|
30
|
+
case "text":
|
|
31
|
+
if ("value" in value) return {
|
|
32
|
+
kind: "text",
|
|
33
|
+
value: value.value ?? ""
|
|
34
|
+
};
|
|
35
|
+
break;
|
|
36
|
+
case "checkbox":
|
|
37
|
+
if ("checked" in value) {
|
|
38
|
+
if (!value.checked) return {
|
|
39
|
+
kind: "toggle",
|
|
40
|
+
state: null
|
|
41
|
+
};
|
|
42
|
+
const first = field.widgets[0];
|
|
43
|
+
if (!first) throw invalidValue(`'${field.name}' has no widget to check`);
|
|
44
|
+
return {
|
|
45
|
+
kind: "toggle",
|
|
46
|
+
state: first.onState
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if ("value" in value) return {
|
|
50
|
+
kind: "toggle",
|
|
51
|
+
state: toggleStateOf(field, value.value)
|
|
52
|
+
};
|
|
53
|
+
break;
|
|
54
|
+
case "radio":
|
|
55
|
+
if ("value" in value) {
|
|
56
|
+
const state = toggleStateOf(field, value.value);
|
|
57
|
+
if (state === null && field.noToggleToOff) throw invalidValue(`'${field.name}' must keep a choice: it can't be cleared`);
|
|
58
|
+
return {
|
|
59
|
+
kind: "toggle",
|
|
60
|
+
state
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
break;
|
|
64
|
+
case "combobox":
|
|
65
|
+
if ("value" in value) return choiceOf(field, value.value === null ? [] : [value.value]);
|
|
66
|
+
break;
|
|
67
|
+
case "listbox":
|
|
68
|
+
if ("selectedValues" in value) return choiceOf(field, value.selectedValues);
|
|
69
|
+
break;
|
|
70
|
+
default: throw invalidValue(`${field.family} fields hold no value you can set`);
|
|
71
|
+
}
|
|
72
|
+
throw invalidValue(`a ${field.family} field takes ${TAKES[field.family]}, not ${shapeOf(value)}`);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Check a choice field's default (`/DV`) before it is written: option values
|
|
76
|
+
* (one free text for a dropdown that allows editing), none twice, and one
|
|
77
|
+
* value unless the list box takes several. `InvalidArg` otherwise.
|
|
78
|
+
*/
|
|
79
|
+
function assertChoiceDefault(target, values) {
|
|
80
|
+
const invalid = (message) => new EngineError(EngineErrorCode.InvalidArg, message, { details: { field: "defaultValue" } });
|
|
81
|
+
if (new Set(values).size !== values.length) throw invalid("the default values must not repeat");
|
|
82
|
+
if (values.length > 1 && !(target.family === "listbox" && target.multiSelect)) throw invalid(`a ${target.family === "listbox" ? "list without multiSelect" : "dropdown"} has one default`);
|
|
83
|
+
const freeText = target.family === "combobox" && target.edit === true;
|
|
84
|
+
const optionValues = new Set(target.options.map((option) => option.value));
|
|
85
|
+
const unknown = values.find((value) => !optionValues.has(value));
|
|
86
|
+
if (unknown !== void 0 && !freeText) throw invalid(`'${unknown}' is not an option value of the ${target.family === "listbox" ? "list" : "dropdown"}`);
|
|
87
|
+
}
|
|
88
|
+
/** Whether `write` would leave `field` as it is. */
|
|
89
|
+
function isNoOpWrite(field, write) {
|
|
90
|
+
switch (write.kind) {
|
|
91
|
+
case "text": return field.family === "text" && field.value === write.value;
|
|
92
|
+
case "toggle": return (field.family === "checkbox" || field.family === "radio") && field.widgets.every((widget) => widget.checked === (widget.onState === write.state));
|
|
93
|
+
case "choice":
|
|
94
|
+
if (field.family === "combobox") return write.values.length === 0 ? field.value === "" : field.value === write.values[0];
|
|
95
|
+
return field.family === "listbox" && field.selectedValues.length === write.values.length && field.selectedValues.every((value, index) => value === write.values[index]);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Whether a reset would leave `field` as it is: its value is its default, and
|
|
100
|
+
* a checkbox's or radio group's buttons show that default.
|
|
101
|
+
*/
|
|
102
|
+
function isAtDefault(field) {
|
|
103
|
+
if (field.valueEntry.kind === "unsupported") return false;
|
|
104
|
+
if (!valueEntriesEqual(field.valueEntry, field.defaultValueEntry)) return false;
|
|
105
|
+
if (field.family !== "checkbox" && field.family !== "radio") return true;
|
|
106
|
+
const entry = field.defaultValueEntry;
|
|
107
|
+
const state = entry.kind === "scalar" ? entry.value : null;
|
|
108
|
+
return field.widgets.every((widget) => widget.checked === (widget.onState === state));
|
|
109
|
+
}
|
|
110
|
+
/** Whether two value entries hold the same value. */
|
|
111
|
+
function valueEntriesEqual(left, right) {
|
|
112
|
+
if (left.kind !== right.kind) return false;
|
|
113
|
+
if (left.kind === "scalar" && right.kind === "scalar") return left.value === right.value;
|
|
114
|
+
if (left.kind === "array" && right.kind === "array") return left.values.length === right.values.length && left.values.every((value, index) => value === right.values[index]);
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
/** A checkbox's or radio group's on-state for an export value; `'Off'` and `null` clear it. */
|
|
118
|
+
function toggleStateOf(field, exportValue) {
|
|
119
|
+
if (exportValue === null || exportValue === "Off") return null;
|
|
120
|
+
const widget = field.widgets.find((candidate) => candidate.exportValue === exportValue);
|
|
121
|
+
if (!widget) throw invalidValue(`no widget of '${field.name}' has the export value '${exportValue}'`);
|
|
122
|
+
return widget.onState;
|
|
123
|
+
}
|
|
124
|
+
function choiceOf(field, values) {
|
|
125
|
+
if (new Set(values).size !== values.length) throw invalidValue("the values must not repeat");
|
|
126
|
+
if (field.family === "listbox" && !field.multiSelect && values.length > 1) throw invalidValue(`'${field.name}' takes one value (it has no multiSelect)`);
|
|
127
|
+
const optionValues = new Set(field.options.map((option) => option.value));
|
|
128
|
+
const freeText = field.family === "combobox" && field.edit && values.length === 1;
|
|
129
|
+
const unknown = values.find((value) => !optionValues.has(value));
|
|
130
|
+
if (!freeText && unknown !== void 0) throw invalidValue(`'${unknown}' is not an option value of '${field.name}'`);
|
|
131
|
+
return {
|
|
132
|
+
kind: "choice",
|
|
133
|
+
values
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function shapeOf(value) {
|
|
137
|
+
if ("checked" in value) return "{ checked }";
|
|
138
|
+
if ("selectedValues" in value) return "{ selectedValues }";
|
|
139
|
+
return "{ value }";
|
|
140
|
+
}
|
|
141
|
+
function invalidValue(message) {
|
|
142
|
+
return new EngineError(EngineErrorCode.InvalidArg, message, { details: { field: "value" } });
|
|
143
|
+
}
|
|
144
|
+
//#endregion
|
|
145
|
+
//#region src/forms/widgets.ts
|
|
146
|
+
/**
|
|
147
|
+
* A widget placement or patch as a `family` widget takes it. `/MK /CA` is a
|
|
148
|
+
* push button's caption and a checkbox's or radio button's symbol
|
|
149
|
+
* (`checkStyle`), so each goes on its own family's widgets only: on another
|
|
150
|
+
* widget, a `null` (as its row reads) is dropped, and a value is refused.
|
|
151
|
+
*/
|
|
152
|
+
function fitWidgetToFamily(family, value) {
|
|
153
|
+
const toggle = family === "checkbox" || family === "radio";
|
|
154
|
+
return fitToFamily(family, fitToFamily(family, value, "caption", family === "pushbutton", "a push button's"), "checkStyle", toggle, "a checkbox's or radio button's");
|
|
155
|
+
}
|
|
156
|
+
function fitToFamily(family, value, key, takes, whose) {
|
|
157
|
+
if (takes || value[key] === void 0) return value;
|
|
158
|
+
if (value[key] !== null) {
|
|
159
|
+
const widget = family === "unknown" ? "this widget" : `a ${family} field's widget`;
|
|
160
|
+
throw new EngineError(EngineErrorCode.InvalidArg, `'${key}' applies to ${whose} widgets, not to ${widget}`, { details: { field: key } });
|
|
161
|
+
}
|
|
162
|
+
const { [key]: _none, ...rest } = value;
|
|
163
|
+
return rest;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* `forms.updateWidget`: the row a widget patch leaves, as an annotation
|
|
167
|
+
* patch leaves it (a move keeps the look), checked against the widget's
|
|
168
|
+
* family first. A new box or turn moves where it stands (`standingRectOf`).
|
|
169
|
+
*/
|
|
170
|
+
function widgetAfterPatch(row, patch) {
|
|
171
|
+
const fitted = fitWidgetToFamily(row.fieldFamily, patch);
|
|
172
|
+
const after = applyAnnotationPatch(row, {
|
|
173
|
+
subtype: "widget",
|
|
174
|
+
...fitted
|
|
175
|
+
});
|
|
176
|
+
if (![
|
|
177
|
+
"box",
|
|
178
|
+
"rect",
|
|
179
|
+
"rotation"
|
|
180
|
+
].some((key) => key in fitted)) return after;
|
|
181
|
+
return {
|
|
182
|
+
...after,
|
|
183
|
+
rect: standingRectOf(after.box, after.rotation)
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Where a widget stands on the page: its box, with its sides swapped under a
|
|
188
|
+
* quarter turn (its contents turn, the frame keeps its place).
|
|
189
|
+
*/
|
|
190
|
+
function standingRectOf(box, rotation) {
|
|
191
|
+
const turn = ((rotation ?? 0) % 360 + 360) % 360;
|
|
192
|
+
if (turn !== 90 && turn !== 270) return box;
|
|
193
|
+
const { x, y, width, height } = box;
|
|
194
|
+
return {
|
|
195
|
+
...box,
|
|
196
|
+
x: x + (width - height) / 2,
|
|
197
|
+
y: y + (height - width) / 2,
|
|
198
|
+
width: height,
|
|
199
|
+
height: width
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
//#endregion
|
|
203
|
+
//#region src/forms/predict.ts
|
|
204
|
+
/**
|
|
205
|
+
* `forms.setValue`: a text field holds the text, cut to its maximum length
|
|
206
|
+
* (in characters); a checkbox checks every widget with the target's export
|
|
207
|
+
* value and on-state; a radio group checks the first button with the value,
|
|
208
|
+
* or every one with it when its radios move in unison; a choice field holds
|
|
209
|
+
* its option values in option order, or a dropdown's free text. Refuses what
|
|
210
|
+
* the engine refuses (`fieldValueWriteOf`).
|
|
211
|
+
*/
|
|
212
|
+
function fieldAfterValue(current, value) {
|
|
213
|
+
const { field } = current;
|
|
214
|
+
const write = fieldValueWriteOf(field, value);
|
|
215
|
+
switch (write.kind) {
|
|
216
|
+
case "text": {
|
|
217
|
+
if (field.family !== "text") return current;
|
|
218
|
+
const text = firstCharacters(write.value, field.maxLength);
|
|
219
|
+
if (text === field.value) return current;
|
|
220
|
+
return redrawn({
|
|
221
|
+
...field,
|
|
222
|
+
value: text,
|
|
223
|
+
valueEntry: {
|
|
224
|
+
kind: "scalar",
|
|
225
|
+
value: text
|
|
226
|
+
}
|
|
227
|
+
}, current);
|
|
228
|
+
}
|
|
229
|
+
case "toggle": {
|
|
230
|
+
if (field.family !== "checkbox" && field.family !== "radio") return current;
|
|
231
|
+
const target = field.widgets.findIndex((widget) => widget.onState === write.state);
|
|
232
|
+
return toggled(current, write.state === null ? -1 : target);
|
|
233
|
+
}
|
|
234
|
+
case "choice":
|
|
235
|
+
if (field.family !== "combobox" && field.family !== "listbox") return current;
|
|
236
|
+
return redrawn(choiceFieldWith(field, write.values), current);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* `forms.reset`: back to the default value. A text field holds its default
|
|
241
|
+
* (or nothing); a choice field its default options; a checkbox or radio
|
|
242
|
+
* group checks the widget its default names, or none.
|
|
243
|
+
*/
|
|
244
|
+
function fieldAfterReset(current) {
|
|
245
|
+
const { field } = current;
|
|
246
|
+
const defaults = field.defaultValueEntry;
|
|
247
|
+
switch (field.family) {
|
|
248
|
+
case "text": {
|
|
249
|
+
if (defaults.kind === "array" || defaults.kind === "unsupported") throw notReset(field);
|
|
250
|
+
const value = defaults.kind === "scalar" ? defaults.value : "";
|
|
251
|
+
const entry = defaults.kind === "scalar" ? defaults : { kind: "none" };
|
|
252
|
+
return redrawn({
|
|
253
|
+
...field,
|
|
254
|
+
value,
|
|
255
|
+
valueEntry: entry
|
|
256
|
+
}, current);
|
|
257
|
+
}
|
|
258
|
+
case "checkbox":
|
|
259
|
+
case "radio": {
|
|
260
|
+
if (defaults.kind === "array" || defaults.kind === "unsupported") throw notReset(field);
|
|
261
|
+
const state = defaults.kind === "scalar" ? defaults.value : null;
|
|
262
|
+
if (state === null || state === "Off") return toggled(current, -1);
|
|
263
|
+
const target = widgetNamedBy(field.widgets, state);
|
|
264
|
+
if (target < 0) throw notReset(field);
|
|
265
|
+
return toggled(current, target);
|
|
266
|
+
}
|
|
267
|
+
case "combobox":
|
|
268
|
+
case "listbox": {
|
|
269
|
+
if (defaults.kind === "unsupported") throw notReset(field);
|
|
270
|
+
let values = defaults.kind === "scalar" ? [defaults.value] : defaults.kind === "array" ? [...defaults.values] : [];
|
|
271
|
+
if (values.length === 1 && values[0] === "" && !choiceMatches(field, values)) values = [];
|
|
272
|
+
if (!choiceMatches(field, values) && !freeTextAllowed(field, values)) throw notReset(field);
|
|
273
|
+
return redrawn(choiceFieldWith(field, values), current);
|
|
274
|
+
}
|
|
275
|
+
default: throw notReset(field);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* `forms.setDisplay`, on each widget's flags, as Acrobat's `Field.display`
|
|
280
|
+
* sets them: visible and printed; hidden; visible but not printed; printed
|
|
281
|
+
* but not shown on screen.
|
|
282
|
+
*/
|
|
283
|
+
function widgetsAfterDisplay(widgets, display) {
|
|
284
|
+
const flags = DISPLAY_FLAGS[display];
|
|
285
|
+
return widgets.map((row) => Object.keys(flags).every((key) => row[key] === flags[key]) ? row : {
|
|
286
|
+
...row,
|
|
287
|
+
...flags
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
const DISPLAY_FLAGS = {
|
|
291
|
+
visible: {
|
|
292
|
+
invisible: false,
|
|
293
|
+
hidden: false,
|
|
294
|
+
noView: false,
|
|
295
|
+
print: true
|
|
296
|
+
},
|
|
297
|
+
hidden: {
|
|
298
|
+
invisible: false,
|
|
299
|
+
hidden: true,
|
|
300
|
+
noView: false,
|
|
301
|
+
print: true
|
|
302
|
+
},
|
|
303
|
+
noPrint: {
|
|
304
|
+
invisible: false,
|
|
305
|
+
hidden: false,
|
|
306
|
+
noView: false,
|
|
307
|
+
print: false
|
|
308
|
+
},
|
|
309
|
+
noView: {
|
|
310
|
+
hidden: false,
|
|
311
|
+
noView: true,
|
|
312
|
+
print: true
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
/**
|
|
316
|
+
* The default (`/DV`) a draft gives its field: a text field's or dropdown's
|
|
317
|
+
* one value, a list box's option values in option order; none without one.
|
|
318
|
+
*/
|
|
319
|
+
function defaultEntryOfDraft(draft) {
|
|
320
|
+
if ((draft.family === "combobox" || draft.family === "listbox") && draft.defaultValue !== void 0) {
|
|
321
|
+
const values = Array.isArray(draft.defaultValue) ? draft.defaultValue : [draft.defaultValue];
|
|
322
|
+
assertChoiceDefault({
|
|
323
|
+
...draft,
|
|
324
|
+
options: draft.options ?? []
|
|
325
|
+
}, values);
|
|
326
|
+
}
|
|
327
|
+
switch (draft.family) {
|
|
328
|
+
case "text":
|
|
329
|
+
case "combobox": return draft.defaultValue !== void 0 ? scalar(draft.defaultValue) : none();
|
|
330
|
+
case "listbox": return choiceEntryOf(inOptionOrder((draft.options ?? []).map(optionOf), draft.defaultValue ?? []));
|
|
331
|
+
default: return none();
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* `forms.create`: the field and its widgets as a read of them returns them.
|
|
336
|
+
* Every flag the draft doesn't set is off, the value is empty (a default
|
|
337
|
+
* only sets the default), a checkbox's export value is `'Yes'` unless its
|
|
338
|
+
* widget names one, and a toggle's widgets start off.
|
|
339
|
+
*/
|
|
340
|
+
function formFieldOfDraft(draft, context) {
|
|
341
|
+
const placements = draft.widgets ?? [];
|
|
342
|
+
const rows = placements.map((placement, at) => widgetRowOfPlacement(draft, placement, {
|
|
343
|
+
ref: context.widgets[at],
|
|
344
|
+
field: context.objectNumber,
|
|
345
|
+
nm: context.widgetNames?.[at]
|
|
346
|
+
}));
|
|
347
|
+
const widgets = rows.map((row) => formWidget(objectNumberOf(row.ref), row.page));
|
|
348
|
+
const options = (draft.family === "combobox" || draft.family === "listbox" ? draft.options ?? [] : []).map(optionOf);
|
|
349
|
+
const base = {
|
|
350
|
+
ref: {
|
|
351
|
+
kind: "objectNumber",
|
|
352
|
+
objectNumber: context.objectNumber
|
|
353
|
+
},
|
|
354
|
+
name: draft.name,
|
|
355
|
+
origin: "acroform",
|
|
356
|
+
readOnly: draft.readOnly ?? false,
|
|
357
|
+
required: draft.required ?? false,
|
|
358
|
+
noExport: draft.noExport ?? false,
|
|
359
|
+
alternateName: draft.alternateName ?? null,
|
|
360
|
+
mappingName: draft.mappingName ?? null,
|
|
361
|
+
valueEntry: { kind: "none" },
|
|
362
|
+
defaultValueEntry: { kind: "none" },
|
|
363
|
+
groupId: draft.groupId ?? context.groupId ?? null,
|
|
364
|
+
createdBy: context.createdBy ?? null,
|
|
365
|
+
createdAt: context.createdAt ?? null,
|
|
366
|
+
filledBy: null,
|
|
367
|
+
filledByName: null,
|
|
368
|
+
filledAt: null,
|
|
369
|
+
importedBy: null
|
|
370
|
+
};
|
|
371
|
+
let field;
|
|
372
|
+
switch (draft.family) {
|
|
373
|
+
case "text": {
|
|
374
|
+
const defaultValue = draft.defaultValue ?? "";
|
|
375
|
+
field = {
|
|
376
|
+
...base,
|
|
377
|
+
family: "text",
|
|
378
|
+
defaultValueEntry: defaultEntryOfDraft(draft),
|
|
379
|
+
value: "",
|
|
380
|
+
defaultValue,
|
|
381
|
+
maxLength: draft.maxLength ?? null,
|
|
382
|
+
multiline: draft.multiline ?? false,
|
|
383
|
+
password: draft.password ?? false,
|
|
384
|
+
comb: draft.comb ?? false,
|
|
385
|
+
widgets
|
|
386
|
+
};
|
|
387
|
+
break;
|
|
388
|
+
}
|
|
389
|
+
case "checkbox": {
|
|
390
|
+
const toggles = placements.map((placement, at) => toggleWidgetOf(widgets[at], placement.exportValue ?? "Yes"));
|
|
391
|
+
field = {
|
|
392
|
+
...base,
|
|
393
|
+
family: "checkbox",
|
|
394
|
+
checked: false,
|
|
395
|
+
exportValue: toggles[0]?.exportValue ?? "Yes",
|
|
396
|
+
widgets: toggles
|
|
397
|
+
};
|
|
398
|
+
break;
|
|
399
|
+
}
|
|
400
|
+
case "radio": {
|
|
401
|
+
const toggles = placements.map((placement, at) => toggleWidgetOf(widgets[at], placement.exportValue ?? ""));
|
|
402
|
+
field = {
|
|
403
|
+
...base,
|
|
404
|
+
family: "radio",
|
|
405
|
+
value: "Off",
|
|
406
|
+
radiosInUnison: draft.radiosInUnison ?? false,
|
|
407
|
+
noToggleToOff: draft.noToggleToOff ?? false,
|
|
408
|
+
widgets: toggles
|
|
409
|
+
};
|
|
410
|
+
break;
|
|
411
|
+
}
|
|
412
|
+
case "combobox":
|
|
413
|
+
field = {
|
|
414
|
+
...base,
|
|
415
|
+
family: "combobox",
|
|
416
|
+
defaultValueEntry: defaultEntryOfDraft(draft),
|
|
417
|
+
value: "",
|
|
418
|
+
defaultValue: draft.defaultValue ?? "",
|
|
419
|
+
edit: draft.edit ?? false,
|
|
420
|
+
options,
|
|
421
|
+
widgets
|
|
422
|
+
};
|
|
423
|
+
break;
|
|
424
|
+
case "listbox": {
|
|
425
|
+
const defaults = draft.defaultValue ?? [];
|
|
426
|
+
field = {
|
|
427
|
+
...base,
|
|
428
|
+
family: "listbox",
|
|
429
|
+
defaultValueEntry: defaultEntryOfDraft(draft),
|
|
430
|
+
selectedValues: [],
|
|
431
|
+
defaultValue: inOptionOrder(options, defaults),
|
|
432
|
+
multiSelect: draft.multiSelect ?? false,
|
|
433
|
+
options,
|
|
434
|
+
topIndex: 0,
|
|
435
|
+
widgets
|
|
436
|
+
};
|
|
437
|
+
break;
|
|
438
|
+
}
|
|
439
|
+
default: field = {
|
|
440
|
+
...base,
|
|
441
|
+
family: draft.family,
|
|
442
|
+
widgets
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
return {
|
|
446
|
+
field,
|
|
447
|
+
widgets: rows
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* `forms.update`: the settings the patch names. A new name replaces the
|
|
452
|
+
* field's own segment of its dotted name; new options keep what is still
|
|
453
|
+
* selected (an editable dropdown keeps its free text) and its default the
|
|
454
|
+
* same way; `null` clears a limit, a name or a default.
|
|
455
|
+
*/
|
|
456
|
+
function formFieldAfter(current, patch) {
|
|
457
|
+
const given = patch;
|
|
458
|
+
let field = { ...current.field };
|
|
459
|
+
if (patch.name !== void 0) {
|
|
460
|
+
const parent = field.name.lastIndexOf(".");
|
|
461
|
+
field.name = parent < 0 ? patch.name : `${field.name.slice(0, parent + 1)}${patch.name}`;
|
|
462
|
+
}
|
|
463
|
+
for (const flag of FLAGS) if (typeof given[flag] === "boolean" && flag in field) field[flag] = given[flag];
|
|
464
|
+
if (patch.alternateName !== void 0) field.alternateName = patch.alternateName || null;
|
|
465
|
+
if (patch.mappingName !== void 0) field.mappingName = patch.mappingName || null;
|
|
466
|
+
if (patch.groupId !== void 0) field.groupId = patch.groupId;
|
|
467
|
+
if (field.family === "text") {
|
|
468
|
+
if ("maxLength" in patch && patch.maxLength !== void 0) field.maxLength = patch.maxLength;
|
|
469
|
+
if ("defaultValue" in patch && patch.defaultValue !== void 0) {
|
|
470
|
+
const value = patch.defaultValue;
|
|
471
|
+
field.defaultValue = value ?? "";
|
|
472
|
+
field.defaultValueEntry = value === null ? none() : scalar(value);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
let redraw = false;
|
|
476
|
+
if (field.family === "combobox" || field.family === "listbox") {
|
|
477
|
+
if ("options" in patch && patch.options) {
|
|
478
|
+
field = withOptions(field, patch.options.map(optionOf));
|
|
479
|
+
redraw = true;
|
|
480
|
+
}
|
|
481
|
+
if ("defaultValue" in patch && patch.defaultValue !== void 0) {
|
|
482
|
+
const values = patch.defaultValue === null ? [] : Array.isArray(patch.defaultValue) ? patch.defaultValue : [patch.defaultValue];
|
|
483
|
+
assertChoiceDefault(field, values);
|
|
484
|
+
field = withDefault(field, values);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
const after = {
|
|
488
|
+
...current,
|
|
489
|
+
field
|
|
490
|
+
};
|
|
491
|
+
return redraw ? redrawn(after.field, after) : after;
|
|
492
|
+
}
|
|
493
|
+
const FLAGS = [
|
|
494
|
+
"readOnly",
|
|
495
|
+
"required",
|
|
496
|
+
"noExport",
|
|
497
|
+
"multiline",
|
|
498
|
+
"password",
|
|
499
|
+
"comb",
|
|
500
|
+
"radiosInUnison",
|
|
501
|
+
"noToggleToOff",
|
|
502
|
+
"edit",
|
|
503
|
+
"multiSelect"
|
|
504
|
+
];
|
|
505
|
+
/** The first `limit` characters of `text` (characters, as the file counts them); all without a limit. */
|
|
506
|
+
function firstCharacters(text, limit) {
|
|
507
|
+
if (!limit) return text;
|
|
508
|
+
const characters = Array.from(text);
|
|
509
|
+
return characters.length > limit ? characters.slice(0, limit).join("") : text;
|
|
510
|
+
}
|
|
511
|
+
/** The field, with every widget's appearance drawn again (a text or choice write). */
|
|
512
|
+
function redrawn(field, current) {
|
|
513
|
+
return {
|
|
514
|
+
field,
|
|
515
|
+
widgets: current.widgets.map((row) => row.hasAppearance ? row : {
|
|
516
|
+
...row,
|
|
517
|
+
hasAppearance: true
|
|
518
|
+
})
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* The widget a checkbox's or radio group's default names: the one whose
|
|
523
|
+
* on-state it is, or, when none is, the one at that position (a field with
|
|
524
|
+
* `/Opt` written by a tool that names its widgets by position). `-1`: none.
|
|
525
|
+
*/
|
|
526
|
+
function widgetNamedBy(widgets, state) {
|
|
527
|
+
const named = widgets.findIndex((widget) => widget.onState === state);
|
|
528
|
+
if (named >= 0 || !/^\d+$/.test(state)) return named;
|
|
529
|
+
return Number(state) < widgets.length ? Number(state) : -1;
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* A checkbox or radio group with widget `target` checked (`-1`: none), and
|
|
533
|
+
* the widgets that go with it: every widget with its export value and
|
|
534
|
+
* on-state for a checkbox or radios in unison, otherwise that one. Its value
|
|
535
|
+
* names the checked widget's on-state (`/V` names the appearance state that
|
|
536
|
+
* is on), or `Off`.
|
|
537
|
+
*/
|
|
538
|
+
function toggled(current, target) {
|
|
539
|
+
const field = current.field;
|
|
540
|
+
if (field.family !== "checkbox" && field.family !== "radio") return current;
|
|
541
|
+
const unison = field.family === "checkbox" || field.radiosInUnison;
|
|
542
|
+
const on = target >= 0 ? field.widgets[target] : null;
|
|
543
|
+
const toggles = field.widgets.map((widget, at) => {
|
|
544
|
+
const checked = on !== null && (unison ? widget.exportValue === on.exportValue && widget.onState === on.onState : at === target);
|
|
545
|
+
return widget.checked === checked ? widget : {
|
|
546
|
+
...widget,
|
|
547
|
+
checked
|
|
548
|
+
};
|
|
549
|
+
});
|
|
550
|
+
const valueEntry = scalar(on ? on.onState : "Off");
|
|
551
|
+
const next = field.family === "checkbox" ? {
|
|
552
|
+
...field,
|
|
553
|
+
widgets: toggles,
|
|
554
|
+
valueEntry,
|
|
555
|
+
checked: toggles.some((widget) => widget.checked)
|
|
556
|
+
} : {
|
|
557
|
+
...field,
|
|
558
|
+
widgets: toggles,
|
|
559
|
+
valueEntry,
|
|
560
|
+
value: toggles.find((widget) => widget.checked)?.exportValue ?? "Off"
|
|
561
|
+
};
|
|
562
|
+
const states = new Map(toggles.map((widget) => [widget.objectNumber, widget.checked ? widget.onState : "Off"]));
|
|
563
|
+
return {
|
|
564
|
+
field: next,
|
|
565
|
+
widgets: current.widgets.map((row) => {
|
|
566
|
+
const state = states.get(objectNumberOf(row.ref));
|
|
567
|
+
return state === void 0 || row.appearanceState === state ? row : {
|
|
568
|
+
...row,
|
|
569
|
+
appearanceState: state
|
|
570
|
+
};
|
|
571
|
+
})
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
/** The option indexes `values` name, each the first option with that value, in option order. */
|
|
575
|
+
function matchedIndexes(options, values) {
|
|
576
|
+
const indexes = /* @__PURE__ */ new Set();
|
|
577
|
+
for (const value of values) {
|
|
578
|
+
const at = options.findIndex((option) => option.value === value);
|
|
579
|
+
if (at >= 0) indexes.add(at);
|
|
580
|
+
}
|
|
581
|
+
return [...indexes].sort((left, right) => left - right);
|
|
582
|
+
}
|
|
583
|
+
const choiceMatches = (field, values) => values.every((value) => field.options.some((option) => option.value === value));
|
|
584
|
+
const freeTextAllowed = (field, values) => field.family === "combobox" && field.edit && values.length === 1;
|
|
585
|
+
/** A choice field holding `values`: its options' selection, its value and `/V`. */
|
|
586
|
+
function choiceFieldWith(field, values) {
|
|
587
|
+
const matched = choiceMatches(field, values) ? matchedIndexes(field.options, values) : [];
|
|
588
|
+
const freeText = values.length > 0 && matched.length === 0;
|
|
589
|
+
const options = field.options.map((option, at) => {
|
|
590
|
+
const selected = matched.includes(at);
|
|
591
|
+
return option.selected === selected ? option : {
|
|
592
|
+
...option,
|
|
593
|
+
selected
|
|
594
|
+
};
|
|
595
|
+
});
|
|
596
|
+
const chosen = freeText ? [...values] : matched.map((at) => field.options[at].value);
|
|
597
|
+
const valueEntry = choiceEntryOf(chosen);
|
|
598
|
+
if (field.family === "combobox") return {
|
|
599
|
+
...field,
|
|
600
|
+
options,
|
|
601
|
+
valueEntry,
|
|
602
|
+
value: chosen[0] ?? ""
|
|
603
|
+
};
|
|
604
|
+
return {
|
|
605
|
+
...field,
|
|
606
|
+
options,
|
|
607
|
+
valueEntry,
|
|
608
|
+
selectedValues: chosen
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
/** How `/V` (or `/DV`) holds choice values: none, one string, or an array. */
|
|
612
|
+
function choiceEntryOf(values) {
|
|
613
|
+
if (values.length === 0) return none();
|
|
614
|
+
return values.length === 1 ? scalar(values[0]) : {
|
|
615
|
+
kind: "array",
|
|
616
|
+
values: [...values]
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
/** `values` that are option values, in option order. */
|
|
620
|
+
function inOptionOrder(options, values) {
|
|
621
|
+
return matchedIndexes(options, values).map((at) => options[at].value);
|
|
622
|
+
}
|
|
623
|
+
/** A choice field with new options: what is still an option stays selected, and stays its default. */
|
|
624
|
+
function withOptions(field, options) {
|
|
625
|
+
const exports = options.map((option) => option.value);
|
|
626
|
+
const keepsFreeText = field.family === "combobox" && field.edit;
|
|
627
|
+
const kept = keptValues(field.family === "combobox" ? field.value === "" ? [] : [field.value] : field.selectedValues, exports, keepsFreeText);
|
|
628
|
+
const reselected = choiceFieldWith(field.family === "listbox" ? {
|
|
629
|
+
...field,
|
|
630
|
+
options,
|
|
631
|
+
topIndex: topRowOf(field.topIndex, options)
|
|
632
|
+
} : {
|
|
633
|
+
...field,
|
|
634
|
+
options
|
|
635
|
+
}, kept);
|
|
636
|
+
const defaults = valuesOfEntry(field.defaultValueEntry);
|
|
637
|
+
if (field.defaultValueEntry.kind === "none") return reselected;
|
|
638
|
+
return withDefault(reselected, keptValues(defaults, exports, keepsFreeText), true);
|
|
639
|
+
}
|
|
640
|
+
/** A list box's top row: an option's position, the last one past the end. */
|
|
641
|
+
function topRowOf(topIndex, options) {
|
|
642
|
+
return Math.max(0, Math.min(topIndex, options.length - 1));
|
|
643
|
+
}
|
|
644
|
+
/** The values still among `exports`; free text survives when nothing else does. */
|
|
645
|
+
function keptValues(values, exports, keepFreeText) {
|
|
646
|
+
const kept = values.filter((value) => exports.includes(value));
|
|
647
|
+
return kept.length === 0 && keepFreeText && values.length > 0 ? [...values] : kept;
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* A choice field's default set to `values` (option order; a dropdown's free
|
|
651
|
+
* text as it is). `filtered`: what new options left of the old default,
|
|
652
|
+
* where none left is an empty default rather than no default.
|
|
653
|
+
*/
|
|
654
|
+
function withDefault(field, values, filtered = false) {
|
|
655
|
+
if (values.length === 0) {
|
|
656
|
+
const entry = !filtered ? none() : field.family === "listbox" && field.multiSelect ? {
|
|
657
|
+
kind: "array",
|
|
658
|
+
values: []
|
|
659
|
+
} : scalar("");
|
|
660
|
+
return field.family === "combobox" ? {
|
|
661
|
+
...field,
|
|
662
|
+
defaultValueEntry: entry,
|
|
663
|
+
defaultValue: ""
|
|
664
|
+
} : {
|
|
665
|
+
...field,
|
|
666
|
+
defaultValueEntry: entry,
|
|
667
|
+
defaultValue: []
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
const matched = choiceMatches(field, values);
|
|
671
|
+
const ordered = matched ? inOptionOrder(field.options, values) : [...values];
|
|
672
|
+
const entry = matched ? choiceEntryOf(ordered) : scalar(values[0]);
|
|
673
|
+
return field.family === "combobox" ? {
|
|
674
|
+
...field,
|
|
675
|
+
defaultValueEntry: entry,
|
|
676
|
+
defaultValue: ordered[0] ?? ""
|
|
677
|
+
} : {
|
|
678
|
+
...field,
|
|
679
|
+
defaultValueEntry: entry,
|
|
680
|
+
defaultValue: ordered
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
function valuesOfEntry(entry) {
|
|
684
|
+
if (entry.kind === "scalar") return [entry.value];
|
|
685
|
+
if (entry.kind === "array") return [...entry.values];
|
|
686
|
+
return [];
|
|
687
|
+
}
|
|
688
|
+
/** A new widget's row: its placement and look, and what attaching it to the field gives it. */
|
|
689
|
+
function widgetRowOfPlacement(draft, placement, at) {
|
|
690
|
+
const { page: _page, exportValue: _exportValue, ...look } = placement;
|
|
691
|
+
const row = annotationOfDraft({
|
|
692
|
+
subtype: "widget",
|
|
693
|
+
...look
|
|
694
|
+
}, {
|
|
695
|
+
ref: at.ref,
|
|
696
|
+
...at.nm !== void 0 ? { nm: at.nm } : {}
|
|
697
|
+
});
|
|
698
|
+
const toggle = draft.family === "checkbox" || draft.family === "radio";
|
|
699
|
+
return {
|
|
700
|
+
...row,
|
|
701
|
+
rect: standingRectOf(row.box, row.rotation),
|
|
702
|
+
field: {
|
|
703
|
+
kind: "objectNumber",
|
|
704
|
+
objectNumber: at.field
|
|
705
|
+
},
|
|
706
|
+
fieldFamily: draft.family,
|
|
707
|
+
print: true,
|
|
708
|
+
hasAppearance: draft.family !== "signature",
|
|
709
|
+
appearanceState: toggle ? "Off" : null,
|
|
710
|
+
caption: draft.family === "pushbutton" ? placement.caption ?? null : null
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
function toggleWidgetOf(widget, exportValue) {
|
|
714
|
+
return {
|
|
715
|
+
...widget,
|
|
716
|
+
onState: exportValue,
|
|
717
|
+
exportValue,
|
|
718
|
+
checked: false
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
const optionOf = (input) => ({
|
|
722
|
+
label: input.label,
|
|
723
|
+
value: input.value,
|
|
724
|
+
selected: false
|
|
725
|
+
});
|
|
726
|
+
const objectNumberOf = (ref) => ref.kind === "objectNumber" ? ref.objectNumber : 0;
|
|
727
|
+
const scalar = (value) => ({
|
|
728
|
+
kind: "scalar",
|
|
729
|
+
value
|
|
730
|
+
});
|
|
731
|
+
const none = () => ({ kind: "none" });
|
|
732
|
+
function notReset(field) {
|
|
733
|
+
return new EngineError(EngineErrorCode.Unknown, `'${field.name}' could not be reset`);
|
|
734
|
+
}
|
|
735
|
+
//#endregion
|
|
736
|
+
//#region src/forms/effects.ts
|
|
737
|
+
/**
|
|
738
|
+
* A script run's effects as the ops of one change, in their order: what a
|
|
739
|
+
* form commit sends with `doc.apply`, all or nothing.
|
|
740
|
+
*/
|
|
741
|
+
function formEffectOps(effects) {
|
|
742
|
+
return effects.map((effect) => {
|
|
743
|
+
switch (effect.kind) {
|
|
744
|
+
case "setValue": return {
|
|
745
|
+
type: "forms.setValue",
|
|
746
|
+
field: effect.ref,
|
|
747
|
+
value: effect.value
|
|
748
|
+
};
|
|
749
|
+
case "setDisplay": return {
|
|
750
|
+
type: "forms.setDisplay",
|
|
751
|
+
field: effect.ref,
|
|
752
|
+
display: effect.display
|
|
753
|
+
};
|
|
754
|
+
case "setAppearanceText": return {
|
|
755
|
+
type: "forms.setAppearanceText",
|
|
756
|
+
field: effect.ref,
|
|
757
|
+
text: effect.text
|
|
758
|
+
};
|
|
759
|
+
case "reset": return {
|
|
760
|
+
type: "forms.reset",
|
|
761
|
+
fields: effect.refs
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
//#endregion
|
|
767
|
+
//#region src/mutation/Change.ts
|
|
768
|
+
/** Whether an item is an op an undo left alone entirely. */
|
|
769
|
+
function isSkippedItem(item) {
|
|
770
|
+
return item.type === "skipped";
|
|
771
|
+
}
|
|
772
|
+
/**
|
|
773
|
+
* Whether an item wrote to the document: not an op an undo left alone, nor
|
|
774
|
+
* an import that left every row of its bundle out.
|
|
775
|
+
*/
|
|
776
|
+
function itemWrote(item) {
|
|
777
|
+
switch (item.type) {
|
|
778
|
+
case "skipped": return false;
|
|
779
|
+
case "annotations.import": return item.annotations.length > 0;
|
|
780
|
+
case "forms.import":
|
|
781
|
+
case "forms.importValues": return item.fields.length > 0;
|
|
782
|
+
default: return true;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
/** Whether a change is an undo (`{ undoOf }`) rather than a list of ops. */
|
|
786
|
+
function isUndoChange(change) {
|
|
787
|
+
return "undoOf" in change;
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* The object numbers a change's creates name: each must be one its editing
|
|
791
|
+
* session holds. An undo names none; what it restores keeps its numbers.
|
|
792
|
+
*/
|
|
793
|
+
function objectNumbersNamedBy(change) {
|
|
794
|
+
if (isUndoChange(change)) return [];
|
|
795
|
+
const named = [];
|
|
796
|
+
for (const op of change.ops) switch (op.type) {
|
|
797
|
+
case "annotations.create":
|
|
798
|
+
if (op.objectNumber !== void 0) named.push(op.objectNumber);
|
|
799
|
+
break;
|
|
800
|
+
case "forms.create":
|
|
801
|
+
if (op.objectNumber !== void 0) named.push(op.objectNumber);
|
|
802
|
+
named.push(...op.widgetObjectNumbers ?? []);
|
|
803
|
+
break;
|
|
804
|
+
case "forms.addWidget":
|
|
805
|
+
if (op.objectNumber !== void 0) named.push(op.objectNumber);
|
|
806
|
+
if (op.splitObjectNumber !== void 0) named.push(op.splitObjectNumber);
|
|
807
|
+
break;
|
|
808
|
+
default: break;
|
|
809
|
+
}
|
|
810
|
+
return named;
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* The object numbers a change's ops refer to: every `{ kind: 'objectNumber' }`
|
|
814
|
+
* ref anywhere in them, the annotation or field an op writes and the parent
|
|
815
|
+
* a reply names among them. A change that refers to a number only a refused
|
|
816
|
+
* change creates can't apply. An undo refers to none: it names its change.
|
|
817
|
+
*/
|
|
818
|
+
function objectNumbersReferencedBy(change) {
|
|
819
|
+
if (isUndoChange(change)) return [];
|
|
820
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
821
|
+
const visit = (value) => {
|
|
822
|
+
if (Array.isArray(value)) {
|
|
823
|
+
value.forEach(visit);
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
if (value === null || typeof value !== "object" || ArrayBuffer.isView(value)) return;
|
|
827
|
+
const record = value;
|
|
828
|
+
if (record.kind === "objectNumber" && typeof record.objectNumber === "number") referenced.add(record.objectNumber);
|
|
829
|
+
for (const field of Object.values(record)) visit(field);
|
|
830
|
+
};
|
|
831
|
+
change.ops.forEach(visit);
|
|
832
|
+
return [...referenced];
|
|
833
|
+
}
|
|
834
|
+
/**
|
|
835
|
+
* A change with bytes it owns, ready to send: each op's resources copied
|
|
836
|
+
* (`resolveAnnotationResources`), a file attachment's `file` completed from
|
|
837
|
+
* its `File` (`withFileFromResource`), a signature appearance copied.
|
|
838
|
+
* `buffers` lists every copy, for a worker's transfer list. The caller's
|
|
839
|
+
* bytes are only read.
|
|
840
|
+
*/
|
|
841
|
+
async function resolveChangeResources(change) {
|
|
842
|
+
if (isUndoChange(change)) return {
|
|
843
|
+
change,
|
|
844
|
+
buffers: []
|
|
845
|
+
};
|
|
846
|
+
const buffers = [];
|
|
847
|
+
const ops = [];
|
|
848
|
+
for (const op of change.ops) switch (op.type) {
|
|
849
|
+
case "annotations.create": {
|
|
850
|
+
const { resources, ...rest } = op;
|
|
851
|
+
const wire = await resolveAnnotationResources(resources);
|
|
852
|
+
buffers.push(...annotationResourceBuffers(wire));
|
|
853
|
+
ops.push({
|
|
854
|
+
...rest,
|
|
855
|
+
data: withFileFromResource(op.data, resources),
|
|
856
|
+
...hasAnnotationResources(wire) ? { resources: wire } : {}
|
|
857
|
+
});
|
|
858
|
+
break;
|
|
859
|
+
}
|
|
860
|
+
case "annotations.update": {
|
|
861
|
+
const { resources, ...rest } = op;
|
|
862
|
+
const wire = await resolveAnnotationResources(resources);
|
|
863
|
+
buffers.push(...annotationResourceBuffers(wire));
|
|
864
|
+
ops.push({
|
|
865
|
+
...rest,
|
|
866
|
+
...hasAnnotationResources(wire) ? { resources: wire } : {}
|
|
867
|
+
});
|
|
868
|
+
break;
|
|
869
|
+
}
|
|
870
|
+
case "forms.setSignatureAppearance": {
|
|
871
|
+
const pdf = op.appearance.pdf.slice();
|
|
872
|
+
buffers.push(pdf.buffer);
|
|
873
|
+
ops.push({
|
|
874
|
+
...op,
|
|
875
|
+
appearance: { pdf }
|
|
876
|
+
});
|
|
877
|
+
break;
|
|
878
|
+
}
|
|
879
|
+
default: ops.push(op);
|
|
880
|
+
}
|
|
881
|
+
return {
|
|
882
|
+
change: { ops },
|
|
883
|
+
buffers
|
|
884
|
+
};
|
|
885
|
+
}
|
|
886
|
+
//#endregion
|
|
887
|
+
export { deletedAttachmentOf as S, assertChoiceDefault as _, objectNumbersReferencedBy as a, isNoOpWrite as b, defaultEntryOfDraft as c, formFieldAfter as d, formFieldOfDraft as f, widgetAfterPatch as g, fitWidgetToFamily as h, objectNumbersNamedBy as i, fieldAfterReset as l, widgetsAfterDisplay as m, isUndoChange as n, resolveChangeResources as o, topRowOf as p, itemWrote as r, formEffectOps as s, isSkippedItem as t, fieldAfterValue as u, fieldValueWriteOf as v, valueEntriesEqual as x, isAtDefault as y };
|
|
888
|
+
|
|
889
|
+
//# sourceMappingURL=Change-CKoxfTNY.js.map
|