pdf-lite 1.5.0 → 1.6.1
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/EXAMPLES.md +51 -70
- package/README.md +1 -1
- package/dist/acroform/appearance/pdf-button-appearance-stream.d.ts +1 -1
- package/dist/acroform/appearance/pdf-button-appearance-stream.js +6 -2
- package/dist/acroform/fields/pdf-button-form-field.d.ts +0 -9
- package/dist/acroform/fields/pdf-button-form-field.js +7 -39
- package/dist/acroform/fields/pdf-choice-form-field.d.ts +2 -1
- package/dist/acroform/fields/pdf-choice-form-field.js +19 -38
- package/dist/acroform/fields/pdf-default-appearance.js +1 -1
- package/dist/acroform/fields/pdf-form-field.d.ts +27 -32
- package/dist/acroform/fields/pdf-form-field.js +180 -94
- package/dist/acroform/fields/pdf-text-form-field.js +6 -33
- package/dist/acroform/fields/types.d.ts +1 -1
- package/dist/acroform/index.d.ts +0 -2
- package/dist/acroform/index.js +0 -2
- package/dist/acroform/pdf-acro-form.d.ts +12 -36
- package/dist/acroform/pdf-acro-form.js +111 -201
- package/dist/acroform/xfa/pdf-xfa-data.d.ts +4 -3
- package/dist/acroform/xfa/pdf-xfa-data.js +16 -12
- package/dist/acroform/xfa/pdf-xfa-form.d.ts +9 -4
- package/dist/acroform/xfa/pdf-xfa-form.js +17 -39
- package/dist/annotations/index.d.ts +0 -1
- package/dist/annotations/index.js +0 -1
- package/dist/annotations/pdf-annotation.d.ts +7 -2
- package/dist/annotations/pdf-annotation.js +30 -19
- package/dist/annotations/pdf-default-resources.d.ts +11 -0
- package/dist/annotations/pdf-default-resources.js +3 -0
- package/dist/core/decoder.js +1 -1
- package/dist/core/objects/pdf-array.d.ts +8 -1
- package/dist/core/objects/pdf-array.js +31 -0
- package/dist/core/objects/pdf-dictionary.d.ts +2 -0
- package/dist/core/objects/pdf-dictionary.js +14 -7
- package/dist/core/objects/pdf-hexadecimal.d.ts +1 -0
- package/dist/core/objects/pdf-hexadecimal.js +3 -3
- package/dist/core/objects/pdf-indirect-object.d.ts +18 -9
- package/dist/core/objects/pdf-indirect-object.js +75 -16
- package/dist/core/objects/pdf-number.d.ts +1 -0
- package/dist/core/objects/pdf-number.js +5 -4
- package/dist/core/objects/pdf-object-reference.d.ts +8 -1
- package/dist/core/objects/pdf-object-reference.js +14 -0
- package/dist/core/objects/pdf-object.d.ts +14 -0
- package/dist/core/objects/pdf-object.js +36 -0
- package/dist/core/objects/pdf-start-xref.d.ts +1 -0
- package/dist/core/objects/pdf-start-xref.js +4 -0
- package/dist/core/objects/pdf-stream.d.ts +47 -7
- package/dist/core/objects/pdf-stream.js +301 -32
- package/dist/core/objects/pdf-string.d.ts +1 -0
- package/dist/core/objects/pdf-string.js +3 -6
- package/dist/core/objects/pdf-trailer.d.ts +1 -0
- package/dist/core/objects/pdf-trailer.js +6 -3
- package/dist/core/objects/pdf-xref-table.js +1 -1
- package/dist/core/ref.d.ts +3 -1
- package/dist/core/ref.js +8 -5
- package/dist/core/tokens/token.d.ts +2 -1
- package/dist/core/tokens/token.js +3 -0
- package/dist/fonts/index.d.ts +0 -1
- package/dist/fonts/index.js +0 -1
- package/dist/fonts/pdf-font.d.ts +32 -27
- package/dist/fonts/pdf-font.js +115 -77
- package/dist/pdf/index.d.ts +2 -0
- package/dist/pdf/index.js +2 -0
- package/dist/pdf/pdf-document.d.ts +63 -37
- package/dist/pdf/pdf-document.js +351 -135
- package/dist/pdf/pdf-page.d.ts +50 -0
- package/dist/pdf/pdf-page.js +144 -0
- package/dist/pdf/pdf-pages.d.ts +28 -0
- package/dist/pdf/pdf-pages.js +94 -0
- package/dist/pdf/pdf-reader.d.ts +5 -1
- package/dist/pdf/pdf-reader.js +36 -2
- package/dist/pdf/pdf-revision.d.ts +3 -3
- package/dist/pdf/pdf-revision.js +7 -7
- package/dist/pdf/pdf-xref-lookup.js +34 -14
- package/dist/signing/document-security-store.d.ts +14 -17
- package/dist/signing/document-security-store.js +19 -34
- package/dist/signing/signer.d.ts +23 -8
- package/dist/signing/signer.js +51 -17
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.js +0 -1
- package/dist/utils/needsCentralWhitespace.d.ts +10 -0
- package/dist/utils/needsCentralWhitespace.js +34 -0
- package/package.json +3 -3
- package/dist/acroform/acroform.d.ts +0 -9
- package/dist/acroform/acroform.js +0 -7
- package/dist/acroform/manager.d.ts +0 -37
- package/dist/acroform/manager.js +0 -57
- package/dist/acroform/pdf-font-encoding-cache.d.ts +0 -27
- package/dist/acroform/pdf-font-encoding-cache.js +0 -188
- package/dist/annotations/pdf-annotation-writer.d.ts +0 -20
- package/dist/annotations/pdf-annotation-writer.js +0 -76
- package/dist/fonts/manager.d.ts +0 -127
- package/dist/fonts/manager.js +0 -378
- package/dist/utils/predictors.d.ts +0 -113
- package/dist/utils/predictors.js +0 -279
|
@@ -5,45 +5,20 @@ import { PdfObjectReference } from '../core/objects/pdf-object-reference.js';
|
|
|
5
5
|
import { PdfIndirectObject } from '../core/objects/pdf-indirect-object.js';
|
|
6
6
|
import { PdfBoolean } from '../core/objects/pdf-boolean.js';
|
|
7
7
|
import { PdfNumber } from '../core/objects/pdf-number.js';
|
|
8
|
-
import { PdfFontEncodingCache } from './pdf-font-encoding-cache.js';
|
|
9
|
-
import { PdfAnnotationWriter } from '../annotations/pdf-annotation-writer.js';
|
|
10
|
-
import { PdfXfaForm } from './xfa/pdf-xfa-form.js';
|
|
11
8
|
import { PdfFormField } from './fields/pdf-form-field.js';
|
|
12
9
|
// Import subclasses to trigger static registration blocks
|
|
13
10
|
import './fields/pdf-text-form-field.js';
|
|
14
11
|
import './fields/pdf-button-form-field.js';
|
|
15
12
|
import './fields/pdf-choice-form-field.js';
|
|
16
13
|
import './fields/pdf-signature-form-field.js';
|
|
14
|
+
import { buildEncodingMap } from '../utils/decodeWithFontEncoding.js';
|
|
15
|
+
import { PdfXfaForm } from './xfa/pdf-xfa-form.js';
|
|
17
16
|
export class PdfAcroForm extends PdfIndirectObject {
|
|
18
|
-
fields;
|
|
19
|
-
_fontEncodingCache;
|
|
20
|
-
document;
|
|
21
|
-
_xfa; // undefined = not set; null = explicitly no XFA
|
|
22
17
|
constructor(options) {
|
|
23
|
-
super(options
|
|
18
|
+
super(options ??
|
|
24
19
|
new PdfIndirectObject({
|
|
25
20
|
content: new PdfDictionary(),
|
|
26
21
|
}));
|
|
27
|
-
this.fields = options?.fields ?? [];
|
|
28
|
-
this.document = options?.document;
|
|
29
|
-
}
|
|
30
|
-
get fontEncodingCache() {
|
|
31
|
-
if (!this._fontEncodingCache) {
|
|
32
|
-
this._fontEncodingCache = new PdfFontEncodingCache(this.document, this.defaultResources);
|
|
33
|
-
}
|
|
34
|
-
return this._fontEncodingCache;
|
|
35
|
-
}
|
|
36
|
-
get fontEncodingMaps() {
|
|
37
|
-
return this.fontEncodingCache.fontEncodingMaps;
|
|
38
|
-
}
|
|
39
|
-
get fontRefs() {
|
|
40
|
-
return this.fontEncodingCache.fontRefs;
|
|
41
|
-
}
|
|
42
|
-
setXfa(xfa) {
|
|
43
|
-
this._xfa = xfa;
|
|
44
|
-
}
|
|
45
|
-
isModified() {
|
|
46
|
-
return this.content.isModified();
|
|
47
22
|
}
|
|
48
23
|
get needAppearances() {
|
|
49
24
|
return (this.content.get('NeedAppearances')?.as(PdfBoolean)?.value ?? false);
|
|
@@ -80,6 +55,69 @@ export class PdfAcroForm extends PdfIndirectObject {
|
|
|
80
55
|
this.content.set('DR', resources);
|
|
81
56
|
}
|
|
82
57
|
}
|
|
58
|
+
get fields() {
|
|
59
|
+
const result = [];
|
|
60
|
+
const seen = new Set();
|
|
61
|
+
const collect = (refs) => {
|
|
62
|
+
for (const ref of refs) {
|
|
63
|
+
const key = ref.key;
|
|
64
|
+
if (seen.has(key))
|
|
65
|
+
continue;
|
|
66
|
+
seen.add(key);
|
|
67
|
+
const resolved = ref.resolve();
|
|
68
|
+
if (!(resolved?.content instanceof PdfDictionary))
|
|
69
|
+
continue;
|
|
70
|
+
const dict = resolved.content;
|
|
71
|
+
const tEntry = dict.get('T');
|
|
72
|
+
const tValue = tEntry instanceof PdfString ? tEntry.value : null;
|
|
73
|
+
const hasFt = dict.has('FT');
|
|
74
|
+
if (tValue) {
|
|
75
|
+
const field = PdfFormField.create(resolved);
|
|
76
|
+
field.form = this;
|
|
77
|
+
result.push(field);
|
|
78
|
+
}
|
|
79
|
+
// Only recurse into Kids for non-terminal (group) fields — those
|
|
80
|
+
// without FT. Terminal fields may have Kids that are pure widget
|
|
81
|
+
// annotations (no T) which would produce duplicate names.
|
|
82
|
+
if (!hasFt) {
|
|
83
|
+
const kids = dict.get('Kids');
|
|
84
|
+
if (kids instanceof PdfArray && kids.items.length > 0) {
|
|
85
|
+
collect(kids.items);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
const fieldsRaw = this.content.get('Fields');
|
|
91
|
+
const resolvedFields = fieldsRaw instanceof PdfObjectReference
|
|
92
|
+
? fieldsRaw.resolve()?.content
|
|
93
|
+
: fieldsRaw;
|
|
94
|
+
collect(resolvedFields instanceof PdfArray
|
|
95
|
+
? resolvedFields.items
|
|
96
|
+
: []);
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
addField(...fields) {
|
|
100
|
+
const content = this.content;
|
|
101
|
+
const fieldsRaw = content.get('Fields');
|
|
102
|
+
let fieldsArray = fieldsRaw instanceof PdfObjectReference
|
|
103
|
+
? fieldsRaw.resolve()?.content
|
|
104
|
+
: fieldsRaw;
|
|
105
|
+
if (!fieldsArray) {
|
|
106
|
+
fieldsArray = new PdfArray();
|
|
107
|
+
content.set('Fields', fieldsArray);
|
|
108
|
+
}
|
|
109
|
+
for (const field of fields) {
|
|
110
|
+
fieldsArray.items.push(field.reference);
|
|
111
|
+
// Auto-add to the page's Annots array
|
|
112
|
+
const page = field.page;
|
|
113
|
+
if (page) {
|
|
114
|
+
page.annotations.items.push(field.reference);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
set fields(newFields) {
|
|
119
|
+
this.content.set('Fields', PdfArray.refs(newFields));
|
|
120
|
+
}
|
|
83
121
|
setValues(values) {
|
|
84
122
|
for (const field of this.fields) {
|
|
85
123
|
const name = field.name;
|
|
@@ -106,188 +144,60 @@ export class PdfAcroForm extends PdfIndirectObject {
|
|
|
106
144
|
}
|
|
107
145
|
return result;
|
|
108
146
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return this.fontEncodingCache.isFontUnicode(fontName);
|
|
114
|
-
}
|
|
115
|
-
static async fromDocument(document) {
|
|
116
|
-
const catalog = document.root;
|
|
117
|
-
if (!catalog)
|
|
118
|
-
return null;
|
|
119
|
-
const acroFormRef = catalog.content.get('AcroForm');
|
|
120
|
-
if (!acroFormRef)
|
|
121
|
-
return null;
|
|
122
|
-
let acroFormDict;
|
|
123
|
-
let acroFormContainer;
|
|
124
|
-
if (acroFormRef instanceof PdfObjectReference) {
|
|
125
|
-
const acroFormObject = await document.readObject(acroFormRef);
|
|
126
|
-
if (!acroFormObject)
|
|
127
|
-
return null;
|
|
128
|
-
if (!(acroFormObject.content instanceof PdfDictionary))
|
|
129
|
-
throw new Error('AcroForm content must be a dictionary');
|
|
130
|
-
acroFormDict = acroFormObject.content;
|
|
131
|
-
acroFormContainer = acroFormObject;
|
|
132
|
-
}
|
|
133
|
-
else if (acroFormRef instanceof PdfDictionary) {
|
|
134
|
-
acroFormDict = acroFormRef;
|
|
135
|
-
acroFormContainer = new PdfIndirectObject({ content: acroFormDict });
|
|
147
|
+
fontEncodingMaps = new Map();
|
|
148
|
+
getFontEncodingMap(fontName) {
|
|
149
|
+
if (this.fontEncodingMaps.has(fontName)) {
|
|
150
|
+
return this.fontEncodingMaps.get(fontName);
|
|
136
151
|
}
|
|
137
|
-
|
|
138
|
-
|
|
152
|
+
const dr = this.defaultResources;
|
|
153
|
+
const fontRaw = dr?.get('Font');
|
|
154
|
+
let fontDict;
|
|
155
|
+
if (fontRaw instanceof PdfObjectReference) {
|
|
156
|
+
const resolved = fontRaw.resolve()?.content;
|
|
157
|
+
if (resolved instanceof PdfDictionary)
|
|
158
|
+
fontDict = resolved;
|
|
139
159
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const getFields = async (fieldRefs, parent) => {
|
|
143
|
-
for (const fieldRef of fieldRefs) {
|
|
144
|
-
const refKey = fieldRef.toString().trim();
|
|
145
|
-
if (fields.has(refKey)) {
|
|
146
|
-
fields.get(refKey).parent = parent;
|
|
147
|
-
continue;
|
|
148
|
-
}
|
|
149
|
-
const fieldObject = await document.readObject(fieldRef);
|
|
150
|
-
if (!fieldObject)
|
|
151
|
-
continue;
|
|
152
|
-
if (!(fieldObject.content instanceof PdfDictionary))
|
|
153
|
-
continue;
|
|
154
|
-
const field = PdfFormField.create({
|
|
155
|
-
other: fieldObject,
|
|
156
|
-
form: acroForm,
|
|
157
|
-
parent,
|
|
158
|
-
});
|
|
159
|
-
const kids = field.kids;
|
|
160
|
-
if (kids.length > 0) {
|
|
161
|
-
await getFields(kids, field);
|
|
162
|
-
}
|
|
163
|
-
acroForm.fields.push(field);
|
|
164
|
-
fields.set(refKey, field);
|
|
165
|
-
}
|
|
166
|
-
};
|
|
167
|
-
const fieldsArray = new PdfArray();
|
|
168
|
-
if (acroForm.content.get('Fields') instanceof PdfArray) {
|
|
169
|
-
fieldsArray.items.push(...acroForm.content
|
|
170
|
-
.get('Fields')
|
|
171
|
-
.as((PdfArray)).items);
|
|
160
|
+
else if (fontRaw instanceof PdfDictionary) {
|
|
161
|
+
fontDict = fontRaw;
|
|
172
162
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
163
|
+
if (!fontDict)
|
|
164
|
+
return null;
|
|
165
|
+
const fontEntry = fontDict.get(fontName);
|
|
166
|
+
if (!fontEntry)
|
|
167
|
+
return null;
|
|
168
|
+
let fontObj;
|
|
169
|
+
if (fontEntry instanceof PdfObjectReference) {
|
|
170
|
+
const resolved = fontEntry.resolve();
|
|
171
|
+
if (resolved?.content instanceof PdfDictionary) {
|
|
172
|
+
fontObj = resolved.content;
|
|
177
173
|
}
|
|
178
174
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
await acroForm.cacheAllFontEncodings();
|
|
182
|
-
// Reset field-level modified flag so only explicitly changed fields are detected
|
|
183
|
-
for (const field of acroForm.fields) {
|
|
184
|
-
field.setModified(false);
|
|
175
|
+
else if (fontEntry instanceof PdfDictionary) {
|
|
176
|
+
fontObj = fontEntry;
|
|
185
177
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
async updatePageAnnotations(document, fieldsByPage) {
|
|
192
|
-
await PdfAnnotationWriter.updatePageAnnotations(document, fieldsByPage);
|
|
193
|
-
}
|
|
194
|
-
async getXfa(document) {
|
|
195
|
-
if (this._xfa) {
|
|
196
|
-
return this._xfa;
|
|
178
|
+
if (!fontObj)
|
|
179
|
+
return null;
|
|
180
|
+
let encObj = fontObj.get('Encoding');
|
|
181
|
+
if (encObj instanceof PdfObjectReference) {
|
|
182
|
+
encObj = encObj.resolve()?.content;
|
|
197
183
|
}
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
184
|
+
const encDict = encObj instanceof PdfDictionary ? encObj : undefined;
|
|
185
|
+
const diffs = encDict?.get('Differences')?.as(PdfArray);
|
|
186
|
+
if (!diffs)
|
|
187
|
+
return null;
|
|
188
|
+
const map = buildEncodingMap(diffs);
|
|
189
|
+
if (map) {
|
|
190
|
+
this.fontEncodingMaps.set(fontName, map);
|
|
201
191
|
}
|
|
202
|
-
|
|
203
|
-
return this._xfa;
|
|
192
|
+
return map;
|
|
204
193
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
if (!
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const isIncremental = document.isIncremental();
|
|
212
|
-
document.setIncremental(true);
|
|
213
|
-
const xfaForm = this._xfa !== undefined
|
|
214
|
-
? this._xfa
|
|
215
|
-
: await PdfXfaForm.fromDocument(document);
|
|
216
|
-
if (xfaForm) {
|
|
217
|
-
// Only send fields whose value was explicitly changed (field.isModified())
|
|
218
|
-
const xfaFields = this.fields
|
|
219
|
-
.filter((f) => f.isModified() && f.fieldType !== 'Signature' && f.name)
|
|
220
|
-
.map((f) => ({ name: f.name, value: f.value }));
|
|
221
|
-
if (xfaFields.length > 0) {
|
|
222
|
-
xfaForm.datasets?.updateFields(xfaFields);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
const fieldsArray = new PdfArray();
|
|
226
|
-
this.content.set('Fields', fieldsArray);
|
|
227
|
-
const fieldsByPage = new Map();
|
|
228
|
-
// Phase 1: add appearance streams standalone (PdfStream — cannot go in ObjStm)
|
|
229
|
-
// and collect field dicts for ObjStm batching.
|
|
230
|
-
const compressibleFields = [];
|
|
231
|
-
for (const field of this.fields) {
|
|
232
|
-
if (field.content.isModified()) {
|
|
233
|
-
const appearances = field.getAppearanceStreamsForWriting();
|
|
234
|
-
if (appearances) {
|
|
235
|
-
document.add(appearances.primary);
|
|
236
|
-
if (appearances.secondary) {
|
|
237
|
-
document.add(appearances.secondary);
|
|
238
|
-
}
|
|
239
|
-
field.setAppearanceReference(appearances.primary.reference, appearances.secondary?.reference);
|
|
240
|
-
if (!field.print) {
|
|
241
|
-
field.print = true;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
compressibleFields.push(field);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
// Phase 2: pack field dicts into ObjStm — pre-assigns their object numbers.
|
|
248
|
-
document.addObjectsAsStream(compressibleFields);
|
|
249
|
-
// Phase 3: build fieldsArray now that field object numbers are stable.
|
|
250
|
-
for (const field of this.fields) {
|
|
251
|
-
let fieldReference;
|
|
252
|
-
if (field.content.isModified()) {
|
|
253
|
-
fieldReference = new PdfObjectReference(field.objectNumber, field.generationNumber);
|
|
254
|
-
const parentRef = field.parentRef;
|
|
255
|
-
const isWidget = field.isWidget;
|
|
256
|
-
if (parentRef && isWidget) {
|
|
257
|
-
const pageKey = `${parentRef.objectNumber}_${parentRef.generationNumber}`;
|
|
258
|
-
if (!fieldsByPage.has(pageKey)) {
|
|
259
|
-
fieldsByPage.set(pageKey, {
|
|
260
|
-
pageRef: parentRef,
|
|
261
|
-
fieldRefs: [],
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
fieldsByPage.get(pageKey).fieldRefs.push(fieldReference);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
else {
|
|
268
|
-
fieldReference = field.reference;
|
|
269
|
-
}
|
|
270
|
-
fieldsArray.push(fieldReference);
|
|
271
|
-
}
|
|
272
|
-
await this.updatePageAnnotations(document, fieldsByPage);
|
|
273
|
-
// Phase 4: pack AcroForm dict into ObjStm AFTER fieldsArray is populated,
|
|
274
|
-
// so the dict is serialized with the correct Fields array.
|
|
275
|
-
if (this.isModified()) {
|
|
276
|
-
document.addObjectsAsStream([this]);
|
|
277
|
-
if (!catalog.content.has('AcroForm')) {
|
|
278
|
-
let updatableCatalog = catalog;
|
|
279
|
-
if (catalog.isImmutable()) {
|
|
280
|
-
updatableCatalog = catalog.clone();
|
|
281
|
-
document.add(updatableCatalog);
|
|
282
|
-
}
|
|
283
|
-
updatableCatalog.content.set('AcroForm', this.reference);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
// XFA datasets stream — PdfXfaData extends PdfIndirectObject<PdfStream>, must stay standalone
|
|
287
|
-
if (xfaForm?.datasets?.isModified()) {
|
|
288
|
-
document.add(xfaForm.datasets);
|
|
194
|
+
get xfa() {
|
|
195
|
+
const xfaEntry = this.content.get('XFA');
|
|
196
|
+
if (!xfaEntry)
|
|
197
|
+
return null;
|
|
198
|
+
if (!(xfaEntry instanceof PdfArray)) {
|
|
199
|
+
return null;
|
|
289
200
|
}
|
|
290
|
-
|
|
291
|
-
document.setIncremental(isIncremental);
|
|
201
|
+
return new PdfXfaForm(xfaEntry);
|
|
292
202
|
}
|
|
293
203
|
}
|
|
@@ -9,12 +9,13 @@ export interface XfaFieldData {
|
|
|
9
9
|
* Provides methods to read/write XML and update individual field values.
|
|
10
10
|
*/
|
|
11
11
|
export declare class PdfXfaData extends PdfIndirectObject<PdfStream> {
|
|
12
|
-
constructor(stream: PdfIndirectObject
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
constructor(stream: PdfIndirectObject);
|
|
13
|
+
get xml(): string;
|
|
14
|
+
set xml(xml: string);
|
|
15
15
|
updateField(name: string, value: string): void;
|
|
16
16
|
updateFields(fields: XfaFieldData[]): void;
|
|
17
17
|
getFieldValue(name: string): string | null;
|
|
18
|
+
importData(fields: Record<string, string | undefined>): void;
|
|
18
19
|
private static updateFieldValue;
|
|
19
20
|
private static escapeRegex;
|
|
20
21
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { PdfIndirectObject } from '../../core/objects/pdf-indirect-object.js';
|
|
2
|
-
import { PdfStream } from '../../core/objects/pdf-stream.js';
|
|
3
2
|
/**
|
|
4
3
|
* Wraps an XFA datasets stream as a typed PDF indirect object.
|
|
5
4
|
* Provides methods to read/write XML and update individual field values.
|
|
@@ -8,29 +7,26 @@ export class PdfXfaData extends PdfIndirectObject {
|
|
|
8
7
|
constructor(stream) {
|
|
9
8
|
super(stream);
|
|
10
9
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return new TextDecoder().decode(decompressed);
|
|
10
|
+
get xml() {
|
|
11
|
+
return this.content.dataAsString;
|
|
14
12
|
}
|
|
15
|
-
|
|
16
|
-
this.content =
|
|
13
|
+
set xml(xml) {
|
|
14
|
+
this.content.dataAsString = xml;
|
|
17
15
|
}
|
|
18
16
|
updateField(name, value) {
|
|
19
|
-
|
|
20
|
-
xml = PdfXfaData.updateFieldValue(xml, name, value);
|
|
21
|
-
this.writeXml(xml);
|
|
17
|
+
this.xml = PdfXfaData.updateFieldValue(this.xml, name, value);
|
|
22
18
|
}
|
|
23
19
|
updateFields(fields) {
|
|
24
20
|
if (fields.length === 0)
|
|
25
21
|
return;
|
|
26
|
-
let xml = this.
|
|
22
|
+
let xml = this.xml;
|
|
27
23
|
for (const { name, value } of fields) {
|
|
28
24
|
xml = PdfXfaData.updateFieldValue(xml, name, value);
|
|
29
25
|
}
|
|
30
|
-
this.
|
|
26
|
+
this.xml = xml;
|
|
31
27
|
}
|
|
32
28
|
getFieldValue(name) {
|
|
33
|
-
const xml = this.
|
|
29
|
+
const xml = this.xml;
|
|
34
30
|
const segments = name.split('.');
|
|
35
31
|
const leafSegment = segments[segments.length - 1];
|
|
36
32
|
const leafName = leafSegment.replace(/\[\d+\]$/, '');
|
|
@@ -40,6 +36,14 @@ export class PdfXfaData extends PdfIndirectObject {
|
|
|
40
36
|
const match = xml.match(contentRegex);
|
|
41
37
|
return match ? match[1] : null;
|
|
42
38
|
}
|
|
39
|
+
importData(fields) {
|
|
40
|
+
for (const field in fields) {
|
|
41
|
+
const value = fields[field];
|
|
42
|
+
if (value === undefined)
|
|
43
|
+
continue;
|
|
44
|
+
this.updateField(field, value);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
43
47
|
static updateFieldValue(xml, fieldName, value) {
|
|
44
48
|
const segments = fieldName.split('.');
|
|
45
49
|
const leafSegment = segments[segments.length - 1];
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
import { PdfDocument } from '../../pdf/pdf-document.js';
|
|
2
1
|
import { PdfArray } from '../../core/objects/pdf-array.js';
|
|
2
|
+
import { PdfObjectReference } from '../../core/objects/pdf-object-reference.js';
|
|
3
|
+
import { PdfIndirectObject } from '../../core/objects/pdf-indirect-object.js';
|
|
3
4
|
import { PdfXfaData } from './pdf-xfa-data.js';
|
|
4
5
|
/**
|
|
5
6
|
* Typed wrapper around the XFA name/stream-ref array.
|
|
6
7
|
* Holds eagerly-loaded references to component streams like datasets.
|
|
7
8
|
*/
|
|
8
|
-
export declare class PdfXfaForm
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
export declare class PdfXfaForm {
|
|
10
|
+
private xfaEntry?;
|
|
11
|
+
constructor(xfaEntry?: PdfArray<PdfObjectReference>);
|
|
12
|
+
get components(): {
|
|
13
|
+
[type: string]: PdfIndirectObject;
|
|
14
|
+
};
|
|
15
|
+
get datasets(): PdfXfaData | null;
|
|
11
16
|
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { PdfArray } from '../../core/objects/pdf-array.js';
|
|
2
|
-
import { PdfDictionary } from '../../core/objects/pdf-dictionary.js';
|
|
3
1
|
import { PdfString } from '../../core/objects/pdf-string.js';
|
|
4
2
|
import { PdfObjectReference } from '../../core/objects/pdf-object-reference.js';
|
|
5
3
|
import { PdfIndirectObject } from '../../core/objects/pdf-indirect-object.js';
|
|
@@ -8,49 +6,29 @@ import { PdfXfaData } from './pdf-xfa-data.js';
|
|
|
8
6
|
* Typed wrapper around the XFA name/stream-ref array.
|
|
9
7
|
* Holds eagerly-loaded references to component streams like datasets.
|
|
10
8
|
*/
|
|
11
|
-
export class PdfXfaForm
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if (acroFormRef instanceof PdfObjectReference) {
|
|
20
|
-
const acroFormObject = await document.readObject(acroFormRef);
|
|
21
|
-
if (!acroFormObject)
|
|
22
|
-
return null;
|
|
23
|
-
acroFormDict = acroFormObject.content.as(PdfDictionary);
|
|
24
|
-
}
|
|
25
|
-
else if (acroFormRef instanceof PdfDictionary) {
|
|
26
|
-
acroFormDict = acroFormRef;
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
const xfaArray = acroFormDict.get('XFA');
|
|
32
|
-
if (!(xfaArray instanceof PdfArray))
|
|
33
|
-
return null;
|
|
34
|
-
const form = new PdfXfaForm(xfaArray.items.slice());
|
|
35
|
-
// Find the datasets reference in the name/ref pairs
|
|
36
|
-
const items = xfaArray.items;
|
|
9
|
+
export class PdfXfaForm {
|
|
10
|
+
xfaEntry;
|
|
11
|
+
constructor(xfaEntry) {
|
|
12
|
+
this.xfaEntry = xfaEntry;
|
|
13
|
+
}
|
|
14
|
+
get components() {
|
|
15
|
+
const result = {};
|
|
16
|
+
const items = this.xfaEntry?.items ?? [];
|
|
37
17
|
for (let i = 0; i < items.length - 1; i += 2) {
|
|
38
18
|
const name = items[i];
|
|
39
19
|
const ref = items[i + 1];
|
|
40
20
|
if (name instanceof PdfString &&
|
|
41
|
-
name.value === 'datasets' &&
|
|
42
21
|
ref instanceof PdfObjectReference) {
|
|
43
|
-
|
|
44
|
-
objectNumber: ref.objectNumber,
|
|
45
|
-
generationNumber: ref.generationNumber,
|
|
46
|
-
allowUnindexed: true,
|
|
47
|
-
}))?.as((PdfIndirectObject));
|
|
48
|
-
if (datasetObject) {
|
|
49
|
-
form.datasets = new PdfXfaData(datasetObject);
|
|
50
|
-
}
|
|
51
|
-
break;
|
|
22
|
+
result[name.value] = ref.resolve().as(PdfIndirectObject);
|
|
52
23
|
}
|
|
53
24
|
}
|
|
54
|
-
return
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
get datasets() {
|
|
28
|
+
const datasetsRef = this.components['datasets'];
|
|
29
|
+
if (!datasetsRef) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
return datasetsRef.becomes(PdfXfaData);
|
|
55
33
|
}
|
|
56
34
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export { PdfAnnotation, type PdfAppearanceStreamDictionary, } from './pdf-annotation.js';
|
|
2
2
|
export { PdfAnnotationFlags } from './pdf-annotation-flags.js';
|
|
3
3
|
export { PdfWidgetAnnotation } from './pdf-widget-annotation.js';
|
|
4
|
-
export { PdfAnnotationWriter } from './pdf-annotation-writer.js';
|
|
@@ -5,6 +5,7 @@ import { PdfArray } from '../core/objects/pdf-array.js';
|
|
|
5
5
|
import { PdfNumber } from '../core/objects/pdf-number.js';
|
|
6
6
|
import { PdfName } from '../core/objects/pdf-name.js';
|
|
7
7
|
import { PdfString } from '../core/objects/pdf-string.js';
|
|
8
|
+
import { PdfPage } from '../pdf/pdf-page.js';
|
|
8
9
|
export type PdfAppearanceStreamDictionary = PdfDictionary<{
|
|
9
10
|
N: PdfObjectReference | PdfDictionary;
|
|
10
11
|
R?: PdfObjectReference | PdfDictionary;
|
|
@@ -23,7 +24,8 @@ export declare class PdfAnnotation extends PdfIndirectObject<PdfDictionary<{
|
|
|
23
24
|
DV: PdfString | PdfName;
|
|
24
25
|
V: PdfString | PdfName;
|
|
25
26
|
DA: PdfString;
|
|
26
|
-
|
|
27
|
+
DR: PdfDictionary | PdfObjectReference;
|
|
28
|
+
Opt: PdfArray<PdfString | PdfArray<PdfString>> | PdfObjectReference;
|
|
27
29
|
MaxLen: PdfNumber;
|
|
28
30
|
Q: PdfNumber;
|
|
29
31
|
Kids: PdfArray<PdfObjectReference>;
|
|
@@ -31,8 +33,10 @@ export declare class PdfAnnotation extends PdfIndirectObject<PdfDictionary<{
|
|
|
31
33
|
F: PdfNumber;
|
|
32
34
|
AP?: PdfAppearanceStreamDictionary;
|
|
33
35
|
P?: PdfObjectReference;
|
|
36
|
+
Parent?: PdfObjectReference<PdfPage>;
|
|
34
37
|
}>> {
|
|
35
|
-
private _annotationFlags
|
|
38
|
+
private _annotationFlags?;
|
|
39
|
+
private get flags_();
|
|
36
40
|
constructor(options?: {
|
|
37
41
|
other?: PdfIndirectObject;
|
|
38
42
|
});
|
|
@@ -58,4 +62,5 @@ export declare class PdfAnnotation extends PdfIndirectObject<PdfDictionary<{
|
|
|
58
62
|
set appearanceStreamDict(dict: PdfAppearanceStreamDictionary | null);
|
|
59
63
|
get parentRef(): PdfObjectReference | null;
|
|
60
64
|
set parentRef(ref: PdfObjectReference | null);
|
|
65
|
+
get page(): PdfPage | null;
|
|
61
66
|
}
|