pdf-oxide 0.3.24
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 +218 -0
- package/binding.gyp +35 -0
- package/package.json +78 -0
- package/src/builders/annotation-builder.ts +367 -0
- package/src/builders/conversion-options-builder.ts +257 -0
- package/src/builders/index.ts +12 -0
- package/src/builders/metadata-builder.ts +317 -0
- package/src/builders/pdf-builder.ts +386 -0
- package/src/builders/search-options-builder.ts +151 -0
- package/src/document-editor-manager.ts +318 -0
- package/src/errors.ts +1629 -0
- package/src/form-field-manager.ts +666 -0
- package/src/hybrid-ml-manager.ts +283 -0
- package/src/index.ts +453 -0
- package/src/managers/accessibility-manager.ts +338 -0
- package/src/managers/annotation-manager.ts +439 -0
- package/src/managers/barcode-manager.ts +235 -0
- package/src/managers/batch-manager.ts +533 -0
- package/src/managers/cache-manager.ts +486 -0
- package/src/managers/compliance-manager.ts +375 -0
- package/src/managers/content-manager.ts +339 -0
- package/src/managers/document-utility-manager.ts +922 -0
- package/src/managers/dom-pdf-creator.ts +365 -0
- package/src/managers/editing-manager.ts +514 -0
- package/src/managers/enterprise-manager.ts +478 -0
- package/src/managers/extended-managers.ts +437 -0
- package/src/managers/extraction-manager.ts +583 -0
- package/src/managers/final-utilities.ts +429 -0
- package/src/managers/hybrid-ml-advanced.ts +479 -0
- package/src/managers/index.ts +239 -0
- package/src/managers/layer-manager.ts +500 -0
- package/src/managers/metadata-manager.ts +303 -0
- package/src/managers/ocr-manager.ts +756 -0
- package/src/managers/optimization-manager.ts +262 -0
- package/src/managers/outline-manager.ts +196 -0
- package/src/managers/page-manager.ts +289 -0
- package/src/managers/pattern-detection.ts +440 -0
- package/src/managers/rendering-manager.ts +863 -0
- package/src/managers/search-manager.ts +385 -0
- package/src/managers/security-manager.ts +345 -0
- package/src/managers/signature-manager.ts +1664 -0
- package/src/managers/streams.ts +618 -0
- package/src/managers/xfa-manager.ts +500 -0
- package/src/pdf-creator-manager.ts +494 -0
- package/src/properties.ts +522 -0
- package/src/result-accessors-manager.ts +867 -0
- package/src/tests/advanced-features.test.ts +414 -0
- package/src/tests/advanced.test.ts +266 -0
- package/src/tests/extended-managers.test.ts +316 -0
- package/src/tests/final-utilities.test.ts +455 -0
- package/src/tests/foundation.test.ts +315 -0
- package/src/tests/high-demand.test.ts +257 -0
- package/src/tests/specialized.test.ts +97 -0
- package/src/thumbnail-manager.ts +272 -0
- package/src/types/common.ts +142 -0
- package/src/types/document-types.ts +457 -0
- package/src/types/index.ts +6 -0
- package/src/types/manager-types.ts +284 -0
- package/src/types/native-bindings.ts +517 -0
- package/src/workers/index.ts +7 -0
- package/src/workers/pool.ts +274 -0
- package/src/workers/worker.ts +131 -0
|
@@ -0,0 +1,666 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FormFieldManager for form field operations
|
|
3
|
+
*
|
|
4
|
+
* Manages form fields in PDF documents including retrieval, modification, and flattening.
|
|
5
|
+
* API is consistent with Python, Java, C#, Go, and Swift implementations.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { EventEmitter } from 'events';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Types of form fields
|
|
12
|
+
*/
|
|
13
|
+
export enum FormFieldType {
|
|
14
|
+
Text = 'Text',
|
|
15
|
+
CheckBox = 'CheckBox',
|
|
16
|
+
RadioButton = 'RadioButton',
|
|
17
|
+
ComboBox = 'ComboBox',
|
|
18
|
+
ListBox = 'ListBox',
|
|
19
|
+
Button = 'Button',
|
|
20
|
+
Signature = 'Signature',
|
|
21
|
+
TextArea = 'TextArea',
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Field visibility options
|
|
26
|
+
*/
|
|
27
|
+
export enum FieldVisibility {
|
|
28
|
+
Visible = 'Visible',
|
|
29
|
+
Hidden = 'Hidden',
|
|
30
|
+
PrintOnly = 'PrintOnly',
|
|
31
|
+
NoView = 'NoView',
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Form field information
|
|
36
|
+
*/
|
|
37
|
+
export interface FormField {
|
|
38
|
+
fieldName: string;
|
|
39
|
+
fieldType: FormFieldType;
|
|
40
|
+
pageIndex?: number;
|
|
41
|
+
isRequired: boolean;
|
|
42
|
+
isReadOnly: boolean;
|
|
43
|
+
visibility: FieldVisibility;
|
|
44
|
+
defaultValue?: string;
|
|
45
|
+
currentValue?: string;
|
|
46
|
+
toolTip?: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Configuration for form field creation
|
|
51
|
+
*/
|
|
52
|
+
export interface FormFieldConfig {
|
|
53
|
+
fieldName: string;
|
|
54
|
+
fieldType?: FormFieldType;
|
|
55
|
+
pageIndex?: number;
|
|
56
|
+
x?: number;
|
|
57
|
+
y?: number;
|
|
58
|
+
width?: number;
|
|
59
|
+
height?: number;
|
|
60
|
+
isRequired?: boolean;
|
|
61
|
+
defaultValue?: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Form Field Manager for form operations
|
|
66
|
+
*
|
|
67
|
+
* Provides methods to:
|
|
68
|
+
* - Retrieve form field information
|
|
69
|
+
* - Get and set field values
|
|
70
|
+
* - Create new form fields
|
|
71
|
+
* - Manage field properties
|
|
72
|
+
* - Flatten forms
|
|
73
|
+
*/
|
|
74
|
+
export class FormFieldManager extends EventEmitter {
|
|
75
|
+
private document: any;
|
|
76
|
+
private resultCache = new Map<string, any>();
|
|
77
|
+
private maxCacheSize = 100;
|
|
78
|
+
|
|
79
|
+
constructor(document: any) {
|
|
80
|
+
super();
|
|
81
|
+
this.document = document;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Gets all form fields in the document
|
|
86
|
+
* Matches: Python getAllFields(), Java getAllFields(), C# GetAllFields()
|
|
87
|
+
*/
|
|
88
|
+
async getAllFields(): Promise<FormField[]> {
|
|
89
|
+
const cacheKey = 'formfields:all';
|
|
90
|
+
if (this.resultCache.has(cacheKey)) {
|
|
91
|
+
return this.resultCache.get(cacheKey);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Call native PdfDocument method
|
|
95
|
+
try {
|
|
96
|
+
const fields = (this.document.getFormFields?.() as any[]) ?? [];
|
|
97
|
+
this.setCached(cacheKey, fields);
|
|
98
|
+
this.emit('fieldsRetrieved', fields.length);
|
|
99
|
+
return fields;
|
|
100
|
+
} catch (err) {
|
|
101
|
+
this.emit('error', err);
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Gets a specific form field by name
|
|
108
|
+
* Matches: Python getField(), Java getField(), C# GetField()
|
|
109
|
+
*/
|
|
110
|
+
async getField(fieldName: string): Promise<FormField | undefined> {
|
|
111
|
+
const allFields = await this.getAllFields();
|
|
112
|
+
return allFields.find((f) => f.fieldName === fieldName);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Gets fields of a specific type
|
|
117
|
+
* Matches: Python getFieldsOfType(), Java getFieldsOfType(), C# GetFieldsOfType()
|
|
118
|
+
*/
|
|
119
|
+
async getFieldsOfType(fieldType: FormFieldType): Promise<FormField[]> {
|
|
120
|
+
const allFields = await this.getAllFields();
|
|
121
|
+
return allFields.filter((f) => f.fieldType === fieldType);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Gets the value of a form field
|
|
126
|
+
* Matches: Python getFieldValue(), Java getFieldValue(), C# GetFieldValue()
|
|
127
|
+
*/
|
|
128
|
+
async getFieldValue(fieldName: string): Promise<string | undefined> {
|
|
129
|
+
const cacheKey = `formfields:value:${fieldName}`;
|
|
130
|
+
if (this.resultCache.has(cacheKey)) {
|
|
131
|
+
return this.resultCache.get(cacheKey);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Call native PdfDocument method
|
|
135
|
+
try {
|
|
136
|
+
const value = this.document.getFieldValue?.(fieldName);
|
|
137
|
+
this.setCached(cacheKey, value);
|
|
138
|
+
return value || undefined;
|
|
139
|
+
} catch (err) {
|
|
140
|
+
this.emit('error', err);
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Sets the value of a form field
|
|
147
|
+
* Matches: Python setFieldValue(), Java setFieldValue(), C# SetFieldValue()
|
|
148
|
+
*/
|
|
149
|
+
async setFieldValue(fieldName: string, value: string): Promise<void> {
|
|
150
|
+
// Call native PdfDocument method
|
|
151
|
+
try {
|
|
152
|
+
this.document.setFieldValue?.(fieldName, value);
|
|
153
|
+
this.clearCachePattern(`formfields:value:${fieldName}`);
|
|
154
|
+
this.emit('fieldValueChanged', fieldName, value);
|
|
155
|
+
} catch (err) {
|
|
156
|
+
this.emit('error', err);
|
|
157
|
+
throw err;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Gets field count
|
|
163
|
+
* Matches: Python getFieldCount(), Java getFieldCount(), C# GetFieldCount()
|
|
164
|
+
*/
|
|
165
|
+
async getFieldCount(): Promise<number> {
|
|
166
|
+
const cacheKey = 'formfields:count';
|
|
167
|
+
if (this.resultCache.has(cacheKey)) {
|
|
168
|
+
return this.resultCache.get(cacheKey);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Call native PdfDocument method via getAllFields
|
|
172
|
+
try {
|
|
173
|
+
const fields = await this.getAllFields();
|
|
174
|
+
const count = fields.length;
|
|
175
|
+
this.setCached(cacheKey, count);
|
|
176
|
+
return count;
|
|
177
|
+
} catch (err) {
|
|
178
|
+
this.emit('error', err);
|
|
179
|
+
return 0;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Checks if form has fields
|
|
185
|
+
* Matches: Python hasForm(), Java hasForm(), C# HasForm()
|
|
186
|
+
*/
|
|
187
|
+
async hasForm(): Promise<boolean> {
|
|
188
|
+
const count = await this.getFieldCount();
|
|
189
|
+
return count > 0;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Creates a new form field
|
|
194
|
+
* Matches: Python createField(), Java createField(), C# CreateField()
|
|
195
|
+
*/
|
|
196
|
+
async createField(config: FormFieldConfig): Promise<void> {
|
|
197
|
+
// In real implementation, would call native FFI
|
|
198
|
+
this.clearCachePattern('formfields:.*');
|
|
199
|
+
this.emit('fieldCreated', config.fieldName);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Removes a form field
|
|
204
|
+
* Matches: Python removeField(), Java removeField(), C# RemoveField()
|
|
205
|
+
*/
|
|
206
|
+
async removeField(fieldName: string): Promise<void> {
|
|
207
|
+
// In real implementation, would call native FFI
|
|
208
|
+
this.clearCachePattern('formfields:.*');
|
|
209
|
+
this.emit('fieldRemoved', fieldName);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Flattens form fields (convert to content)
|
|
214
|
+
* Matches: Python flattenForm(), Java flattenForm(), C# FlattenForm()
|
|
215
|
+
*/
|
|
216
|
+
async flattenForm(): Promise<void> {
|
|
217
|
+
// In real implementation, would call native FFI
|
|
218
|
+
this.clearCachePattern('formfields:.*');
|
|
219
|
+
this.emit('formFlattened');
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Resets all form fields to defaults
|
|
224
|
+
* Matches: Python resetForm(), Java resetForm(), C# ResetForm()
|
|
225
|
+
*/
|
|
226
|
+
async resetForm(): Promise<void> {
|
|
227
|
+
// In real implementation, would call native FFI
|
|
228
|
+
this.clearCachePattern('formfields:.*');
|
|
229
|
+
this.emit('formReset');
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Clears the result cache
|
|
234
|
+
* Matches: Python clearCache(), Java clearCache(), C# ClearCache()
|
|
235
|
+
*/
|
|
236
|
+
clearCache(): void {
|
|
237
|
+
this.resultCache.clear();
|
|
238
|
+
this.emit('cacheCleared');
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Gets cache statistics
|
|
243
|
+
* Matches: Python getCacheStats(), Java getCacheStats(), C# GetCacheStats()
|
|
244
|
+
*/
|
|
245
|
+
getCacheStats(): Record<string, any> {
|
|
246
|
+
return {
|
|
247
|
+
cacheSize: this.resultCache.size,
|
|
248
|
+
maxCacheSize: this.maxCacheSize,
|
|
249
|
+
entries: Array.from(this.resultCache.keys()),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// ========== New FFI-based Form Operations (22 new methods) ==========
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Gets the AcroForm handle from the document
|
|
257
|
+
* Provides access to lower-level form operations
|
|
258
|
+
* @returns AcroForm handle
|
|
259
|
+
*/
|
|
260
|
+
async getFormAcroform(): Promise<any> {
|
|
261
|
+
const cacheKey = 'form:acroform';
|
|
262
|
+
if (this.resultCache.has(cacheKey)) {
|
|
263
|
+
return this.resultCache.get(cacheKey);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// In real implementation, would call native FFI
|
|
267
|
+
// FormFieldFFI.documentGetAcroform(docHandle)
|
|
268
|
+
const acroformHandle = null;
|
|
269
|
+
this.setCached(cacheKey, acroformHandle);
|
|
270
|
+
return acroformHandle;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Exports form data to a file
|
|
275
|
+
* Supports FDF (0), XFDF (1), and JSON (2) formats
|
|
276
|
+
* @param filename Path to output file
|
|
277
|
+
* @param format Format type (0=FDF, 1=XFDF, 2=JSON)
|
|
278
|
+
* @returns Number of fields exported
|
|
279
|
+
*/
|
|
280
|
+
async exportFormData(filename: string, format: number = 0): Promise<number> {
|
|
281
|
+
// In real implementation, would call native FFI
|
|
282
|
+
// FormFieldFFI.formFieldExportFormData(acroformHandle, filename, format)
|
|
283
|
+
this.clearCachePattern('form:.*');
|
|
284
|
+
this.emit('formDataExported', filename, format);
|
|
285
|
+
return 0;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Exports form data to bytes in memory
|
|
290
|
+
* Supports FDF (0), XFDF (1), and JSON (2) formats
|
|
291
|
+
* @param format Format type (0=FDF, 1=XFDF, 2=JSON)
|
|
292
|
+
* @returns Form data as byte array
|
|
293
|
+
*/
|
|
294
|
+
async exportFormDataBytes(format: number = 0): Promise<Uint8Array> {
|
|
295
|
+
// In real implementation, would call native FFI
|
|
296
|
+
// FormFieldFFI.formFieldExportFormDataBytes(acroformHandle, format)
|
|
297
|
+
this.emit('formDataExportedToBytes', format);
|
|
298
|
+
return new Uint8Array();
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Imports form data from a file
|
|
303
|
+
* Supports FDF, XFDF, and JSON formats (auto-detected)
|
|
304
|
+
* @param filename Path to form data file
|
|
305
|
+
* @returns Number of fields updated
|
|
306
|
+
*/
|
|
307
|
+
async importFormData(filename: string): Promise<number> {
|
|
308
|
+
// In real implementation, would call native FFI
|
|
309
|
+
// FormFieldFFI.formFieldImportFormData(acroformHandle, filename)
|
|
310
|
+
this.clearCachePattern('form:.*');
|
|
311
|
+
this.emit('formDataImported', filename);
|
|
312
|
+
return 0;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Resets all form fields to their default values
|
|
317
|
+
* @returns Number of fields reset
|
|
318
|
+
*/
|
|
319
|
+
async resetAllFields(): Promise<number> {
|
|
320
|
+
// In real implementation, would call native FFI
|
|
321
|
+
// FormFieldFFI.documentResetFormFields(docHandle)
|
|
322
|
+
this.clearCachePattern('form:.*');
|
|
323
|
+
this.emit('allFieldsReset');
|
|
324
|
+
return 0;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Gets the default value of a form field
|
|
329
|
+
* @param fieldName Name of the field
|
|
330
|
+
* @returns Default value or empty string
|
|
331
|
+
*/
|
|
332
|
+
async getFieldDefaultValue(fieldName: string): Promise<string> {
|
|
333
|
+
const cacheKey = `form:defaultvalue:${fieldName}`;
|
|
334
|
+
if (this.resultCache.has(cacheKey)) {
|
|
335
|
+
return this.resultCache.get(cacheKey);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// In real implementation, would call native FFI
|
|
339
|
+
// FormFieldFFI.formFieldGetDefaultValue(fieldHandle)
|
|
340
|
+
const value = '';
|
|
341
|
+
this.setCached(cacheKey, value);
|
|
342
|
+
return value;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Sets the default value of a form field
|
|
347
|
+
* @param fieldName Name of the field
|
|
348
|
+
* @param value New default value
|
|
349
|
+
*/
|
|
350
|
+
async setFieldDefaultValue(fieldName: string, value: string): Promise<void> {
|
|
351
|
+
// In real implementation, would call native FFI
|
|
352
|
+
// FormFieldFFI.formFieldSetDefaultValue(fieldHandle, value)
|
|
353
|
+
this.clearCachePattern(`form:defaultvalue:${fieldName}`);
|
|
354
|
+
this.emit('fieldDefaultValueChanged', fieldName, value);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Gets the flags of a form field (combination of bit flags)
|
|
359
|
+
* @param fieldName Name of the field
|
|
360
|
+
* @returns Field flags as integer
|
|
361
|
+
*/
|
|
362
|
+
async getFieldFlags(fieldName: string): Promise<number> {
|
|
363
|
+
const cacheKey = `form:flags:${fieldName}`;
|
|
364
|
+
if (this.resultCache.has(cacheKey)) {
|
|
365
|
+
return this.resultCache.get(cacheKey);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// In real implementation, would call native FFI
|
|
369
|
+
// FormFieldFFI.formFieldGetFlags(fieldHandle)
|
|
370
|
+
const flags = 0;
|
|
371
|
+
this.setCached(cacheKey, flags);
|
|
372
|
+
return flags;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Sets the flags of a form field
|
|
377
|
+
* Flags control field properties like readonly, required, etc.
|
|
378
|
+
* @param fieldName Name of the field
|
|
379
|
+
* @param flags New flags value
|
|
380
|
+
*/
|
|
381
|
+
async setFieldFlags(fieldName: string, flags: number): Promise<void> {
|
|
382
|
+
// In real implementation, would call native FFI
|
|
383
|
+
// FormFieldFFI.formFieldSetFlags(fieldHandle, flags)
|
|
384
|
+
this.clearCachePattern(`form:flags:${fieldName}`);
|
|
385
|
+
this.emit('fieldFlagsChanged', fieldName, flags);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Gets the tooltip text for a form field
|
|
390
|
+
* @param fieldName Name of the field
|
|
391
|
+
* @returns Tooltip text or empty string
|
|
392
|
+
*/
|
|
393
|
+
async getFieldTooltip(fieldName: string): Promise<string> {
|
|
394
|
+
const cacheKey = `form:tooltip:${fieldName}`;
|
|
395
|
+
if (this.resultCache.has(cacheKey)) {
|
|
396
|
+
return this.resultCache.get(cacheKey);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// In real implementation, would call native FFI
|
|
400
|
+
// FormFieldFFI.formFieldGetTooltip(fieldHandle)
|
|
401
|
+
const tooltip = '';
|
|
402
|
+
this.setCached(cacheKey, tooltip);
|
|
403
|
+
return tooltip;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Sets the tooltip text for a form field
|
|
408
|
+
* @param fieldName Name of the field
|
|
409
|
+
* @param tooltip New tooltip text
|
|
410
|
+
*/
|
|
411
|
+
async setFieldTooltip(fieldName: string, tooltip: string): Promise<void> {
|
|
412
|
+
// In real implementation, would call native FFI
|
|
413
|
+
// FormFieldFFI.formFieldSetTooltip(fieldHandle, tooltip)
|
|
414
|
+
this.clearCachePattern(`form:tooltip:${fieldName}`);
|
|
415
|
+
this.emit('fieldTooltipChanged', fieldName, tooltip);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Gets the alternate name (UI name) for a form field
|
|
420
|
+
* @param fieldName Name of the field
|
|
421
|
+
* @returns Alternate name or empty string
|
|
422
|
+
*/
|
|
423
|
+
async getFieldAlternateName(fieldName: string): Promise<string> {
|
|
424
|
+
const cacheKey = `form:altname:${fieldName}`;
|
|
425
|
+
if (this.resultCache.has(cacheKey)) {
|
|
426
|
+
return this.resultCache.get(cacheKey);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// In real implementation, would call native FFI
|
|
430
|
+
// FormFieldFFI.formFieldGetAlternateName(fieldHandle)
|
|
431
|
+
const name = '';
|
|
432
|
+
this.setCached(cacheKey, name);
|
|
433
|
+
return name;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Sets the alternate name (UI name) for a form field
|
|
438
|
+
* @param fieldName Name of the field
|
|
439
|
+
* @param alternateName New alternate name
|
|
440
|
+
*/
|
|
441
|
+
async setFieldAlternateName(fieldName: string, alternateName: string): Promise<void> {
|
|
442
|
+
// In real implementation, would call native FFI
|
|
443
|
+
// FormFieldFFI.formFieldSetAlternateName(fieldHandle, alternateName)
|
|
444
|
+
this.clearCachePattern(`form:altname:${fieldName}`);
|
|
445
|
+
this.emit('fieldAlternateNameChanged', fieldName, alternateName);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Checks if a form field is read-only
|
|
450
|
+
* @param fieldName Name of the field
|
|
451
|
+
* @returns True if field is read-only
|
|
452
|
+
*/
|
|
453
|
+
async isFieldReadonly(fieldName: string): Promise<boolean> {
|
|
454
|
+
const cacheKey = `form:readonly:${fieldName}`;
|
|
455
|
+
if (this.resultCache.has(cacheKey)) {
|
|
456
|
+
return this.resultCache.get(cacheKey);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// In real implementation, would call native FFI
|
|
460
|
+
// FormFieldFFI.formFieldIsReadonly(fieldHandle)
|
|
461
|
+
const readonly = false;
|
|
462
|
+
this.setCached(cacheKey, readonly);
|
|
463
|
+
return readonly;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Sets the read-only status of a form field
|
|
468
|
+
* @param fieldName Name of the field
|
|
469
|
+
* @param readonly True to make field read-only
|
|
470
|
+
*/
|
|
471
|
+
async setFieldReadonly(fieldName: string, readonly: boolean): Promise<void> {
|
|
472
|
+
// In real implementation, would call native FFI
|
|
473
|
+
// FormFieldFFI.formFieldSetReadonly(fieldHandle, readonly)
|
|
474
|
+
this.clearCachePattern(`form:readonly:${fieldName}`);
|
|
475
|
+
this.emit('fieldReadonlyChanged', fieldName, readonly);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Checks if a form field is required
|
|
480
|
+
* @param fieldName Name of the field
|
|
481
|
+
* @returns True if field is required
|
|
482
|
+
*/
|
|
483
|
+
async isFieldRequired(fieldName: string): Promise<boolean> {
|
|
484
|
+
const cacheKey = `form:required:${fieldName}`;
|
|
485
|
+
if (this.resultCache.has(cacheKey)) {
|
|
486
|
+
return this.resultCache.get(cacheKey);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// In real implementation, would call native FFI
|
|
490
|
+
// FormFieldFFI.formFieldIsRequired(fieldHandle)
|
|
491
|
+
const required = false;
|
|
492
|
+
this.setCached(cacheKey, required);
|
|
493
|
+
return required;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Sets the required status of a form field
|
|
498
|
+
* @param fieldName Name of the field
|
|
499
|
+
* @param required True to make field required
|
|
500
|
+
*/
|
|
501
|
+
async setFieldRequired(fieldName: string, required: boolean): Promise<void> {
|
|
502
|
+
// In real implementation, would call native FFI
|
|
503
|
+
// FormFieldFFI.formFieldSetRequired(fieldHandle, required)
|
|
504
|
+
this.clearCachePattern(`form:required:${fieldName}`);
|
|
505
|
+
this.emit('fieldRequiredChanged', fieldName, required);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* Gets the background color of a form field
|
|
510
|
+
* @param fieldName Name of the field
|
|
511
|
+
* @returns Color as [R, G, B] array (0-255) or null if no color
|
|
512
|
+
*/
|
|
513
|
+
async getFieldBackgroundColor(
|
|
514
|
+
fieldName: string
|
|
515
|
+
): Promise<[number, number, number] | null> {
|
|
516
|
+
const cacheKey = `form:bgcolor:${fieldName}`;
|
|
517
|
+
if (this.resultCache.has(cacheKey)) {
|
|
518
|
+
return this.resultCache.get(cacheKey);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// In real implementation, would call native FFI
|
|
522
|
+
// FormFieldFFI.formFieldGetBackgroundColor(fieldHandle) -> packed RGB
|
|
523
|
+
// Unpack: [(rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF]
|
|
524
|
+
const color: [number, number, number] | null = null;
|
|
525
|
+
this.setCached(cacheKey, color);
|
|
526
|
+
return color;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* Sets the background color of a form field
|
|
531
|
+
* @param fieldName Name of the field
|
|
532
|
+
* @param red Red component (0-255)
|
|
533
|
+
* @param green Green component (0-255)
|
|
534
|
+
* @param blue Blue component (0-255)
|
|
535
|
+
*/
|
|
536
|
+
async setFieldBackgroundColor(
|
|
537
|
+
fieldName: string,
|
|
538
|
+
red: number,
|
|
539
|
+
green: number,
|
|
540
|
+
blue: number
|
|
541
|
+
): Promise<void> {
|
|
542
|
+
// In real implementation, would call native FFI
|
|
543
|
+
// FormFieldFFI.formFieldSetBackgroundColor(fieldHandle, red, green, blue)
|
|
544
|
+
this.clearCachePattern(`form:bgcolor:${fieldName}`);
|
|
545
|
+
this.emit('fieldBackgroundColorChanged', fieldName, [red, green, blue]);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Gets the text color of a form field
|
|
550
|
+
* @param fieldName Name of the field
|
|
551
|
+
* @returns Color as [R, G, B] array (0-255) or null if no color
|
|
552
|
+
*/
|
|
553
|
+
async getFieldTextColor(fieldName: string): Promise<[number, number, number] | null> {
|
|
554
|
+
const cacheKey = `form:textcolor:${fieldName}`;
|
|
555
|
+
if (this.resultCache.has(cacheKey)) {
|
|
556
|
+
return this.resultCache.get(cacheKey);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// In real implementation, would call native FFI
|
|
560
|
+
// FormFieldFFI.formFieldGetTextColor(fieldHandle) -> packed RGB
|
|
561
|
+
// Unpack: [(rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF]
|
|
562
|
+
const color: [number, number, number] | null = null;
|
|
563
|
+
this.setCached(cacheKey, color);
|
|
564
|
+
return color;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Sets the text color of a form field
|
|
569
|
+
* @param fieldName Name of the field
|
|
570
|
+
* @param red Red component (0-255)
|
|
571
|
+
* @param green Green component (0-255)
|
|
572
|
+
* @param blue Blue component (0-255)
|
|
573
|
+
*/
|
|
574
|
+
async setFieldTextColor(
|
|
575
|
+
fieldName: string,
|
|
576
|
+
red: number,
|
|
577
|
+
green: number,
|
|
578
|
+
blue: number
|
|
579
|
+
): Promise<void> {
|
|
580
|
+
// In real implementation, would call native FFI
|
|
581
|
+
// FormFieldFFI.formFieldSetTextColor(fieldHandle, red, green, blue)
|
|
582
|
+
this.clearCachePattern(`form:textcolor:${fieldName}`);
|
|
583
|
+
this.emit('fieldTextColorChanged', fieldName, [red, green, blue]);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Validates a form field
|
|
588
|
+
* Checks field consistency and compliance
|
|
589
|
+
* @param fieldName Name of the field
|
|
590
|
+
* @returns True if field is valid
|
|
591
|
+
*/
|
|
592
|
+
async validateField(fieldName: string): Promise<boolean> {
|
|
593
|
+
// In real implementation, would call native FFI
|
|
594
|
+
// FormFieldFFI.formFieldValidate(fieldHandle)
|
|
595
|
+
this.emit('fieldValidated', fieldName);
|
|
596
|
+
return true;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* Gets form statistics
|
|
601
|
+
* @returns Object with form statistics
|
|
602
|
+
*/
|
|
603
|
+
async getFormStatistics(): Promise<Record<string, number>> {
|
|
604
|
+
const cacheKey = 'form:statistics';
|
|
605
|
+
if (this.resultCache.has(cacheKey)) {
|
|
606
|
+
return this.resultCache.get(cacheKey);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// In real implementation, would combine multiple FFI calls
|
|
610
|
+
const stats = {
|
|
611
|
+
total_fields: 0,
|
|
612
|
+
required_fields: 0,
|
|
613
|
+
readonly_fields: 0,
|
|
614
|
+
};
|
|
615
|
+
this.setCached(cacheKey, stats);
|
|
616
|
+
return stats;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* Batch sets multiple field values
|
|
621
|
+
* @param values Map of field names to values
|
|
622
|
+
* @returns Number of fields updated
|
|
623
|
+
*/
|
|
624
|
+
async batchSetValues(values: Record<string, string>): Promise<number> {
|
|
625
|
+
// In real implementation, would call FFI for each field
|
|
626
|
+
this.clearCachePattern('form:.*');
|
|
627
|
+
this.emit('batchValuesSet', Object.keys(values).length);
|
|
628
|
+
return Object.keys(values).length;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* Batch gets multiple field values
|
|
633
|
+
* @param fieldNames Array of field names
|
|
634
|
+
* @returns Map of field names to values
|
|
635
|
+
*/
|
|
636
|
+
async getBatchValues(fieldNames: string[]): Promise<Record<string, string>> {
|
|
637
|
+
const result: Record<string, string> = {};
|
|
638
|
+
for (const name of fieldNames) {
|
|
639
|
+
result[name] = '';
|
|
640
|
+
}
|
|
641
|
+
return result;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
// Private helper methods
|
|
645
|
+
private setCached(key: string, value: any): void {
|
|
646
|
+
this.resultCache.set(key, value);
|
|
647
|
+
|
|
648
|
+
// Simple LRU eviction
|
|
649
|
+
if (this.resultCache.size > this.maxCacheSize) {
|
|
650
|
+
const firstKey = this.resultCache.keys().next().value;
|
|
651
|
+
if (firstKey !== undefined) {
|
|
652
|
+
this.resultCache.delete(firstKey);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
private clearCachePattern(pattern: string): void {
|
|
658
|
+
const regex = new RegExp(pattern);
|
|
659
|
+
const keysToDelete = Array.from(this.resultCache.keys()).filter((key) =>
|
|
660
|
+
regex.test(key)
|
|
661
|
+
);
|
|
662
|
+
keysToDelete.forEach((key) => this.resultCache.delete(key));
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
export default FormFieldManager;
|