@orkestrel/form 0.0.11 → 0.0.13
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 +6 -1
- package/dist/src/browser/index.d.ts +6 -572
- package/dist/src/browser/index.js +84 -182
- package/dist/src/browser/index.js.map +1 -1
- package/dist/src/core/index.cjs +63 -15
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +30 -9
- package/dist/src/core/index.d.ts +30 -9
- package/dist/src/core/index.js +63 -15
- package/dist/src/core/index.js.map +1 -1
- package/package.json +10 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/browser/errors.ts","../../../src/core/constants.ts","../../../src/core/helpers.ts","../../../src/browser/helpers.ts","../../../src/browser/validators.ts","../../../src/browser/FormBinding.ts","../../../src/browser/factories.ts"],"sourcesContent":["import type { FormBindingErrorCode } from './types.js'\nimport { isInstance } from '@orkestrel/contract'\n\n/** Reports an incompatible control, overlapping submission, or native DOM failure. */\nexport class FormBindingError extends Error {\n\treadonly code: FormBindingErrorCode\n\treadonly context: Readonly<Record<string, unknown>> | undefined\n\n\t/**\n\t * Creates a native binding refusal.\n\t * @param code - The refusal category.\n\t * @param message - The explanation.\n\t * @param context - The associated field or cause.\n\t */\n\tconstructor(\n\t\tcode: FormBindingErrorCode,\n\t\tmessage: string,\n\t\tcontext?: Readonly<Record<string, unknown>>,\n\t) {\n\t\tsuper(message)\n\t\tthis.name = 'FormBindingError'\n\t\tthis.code = code\n\t\tthis.context = context === undefined ? undefined : Object.freeze({ ...context })\n\t}\n}\n\n/**\n * Checks whether a value is a native binding refusal.\n * @param value - The value to inspect.\n * @returns True if the value is a native binding refusal; false otherwise.\n * @example\n * ```ts\n * isFormBindingError(new FormBindingError('CONTROL', 'Duplicate text controls')) // true\n * ```\n */\nexport function isFormBindingError(value: unknown): value is FormBindingError {\n\treturn isInstance(value, FormBindingError)\n}\n","import type { FieldControl, FieldRuleName, FormStatus } from './types.js'\n\n/** Lists every field control, in the order declared by the public contract. */\nexport const FIELD_CONTROLS: readonly FieldControl[] = Object.freeze([\n\t'text',\n\t'editor',\n\t'password',\n\t'number',\n\t'date',\n\t'time',\n\t'datetime',\n\t'color',\n\t'confirm',\n\t'select',\n\t'checkbox',\n\t'file',\n])\n\n/** Lists the members every field declares, whatever its control. */\nexport const FIELD_BASE_KEYS: readonly string[] = Object.freeze([\n\t'control',\n\t'name',\n\t'label',\n\t'help',\n\t'group',\n\t'hidden',\n\t'disabled',\n\t'locked',\n\t'rule',\n\t'meta',\n])\n\n/**\n * Lists every member one field control permits, composed from {@link FIELD_BASE_KEYS} and the\n * members the control's own interface adds.\n */\nexport const FIELD_KEYS: Readonly<Record<FieldControl, readonly string[]>> = Object.freeze({\n\ttext: Object.freeze([...FIELD_BASE_KEYS, 'default', 'placeholder']),\n\teditor: Object.freeze([...FIELD_BASE_KEYS, 'default', 'placeholder']),\n\tpassword: Object.freeze([...FIELD_BASE_KEYS, 'mask']),\n\tnumber: Object.freeze([...FIELD_BASE_KEYS, 'default', 'placeholder']),\n\tdate: Object.freeze([...FIELD_BASE_KEYS, 'default']),\n\ttime: Object.freeze([...FIELD_BASE_KEYS, 'default']),\n\tdatetime: Object.freeze([...FIELD_BASE_KEYS, 'default']),\n\tcolor: Object.freeze([...FIELD_BASE_KEYS, 'default']),\n\tconfirm: Object.freeze([...FIELD_BASE_KEYS, 'default']),\n\tselect: Object.freeze([...FIELD_BASE_KEYS, 'choices', 'default', 'open']),\n\tcheckbox: Object.freeze([...FIELD_BASE_KEYS, 'choices', 'default']),\n\tfile: Object.freeze([...FIELD_BASE_KEYS, 'accept', 'multiple']),\n})\n\n/** Lists every form lifecycle status. */\nexport const FORM_STATUSES: readonly FormStatus[] = Object.freeze([\n\t'editing',\n\t'settled',\n\t'abandoned',\n])\n\n/** Holds the default failure copy for every named field rule. */\nexport const RULE_MESSAGES: Readonly<Record<FieldRuleName, string>> = Object.freeze({\n\trequired: 'This field is required',\n\tminimum: 'Must be at least {limit}',\n\tmaximum: 'Must be at most {limit}',\n\tstep: 'Must be a multiple of {limit}',\n\tpattern: 'Must match the required format',\n\temail: 'Must be a valid email address',\n\turl: 'Must be a valid URL',\n\tinteger: 'Must be an integer',\n\talphanumeric: 'Must contain only letters and numbers',\n})\n\n/** Matches a practical whole-address email shape. */\nexport const EMAIL_PATTERN = Object.freeze(/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/)\n\n/** Matches an absolute HTTP or HTTPS URL shape. */\nexport const URL_PATTERN = Object.freeze(/^https?:\\/\\/[^\\s]+$/)\n\n/** Matches one or more ASCII letters or digits. */\nexport const ALPHANUMERIC_PATTERN = Object.freeze(/^[A-Za-z0-9]+$/)\n\n/** Matches a signed or unsigned base-ten integer string. */\nexport const INTEGER_PATTERN = Object.freeze(/^[+-]?\\d+$/)\n\n/** Matches a six-digit hexadecimal color string. */\nexport const COLOR_PATTERN = Object.freeze(/^#[0-9A-Fa-f]{6}$/)\n\n/** Matches an ISO calendar date string in `YYYY-MM-DD` form. */\nexport const DATE_PATTERN = Object.freeze(/^\\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\\d|3[01])$/)\n\n/** Matches a 24-hour time string with optional seconds. */\nexport const TIME_PATTERN = Object.freeze(/^(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d)?$/)\n\n/** Matches an ISO local date and time string with optional seconds. */\nexport const DATETIME_PATTERN = Object.freeze(\n\t/^\\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\\d|3[01])T(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d)?$/,\n)\n\n/** Caps the accepted source length for an authored regular expression, at 256. */\nexport const PATTERN_LIMIT = 256\n\n/** Caps the number of fields one schema may declare, at 512. */\nexport const FIELD_LIMIT = 512\n\n/** Caps the number of groups one schema may declare, at 64. */\nexport const GROUP_LIMIT = 64\n\n/** Caps the number of choices one `select` or `checkbox` field may offer, at 1024. */\nexport const CHOICE_LIMIT = 1024\n\n/** Caps the number of entries one list-valued answer may hold, at 1024. */\nexport const LIST_LIMIT = 1024\n\n/** Caps the length, in UTF-16 code units, of a schema, group, or field name, at 128. */\nexport const NAME_LIMIT = 128\n\n/** Caps the length, in UTF-16 code units, of any single retained string, at 65536. */\nexport const STRING_LIMIT = 65536\n\n/** Caps the total length, in UTF-16 code units, of every string one schema retains, at 1048576. */\nexport const TEXT_LIMIT = 1048576\n\n/** Caps the total number of records, arrays, and leaves one schema retains, at 16384. */\nexport const NODE_LIMIT = 16384\n","import type { JSONRecord, JSONValue } from '@orkestrel/contract'\nimport type {\n\tEvaluationOptions,\n\tFieldError,\n\tFieldControl,\n\tFieldRuleName,\n\tFieldValue,\n\tFormField,\n\tFormGroup,\n\tFormSchema,\n\tFormValues,\n} from './types.js'\nimport {\n\tattempt,\n\tcloneJSONRecord,\n\tisArray,\n\tisBoolean,\n\tisFiniteNumber,\n\tisInteger,\n\tisContractError,\n\tisRecord,\n\tisString,\n\treadArrayEntries,\n} from '@orkestrel/contract'\nimport { cloneValue } from './cloners.js'\nimport {\n\tALPHANUMERIC_PATTERN,\n\tCHOICE_LIMIT,\n\tCOLOR_PATTERN,\n\tDATE_PATTERN,\n\tDATETIME_PATTERN,\n\tEMAIL_PATTERN,\n\tFIELD_CONTROLS,\n\tFIELD_LIMIT,\n\tGROUP_LIMIT,\n\tINTEGER_PATTERN,\n\tLIST_LIMIT,\n\tNAME_LIMIT,\n\tNODE_LIMIT,\n\tPATTERN_LIMIT,\n\tRULE_MESSAGES,\n\tSTRING_LIMIT,\n\tTEXT_LIMIT,\n\tTIME_PATTERN,\n\tURL_PATTERN,\n} from './constants.js'\nimport { FormError } from './errors.js'\n\n/**\n * Writes one own enumerable data property onto a record.\n *\n * @param target - The record to write into.\n * @param name - The property name to write.\n * @param value - The value to store.\n *\n * @remarks\n * Plain assignment runs an inherited setter, so writing a `__proto__` key that way reaches\n * `Object.prototype` and leaves the record without the entry. Defining the property writes the\n * record itself, whatever the prototype chain declares. The entry stays writable and configurable.\n *\n * @example\n * ```ts\n * const values: Record<string, number> = {}\n * defineEntry(values, '__proto__', 1)\n * Object.hasOwn(values, '__proto__') // true\n * ```\n */\nexport function defineEntry<T>(target: Record<string, T>, name: string, value: T): void {\n\tObject.defineProperty(target, name, {\n\t\tvalue,\n\t\tenumerable: true,\n\t\tconfigurable: true,\n\t\twritable: true,\n\t})\n}\n\n/**\n * Writes one own enumerable data property that cannot be rewritten or removed.\n *\n * @param target - The record to write into.\n * @param name - The property name to write.\n * @param value - The value to store.\n *\n * @remarks\n * The prototype-safe write of {@link defineEntry}, frozen: the entry is neither writable nor\n * configurable, so the record a parser hands back cannot be edited through the key it filled.\n *\n * @example\n * ```ts\n * const values: Record<string, number> = {}\n * freezeEntry(values, '__proto__', 1)\n * Object.getOwnPropertyDescriptor(values, '__proto__')?.writable // false\n * ```\n */\nexport function freezeEntry<T>(target: Record<string, T>, name: string, value: T): void {\n\tObject.defineProperty(target, name, {\n\t\tvalue,\n\t\tenumerable: true,\n\t\tconfigurable: false,\n\t\twritable: false,\n\t})\n}\n\n/**\n * Checks whether a value has the shape required by one field control.\n *\n * @remarks\n * Every write and every seeded value passes through this gate, and it reads `STRING_LIMIT` and\n * `LIST_LIMIT` before it consults the control, so no regular expression sees an over-long value.\n *\n * @param field - The field that owns the value.\n * @param value - The unknown value to inspect.\n * @returns True if the control can hold the value; false otherwise.\n */\nexport function matchesField(field: FormField, value: unknown): value is FieldValue {\n\tif (isString(value) && value.length > STRING_LIMIT) return false\n\n\tlet entries: readonly unknown[] | undefined\n\tif (isArray(value)) {\n\t\tconst length = attempt(() => value.length)\n\t\tif (!length.success || length.value > LIST_LIMIT) return false\n\n\t\tconst read = readArrayEntries(value)\n\t\tif (!read.success || !read.value.dense) return false\n\n\t\tentries = read.value.entries\n\t\tif (entries.some((entry) => !isString(entry) || entry.length > STRING_LIMIT)) return false\n\t}\n\n\tswitch (field.control) {\n\t\tcase 'text':\n\t\tcase 'editor':\n\t\tcase 'password':\n\t\t\treturn isString(value)\n\t\tcase 'number':\n\t\t\treturn isFiniteNumber(value)\n\t\tcase 'date':\n\t\t\treturn isString(value) && DATE_PATTERN.test(value)\n\t\tcase 'time':\n\t\t\treturn isString(value) && TIME_PATTERN.test(value)\n\t\tcase 'datetime':\n\t\t\treturn isString(value) && DATETIME_PATTERN.test(value)\n\t\tcase 'color':\n\t\t\treturn isString(value) && COLOR_PATTERN.test(value)\n\t\tcase 'confirm':\n\t\t\treturn isBoolean(value)\n\t\tcase 'select':\n\t\t\treturn (\n\t\t\t\tisString(value) &&\n\t\t\t\t!field.choices.some((choice) => choice.value === value && choice.disabled === true) &&\n\t\t\t\t(field.open === true ||\n\t\t\t\t\tfield.choices.some((choice) => choice.value === value && choice.disabled !== true))\n\t\t\t)\n\t\tcase 'checkbox':\n\t\t\treturn (\n\t\t\t\tentries !== undefined &&\n\t\t\t\tentries.every(\n\t\t\t\t\t(entry) =>\n\t\t\t\t\t\tisString(entry) &&\n\t\t\t\t\t\tfield.choices.some((choice) => choice.value === entry && choice.disabled !== true),\n\t\t\t\t) &&\n\t\t\t\tnew Set(entries).size === entries.length\n\t\t\t)\n\t\tcase 'file':\n\t\t\treturn entries !== undefined && (field.multiple === true || entries.length <= 1)\n\t}\n}\n\n/**\n * Decides whether a raw binding value projects to an answered field.\n *\n * @remarks\n * Bind with `fill(name, matchesAnswer(raw) ? raw : undefined)`. This projection treats an absent\n * value and a string containing only whitespace as unanswered. Every other field value is an\n * answer, including an empty list, `false`, and zero. Core evaluation does not use this projection:\n * its `required` rule remains presence-only.\n *\n * @param value - The raw field value, or absence.\n * @returns True if the binding preserves the value as an answer; false otherwise.\n */\nexport function matchesAnswer(value: FieldValue | undefined): boolean {\n\treturn value !== undefined && (!isString(value) || value.trim().length > 0)\n}\n\n/**\n * Checks whether a named rule applies to one field control.\n *\n * @remarks\n * The runtime control-membership check keeps this boundary total for JavaScript callers that\n * bypass the declared {@link FieldControl} contract.\n *\n * @param control - The field control to inspect.\n * @param rule - The named rule to inspect.\n * @returns True if the control evaluates that rule; false otherwise.\n */\nexport function appliesRule(control: FieldControl, rule: FieldRuleName): boolean {\n\tif (!FIELD_CONTROLS.some((candidate) => candidate === control)) return false\n\n\tswitch (rule) {\n\t\tcase 'required':\n\t\t\treturn true\n\t\tcase 'minimum':\n\t\tcase 'maximum':\n\t\t\treturn control !== 'color' && control !== 'confirm' && control !== 'select'\n\t\tcase 'step':\n\t\t\treturn control === 'number'\n\t\tcase 'pattern':\n\t\tcase 'email':\n\t\tcase 'url':\n\t\tcase 'alphanumeric':\n\t\t\treturn (\n\t\t\t\tcontrol !== 'number' &&\n\t\t\t\tcontrol !== 'confirm' &&\n\t\t\t\tcontrol !== 'checkbox' &&\n\t\t\t\tcontrol !== 'file'\n\t\t\t)\n\t\tcase 'integer':\n\t\t\treturn control !== 'confirm' && control !== 'checkbox' && control !== 'file'\n\t}\n\n\treturn false\n}\n\n/**\n * Evaluates one field rule against its current value.\n *\n * @param field - The field and rule to evaluate.\n * @param value - The current value, or absence.\n * @param values - Every value available to a custom rule.\n * @param messages - Optional rule-specific message replacements.\n * @returns Every failure in rule order.\n * @throws Thrown when a {@link FieldValidator} supplied through {@link FieldRule.custom} throws:\n * its own value escapes unchanged, because this helper adds no boundary around it.\n */\nexport function evaluateField(\n\tfield: FormField,\n\tvalue: FieldValue | undefined,\n\tvalues: FormValues,\n\tmessages?: Readonly<Partial<Record<FieldRuleName, string>>>,\n): readonly FieldError[] {\n\tconst errors: FieldError[] = []\n\tconst rule = field.rule\n\n\tif (value === undefined) {\n\t\tif (rule?.required === true && appliesRule(field.control, 'required')) {\n\t\t\terrors.push(createFieldError(field, 'required', undefined, messages))\n\t\t}\n\t}\n\n\tif (rule === undefined) return Object.freeze(errors)\n\n\tif (rule.minimum !== undefined && appliesRule(field.control, 'minimum')) {\n\t\tlet failed = false\n\n\t\tswitch (field.control) {\n\t\t\tcase 'text':\n\t\t\tcase 'editor':\n\t\t\tcase 'password':\n\t\t\t\tfailed = isString(value) && isFiniteNumber(rule.minimum) && value.length < rule.minimum\n\t\t\t\tbreak\n\t\t\tcase 'number':\n\t\t\t\tfailed = isFiniteNumber(value) && isFiniteNumber(rule.minimum) && value < rule.minimum\n\t\t\t\tbreak\n\t\t\tcase 'date':\n\t\t\tcase 'time':\n\t\t\tcase 'datetime':\n\t\t\t\tfailed = isString(value) && isString(rule.minimum) && value < rule.minimum\n\t\t\t\tbreak\n\t\t\tcase 'checkbox':\n\t\t\tcase 'file':\n\t\t\t\tfailed = isArray(value) && isFiniteNumber(rule.minimum) && value.length < rule.minimum\n\t\t\t\tbreak\n\t\t\tcase 'color':\n\t\t\tcase 'confirm':\n\t\t\tcase 'select':\n\t\t\t\tbreak\n\t\t}\n\n\t\tif (failed) {\n\t\t\terrors.push(createFieldError(field, 'minimum', rule.minimum, messages))\n\t\t}\n\t}\n\n\tif (rule.maximum !== undefined && appliesRule(field.control, 'maximum')) {\n\t\tlet failed = false\n\n\t\tswitch (field.control) {\n\t\t\tcase 'text':\n\t\t\tcase 'editor':\n\t\t\tcase 'password':\n\t\t\t\tfailed = isString(value) && isFiniteNumber(rule.maximum) && value.length > rule.maximum\n\t\t\t\tbreak\n\t\t\tcase 'number':\n\t\t\t\tfailed = isFiniteNumber(value) && isFiniteNumber(rule.maximum) && value > rule.maximum\n\t\t\t\tbreak\n\t\t\tcase 'date':\n\t\t\tcase 'time':\n\t\t\tcase 'datetime':\n\t\t\t\tfailed = isString(value) && isString(rule.maximum) && value > rule.maximum\n\t\t\t\tbreak\n\t\t\tcase 'checkbox':\n\t\t\tcase 'file':\n\t\t\t\tfailed = isArray(value) && isFiniteNumber(rule.maximum) && value.length > rule.maximum\n\t\t\t\tbreak\n\t\t\tcase 'color':\n\t\t\tcase 'confirm':\n\t\t\tcase 'select':\n\t\t\t\tbreak\n\t\t}\n\n\t\tif (failed) {\n\t\t\terrors.push(createFieldError(field, 'maximum', rule.maximum, messages))\n\t\t}\n\t}\n\n\tif (rule.step !== undefined && appliesRule(field.control, 'step') && isFiniteNumber(value)) {\n\t\tconst base = isFiniteNumber(rule.minimum) ? rule.minimum : 0\n\t\tconst multiple = (value - base) / rule.step\n\n\t\tif (\n\t\t\t!isFiniteNumber(rule.step) ||\n\t\t\trule.step === 0 ||\n\t\t\t!isFiniteNumber(multiple) ||\n\t\t\tMath.abs(multiple - Math.round(multiple)) > 1e-9\n\t\t) {\n\t\t\terrors.push(createFieldError(field, 'step', rule.step, messages))\n\t\t}\n\t}\n\n\tif (isString(value)) {\n\t\tif (rule.pattern !== undefined && appliesRule(field.control, 'pattern')) {\n\t\t\tconst pattern = rule.pattern\n\n\t\t\tif (pattern.length > PATTERN_LIMIT) {\n\t\t\t\terrors.push(createFieldError(field, 'pattern', undefined, messages))\n\t\t\t} else {\n\t\t\t\tconst outcome = attempt(() => new RegExp(pattern).test(value))\n\n\t\t\t\tif (!outcome.success || !outcome.value) {\n\t\t\t\t\terrors.push(createFieldError(field, 'pattern', undefined, messages))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (rule.email === true && appliesRule(field.control, 'email') && !EMAIL_PATTERN.test(value)) {\n\t\t\terrors.push(createFieldError(field, 'email', undefined, messages))\n\t\t}\n\n\t\tif (rule.url === true && appliesRule(field.control, 'url') && !URL_PATTERN.test(value)) {\n\t\t\terrors.push(createFieldError(field, 'url', undefined, messages))\n\t\t}\n\n\t\tif (\n\t\t\trule.alphanumeric === true &&\n\t\t\tappliesRule(field.control, 'alphanumeric') &&\n\t\t\t!ALPHANUMERIC_PATTERN.test(value)\n\t\t) {\n\t\t\terrors.push(createFieldError(field, 'alphanumeric', undefined, messages))\n\t\t}\n\n\t\tif (\n\t\t\trule.integer === true &&\n\t\t\tappliesRule(field.control, 'integer') &&\n\t\t\t!INTEGER_PATTERN.test(value)\n\t\t) {\n\t\t\terrors.push(createFieldError(field, 'integer', undefined, messages))\n\t\t}\n\t}\n\n\tif (\n\t\tvalue !== undefined &&\n\t\tfield.control === 'number' &&\n\t\trule.integer === true &&\n\t\tappliesRule(field.control, 'integer') &&\n\t\t!isInteger(value)\n\t) {\n\t\terrors.push(createFieldError(field, 'integer', undefined, messages))\n\t}\n\n\tif (rule.custom !== undefined) {\n\t\tconst result = rule.custom(value, values)\n\n\t\tif (isString(result)) errors.push(Object.freeze({ field: field.name, message: result }))\n\t}\n\n\treturn Object.freeze(errors)\n}\n\n/**\n * Evaluates every active field in schema order.\n *\n * @param schema - The form schema to evaluate.\n * @param values - The values keyed by field name.\n * @param options - Optional message replacements and the effective disabled field set.\n * @returns Every field failure in schema and rule order.\n * @throws Thrown when a {@link FieldValidator} supplied through {@link FieldRule.custom} throws:\n * its own value escapes unchanged, because this helper adds no boundary around it.\n */\nexport function evaluateForm(\n\tschema: FormSchema,\n\tvalues: FormValues,\n\toptions?: EvaluationOptions,\n): readonly FieldError[] {\n\tconst errors: FieldError[] = []\n\n\tfor (const field of schema.fields) {\n\t\tconst active =\n\t\t\toptions?.disabled === undefined ? field.disabled !== true : !options.disabled.has(field.name)\n\n\t\tif (active) {\n\t\t\tconst value = Object.hasOwn(values, field.name) ? values[field.name] : undefined\n\t\t\terrors.push(...evaluateField(field, value, values, options?.messages))\n\t\t}\n\t}\n\n\treturn Object.freeze(errors)\n}\n\n/**\n * Computes the values explicitly seeded by a schema.\n *\n * @remarks\n * `password` and `file` declare no default, so a field of either control never appears in the\n * result.\n *\n * @param schema - The schema whose defaults to collect.\n * @returns A value record containing only fields with defaults.\n */\nexport function computeDefaults(schema: FormSchema): FormValues {\n\tconst defaults: Record<string, FieldValue> = {}\n\n\tfor (const field of schema.fields) {\n\t\tswitch (field.control) {\n\t\t\tcase 'checkbox':\n\t\t\t\tif (field.default !== undefined) {\n\t\t\t\t\tdefineEntry(defaults, field.name, cloneValue(field.default))\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'password':\n\t\t\tcase 'file':\n\t\t\t\tbreak\n\t\t\tcase 'text':\n\t\t\tcase 'editor':\n\t\t\tcase 'number':\n\t\t\tcase 'date':\n\t\t\tcase 'time':\n\t\t\tcase 'datetime':\n\t\t\tcase 'color':\n\t\t\tcase 'confirm':\n\t\t\tcase 'select':\n\t\t\t\tif (field.default !== undefined) {\n\t\t\t\t\tdefineEntry(defaults, field.name, field.default)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\treturn Object.freeze(defaults)\n}\n\n/**\n * Compares two field values by scalar identity or ordered list content.\n *\n * @param a - The first field value.\n * @param b - The second field value.\n * @returns True if both values contain the same answer; false otherwise.\n */\nexport function matchesValue(a: FieldValue, b: FieldValue): boolean {\n\tif (isArray(a) || isArray(b)) {\n\t\treturn (\n\t\t\tisArray(a) &&\n\t\t\tisArray(b) &&\n\t\t\ta.length === b.length &&\n\t\t\ta.every((entry, index) => entry === b[index])\n\t\t)\n\t}\n\n\treturn a === b\n}\n\n/**\n * Extracts the names whose answers differ between two form value records.\n *\n * @remarks\n * Presence is compared in both directions before present values are compared through\n * {@link matchesValue}. The returned set is a new snapshot, exposed as readonly because later\n * changes to either input never alter its membership.\n *\n * @param current - The values the form holds.\n * @param opened - The values held when the form opened.\n * @returns A readonly snapshot of changed field names.\n */\nexport function extractChanges(current: FormValues, opened: FormValues): ReadonlySet<string> {\n\tconst names = new Set([...Object.keys(current), ...Object.keys(opened)])\n\tconst changed = new Set<string>()\n\n\tfor (const name of names) {\n\t\tconst hasCurrent = Object.hasOwn(current, name)\n\t\tconst hasOpened = Object.hasOwn(opened, name)\n\n\t\tif (hasCurrent !== hasOpened) {\n\t\t\tchanged.add(name)\n\t\t\tcontinue\n\t\t}\n\n\t\tconst now = current[name]\n\t\tconst before = opened[name]\n\t\tif (now === undefined || before === undefined || !matchesValue(now, before)) changed.add(name)\n\t}\n\n\treturn changed\n}\n\n/**\n * Compares two form value records by keys and value content.\n *\n * @param a - The first value record.\n * @param b - The second value record.\n * @returns True if both records contain the same answers; false otherwise.\n */\nexport function matchesValues(a: FormValues, b: FormValues): boolean {\n\treturn extractChanges(a, b).size === 0\n}\n\n/**\n * Resolves and interpolates one rule message.\n *\n * @remarks\n * A replacement in `messages` is read first and {@link RULE_MESSAGES} supplies the copy otherwise,\n * and `{limit}` in whichever text wins is replaced with the rule's operand.\n *\n * @param rule - The rule whose message to resolve.\n * @param limit - The optional operand substituted for `{limit}`.\n * @param messages - Optional rule-specific message replacements.\n * @returns The resolved failure text.\n */\nexport function formatMessage(\n\trule: FieldRuleName,\n\tlimit?: number | string,\n\tmessages?: Readonly<Partial<Record<FieldRuleName, string>>>,\n): string {\n\tconst message = messages?.[rule] ?? RULE_MESSAGES[rule]\n\treturn limit === undefined ? message : message.replaceAll('{limit}', String(limit))\n}\n\n/**\n * Creates one named-rule failure against a field.\n *\n * @param field - The field the rule failed on.\n * @param rule - The named rule that failed.\n * @param limit - The rule's operand, substituted for `{limit}`, or absence when it carries none.\n * @param messages - Optional rule-specific message replacements.\n * @returns A frozen {@link FieldError} carrying the field's name, the resolved text, and the rule.\n *\n * @remarks\n * A `custom` validator and the form's `invalidate` method both report a message of their own\n * under no rule name, so neither builds its failure here.\n *\n * @example\n * ```ts\n * const field: FormField = { control: 'text', name: 'nickname', rule: { minimum: 3 } }\n * const error = createFieldError(field, 'minimum', 3)\n * error.message // 'Must be at least 3'\n * ```\n */\nexport function createFieldError(\n\tfield: FormField,\n\trule: FieldRuleName,\n\tlimit: number | string | undefined,\n\tmessages?: Readonly<Partial<Record<FieldRuleName, string>>>,\n): FieldError {\n\treturn Object.freeze({ field: field.name, message: formatMessage(rule, limit, messages), rule })\n}\n\n/**\n * Projects a schema into JSON while removing custom validators and absent values.\n *\n * @param schema - The schema to project.\n * @returns A deep JSON copy of the serializable schema.\n * @throws A {@link FormError} coded `SCHEMA` when accessor-bearing metadata cannot be owned. A\n * non-contract throw while reading metadata escapes unchanged.\n */\nexport function serializeForm(schema: FormSchema): JSONRecord {\n\tconst output: Record<string, JSONValue> = {}\n\n\tif (schema.name !== undefined) output.name = schema.name\n\tif (schema.label !== undefined) output.label = schema.label\n\tif (schema.help !== undefined) output.help = schema.help\n\tif (schema.groups !== undefined) {\n\t\toutput.groups = schema.groups.map((group): JSONRecord => {\n\t\t\tconst entry: Record<string, JSONValue> = { name: group.name, label: group.label }\n\t\t\tif (group.help !== undefined) entry.help = group.help\n\t\t\treturn entry\n\t\t})\n\t}\n\n\toutput.fields = schema.fields.map((field): JSONRecord => {\n\t\tconst entry: Record<string, JSONValue> = {\n\t\t\tcontrol: field.control,\n\t\t\tname: field.name,\n\t\t}\n\n\t\tif (field.label !== undefined) entry.label = field.label\n\t\tif (field.help !== undefined) entry.help = field.help\n\t\tif (field.group !== undefined) entry.group = field.group\n\t\tif (field.hidden !== undefined) entry.hidden = field.hidden\n\t\tif (field.disabled !== undefined) entry.disabled = field.disabled\n\t\tif (field.locked !== undefined) entry.locked = field.locked\n\t\tconst meta = field.meta\n\t\tif (meta !== undefined) {\n\t\t\ttry {\n\t\t\t\tentry.meta = cloneJSONRecord(meta)\n\t\t\t} catch (error) {\n\t\t\t\tif (!isContractError(error)) throw error\n\t\t\t\tthrow new FormError('SCHEMA', `Field \"${field.name}\" has metadata that cannot be owned`, {\n\t\t\t\t\tfield: field.name,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tswitch (field.control) {\n\t\t\tcase 'text':\n\t\t\tcase 'editor':\n\t\t\tcase 'number':\n\t\t\t\tif (field.default !== undefined) entry.default = field.default\n\t\t\t\tif (field.placeholder !== undefined) entry.placeholder = field.placeholder\n\t\t\t\tbreak\n\t\t\tcase 'password':\n\t\t\t\tif (field.mask !== undefined) entry.mask = field.mask\n\t\t\t\tbreak\n\t\t\tcase 'date':\n\t\t\tcase 'time':\n\t\t\tcase 'datetime':\n\t\t\tcase 'color':\n\t\t\tcase 'confirm':\n\t\t\t\tif (field.default !== undefined) entry.default = field.default\n\t\t\t\tbreak\n\t\t\tcase 'select':\n\t\t\t\tentry.choices = field.choices.map((choice): JSONRecord => {\n\t\t\t\t\tconst option: Record<string, JSONValue> = {\n\t\t\t\t\t\tvalue: choice.value,\n\t\t\t\t\t\tlabel: choice.label,\n\t\t\t\t\t}\n\t\t\t\t\tif (choice.help !== undefined) option.help = choice.help\n\t\t\t\t\tif (choice.disabled !== undefined) option.disabled = choice.disabled\n\t\t\t\t\treturn option\n\t\t\t\t})\n\t\t\t\tif (field.default !== undefined) entry.default = field.default\n\t\t\t\tif (field.open !== undefined) entry.open = field.open\n\t\t\t\tbreak\n\t\t\tcase 'checkbox':\n\t\t\t\tentry.choices = field.choices.map((choice): JSONRecord => {\n\t\t\t\t\tconst option: Record<string, JSONValue> = {\n\t\t\t\t\t\tvalue: choice.value,\n\t\t\t\t\t\tlabel: choice.label,\n\t\t\t\t\t}\n\t\t\t\t\tif (choice.help !== undefined) option.help = choice.help\n\t\t\t\t\tif (choice.disabled !== undefined) option.disabled = choice.disabled\n\t\t\t\t\treturn option\n\t\t\t\t})\n\t\t\t\tif (field.default !== undefined) entry.default = field.default\n\t\t\t\tbreak\n\t\t\tcase 'file':\n\t\t\t\tif (field.accept !== undefined) entry.accept = field.accept\n\t\t\t\tif (field.multiple !== undefined) entry.multiple = field.multiple\n\t\t\t\tbreak\n\t\t}\n\n\t\tif (field.rule !== undefined) {\n\t\t\tconst rule: Record<string, JSONValue> = {}\n\n\t\t\tif (field.rule.required !== undefined) rule.required = field.rule.required\n\t\t\tif (field.rule.minimum !== undefined) rule.minimum = field.rule.minimum\n\t\t\tif (field.rule.maximum !== undefined) rule.maximum = field.rule.maximum\n\t\t\tif (field.rule.step !== undefined) rule.step = field.rule.step\n\t\t\tif (field.rule.pattern !== undefined) rule.pattern = field.rule.pattern\n\t\t\tif (field.rule.email !== undefined) rule.email = field.rule.email\n\t\t\tif (field.rule.url !== undefined) rule.url = field.rule.url\n\t\t\tif (field.rule.integer !== undefined) rule.integer = field.rule.integer\n\t\t\tif (field.rule.alphanumeric !== undefined) rule.alphanumeric = field.rule.alphanumeric\n\t\t\tif (Object.keys(rule).length > 0) entry.rule = rule\n\t\t}\n\n\t\treturn entry\n\t})\n\n\treturn cloneJSONRecord(output)\n}\n\n/**\n * Selects referenced groups in first-reference field order.\n *\n * @param schema - The schema whose group references to resolve.\n * @returns The referenced schema groups without duplicates.\n */\nexport function extractGroups(schema: FormSchema): readonly FormGroup[] {\n\tconst groups: FormGroup[] = []\n\n\tif (schema.groups === undefined) return Object.freeze(groups)\n\n\tfor (const field of schema.fields) {\n\t\tif (field.group !== undefined && !groups.some((group) => group.name === field.group)) {\n\t\t\tconst group = schema.groups.find((entry) => entry.name === field.group)\n\t\t\tif (group !== undefined) groups.push(group)\n\t\t}\n\t}\n\n\treturn Object.freeze(groups)\n}\n\n/**\n * Audits a structurally valid schema for domain invariants.\n *\n * @param schema - The form schema to audit.\n * @returns Human-readable invariant violations, or an empty list when the schema is sound.\n */\nexport function auditSchema(schema: FormSchema): readonly string[] {\n\tconst faults: string[] = []\n\tconst fields = new Set<string>()\n\tconst groups = new Set<string>()\n\tlet choiceExceeded: string | undefined\n\tlet nameExceeded = schema.name !== undefined && schema.name.length > NAME_LIMIT\n\n\tif (schema.fields.length > FIELD_LIMIT) {\n\t\tfaults.push(`Schema declares more than ${FIELD_LIMIT} fields`)\n\t}\n\tif (schema.groups !== undefined && schema.groups.length > GROUP_LIMIT) {\n\t\tfaults.push(`Schema declares more than ${GROUP_LIMIT} groups`)\n\t}\n\n\tif (schema.groups !== undefined) {\n\t\tconst count = Math.min(schema.groups.length, GROUP_LIMIT + 1)\n\t\tfor (let index = 0; index < count; index += 1) {\n\t\t\tconst group = schema.groups[index]\n\t\t\tif (group !== undefined && group.name.length > NAME_LIMIT) nameExceeded = true\n\t\t}\n\t}\n\n\tconst fieldCount = Math.min(schema.fields.length, FIELD_LIMIT + 1)\n\tfor (let index = 0; index < fieldCount; index += 1) {\n\t\tconst field = schema.fields[index]\n\t\tif (field === undefined) continue\n\n\t\tif (\n\t\t\tfield.name.length > NAME_LIMIT ||\n\t\t\t(field.group !== undefined && field.group.length > NAME_LIMIT)\n\t\t) {\n\t\t\tnameExceeded = true\n\t\t}\n\t\tif (\n\t\t\tchoiceExceeded === undefined &&\n\t\t\t(field.control === 'select' || field.control === 'checkbox') &&\n\t\t\tfield.choices.length > CHOICE_LIMIT\n\t\t) {\n\t\t\tchoiceExceeded = field.name\n\t\t}\n\t}\n\n\tif (choiceExceeded !== undefined) {\n\t\tfaults.push(`Field \"${choiceExceeded}\" offers more than ${CHOICE_LIMIT} choices`)\n\t}\n\tif (nameExceeded) faults.push(`Schema contains a name longer than ${NAME_LIMIT}`)\n\n\tconst pending: unknown[] = [schema]\n\tconst metadata: boolean[] = [false]\n\tlet position = 0\n\tlet stringExceeded = false\n\tlet textExceeded = false\n\tlet nodeExceeded = false\n\tlet text = 0\n\n\twhile (position < pending.length) {\n\t\tconst node = pending[position]\n\t\tconst inMeta = metadata[position] === true\n\t\tposition += 1\n\n\t\tif (isString(node)) {\n\t\t\tif (node.length > STRING_LIMIT) stringExceeded = true\n\t\t\ttext = Math.min(TEXT_LIMIT + 1, text + node.length)\n\t\t\tif (text > TEXT_LIMIT) textExceeded = true\n\t\t\tcontinue\n\t\t}\n\n\t\tif (isArray(node)) {\n\t\t\tconst length = attempt(() => node.length)\n\t\t\tif (!length.success || length.value > NODE_LIMIT - pending.length) {\n\t\t\t\tnodeExceeded = true\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst read = readArrayEntries(node)\n\t\t\tif (!read.success || !read.value.dense) continue\n\n\t\t\tfor (let index = 0; index < read.value.entries.length; index += 1) {\n\t\t\t\tconst entry = read.value.entries[index]\n\t\t\t\tif (entry !== undefined) {\n\t\t\t\t\tpending.push(entry)\n\t\t\t\t\tmetadata.push(inMeta)\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif (!isRecord(node)) continue\n\n\t\tconst keys = attempt(() => Object.keys(node))\n\t\tif (!keys.success) continue\n\n\t\tfor (const key of keys.value) {\n\t\t\tif (inMeta) {\n\t\t\t\tif (key.length > STRING_LIMIT) stringExceeded = true\n\t\t\t\ttext = Math.min(TEXT_LIMIT + 1, text + key.length)\n\t\t\t\tif (text > TEXT_LIMIT) textExceeded = true\n\t\t\t}\n\n\t\t\tconst value = attempt(() => node[key])\n\t\t\tif (!value.success || value.value === undefined) continue\n\t\t\tif (pending.length >= NODE_LIMIT) {\n\t\t\t\tnodeExceeded = true\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tpending.push(value.value)\n\t\t\tmetadata.push(inMeta || key === 'meta')\n\t\t}\n\t}\n\n\tif (stringExceeded) faults.push(`Schema contains a string longer than ${STRING_LIMIT}`)\n\tif (textExceeded) faults.push(`Schema retains more than ${TEXT_LIMIT} string code units`)\n\tif (nodeExceeded) faults.push(`Schema retains more than ${NODE_LIMIT} nodes`)\n\n\tif (schema.groups !== undefined) {\n\t\tconst count = Math.min(schema.groups.length, GROUP_LIMIT + 1)\n\t\tfor (let index = 0; index < count; index += 1) {\n\t\t\tconst group = schema.groups[index]\n\t\t\tif (group === undefined) continue\n\t\t\tif (groups.has(group.name)) faults.push(`Group \"${group.name}\" is declared more than once`)\n\t\t\tgroups.add(group.name)\n\t\t}\n\t}\n\n\tfor (let fieldIndex = 0; fieldIndex < fieldCount; fieldIndex += 1) {\n\t\tconst field = schema.fields[fieldIndex]\n\t\tif (field === undefined) continue\n\t\tif (field.name.length === 0) faults.push('Field \"\" has an empty name')\n\t\tif (field.name === '__proto__') faults.push('Field \"__proto__\" has a refused name')\n\t\tif (fields.has(field.name)) faults.push(`Field \"${field.name}\" is declared more than once`)\n\t\tfields.add(field.name)\n\n\t\tif (field.group !== undefined && !groups.has(field.group)) {\n\t\t\tfaults.push(`Field \"${field.name}\" references missing group \"${field.group}\"`)\n\t\t}\n\n\t\tswitch (field.control) {\n\t\t\tcase 'password':\n\t\t\tcase 'file':\n\t\t\t\tbreak\n\t\t\tcase 'text':\n\t\t\tcase 'editor':\n\t\t\tcase 'number':\n\t\t\tcase 'date':\n\t\t\tcase 'time':\n\t\t\tcase 'datetime':\n\t\t\tcase 'color':\n\t\t\tcase 'confirm':\n\t\t\tcase 'select':\n\t\t\tcase 'checkbox':\n\t\t\t\tif (field.default !== undefined && !matchesField(field, field.default)) {\n\t\t\t\t\tfaults.push(`Field \"${field.name}\" has an invalid default`)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t}\n\n\t\tif (field.control === 'select' || field.control === 'checkbox') {\n\t\t\tconst choices = new Set<string>()\n\t\t\tconst count = Math.min(field.choices.length, CHOICE_LIMIT + 1)\n\t\t\tlet enabled = 0\n\n\t\t\tfor (let index = 0; index < count; index += 1) {\n\t\t\t\tconst choice = field.choices[index]\n\t\t\t\tif (choice === undefined) continue\n\t\t\t\tif (choice.disabled !== true) enabled += 1\n\t\t\t\tif (choices.has(choice.value)) {\n\t\t\t\t\tfaults.push(`Field \"${field.name}\" offers choice \"${choice.value}\" more than once`)\n\t\t\t\t}\n\t\t\t\tchoices.add(choice.value)\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tfield.control === 'select' &&\n\t\t\t\tfield.rule?.required === true &&\n\t\t\t\tfield.open !== true &&\n\t\t\t\tenabled === 0\n\t\t\t) {\n\t\t\t\tfaults.push(`Field \"${field.name}\" is required but offers no enabled choice`)\n\t\t\t}\n\n\t\t\tconst minimum = field.rule?.minimum\n\t\t\tif (\n\t\t\t\tfield.control === 'checkbox' &&\n\t\t\t\tisFiniteNumber(minimum) &&\n\t\t\t\tminimum > 0 &&\n\t\t\t\tminimum > enabled\n\t\t\t) {\n\t\t\t\tfaults.push(\n\t\t\t\t\t`Field \"${field.name}\" has minimum ${minimum} but offers only ${enabled} enabled ${enabled === 1 ? 'choice' : 'choices'}`,\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\tconst rule = field.rule\n\t\tif (rule === undefined) continue\n\n\t\tconst temporal =\n\t\t\tfield.control === 'date' || field.control === 'time' || field.control === 'datetime'\n\t\tif (rule.minimum !== undefined && !appliesRule(field.control, 'minimum')) {\n\t\t\tfaults.push(`Field \"${field.name}\" has minimum on ${field.control}`)\n\t\t} else if (isString(rule.minimum) && !temporal) {\n\t\t\tfaults.push(`Field \"${field.name}\" has a string minimum on ${field.control}`)\n\t\t}\n\t\tif (rule.maximum !== undefined && !appliesRule(field.control, 'maximum')) {\n\t\t\tfaults.push(`Field \"${field.name}\" has maximum on ${field.control}`)\n\t\t} else if (isString(rule.maximum) && !temporal) {\n\t\t\tfaults.push(`Field \"${field.name}\" has a string maximum on ${field.control}`)\n\t\t}\n\t\tif (isFiniteNumber(rule.minimum) && temporal) {\n\t\t\tfaults.push(`Field \"${field.name}\" has a numeric minimum on ${field.control}`)\n\t\t}\n\t\tif (isFiniteNumber(rule.maximum) && temporal) {\n\t\t\tfaults.push(`Field \"${field.name}\" has a numeric maximum on ${field.control}`)\n\t\t}\n\t\tif (\n\t\t\tisFiniteNumber(rule.maximum) &&\n\t\t\trule.maximum < 0 &&\n\t\t\t(field.control === 'text' ||\n\t\t\t\tfield.control === 'editor' ||\n\t\t\t\tfield.control === 'password' ||\n\t\t\t\tfield.control === 'checkbox' ||\n\t\t\t\tfield.control === 'file')\n\t\t) {\n\t\t\tfaults.push(`Field \"${field.name}\" has a negative maximum on ${field.control}`)\n\t\t}\n\n\t\tif (rule.step !== undefined && !appliesRule(field.control, 'step')) {\n\t\t\tfaults.push(`Field \"${field.name}\" has step on ${field.control}`)\n\t\t}\n\t\tif (rule.step !== undefined && rule.step <= 0) {\n\t\t\tfaults.push(`Field \"${field.name}\" has a non-positive step`)\n\t\t}\n\n\t\tif (rule.pattern !== undefined && !appliesRule(field.control, 'pattern')) {\n\t\t\tfaults.push(`Field \"${field.name}\" has pattern on ${field.control}`)\n\t\t}\n\t\tif (rule.email === true && !appliesRule(field.control, 'email')) {\n\t\t\tfaults.push(`Field \"${field.name}\" has email on ${field.control}`)\n\t\t}\n\t\tif (rule.url === true && !appliesRule(field.control, 'url')) {\n\t\t\tfaults.push(`Field \"${field.name}\" has url on ${field.control}`)\n\t\t}\n\t\tif (rule.alphanumeric === true && !appliesRule(field.control, 'alphanumeric')) {\n\t\t\tfaults.push(`Field \"${field.name}\" has alphanumeric on ${field.control}`)\n\t\t}\n\t\tif (rule.integer === true && !appliesRule(field.control, 'integer')) {\n\t\t\tfaults.push(`Field \"${field.name}\" has integer on ${field.control}`)\n\t\t}\n\n\t\tif (rule.pattern !== undefined) {\n\t\t\tif (rule.pattern.length > PATTERN_LIMIT) {\n\t\t\t\tfaults.push(`Field \"${field.name}\" has a pattern longer than ${PATTERN_LIMIT}`)\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tRegExp(rule.pattern)\n\t\t\t\t} catch {\n\t\t\t\t\tfaults.push(`Field \"${field.name}\" has an invalid pattern`)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (\n\t\t\t(isFiniteNumber(rule.minimum) &&\n\t\t\t\tisFiniteNumber(rule.maximum) &&\n\t\t\t\trule.minimum > rule.maximum) ||\n\t\t\t(isString(rule.minimum) && isString(rule.maximum) && rule.minimum > rule.maximum)\n\t\t) {\n\t\t\tfaults.push(`Field \"${field.name}\" has minimum greater than maximum`)\n\t\t}\n\n\t\tif (field.control === 'date') {\n\t\t\tif (isString(rule.minimum) && !DATE_PATTERN.test(rule.minimum)) {\n\t\t\t\tfaults.push(`Field \"${field.name}\" has an invalid date minimum`)\n\t\t\t}\n\t\t\tif (isString(rule.maximum) && !DATE_PATTERN.test(rule.maximum)) {\n\t\t\t\tfaults.push(`Field \"${field.name}\" has an invalid date maximum`)\n\t\t\t}\n\t\t}\n\n\t\tif (field.control === 'time') {\n\t\t\tif (isString(rule.minimum) && !TIME_PATTERN.test(rule.minimum)) {\n\t\t\t\tfaults.push(`Field \"${field.name}\" has an invalid time minimum`)\n\t\t\t}\n\t\t\tif (isString(rule.maximum) && !TIME_PATTERN.test(rule.maximum)) {\n\t\t\t\tfaults.push(`Field \"${field.name}\" has an invalid time maximum`)\n\t\t\t}\n\t\t}\n\n\t\tif (field.control === 'datetime') {\n\t\t\tif (isString(rule.minimum) && !DATETIME_PATTERN.test(rule.minimum)) {\n\t\t\t\tfaults.push(`Field \"${field.name}\" has an invalid datetime minimum`)\n\t\t\t}\n\t\t\tif (isString(rule.maximum) && !DATETIME_PATTERN.test(rule.maximum)) {\n\t\t\t\tfaults.push(`Field \"${field.name}\" has an invalid datetime maximum`)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn Object.freeze(faults)\n}\n","import type { FieldError, FieldRuleName, FieldValue, FormField } from '../core/types.js'\nimport type { FormControl } from './types.js'\nimport { formatMessage, matchesAnswer, matchesField } from '../core/helpers.js'\nimport { FormBindingError } from './errors.js'\n\n/**\n * Checks a native control population against a field's declared value shape.\n * @param field - The declared field.\n * @param controls - Associated controls sharing its name.\n * @returns True if the population has an unambiguous compatible shape; false otherwise.\n * @example\n * ```ts\n * matchesFormControls({ control: 'text', name: 'name' }, [document.createElement('input')]) // true\n * ```\n */\nexport function matchesFormControls(field: FormField, controls: readonly FormControl[]): boolean {\n\tif (controls.length === 0) return true\n\tif (controls.length > 1 && field.control !== 'checkbox' && field.control !== 'select')\n\t\treturn false\n\treturn controls.every((control) => {\n\t\tif (control instanceof HTMLTextAreaElement)\n\t\t\treturn field.control === 'editor' && controls.length === 1\n\t\tif (control instanceof HTMLSelectElement) {\n\t\t\treturn (\n\t\t\t\tcontrols.length === 1 &&\n\t\t\t\t(control.multiple ? field.control === 'checkbox' : field.control === 'select')\n\t\t\t)\n\t\t}\n\t\tswitch (field.control) {\n\t\t\tcase 'text':\n\t\t\t\treturn ['text', 'search', 'email', 'url', 'tel', 'hidden'].includes(control.type)\n\t\t\tcase 'password':\n\t\t\t\treturn control.type === 'password' || control.type === 'text'\n\t\t\tcase 'number':\n\t\t\t\treturn control.type === 'number' || control.type === 'range'\n\t\t\tcase 'datetime':\n\t\t\t\treturn control.type === 'datetime-local'\n\t\t\tcase 'confirm':\n\t\t\t\treturn control.type === 'checkbox'\n\t\t\tcase 'checkbox':\n\t\t\t\treturn (\n\t\t\t\t\tcontrol.type === 'checkbox' &&\n\t\t\t\t\tcontrols.every((entry) => entry instanceof HTMLInputElement)\n\t\t\t\t)\n\t\t\tcase 'select':\n\t\t\t\treturn (\n\t\t\t\t\tcontrol.type === 'radio' &&\n\t\t\t\t\tcontrols.every((entry) => entry instanceof HTMLInputElement && entry.type === 'radio')\n\t\t\t\t)\n\t\t\tcase 'editor':\n\t\t\t\treturn false\n\t\t\tdefault:\n\t\t\t\treturn control.type === field.control\n\t\t}\n\t})\n}\n\n/**\n * Reads native constraint messages not already reported by document rules.\n * @param control - The native control with binding-owned custom validity removed.\n * @param errors - The document's reported failures.\n * @returns Uncovered constraint messages, preserving authored custom validity.\n * @remarks\n * A lone native failure retains platform copy. Competing failures use constraint-specific\n * copy because the platform exposes only one message for the whole control.\n * @example\n * ```ts\n * const input = document.createElement('input')\n * input.name = 'name'\n * input.required = true\n * readNativeMessages(input, [{ field: 'name', rule: 'required', message: 'Enter a name' }]) // []\n * ```\n */\nexport function readNativeMessages(\n\tcontrol: FormControl,\n\terrors: readonly FieldError[],\n): readonly string[] {\n\tconst rules = new Set(\n\t\terrors.filter((error) => error.field === control.name).map((error) => error.rule),\n\t)\n\tconst validity = control.validity\n\tconst failures = new Map<FieldRuleName, string>()\n\tif (validity.valueMissing) failures.set('required', formatMessage('required'))\n\tif (validity.rangeUnderflow)\n\t\tfailures.set('minimum', formatMessage('minimum', control.getAttribute('min') ?? ''))\n\tif (validity.rangeOverflow)\n\t\tfailures.set('maximum', formatMessage('maximum', control.getAttribute('max') ?? ''))\n\tif (validity.tooShort)\n\t\tfailures.set('minimum', formatMessage('minimum', control.getAttribute('minlength') ?? ''))\n\tif (validity.tooLong)\n\t\tfailures.set('maximum', formatMessage('maximum', control.getAttribute('maxlength') ?? ''))\n\tif (validity.stepMismatch) failures.set('step', 'Use a permitted value for this step')\n\tif (validity.patternMismatch) failures.set('pattern', formatMessage('pattern'))\n\tif (validity.typeMismatch && control instanceof HTMLInputElement) {\n\t\tif (control.type === 'email') failures.set('email', formatMessage('email'))\n\t\telse if (control.type === 'url') failures.set('url', formatMessage('url'))\n\t}\n\tconst messages: string[] = []\n\tif (validity.customError) messages.push(control.validationMessage)\n\tconst lone = failures.size + Number(validity.customError) + Number(validity.badInput) === 1\n\tif (validity.badInput) messages.push(lone ? control.validationMessage : 'Enter a valid value')\n\tfor (const [rule, message] of failures) {\n\t\tif (!rules.has(rule)) messages.push(lone ? control.validationMessage : message)\n\t}\n\treturn messages\n}\n\n/**\n * Reads one compatible native population using the document's blank-to-absence semantics.\n * @param field - The field declaring the answer shape.\n * @param controls - Controls sharing the field's name, in native order.\n * @returns The native answer, or undefined for an absent answer or empty population.\n * @throws Thrown when the population or answer is incompatible, including numeric bad input.\n * @example\n * ```ts\n * const input = document.createElement('input')\n * input.value = 'Ada'\n * readFormControls({ control: 'text', name: 'name' }, [input]) // 'Ada'\n * ```\n */\nexport function readFormControls(\n\tfield: FormField,\n\tcontrols: readonly FormControl[],\n): FieldValue | undefined {\n\tif (!matchesFormControls(field, controls)) {\n\t\tthrow new FormBindingError('CONTROL', `Incompatible controls for \"${field.name}\"`, {\n\t\t\tfield: field.name,\n\t\t})\n\t}\n\tconst first = controls[0]\n\tif (first === undefined) return undefined\n\tlet value: FieldValue | undefined\n\tif (field.control === 'checkbox') {\n\t\tvalue =\n\t\t\tfirst instanceof HTMLSelectElement\n\t\t\t\t? Array.from(first.selectedOptions, (option) => option.value)\n\t\t\t\t: controls\n\t\t\t\t\t\t.filter((control) => control instanceof HTMLInputElement && control.checked)\n\t\t\t\t\t\t.map((control) => control.value)\n\t} else if (field.control === 'select' && first instanceof HTMLInputElement) {\n\t\tvalue = controls.find(\n\t\t\t(control) => control instanceof HTMLInputElement && control.checked,\n\t\t)?.value\n\t} else if (field.control === 'confirm' && first instanceof HTMLInputElement) {\n\t\tvalue = first.checked\n\t} else if (field.control === 'number' && first instanceof HTMLInputElement) {\n\t\tif (first.validity.badInput)\n\t\t\tthrow new FormBindingError('CONTROL', 'Enter a number', { field: field.name })\n\t\tvalue = first.value === '' ? undefined : first.valueAsNumber\n\t} else if (field.control === 'file' && first instanceof HTMLInputElement) {\n\t\tvalue = Array.from(first.files ?? [], (file) => file.name)\n\t} else {\n\t\tvalue = first.value\n\t}\n\tif (!matchesAnswer(value)) return undefined\n\tif (value !== undefined && !matchesField(field, value)) {\n\t\tthrow new FormBindingError('CONTROL', `Incompatible native answer for \"${field.name}\"`, {\n\t\t\tfield: field.name,\n\t\t})\n\t}\n\treturn value\n}\n","import type { FormControl } from './types.js'\nimport { isInstance } from '@orkestrel/contract'\n\n/**\n * Checks whether a value is a native answer control.\n * @param value - The value to inspect.\n * @returns True if the value is an input, select, or textarea; false otherwise.\n * @example\n * ```ts\n * isFormControl(document.createElement('input')) // true\n * ```\n */\nexport function isFormControl(value: unknown): value is FormControl {\n\treturn (\n\t\t(typeof HTMLInputElement !== 'undefined' && isInstance(value, HTMLInputElement)) ||\n\t\t(typeof HTMLSelectElement !== 'undefined' && isInstance(value, HTMLSelectElement)) ||\n\t\t(typeof HTMLTextAreaElement !== 'undefined' && isInstance(value, HTMLTextAreaElement))\n\t)\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type { FieldError, FieldValue, FormField, FormInterface } from '../core/types.js'\nimport type {\n\tFormBindingAttribute,\n\tFormBindingEventMap,\n\tFormBindingInterface,\n\tFormBindingOptions,\n\tFormBindingValidity,\n\tFormControl,\n} from './types.js'\nimport { Emitter } from '@orkestrel/emitter'\nimport { matchesValue } from '../core/helpers.js'\nimport { FormBindingError, isFormBindingError } from './errors.js'\nimport { matchesFormControls, readFormControls, readNativeMessages } from './helpers.js'\nimport { isFormControl } from './validators.js'\n\n/** Implements a controlled native form over a borrowed document. */\nexport class FormBinding implements FormBindingInterface {\n\treadonly #element: HTMLFormElement\n\treadonly #document: FormInterface\n\treadonly #options: FormBindingOptions | undefined\n\treadonly #emitter: Emitter<FormBindingEventMap>\n\treadonly #observer: MutationObserver\n\treadonly #listeners = new AbortController()\n\treadonly #attributes = new Map<Element, Map<string, FormBindingAttribute>>()\n\treadonly #validity = new Map<FormControl, FormBindingValidity>()\n\treadonly #feedback = new Map<string, HTMLElement>()\n\treadonly #excluded = new Set<string>()\n\treadonly #logical = new Set<string>()\n\treadonly #unreadable = new Set<string>()\n\treadonly #names = new Map<FormControl, string>()\n\treadonly #readings = new Map<FormControl, string>()\n\treadonly #deferred = new Set<string>()\n\treadonly #refresh = this.#onState.bind(this)\n\treadonly #fill = this.#onFill.bind(this)\n\treadonly #disable = this.#onDisable.bind(this)\n\treadonly #enable = this.#onEnable.bind(this)\n\treadonly #clear = this.#onClear.bind(this)\n\treadonly #abandon = this.destroy.bind(this)\n\t#controls: ReadonlyMap<string, readonly FormControl[]> = new Map()\n\t#summary: HTMLUListElement | undefined\n\t#summaryText = ''\n\t#destroyed = false\n\t#running = false\n\t#preserve: boolean | undefined\n\t#reading = false\n\t#excluding: string | undefined\n\t#changed = false\n\t#notified = false\n\t#scheduled = false\n\t#submitting = false\n\t#pointer: number | undefined\n\t#release: ReturnType<typeof setTimeout> | undefined\n\n\t/**\n\t * Binds existing controls to the supplied document's answers.\n\t * @param element - The native form, including its externally associated controls.\n\t * @param document - The borrowed answer document.\n\t * @param options - Feedback destinations and listeners.\n\t * @throws Thrown when controls contradict the schema or native initialization fails.\n\t */\n\tconstructor(element: HTMLFormElement, document: FormInterface, options?: FormBindingOptions) {\n\t\tthis.#element = element\n\t\tthis.#document = document\n\t\tthis.#options = options\n\t\tthis.#emitter = new Emitter<FormBindingEventMap>(options)\n\t\tthis.#observer = new MutationObserver(() => this.#onDocument(true))\n\t\tfor (const name of document.disabled) this.#logical.add(name)\n\t\ttry {\n\t\t\tthis.#controls = this.#discover()\n\t\t\tconst signal = this.#listeners.signal\n\t\t\telement.addEventListener('submit', (event) => this.#onSubmit(event), { signal })\n\t\t\telement.addEventListener('reset', (event) => this.#onReset(event), { signal })\n\t\t\telement.ownerDocument.addEventListener('input', (event) => this.#onInput(event), { signal })\n\t\t\telement.ownerDocument.addEventListener('change', (event) => this.#onInput(event), { signal })\n\t\t\telement.ownerDocument.addEventListener('focusout', (event) => this.#onBlur(event), { signal })\n\t\t\telement.ownerDocument.addEventListener('click', (event) => this.#onClick(event), { signal })\n\t\t\tif (options?.defer) {\n\t\t\t\telement.ownerDocument.addEventListener('pointerdown', (event) => this.#onPress(event), {\n\t\t\t\t\tsignal,\n\t\t\t\t\tcapture: true,\n\t\t\t\t})\n\t\t\t\telement.ownerDocument.addEventListener('pointerup', (event) => this.#onRelease(event), {\n\t\t\t\t\tsignal,\n\t\t\t\t\tcapture: true,\n\t\t\t\t})\n\t\t\t\telement.ownerDocument.addEventListener('pointercancel', (event) => this.#onRelease(event), {\n\t\t\t\t\tsignal,\n\t\t\t\t\tcapture: true,\n\t\t\t\t})\n\t\t\t\telement.ownerDocument.defaultView?.addEventListener('blur', () => this.#finishPress(), {\n\t\t\t\t\tsignal,\n\t\t\t\t})\n\t\t\t}\n\t\t\tdocument.emitter.on('fill', this.#fill)\n\t\t\tdocument.emitter.on('disable', this.#disable)\n\t\t\tdocument.emitter.on('enable', this.#enable)\n\t\t\tdocument.emitter.on('clear', this.#clear)\n\t\t\tdocument.emitter.on('abandon', this.#abandon)\n\t\t\tfor (const event of ['touch', 'validate', 'prepare', 'accept', 'abort', 'submit'] as const) {\n\t\t\t\tdocument.emitter.on(event, this.#refresh)\n\t\t\t}\n\t\t\tthis.refresh()\n\t\t\tif (!this.#destroyed) {\n\t\t\t\tthis.#observer.observe(element.ownerDocument, {\n\t\t\t\t\tsubtree: true,\n\t\t\t\t\tchildList: true,\n\t\t\t\t\tattributes: true,\n\t\t\t\t\tattributeFilter: [\n\t\t\t\t\t\t'name',\n\t\t\t\t\t\t'form',\n\t\t\t\t\t\t'id',\n\t\t\t\t\t\t'type',\n\t\t\t\t\t\t'multiple',\n\t\t\t\t\t\t'disabled',\n\t\t\t\t\t\t'required',\n\t\t\t\t\t\t'min',\n\t\t\t\t\t\t'max',\n\t\t\t\t\t\t'step',\n\t\t\t\t\t\t'pattern',\n\t\t\t\t\t\t'minlength',\n\t\t\t\t\t\t'maxlength',\n\t\t\t\t\t\t'value',\n\t\t\t\t\t\t'hidden',\n\t\t\t\t\t\t'inert',\n\t\t\t\t\t\t'style',\n\t\t\t\t\t\t'class',\n\t\t\t\t\t],\n\t\t\t\t})\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.destroy()\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t/** Holds the native form. */\n\tget element(): HTMLFormElement {\n\t\treturn this.#element\n\t}\n\t/** Holds the borrowed answer document. */\n\tget document(): FormInterface {\n\t\treturn this.#document\n\t}\n\t/** Reports whether the binding released its resources. */\n\tget destroyed(): boolean {\n\t\treturn this.#destroyed\n\t}\n\t/** Holds the binding's isolated event emitter. */\n\tget emitter(): EmitterInterface<FormBindingEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\t/** Imports mounted enabled controls without acknowledging their answers. */\n\tread(): void {\n\t\tif (this.#destroyed || this.#reading || this.#document.status !== 'editing') return\n\t\tconst controls = this.#discover()\n\t\tconst answers = new Map<string, FieldValue | undefined>()\n\t\tfor (const field of this.#document.schema.fields) {\n\t\t\tconst group = controls.get(field.name)\n\t\t\tif (group === undefined || field.locked || this.#logical.has(field.name)) continue\n\t\t\tconst enabled = group.filter((control) => !this.#nativeDisabled(control))\n\t\t\tif (enabled.length === 0) continue\n\t\t\tif (enabled.some((control) => control.validity.badInput)) {\n\t\t\t\tthis.#unreadable.add(field.name)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tthis.#unreadable.delete(field.name)\n\t\t\tanswers.set(field.name, readFormControls(field, enabled))\n\t\t}\n\t\tthis.#controls = controls\n\t\tthis.#reading = true\n\t\ttry {\n\t\t\tthis.#exclusions()\n\t\t\tfor (const [name, value] of answers) {\n\t\t\t\tif (this.#destroyed) break\n\t\t\t\tconst values = this.#document.values\n\t\t\t\tconst previous = Object.hasOwn(values, name) ? values[name] : undefined\n\t\t\t\tif (\n\t\t\t\t\tprevious === undefined || value === undefined\n\t\t\t\t\t\t? previous !== value\n\t\t\t\t\t\t: !matchesValue(previous, value)\n\t\t\t\t)\n\t\t\t\t\tthis.#document.fill(name, value)\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.#reading = false\n\t\t\tif (!this.#destroyed) this.#drain()\n\t\t}\n\t}\n\n\t/** Rediscovers controls and projects the document into the native form. */\n\trefresh(): void {\n\t\tif (this.#destroyed) return\n\t\tthis.#unreadable.clear()\n\t\tthis.#drain()\n\t}\n\n\t/** Releases owned DOM effects and listeners without destroying the document. */\n\tdestroy(): void {\n\t\tif (this.#destroyed) return\n\t\tthis.#destroyed = true\n\t\tthis.#observer.disconnect()\n\t\tthis.#listeners.abort()\n\t\tthis.#clearPress()\n\t\tthis.#document.emitter.off('fill', this.#fill)\n\t\tthis.#document.emitter.off('disable', this.#disable)\n\t\tthis.#document.emitter.off('enable', this.#enable)\n\t\tthis.#document.emitter.off('clear', this.#clear)\n\t\tthis.#document.emitter.off('abandon', this.#abandon)\n\t\tfor (const event of ['touch', 'validate', 'prepare', 'accept', 'abort', 'submit'] as const) {\n\t\t\tthis.#document.emitter.off(event, this.#refresh)\n\t\t}\n\t\tfor (const element of this.#attributes.keys()) this.#restore(element)\n\t\tfor (const control of this.#validity.keys()) this.#restoreValidity(control)\n\t\tfor (const node of this.#feedback.values()) node.remove()\n\t\tthis.#summary?.remove()\n\t\tif (this.#document.status === 'editing') {\n\t\t\tfor (const name of this.#excluded) {\n\t\t\t\tif (!this.#logical.has(name)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.#document.enable(name)\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tthis.#emitter.emit('error', error)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.#excluded.clear()\n\t\tthis.#feedback.clear()\n\t\tthis.#names.clear()\n\t\tthis.#readings.clear()\n\t\tthis.#unreadable.clear()\n\t\tthis.#logical.clear()\n\t\tthis.#controls = new Map()\n\t\tthis.#summary = undefined\n\t\tthis.#emitter.destroy()\n\t}\n\n\t#drain(preserve = false): void {\n\t\tif (this.#destroyed) return\n\t\tthis.#preserve = this.#preserve === false ? false : preserve\n\t\tif (this.#running || this.#reading) return\n\t\tthis.#running = true\n\t\ttry {\n\t\t\tlet turns = 0\n\t\t\twhile (this.#preserve !== undefined && !this.#destroyed && turns < 2) {\n\t\t\t\tconst retaining = this.#preserve\n\t\t\t\tthis.#preserve = undefined\n\t\t\t\tthis.#changed = false\n\t\t\t\tthis.#controls = this.#discover()\n\t\t\t\tthis.#releaseRemoved()\n\t\t\t\tthis.#exclusions()\n\t\t\t\tif (this.#destroyed) break\n\t\t\t\tthis.#paint(retaining)\n\t\t\t\tif (!this.#destroyed && (this.#changed || !this.#notified)) {\n\t\t\t\t\tthis.#notified = true\n\t\t\t\t\tthis.#emitter.emit('render')\n\t\t\t\t}\n\t\t\t\tturns += 1\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.#preserve = undefined\n\t\t\tthrow isFormBindingError(error)\n\t\t\t\t? error\n\t\t\t\t: new FormBindingError('DOM', 'Native form projection failed', { cause: error })\n\t\t} finally {\n\t\t\tthis.#running = false\n\t\t\tif (this.#preserve !== undefined && !this.#destroyed && !this.#scheduled) {\n\t\t\t\tthis.#scheduled = true\n\t\t\t\tqueueMicrotask(() => {\n\t\t\t\t\tthis.#scheduled = false\n\t\t\t\t\tif (!this.#destroyed) this.#onDocument(this.#preserve ?? false)\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\t#discover(): ReadonlyMap<string, readonly FormControl[]> {\n\t\tconst groups = new Map<string, FormControl[]>()\n\t\tfor (const control of Array.from(this.#element.elements)) {\n\t\t\tif (\n\t\t\t\t!isFormControl(control) ||\n\t\t\t\tcontrol.form !== this.#element ||\n\t\t\t\t!this.#document.field(control.name)\n\t\t\t)\n\t\t\t\tcontinue\n\t\t\tif (\n\t\t\t\tcontrol instanceof HTMLInputElement &&\n\t\t\t\t['submit', 'reset', 'button', 'image'].includes(control.type)\n\t\t\t)\n\t\t\t\tcontinue\n\t\t\tconst group = groups.get(control.name) ?? []\n\t\t\tgroup.push(control)\n\t\t\tgroups.set(control.name, group)\n\t\t}\n\t\tfor (const field of this.#document.schema.fields) {\n\t\t\tconst group = groups.get(field.name)\n\t\t\tif (group !== undefined && !matchesFormControls(field, group)) {\n\t\t\t\tthrow new FormBindingError('CONTROL', `Incompatible controls for \"${field.name}\"`, {\n\t\t\t\t\tfield: field.name,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\treturn groups\n\t}\n\n\t#nativeDisabled(control: FormControl): boolean {\n\t\tconst owned = this.#attributes.get(control)?.get('disabled')\n\t\tif (\n\t\t\towned !== undefined &&\n\t\t\tcontrol.getAttribute('disabled') === owned.value &&\n\t\t\towned.original === null\n\t\t) {\n\t\t\t// A model-owned disabled attribute cannot become a native exclusion on the next scan.\n\t\t\tlet ancestor = control.parentElement\n\t\t\twhile (ancestor !== null) {\n\t\t\t\tif (ancestor instanceof HTMLFieldSetElement && ancestor.disabled) {\n\t\t\t\t\tconst legend = Array.from(ancestor.children).find(\n\t\t\t\t\t\t(child) => child instanceof HTMLLegendElement,\n\t\t\t\t\t)\n\t\t\t\t\tif (legend === undefined || !legend.contains(control)) return true\n\t\t\t\t}\n\t\t\t\tancestor = ancestor.parentElement\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\t\treturn control.matches(':disabled')\n\t}\n\n\t#exclusions(): void {\n\t\tif (this.#document.status !== 'editing') return\n\t\tfor (const field of this.#document.schema.fields) {\n\t\t\tif (this.#destroyed) return\n\t\t\tconst group = this.#controls.get(field.name)\n\t\t\tconst excluded =\n\t\t\t\tgroup !== undefined && group.every((control) => this.#nativeDisabled(control))\n\t\t\tif (excluded && !this.#logical.has(field.name) && !this.#excluded.has(field.name)) {\n\t\t\t\tthis.#excluded.add(field.name)\n\t\t\t\tthis.#excluding = field.name\n\t\t\t\ttry {\n\t\t\t\t\tthis.#document.disable(field.name)\n\t\t\t\t} finally {\n\t\t\t\t\tthis.#excluding = undefined\n\t\t\t\t}\n\t\t\t} else if (!excluded && this.#excluded.delete(field.name) && !this.#logical.has(field.name)) {\n\t\t\t\tthis.#excluding = field.name\n\t\t\t\ttry {\n\t\t\t\t\tthis.#document.enable(field.name)\n\t\t\t\t} finally {\n\t\t\t\t\tthis.#excluding = undefined\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t#paint(preserve: boolean): void {\n\t\tthis.#attribute(this.#element, 'novalidate', '')\n\t\tthis.#attribute(\n\t\t\tthis.#element,\n\t\t\t'aria-busy',\n\t\t\tthis.#document.pending === undefined ? 'false' : 'true',\n\t\t)\n\t\tconst errors: FieldError[] = [...this.#document.errors]\n\t\tconst values = this.#document.values\n\t\tfor (const field of this.#document.schema.fields) {\n\t\t\tif (this.#destroyed) return\n\t\t\tconst group = this.#controls.get(field.name) ?? []\n\t\t\tfor (const control of group) {\n\t\t\t\tthis.#metadata(field, control)\n\t\t\t\tif (!this.#unreadable.has(field.name))\n\t\t\t\t\tthis.#value(\n\t\t\t\t\t\tfield,\n\t\t\t\t\t\tcontrol,\n\t\t\t\t\t\tObject.hasOwn(values, field.name) ? values[field.name] : undefined,\n\t\t\t\t\t\tpreserve,\n\t\t\t\t\t)\n\t\t\t\tif (this.#destroyed) return\n\t\t\t\tthis.#restoreValidity(control)\n\t\t\t\tif (\n\t\t\t\t\t!this.#document.disabled.has(field.name) &&\n\t\t\t\t\t!control.validity.valid &&\n\t\t\t\t\tcontrol.willValidate\n\t\t\t\t) {\n\t\t\t\t\tfor (const message of readNativeMessages(control, this.#document.errors))\n\t\t\t\t\t\terrors.push({ field: field.name, message })\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor (const field of this.#document.schema.fields) {\n\t\t\tif (this.#destroyed) return\n\t\t\tconst messages = [\n\t\t\t\t...new Set(\n\t\t\t\t\terrors.filter((error) => error.field === field.name).map((error) => error.message),\n\t\t\t\t),\n\t\t\t]\n\t\t\tconst message = messages.join('\\n')\n\t\t\tconst visible =\n\t\t\t\tthis.#document.touched.has(field.name) && !this.#document.disabled.has(field.name)\n\t\t\tconst group = this.#controls.get(field.name) ?? []\n\t\t\tlet feedback = this.#feedback.get(field.name)\n\t\t\tif (\n\t\t\t\tfeedback === undefined &&\n\t\t\t\t(group.length > 0 || this.#options?.feedback?.has(field.name))\n\t\t\t) {\n\t\t\t\tfeedback = this.#element.ownerDocument.createElement('span')\n\t\t\t\tfeedback.id = `form-feedback-${crypto.randomUUID()}`\n\t\t\t\tfeedback.dataset.formFeedback = field.name\n\t\t\t\tconst destination = this.#options?.feedback?.get(field.name)\n\t\t\t\tif (destination !== undefined) destination.append(feedback)\n\t\t\t\telse (group.at(-1) ?? this.#element).insertAdjacentElement('afterend', feedback)\n\t\t\t\tthis.#feedback.set(field.name, feedback)\n\t\t\t}\n\t\t\tif (feedback !== undefined) {\n\t\t\t\tif (feedback.textContent !== message) {\n\t\t\t\t\tfeedback.textContent = message\n\t\t\t\t\tthis.#changed = true\n\t\t\t\t}\n\t\t\t\tif (feedback.hidden !== (!visible || message === '')) {\n\t\t\t\t\tfeedback.hidden = !visible || message === ''\n\t\t\t\t\tthis.#changed = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const control of group) {\n\t\t\t\tif (message !== '' && !control.validity.customError) {\n\t\t\t\t\tthis.#validity.set(control, { original: '', value: message })\n\t\t\t\t\tcontrol.setCustomValidity(message)\n\t\t\t\t}\n\t\t\t\tthis.#attribute(control, 'aria-invalid', visible && message !== '' ? 'true' : null)\n\t\t\t\tif (feedback !== undefined)\n\t\t\t\t\tthis.#description(control, feedback.id, visible && message !== '')\n\t\t\t}\n\t\t}\n\t\tthis.#paintSummary(\n\t\t\terrors.filter(\n\t\t\t\t(error) =>\n\t\t\t\t\tthis.#document.touched.has(error.field) && !this.#document.disabled.has(error.field),\n\t\t\t),\n\t\t)\n\t\tfor (const control of Array.from(this.#element.elements)) {\n\t\t\tif (\n\t\t\t\t(control instanceof HTMLButtonElement && control.type === 'submit') ||\n\t\t\t\t(control instanceof HTMLInputElement && ['submit', 'image'].includes(control.type))\n\t\t\t) {\n\t\t\t\tthis.#attribute(\n\t\t\t\t\tcontrol,\n\t\t\t\t\t'aria-busy',\n\t\t\t\t\tthis.#document.pending === undefined ? 'false' : 'true',\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t}\n\n\t#metadata(field: FormField, control: FormControl): void {\n\t\tif (this.#logical.has(field.name)) this.#attribute(control, 'disabled', '')\n\t\telse this.#releaseAttribute(control, 'disabled')\n\t\tif (\n\t\t\tfield.locked &&\n\t\t\t!(control instanceof HTMLSelectElement) &&\n\t\t\t!(\n\t\t\t\tcontrol instanceof HTMLInputElement &&\n\t\t\t\t['radio', 'checkbox', 'file', 'range', 'color'].includes(control.type)\n\t\t\t)\n\t\t)\n\t\t\tthis.#attribute(control, 'readonly', '')\n\t\tif (field.rule?.required && !['confirm', 'checkbox', 'file'].includes(field.control))\n\t\t\tthis.#attribute(control, 'required', '')\n\t\tif (\n\t\t\tfield.control === 'number' ||\n\t\t\tfield.control === 'date' ||\n\t\t\tfield.control === 'time' ||\n\t\t\tfield.control === 'datetime'\n\t\t) {\n\t\t\tif (field.rule?.minimum !== undefined && !control.hasAttribute('min'))\n\t\t\t\tthis.#attribute(control, 'min', String(field.rule.minimum))\n\t\t\tif (field.rule?.maximum !== undefined && !control.hasAttribute('max'))\n\t\t\t\tthis.#attribute(control, 'max', String(field.rule.maximum))\n\t\t\tif (\n\t\t\t\tfield.control === 'number' &&\n\t\t\t\tfield.rule?.step !== undefined &&\n\t\t\t\t!control.hasAttribute('step')\n\t\t\t)\n\t\t\t\tthis.#attribute(control, 'step', String(field.rule.step))\n\t\t}\n\t}\n\n\t#value(\n\t\tfield: FormField,\n\t\tcontrol: FormControl,\n\t\tvalue: FieldValue | undefined,\n\t\tpreserve: boolean,\n\t): void {\n\t\tif (\n\t\t\tpreserve &&\n\t\t\t!field.locked &&\n\t\t\tcontrol.ownerDocument.activeElement === control &&\n\t\t\tthis.#readings.has(control) &&\n\t\t\t(control instanceof HTMLTextAreaElement ||\n\t\t\t\t(control instanceof HTMLInputElement &&\n\t\t\t\t\t['text', 'search', 'email', 'url', 'tel', 'password'].includes(control.type))) &&\n\t\t\tcontrol.value !== this.#readings.get(control)\n\t\t)\n\t\t\treturn\n\t\tlet changed = false\n\t\tif (control instanceof HTMLInputElement && control.type === 'file') {\n\t\t\t// The browser alone owns bytes. A differing saved name cannot create a FileList.\n\t\t\tconst names = Array.from(control.files ?? [], (file) => file.name)\n\t\t\tif (names.length > 0 && (value === undefined || !matchesValue(names, value))) {\n\t\t\t\tcontrol.value = ''\n\t\t\t\tthis.#changed = true\n\t\t\t\tthis.#emitter.emit('write', control)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tif (\n\t\t\tcontrol instanceof HTMLInputElement &&\n\t\t\t(control.type === 'checkbox' || control.type === 'radio')\n\t\t) {\n\t\t\tconst checked =\n\t\t\t\tfield.control === 'confirm'\n\t\t\t\t\t? value === true\n\t\t\t\t\t: Array.isArray(value)\n\t\t\t\t\t\t? value.includes(control.value)\n\t\t\t\t\t\t: value === control.value\n\t\t\tif (control.checked !== checked) {\n\t\t\t\tcontrol.checked = checked\n\t\t\t\tchanged = true\n\t\t\t}\n\t\t} else if (control instanceof HTMLSelectElement && control.multiple) {\n\t\t\tfor (const option of Array.from(control.options)) {\n\t\t\t\tconst selected = Array.isArray(value) && value.includes(option.value)\n\t\t\t\tif (option.selected !== selected) {\n\t\t\t\t\toption.selected = selected\n\t\t\t\t\tchanged = true\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconst text = value === undefined ? '' : String(value)\n\t\t\tif (\n\t\t\t\tcontrol.value !== text ||\n\t\t\t\t(control instanceof HTMLInputElement && control.validity.badInput)\n\t\t\t) {\n\t\t\t\tconst before = control.value\n\t\t\t\tconst invalid = control.validity.badInput\n\t\t\t\tcontrol.value = text\n\t\t\t\tif (control.value !== before || invalid) changed = true\n\t\t\t}\n\t\t}\n\t\tthis.#readings.set(control, control.value)\n\t\tif (changed) {\n\t\t\tthis.#changed = true\n\t\t\tthis.#emitter.emit('write', control)\n\t\t}\n\t}\n\n\t#attribute(element: Element, name: string, value: string | null): void {\n\t\tconst attributes = this.#attributes.get(element) ?? new Map<string, FormBindingAttribute>()\n\t\tconst previous = attributes.get(name)\n\t\tconst current = element.getAttribute(name)\n\t\tconst original =\n\t\t\tprevious === undefined || previous.value !== current ? current : previous.original\n\t\tif (current !== value) {\n\t\t\tif (value === null) element.removeAttribute(name)\n\t\t\telse element.setAttribute(name, value)\n\t\t\tthis.#changed = true\n\t\t}\n\t\tattributes.set(name, { original, value })\n\t\tthis.#attributes.set(element, attributes)\n\t}\n\n\t#description(control: FormControl, id: string, shown: boolean): void {\n\t\tconst tokens = (control.getAttribute('aria-describedby') ?? '')\n\t\t\t.split(/\\s+/)\n\t\t\t.filter((token) => token !== '' && token !== id)\n\t\tif (shown) tokens.push(id)\n\t\tthis.#attribute(control, 'aria-describedby', tokens.length === 0 ? null : tokens.join(' '))\n\t}\n\n\t#releaseAttribute(element: Element, name: string): void {\n\t\tconst attributes = this.#attributes.get(element)\n\t\tconst owned = attributes?.get(name)\n\t\tif (owned === undefined) return\n\t\tif (element.getAttribute(name) === owned.value) {\n\t\t\tif (owned.original === null) element.removeAttribute(name)\n\t\t\telse element.setAttribute(name, owned.original)\n\t\t\tthis.#changed = true\n\t\t}\n\t\tattributes?.delete(name)\n\t}\n\n\t#restore(element: Element): void {\n\t\tfor (const name of this.#attributes.get(element)?.keys() ?? [])\n\t\t\tthis.#releaseAttribute(element, name)\n\t\tconst ids = new Set([...this.#feedback.values()].map((feedback) => feedback.id))\n\t\tconst description = element.getAttribute('aria-describedby')\n\t\tif (description !== null) {\n\t\t\tconst tokens = description.split(/\\s+/).filter((token) => token !== '' && !ids.has(token))\n\t\t\tif (tokens.length === 0) element.removeAttribute('aria-describedby')\n\t\t\telse if (tokens.join(' ') !== description)\n\t\t\t\telement.setAttribute('aria-describedby', tokens.join(' '))\n\t\t}\n\t\tthis.#attributes.delete(element)\n\t}\n\n\t#restoreValidity(control: FormControl): void {\n\t\tconst owned = this.#validity.get(control)\n\t\tif (\n\t\t\towned !== undefined &&\n\t\t\tcontrol.validity.customError &&\n\t\t\tcontrol.validationMessage === owned.value\n\t\t)\n\t\t\tcontrol.setCustomValidity(owned.original)\n\t\tthis.#validity.delete(control)\n\t}\n\n\t#releaseRemoved(): void {\n\t\tconst live = new Set([...this.#controls.values()].flat())\n\t\tfor (const [control, name] of this.#names) {\n\t\t\tif (!live.has(control) || control.name !== name) {\n\t\t\t\tthis.#restoreValidity(control)\n\t\t\t\tthis.#restore(control)\n\t\t\t\tthis.#names.delete(control)\n\t\t\t\tthis.#readings.delete(control)\n\t\t\t}\n\t\t}\n\t\tfor (const control of live) this.#names.set(control, control.name)\n\t\tfor (const element of this.#attributes.keys()) {\n\t\t\tif (\n\t\t\t\t(isFormControl(element) || element instanceof HTMLButtonElement) &&\n\t\t\t\telement.form !== this.#element\n\t\t\t)\n\t\t\t\tthis.#restore(element)\n\t\t}\n\t\tfor (const [name, feedback] of this.#feedback) {\n\t\t\tif (!this.#controls.has(name) && !this.#options?.feedback?.has(name)) {\n\t\t\t\tfeedback.remove()\n\t\t\t\tthis.#feedback.delete(name)\n\t\t\t}\n\t\t}\n\t}\n\n\t#paintSummary(errors: readonly FieldError[]): void {\n\t\tconst destination = this.#options?.summary\n\t\tif (destination === undefined) return\n\t\tconst text = JSON.stringify(\n\t\t\terrors.map((error) => [error.field, error.message, this.#focusable(error.field)?.id]),\n\t\t)\n\t\tif (text === this.#summaryText) return\n\t\tthis.#summaryText = text\n\t\tthis.#changed = true\n\t\tthis.#summary?.remove()\n\t\tthis.#summary = this.#element.ownerDocument.createElement('ul')\n\t\tthis.#summary.dataset.formSummary = ''\n\t\tthis.#summary.hidden = errors.length === 0\n\t\tfor (const error of errors) {\n\t\t\tconst entry = this.#element.ownerDocument.createElement('li')\n\t\t\tconst target = this.#focusable(error.field)\n\t\t\tconst label = this.#document.field(error.field)?.label ?? error.field\n\t\t\tif (target === undefined) entry.textContent = `${label}: ${error.message}`\n\t\t\telse {\n\t\t\t\tif (target.id === '') this.#attribute(target, 'id', `form-control-${crypto.randomUUID()}`)\n\t\t\t\tconst link = this.#element.ownerDocument.createElement('a')\n\t\t\t\tlink.href = `#${target.id}`\n\t\t\t\tlink.textContent = `${label}: ${error.message}`\n\t\t\t\tlink.dataset.formField = error.field\n\t\t\t\tentry.append(link)\n\t\t\t}\n\t\t\tthis.#summary.append(entry)\n\t\t}\n\t\tdestination.append(this.#summary)\n\t}\n\n\t#focusable(name: string): FormControl | undefined {\n\t\treturn this.#controls\n\t\t\t.get(name)\n\t\t\t?.find(\n\t\t\t\t(control) =>\n\t\t\t\t\t!control.matches(':disabled') &&\n\t\t\t\t\tcontrol.closest('[inert]') === null &&\n\t\t\t\t\tcontrol.getClientRects().length > 0 &&\n\t\t\t\t\t!['hidden', 'collapse'].includes(getComputedStyle(control).visibility) &&\n\t\t\t\t\t!(control instanceof HTMLInputElement && control.type === 'hidden'),\n\t\t\t)\n\t}\n\n\t#onDocument(preserve = false): void {\n\t\tif (this.#destroyed) return\n\t\ttry {\n\t\t\tthis.#drain(preserve)\n\t\t} catch (error) {\n\t\t\tthis.#emitter.emit('error', error)\n\t\t}\n\t}\n\n\t#onFill(name: string): void {\n\t\tthis.#unreadable.delete(name)\n\t\tthis.#onState()\n\t}\n\n\t#onState(): void {\n\t\tthis.#notified = false\n\t\tthis.#onDocument()\n\t}\n\n\t#onDisable(name: string): void {\n\t\tif (this.#excluding !== name) this.#logical.add(name)\n\t\tthis.#onState()\n\t}\n\n\t#onEnable(name: string): void {\n\t\tif (this.#excluding !== name) {\n\t\t\tthis.#logical.delete(name)\n\t\t\tthis.#excluded.delete(name)\n\t\t}\n\t\tthis.#onState()\n\t}\n\n\t#onClear(): void {\n\t\tthis.#clearPress()\n\t\tthis.#logical.clear()\n\t\tthis.#excluded.clear()\n\t\tthis.#unreadable.clear()\n\t\tfor (const name of this.#document.disabled) this.#logical.add(name)\n\t\tthis.#onState()\n\t}\n\n\t#onInput(event: Event): void {\n\t\tconst control = event.target\n\t\tif (\n\t\t\t!isFormControl(control) ||\n\t\t\tcontrol.form !== this.#element ||\n\t\t\t!this.#document.field(control.name) ||\n\t\t\tthis.#destroyed\n\t\t)\n\t\t\treturn\n\t\ttry {\n\t\t\tthis.read()\n\t\t} catch (error) {\n\t\t\tthis.#emitter.emit('error', error)\n\t\t}\n\t}\n\n\t#onClick(event: MouseEvent): void {\n\t\tconst control = event.target\n\t\tif (control instanceof Element) {\n\t\t\tconst link = control.closest('a[data-form-field]')\n\t\t\tif (\n\t\t\t\tlink instanceof HTMLAnchorElement &&\n\t\t\t\tthis.#summary?.contains(link) &&\n\t\t\t\tlink.dataset.formField !== undefined\n\t\t\t) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tthis.#focusable(link.dataset.formField)?.focus()\n\t\t\t}\n\t\t}\n\t\tif (\n\t\t\tcontrol instanceof HTMLInputElement &&\n\t\t\tcontrol.form === this.#element &&\n\t\t\tthis.#document.field(control.name)?.locked &&\n\t\t\t['file', 'checkbox', 'radio', 'color'].includes(control.type)\n\t\t)\n\t\t\tevent.preventDefault()\n\t}\n\n\t#onBlur(event: FocusEvent): void {\n\t\tlet control = event.target\n\t\tfor (const [native, presentation] of this.#options?.presentations ?? []) {\n\t\t\tif (control === presentation) {\n\t\t\t\tcontrol = native\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif (\n\t\t\t!isFormControl(control) ||\n\t\t\tcontrol.form !== this.#element ||\n\t\t\t!this.#document.field(control.name) ||\n\t\t\tthis.#destroyed ||\n\t\t\tthis.#document.status !== 'editing'\n\t\t)\n\t\t\treturn\n\t\tif (event.relatedTarget === this.#options?.presentations?.get(control)) return\n\t\tif (this.#pointer !== undefined) {\n\t\t\tthis.#deferred.add(control.name)\n\t\t\treturn\n\t\t}\n\t\ttry {\n\t\t\tthis.#document.touch(control.name)\n\t\t\tthis.#drain()\n\t\t} catch (error) {\n\t\t\tthis.#emitter.emit('error', error)\n\t\t}\n\t}\n\n\t#onPress(event: PointerEvent): void {\n\t\tif (!event.isPrimary || event.button !== 0 || !(event.target instanceof Element)) return\n\t\tconst button = event.target.closest('button,input')\n\t\tif (\n\t\t\t!(\n\t\t\t\t(button instanceof HTMLButtonElement ||\n\t\t\t\t\t(button instanceof HTMLInputElement &&\n\t\t\t\t\t\t['button', 'submit', 'reset', 'image'].includes(button.type))) &&\n\t\t\t\tbutton.form === this.#element &&\n\t\t\t\t!button.matches(':disabled')\n\t\t\t)\n\t\t)\n\t\t\treturn\n\t\tthis.#finishPress()\n\t\tthis.#pointer = event.pointerId\n\t}\n\n\t#onRelease(event: PointerEvent): void {\n\t\tif (event.pointerId !== this.#pointer) return\n\t\t// A task keeps the pointerup-to-click sequence free of layout-changing feedback.\n\t\tif (this.#release !== undefined) clearTimeout(this.#release)\n\t\tthis.#release = setTimeout(() => this.#finishPress(), 0)\n\t}\n\n\t#finishPress(): void {\n\t\tconst names = [...this.#deferred]\n\t\tthis.#clearPress()\n\t\tif (this.#destroyed || this.#document.status !== 'editing') return\n\t\ttry {\n\t\t\tfor (const name of names) {\n\t\t\t\tif (this.#destroyed) break\n\t\t\t\tthis.#document.touch(name)\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.#emitter.emit('error', error)\n\t\t}\n\t}\n\n\t#clearPress(): void {\n\t\tif (this.#release !== undefined) clearTimeout(this.#release)\n\t\tthis.#release = undefined\n\t\tthis.#pointer = undefined\n\t\tthis.#deferred.clear()\n\t}\n\n\t#onSubmit(event: SubmitEvent): void {\n\t\tif (event.defaultPrevented || this.#destroyed) return\n\t\tevent.preventDefault()\n\t\tif (this.#submitting || this.#document.pending !== undefined) {\n\t\t\tthis.#emitter.emit(\n\t\t\t\t'error',\n\t\t\t\tnew FormBindingError('PENDING', 'A submission is already pending'),\n\t\t\t)\n\t\t\treturn\n\t\t}\n\t\tthis.#submitting = true\n\t\ttry {\n\t\t\tthis.read()\n\t\t\tif (this.#destroyed) return\n\t\t\tfor (const field of this.#document.schema.fields) {\n\t\t\t\tif (!this.#document.disabled.has(field.name)) this.#document.touch(field.name)\n\t\t\t\tif (this.#destroyed) return\n\t\t\t}\n\t\t\tthis.#drain()\n\t\t\tconst native = [...this.#controls].filter(\n\t\t\t\t([name, controls]) =>\n\t\t\t\t\t!this.#document.disabled.has(name) &&\n\t\t\t\t\tcontrols.some((control) => control.willValidate && !control.validity.valid),\n\t\t\t)\n\t\t\tif (native.length > 0) {\n\t\t\t\tfor (const [name] of native) {\n\t\t\t\t\tconst target = this.#focusable(name)\n\t\t\t\t\tif (target !== undefined) {\n\t\t\t\t\t\ttarget.focus()\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst result = this.#document.prepare()\n\t\t\tif (this.#destroyed) return\n\t\t\tthis.#drain()\n\t\t\tif (result.success) {\n\t\t\t\tif (!result.value.signal.aborted && this.#document.pending === result.value)\n\t\t\t\t\tthis.#emitter.emit('submit', result.value, event.submitter ?? undefined)\n\t\t\t} else {\n\t\t\t\tfor (const error of result.error) {\n\t\t\t\t\tconst target = this.#focusable(error.field)\n\t\t\t\t\tif (target !== undefined) {\n\t\t\t\t\t\ttarget.focus()\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.#emitter.emit('error', error)\n\t\t} finally {\n\t\t\tthis.#submitting = false\n\t\t}\n\t}\n\n\t#onReset(event: Event): void {\n\t\tif (event.defaultPrevented || this.#destroyed) return\n\t\tevent.preventDefault()\n\t\ttry {\n\t\t\tthis.#document.clear()\n\t\t\tthis.refresh()\n\t\t} catch (error) {\n\t\t\tthis.#emitter.emit('error', error)\n\t\t}\n\t}\n}\n","import type { FormInterface } from '../core/types.js'\nimport type { FormBindingInterface, FormBindingOptions } from './types.js'\nimport { FormBinding } from './FormBinding.js'\n\n/**\n * Creates a native form binding exposed through its lifecycle interface.\n * @param element - The native form.\n * @param document - The borrowed answer document.\n * @param options - Feedback destinations and listeners.\n * @returns The initialized native binding.\n * @example\n * ```ts\n * const binding = createFormBinding(element, document)\n * binding.refresh()\n * ```\n */\nexport function createFormBinding(\n\telement: HTMLFormElement,\n\tdocument: FormInterface,\n\toptions?: FormBindingOptions,\n): FormBindingInterface {\n\treturn new FormBinding(element, document, options)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/browser/errors.ts","../../../src/browser/helpers.ts","../../../src/browser/validators.ts","../../../src/browser/FormBinding.ts","../../../src/browser/factories.ts"],"sourcesContent":["import type { FormBindingErrorCode } from './types.js'\nimport { isInstance } from '@orkestrel/contract'\n\n/** Reports an incompatible control, overlapping submission, or native DOM failure. */\nexport class FormBindingError extends Error {\n\treadonly code: FormBindingErrorCode\n\treadonly context: Readonly<Record<string, unknown>> | undefined\n\n\t/**\n\t * Creates a native binding refusal.\n\t * @param code - The refusal category.\n\t * @param message - The explanation.\n\t * @param context - The associated field or cause.\n\t */\n\tconstructor(\n\t\tcode: FormBindingErrorCode,\n\t\tmessage: string,\n\t\tcontext?: Readonly<Record<string, unknown>>,\n\t) {\n\t\tsuper(message)\n\t\tthis.name = 'FormBindingError'\n\t\tthis.code = code\n\t\tthis.context = context === undefined ? undefined : Object.freeze({ ...context })\n\t}\n}\n\n/**\n * Checks whether a value is a native binding refusal.\n * @param value - The value to inspect.\n * @returns True if the value is a native binding refusal; false otherwise.\n * @example\n * ```ts\n * isFormBindingError(new FormBindingError('CONTROL', 'Duplicate text controls')) // true\n * ```\n */\nexport function isFormBindingError(value: unknown): value is FormBindingError {\n\treturn isInstance(value, FormBindingError)\n}\n","import type { FieldError, FieldRuleName, FieldValue, FormField } from '@src/core'\nimport type { FormControl } from './types.js'\nimport { formatMessage, matchesAnswer, matchesField } from '@src/core'\nimport { FormBindingError } from './errors.js'\n\n/**\n * Checks a native control population against a field's declared value shape.\n * @param field - The declared field.\n * @param controls - Associated controls sharing its name.\n * @returns True if the population has an unambiguous compatible shape; false otherwise.\n * @example\n * ```ts\n * matchesFormControls({ control: 'text', name: 'name' }, [document.createElement('input')]) // true\n * ```\n */\nexport function matchesFormControls(field: FormField, controls: readonly FormControl[]): boolean {\n\tif (controls.length === 0) return true\n\tif (controls.length > 1 && field.control !== 'checkbox' && field.control !== 'select')\n\t\treturn false\n\treturn controls.every((control) => {\n\t\tif (control instanceof HTMLTextAreaElement)\n\t\t\treturn field.control === 'editor' && controls.length === 1\n\t\tif (control instanceof HTMLSelectElement) {\n\t\t\treturn (\n\t\t\t\tcontrols.length === 1 &&\n\t\t\t\t(control.multiple\n\t\t\t\t\t? field.control === 'checkbox' || field.control === 'list'\n\t\t\t\t\t: field.control === 'select')\n\t\t\t)\n\t\t}\n\t\tswitch (field.control) {\n\t\t\tcase 'text':\n\t\t\t\treturn ['text', 'search', 'email', 'url', 'tel', 'hidden'].includes(control.type)\n\t\t\tcase 'password':\n\t\t\t\treturn control.type === 'password' || control.type === 'text'\n\t\t\tcase 'number':\n\t\t\t\treturn control.type === 'number' || control.type === 'range'\n\t\t\tcase 'datetime':\n\t\t\t\treturn control.type === 'datetime-local'\n\t\t\tcase 'confirm':\n\t\t\t\treturn control.type === 'checkbox'\n\t\t\tcase 'checkbox':\n\t\t\t\treturn (\n\t\t\t\t\tcontrol.type === 'checkbox' &&\n\t\t\t\t\tcontrols.every((entry) => entry instanceof HTMLInputElement)\n\t\t\t\t)\n\t\t\tcase 'select':\n\t\t\t\treturn (\n\t\t\t\t\tcontrol.type === 'radio' &&\n\t\t\t\t\tcontrols.every((entry) => entry instanceof HTMLInputElement && entry.type === 'radio')\n\t\t\t\t)\n\t\t\tcase 'editor':\n\t\t\t\treturn false\n\t\t\tdefault:\n\t\t\t\treturn control.type === field.control\n\t\t}\n\t})\n}\n\n/**\n * Reads native constraint messages not already reported by document rules.\n * @param control - The native control with binding-owned custom validity removed.\n * @param errors - The document's reported failures.\n * @returns Uncovered constraint messages, preserving authored custom validity.\n * @remarks\n * A lone native failure retains platform copy. Competing failures use constraint-specific\n * copy because the platform exposes only one message for the whole control.\n * @example\n * ```ts\n * const input = document.createElement('input')\n * input.name = 'name'\n * input.required = true\n * readNativeMessages(input, [{ field: 'name', rule: 'required', message: 'Enter a name' }]) // []\n * ```\n */\nexport function readNativeMessages(\n\tcontrol: FormControl,\n\terrors: readonly FieldError[],\n): readonly string[] {\n\tconst rules = new Set(\n\t\terrors.filter((error) => error.field === control.name).map((error) => error.rule),\n\t)\n\tconst validity = control.validity\n\tconst failures = new Map<FieldRuleName, string>()\n\tif (validity.valueMissing) failures.set('required', formatMessage('required'))\n\tif (validity.rangeUnderflow)\n\t\tfailures.set('minimum', formatMessage('minimum', control.getAttribute('min') ?? ''))\n\tif (validity.rangeOverflow)\n\t\tfailures.set('maximum', formatMessage('maximum', control.getAttribute('max') ?? ''))\n\tif (validity.tooShort)\n\t\tfailures.set('minimum', formatMessage('minimum', control.getAttribute('minlength') ?? ''))\n\tif (validity.tooLong)\n\t\tfailures.set('maximum', formatMessage('maximum', control.getAttribute('maxlength') ?? ''))\n\tif (validity.stepMismatch) failures.set('step', 'Use a permitted value for this step')\n\tif (validity.patternMismatch) failures.set('pattern', formatMessage('pattern'))\n\tif (validity.typeMismatch && control instanceof HTMLInputElement) {\n\t\tif (control.type === 'email') failures.set('email', formatMessage('email'))\n\t\telse if (control.type === 'url') failures.set('url', formatMessage('url'))\n\t}\n\tconst messages: string[] = []\n\tif (validity.customError) messages.push(control.validationMessage)\n\tconst lone = failures.size + Number(validity.customError) + Number(validity.badInput) === 1\n\tif (validity.badInput) messages.push(lone ? control.validationMessage : 'Enter a valid value')\n\tfor (const [rule, message] of failures) {\n\t\tif (!rules.has(rule)) messages.push(lone ? control.validationMessage : message)\n\t}\n\treturn messages\n}\n\n/**\n * Reads one compatible native population using the document's blank-to-absence semantics.\n * @param field - The field declaring the answer shape.\n * @param controls - Controls sharing the field's name, in native order.\n * @returns The native answer, or undefined for an absent answer or empty population.\n * @throws Thrown when the population or answer is incompatible, including numeric bad input.\n * @example\n * ```ts\n * const input = document.createElement('input')\n * input.value = 'Ada'\n * readFormControls({ control: 'text', name: 'name' }, [input]) // 'Ada'\n * ```\n */\nexport function readFormControls(\n\tfield: FormField,\n\tcontrols: readonly FormControl[],\n): FieldValue | undefined {\n\tif (!matchesFormControls(field, controls)) {\n\t\tthrow new FormBindingError('CONTROL', `Incompatible controls for \"${field.name}\"`, {\n\t\t\tfield: field.name,\n\t\t})\n\t}\n\tconst first = controls[0]\n\tif (first === undefined) return undefined\n\tlet value: FieldValue | undefined\n\tif (field.control === 'list' && first instanceof HTMLSelectElement) {\n\t\tvalue = Array.from(first.selectedOptions)\n\t\t\t.filter((option) => !option.matches(':disabled'))\n\t\t\t.map((option) => option.value)\n\t} else if (field.control === 'checkbox') {\n\t\tvalue =\n\t\t\tfirst instanceof HTMLSelectElement\n\t\t\t\t? Array.from(first.selectedOptions, (option) => option.value)\n\t\t\t\t: controls\n\t\t\t\t\t\t.filter((control) => control instanceof HTMLInputElement && control.checked)\n\t\t\t\t\t\t.map((control) => control.value)\n\t} else if (field.control === 'select' && first instanceof HTMLInputElement) {\n\t\tvalue = controls.find(\n\t\t\t(control) => control instanceof HTMLInputElement && control.checked,\n\t\t)?.value\n\t} else if (field.control === 'confirm' && first instanceof HTMLInputElement) {\n\t\tvalue = first.checked\n\t} else if (field.control === 'number' && first instanceof HTMLInputElement) {\n\t\tif (first.validity.badInput)\n\t\t\tthrow new FormBindingError('CONTROL', 'Enter a number', { field: field.name })\n\t\tvalue = first.value === '' ? undefined : first.valueAsNumber\n\t} else if (field.control === 'file' && first instanceof HTMLInputElement) {\n\t\tvalue = Array.from(first.files ?? [], (file) => file.name)\n\t} else {\n\t\tvalue = first.value\n\t}\n\tif (!matchesAnswer(value)) return undefined\n\tif (value !== undefined && !matchesField(field, value)) {\n\t\tthrow new FormBindingError('CONTROL', `Incompatible native answer for \"${field.name}\"`, {\n\t\t\tfield: field.name,\n\t\t})\n\t}\n\treturn value\n}\n","import type { FormControl } from './types.js'\nimport { isInstance } from '@orkestrel/contract'\n\n/**\n * Checks whether a value is a native answer control.\n * @param value - The value to inspect.\n * @returns True if the value is an input, select, or textarea; false otherwise.\n * @example\n * ```ts\n * isFormControl(document.createElement('input')) // true\n * ```\n */\nexport function isFormControl(value: unknown): value is FormControl {\n\treturn (\n\t\t(typeof HTMLInputElement !== 'undefined' && isInstance(value, HTMLInputElement)) ||\n\t\t(typeof HTMLSelectElement !== 'undefined' && isInstance(value, HTMLSelectElement)) ||\n\t\t(typeof HTMLTextAreaElement !== 'undefined' && isInstance(value, HTMLTextAreaElement))\n\t)\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type { FieldError, FieldValue, FormField, FormInterface } from '@src/core'\nimport type {\n\tFormBindingAttribute,\n\tFormBindingEventMap,\n\tFormBindingInterface,\n\tFormBindingOptions,\n\tFormBindingValidity,\n\tFormControl,\n} from './types.js'\nimport { Emitter } from '@orkestrel/emitter'\nimport { matchesValue } from '@src/core'\nimport { FormBindingError, isFormBindingError } from './errors.js'\nimport { matchesFormControls, readFormControls, readNativeMessages } from './helpers.js'\nimport { isFormControl } from './validators.js'\n\n/** Implements a controlled native form over a borrowed document. */\nexport class FormBinding implements FormBindingInterface {\n\treadonly #element: HTMLFormElement\n\treadonly #document: FormInterface\n\treadonly #options: FormBindingOptions | undefined\n\treadonly #emitter: Emitter<FormBindingEventMap>\n\treadonly #observer: MutationObserver\n\treadonly #listeners = new AbortController()\n\treadonly #attributes = new Map<Element, Map<string, FormBindingAttribute>>()\n\treadonly #validity = new Map<FormControl, FormBindingValidity>()\n\treadonly #feedback = new Map<string, HTMLElement>()\n\treadonly #excluded = new Set<string>()\n\treadonly #logical = new Set<string>()\n\treadonly #unreadable = new Set<string>()\n\treadonly #names = new Map<FormControl, string>()\n\treadonly #readings = new Map<FormControl, string>()\n\treadonly #lists = new Map<HTMLSelectElement, HTMLSelectElement>()\n\treadonly #resets = new Map<HTMLSelectElement, readonly string[]>()\n\treadonly #deferred = new Set<string>()\n\treadonly #refresh = this.#onState.bind(this)\n\treadonly #fill = this.#onFill.bind(this)\n\treadonly #disable = this.#onDisable.bind(this)\n\treadonly #enable = this.#onEnable.bind(this)\n\treadonly #clear = this.#onClear.bind(this)\n\treadonly #abandon = this.destroy.bind(this)\n\t#controls: ReadonlyMap<string, readonly FormControl[]> = new Map()\n\t#summary: HTMLUListElement | undefined\n\t#summaryText = ''\n\t#destroyed = false\n\t#running = false\n\t#preserve: boolean | undefined\n\t#reading = false\n\t#excluding: string | undefined\n\t#changed = false\n\t#notified = false\n\t#scheduled = false\n\t#submitting = false\n\t#pointer: number | undefined\n\t#release: ReturnType<typeof setTimeout> | undefined\n\n\t/**\n\t * Binds existing controls to the supplied document's answers.\n\t * @param element - The native form, including its externally associated controls.\n\t * @param document - The borrowed answer document.\n\t * @param options - Feedback destinations and listeners.\n\t * @throws Thrown when controls contradict the schema or native initialization fails.\n\t */\n\tconstructor(element: HTMLFormElement, document: FormInterface, options?: FormBindingOptions) {\n\t\tthis.#element = element\n\t\tthis.#document = document\n\t\tthis.#options = options\n\t\tthis.#emitter = new Emitter<FormBindingEventMap>(options)\n\t\tthis.#observer = new MutationObserver(() => this.#onDocument(true))\n\t\tfor (const name of document.disabled) this.#logical.add(name)\n\t\ttry {\n\t\t\tthis.#controls = this.#discover()\n\t\t\tconst signal = this.#listeners.signal\n\t\t\telement.addEventListener('submit', (event) => this.#onSubmit(event), { signal })\n\t\t\telement.addEventListener('reset', (event) => this.#onReset(event), { signal })\n\t\t\telement.ownerDocument.addEventListener('input', (event) => this.#onInput(event), { signal })\n\t\t\telement.ownerDocument.addEventListener('change', (event) => this.#onInput(event), { signal })\n\t\t\telement.ownerDocument.addEventListener('focusout', (event) => this.#onBlur(event), { signal })\n\t\t\telement.ownerDocument.addEventListener('click', (event) => this.#onClick(event), { signal })\n\t\t\tif (options?.defer) {\n\t\t\t\telement.ownerDocument.addEventListener('pointerdown', (event) => this.#onPress(event), {\n\t\t\t\t\tsignal,\n\t\t\t\t\tcapture: true,\n\t\t\t\t})\n\t\t\t\telement.ownerDocument.addEventListener('pointerup', (event) => this.#onRelease(event), {\n\t\t\t\t\tsignal,\n\t\t\t\t\tcapture: true,\n\t\t\t\t})\n\t\t\t\telement.ownerDocument.addEventListener('pointercancel', (event) => this.#onRelease(event), {\n\t\t\t\t\tsignal,\n\t\t\t\t\tcapture: true,\n\t\t\t\t})\n\t\t\t\telement.ownerDocument.defaultView?.addEventListener('blur', () => this.#finishPress(), {\n\t\t\t\t\tsignal,\n\t\t\t\t})\n\t\t\t}\n\t\t\tdocument.emitter.on('fill', this.#fill)\n\t\t\tdocument.emitter.on('disable', this.#disable)\n\t\t\tdocument.emitter.on('enable', this.#enable)\n\t\t\tdocument.emitter.on('clear', this.#clear)\n\t\t\tdocument.emitter.on('abandon', this.#abandon)\n\t\t\tfor (const event of ['touch', 'validate', 'prepare', 'accept', 'abort', 'submit'] as const) {\n\t\t\t\tdocument.emitter.on(event, this.#refresh)\n\t\t\t}\n\t\t\tthis.refresh()\n\t\t\tif (!this.#destroyed) {\n\t\t\t\tthis.#observer.observe(element.ownerDocument, {\n\t\t\t\t\tsubtree: true,\n\t\t\t\t\tchildList: true,\n\t\t\t\t\tattributes: true,\n\t\t\t\t\tattributeFilter: [\n\t\t\t\t\t\t'name',\n\t\t\t\t\t\t'form',\n\t\t\t\t\t\t'id',\n\t\t\t\t\t\t'type',\n\t\t\t\t\t\t'multiple',\n\t\t\t\t\t\t'disabled',\n\t\t\t\t\t\t'required',\n\t\t\t\t\t\t'min',\n\t\t\t\t\t\t'max',\n\t\t\t\t\t\t'step',\n\t\t\t\t\t\t'pattern',\n\t\t\t\t\t\t'minlength',\n\t\t\t\t\t\t'maxlength',\n\t\t\t\t\t\t'value',\n\t\t\t\t\t\t'hidden',\n\t\t\t\t\t\t'inert',\n\t\t\t\t\t\t'style',\n\t\t\t\t\t\t'class',\n\t\t\t\t\t],\n\t\t\t\t})\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.destroy()\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t/** Holds the native form. */\n\tget element(): HTMLFormElement {\n\t\treturn this.#element\n\t}\n\t/** Holds the borrowed answer document. */\n\tget document(): FormInterface {\n\t\treturn this.#document\n\t}\n\t/** Reports whether the binding released its resources. */\n\tget destroyed(): boolean {\n\t\treturn this.#destroyed\n\t}\n\t/** Holds the binding's isolated event emitter. */\n\tget emitter(): EmitterInterface<FormBindingEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\t/** Imports mounted enabled controls without acknowledging their answers. */\n\tread(): void {\n\t\tif (this.#destroyed || this.#reading || this.#document.status !== 'editing') return\n\t\tconst controls = this.#discover()\n\t\tconst answers = new Map<string, FieldValue | undefined>()\n\t\tfor (const field of this.#document.schema.fields) {\n\t\t\tconst group = controls.get(field.name)\n\t\t\tif (group === undefined || field.locked || this.#logical.has(field.name)) continue\n\t\t\tconst enabled = group.filter((control) => !this.#nativeDisabled(control))\n\t\t\tif (enabled.length === 0) continue\n\t\t\tif (enabled.some((control) => control.validity.badInput)) {\n\t\t\t\tthis.#unreadable.add(field.name)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tthis.#unreadable.delete(field.name)\n\t\t\tanswers.set(field.name, readFormControls(field, enabled))\n\t\t}\n\t\tthis.#controls = controls\n\t\tthis.#reading = true\n\t\ttry {\n\t\t\tthis.#exclusions()\n\t\t\tfor (const [name, value] of answers) {\n\t\t\t\tif (this.#destroyed) break\n\t\t\t\tconst values = this.#document.values\n\t\t\t\tconst previous = Object.hasOwn(values, name) ? values[name] : undefined\n\t\t\t\tif (\n\t\t\t\t\tprevious === undefined || value === undefined\n\t\t\t\t\t\t? previous !== value\n\t\t\t\t\t\t: !matchesValue(previous, value)\n\t\t\t\t)\n\t\t\t\t\tthis.#document.fill(name, value)\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.#reading = false\n\t\t\tif (!this.#destroyed) this.#drain()\n\t\t}\n\t}\n\n\t/** Rediscovers controls and projects the document into the native form. */\n\trefresh(): void {\n\t\tif (this.#destroyed) return\n\t\tthis.#unreadable.clear()\n\t\tthis.#drain()\n\t}\n\n\t/** Releases owned DOM effects and listeners without destroying the document. */\n\tdestroy(): void {\n\t\tif (this.#destroyed) return\n\t\tthis.#destroyed = true\n\t\tthis.#observer.disconnect()\n\t\tthis.#listeners.abort()\n\t\tthis.#clearPress()\n\t\tthis.#document.emitter.off('fill', this.#fill)\n\t\tthis.#document.emitter.off('disable', this.#disable)\n\t\tthis.#document.emitter.off('enable', this.#enable)\n\t\tthis.#document.emitter.off('clear', this.#clear)\n\t\tthis.#document.emitter.off('abandon', this.#abandon)\n\t\tfor (const event of ['touch', 'validate', 'prepare', 'accept', 'abort', 'submit'] as const) {\n\t\t\tthis.#document.emitter.off(event, this.#refresh)\n\t\t}\n\t\tfor (const element of this.#attributes.keys()) this.#restore(element)\n\t\tfor (const control of this.#validity.keys()) this.#restoreValidity(control)\n\t\tfor (const node of this.#feedback.values()) node.remove()\n\t\tthis.#summary?.remove()\n\t\tif (this.#document.status === 'editing') {\n\t\t\tfor (const name of this.#excluded) {\n\t\t\t\tif (!this.#logical.has(name)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.#document.enable(name)\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tthis.#emitter.emit('error', error)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.#excluded.clear()\n\t\tthis.#feedback.clear()\n\t\tthis.#names.clear()\n\t\tthis.#readings.clear()\n\t\tthis.#lists.clear()\n\t\tthis.#resets.clear()\n\t\tthis.#unreadable.clear()\n\t\tthis.#logical.clear()\n\t\tthis.#controls = new Map()\n\t\tthis.#summary = undefined\n\t\tthis.#emitter.destroy()\n\t}\n\n\t#drain(preserve = false): void {\n\t\tif (this.#destroyed) return\n\t\tthis.#preserve = this.#preserve === false ? false : preserve\n\t\tif (this.#running || this.#reading) return\n\t\tthis.#running = true\n\t\ttry {\n\t\t\tlet turns = 0\n\t\t\twhile (this.#preserve !== undefined && !this.#destroyed && turns < 2) {\n\t\t\t\tconst retaining = this.#preserve\n\t\t\t\tthis.#preserve = undefined\n\t\t\t\tthis.#changed = false\n\t\t\t\tthis.#controls = this.#discover()\n\t\t\t\tthis.#releaseRemoved()\n\t\t\t\tthis.#exclusions()\n\t\t\t\tif (this.#destroyed) break\n\t\t\t\tthis.#paint(retaining)\n\t\t\t\tif (!this.#destroyed && (this.#changed || !this.#notified)) {\n\t\t\t\t\tthis.#notified = true\n\t\t\t\t\tthis.#emitter.emit('render')\n\t\t\t\t}\n\t\t\t\tturns += 1\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.#preserve = undefined\n\t\t\tthrow isFormBindingError(error)\n\t\t\t\t? error\n\t\t\t\t: new FormBindingError('DOM', 'Native form projection failed', { cause: error })\n\t\t} finally {\n\t\t\tthis.#running = false\n\t\t\tif (this.#preserve !== undefined && !this.#destroyed && !this.#scheduled) {\n\t\t\t\tthis.#scheduled = true\n\t\t\t\tqueueMicrotask(() => {\n\t\t\t\t\tthis.#scheduled = false\n\t\t\t\t\tif (!this.#destroyed) this.#onDocument(this.#preserve ?? false)\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\t#discover(): ReadonlyMap<string, readonly FormControl[]> {\n\t\tconst groups = new Map<string, FormControl[]>()\n\t\tfor (const control of Array.from(this.#element.elements)) {\n\t\t\tif (\n\t\t\t\t!isFormControl(control) ||\n\t\t\t\tcontrol.form !== this.#element ||\n\t\t\t\t!this.#document.field(control.name)\n\t\t\t)\n\t\t\t\tcontinue\n\t\t\tif (\n\t\t\t\tcontrol instanceof HTMLInputElement &&\n\t\t\t\t['submit', 'reset', 'button', 'image'].includes(control.type)\n\t\t\t)\n\t\t\t\tcontinue\n\t\t\tconst group = groups.get(control.name) ?? []\n\t\t\tgroup.push(control)\n\t\t\tgroups.set(control.name, group)\n\t\t}\n\t\tfor (const field of this.#document.schema.fields) {\n\t\t\tconst group = groups.get(field.name)\n\t\t\tif (group !== undefined && !matchesFormControls(field, group)) {\n\t\t\t\tthrow new FormBindingError('CONTROL', `Incompatible controls for \"${field.name}\"`, {\n\t\t\t\t\tfield: field.name,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\treturn groups\n\t}\n\n\t#nativeDisabled(control: FormControl): boolean {\n\t\tconst owned = this.#attributes.get(control)?.get('disabled')\n\t\tif (\n\t\t\towned !== undefined &&\n\t\t\tcontrol.getAttribute('disabled') === owned.value &&\n\t\t\towned.original === null\n\t\t) {\n\t\t\t// A model-owned disabled attribute cannot become a native exclusion on the next scan.\n\t\t\tlet ancestor = control.parentElement\n\t\t\twhile (ancestor !== null) {\n\t\t\t\tif (ancestor instanceof HTMLFieldSetElement && ancestor.disabled) {\n\t\t\t\t\tconst legend = Array.from(ancestor.children).find(\n\t\t\t\t\t\t(child) => child instanceof HTMLLegendElement,\n\t\t\t\t\t)\n\t\t\t\t\tif (legend === undefined || !legend.contains(control)) return true\n\t\t\t\t}\n\t\t\t\tancestor = ancestor.parentElement\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\t\treturn control.matches(':disabled')\n\t}\n\n\t#exclusions(): void {\n\t\tif (this.#document.status !== 'editing') return\n\t\tfor (const field of this.#document.schema.fields) {\n\t\t\tif (this.#destroyed) return\n\t\t\tconst group = this.#controls.get(field.name)\n\t\t\tconst excluded =\n\t\t\t\tgroup !== undefined && group.every((control) => this.#nativeDisabled(control))\n\t\t\tif (excluded && !this.#logical.has(field.name) && !this.#excluded.has(field.name)) {\n\t\t\t\tthis.#excluded.add(field.name)\n\t\t\t\tthis.#excluding = field.name\n\t\t\t\ttry {\n\t\t\t\t\tthis.#document.disable(field.name)\n\t\t\t\t} finally {\n\t\t\t\t\tthis.#excluding = undefined\n\t\t\t\t}\n\t\t\t} else if (!excluded && this.#excluded.delete(field.name) && !this.#logical.has(field.name)) {\n\t\t\t\tthis.#excluding = field.name\n\t\t\t\ttry {\n\t\t\t\t\tthis.#document.enable(field.name)\n\t\t\t\t} finally {\n\t\t\t\t\tthis.#excluding = undefined\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t#paint(preserve: boolean): void {\n\t\tthis.#attribute(this.#element, 'novalidate', '')\n\t\tthis.#attribute(\n\t\t\tthis.#element,\n\t\t\t'aria-busy',\n\t\t\tthis.#document.pending === undefined ? 'false' : 'true',\n\t\t)\n\t\tconst errors: FieldError[] = [...this.#document.errors]\n\t\tconst values = this.#document.values\n\t\tfor (const field of this.#document.schema.fields) {\n\t\t\tif (this.#destroyed) return\n\t\t\tconst group = this.#controls.get(field.name) ?? []\n\t\t\tfor (const control of group) {\n\t\t\t\tthis.#metadata(field, control)\n\t\t\t\tif (!this.#unreadable.has(field.name))\n\t\t\t\t\tthis.#value(\n\t\t\t\t\t\tfield,\n\t\t\t\t\t\tcontrol,\n\t\t\t\t\t\tObject.hasOwn(values, field.name) ? values[field.name] : undefined,\n\t\t\t\t\t\tpreserve,\n\t\t\t\t\t)\n\t\t\t\tif (this.#destroyed) return\n\t\t\t\tthis.#restoreValidity(control)\n\t\t\t\tif (\n\t\t\t\t\t!this.#document.disabled.has(field.name) &&\n\t\t\t\t\t!control.validity.valid &&\n\t\t\t\t\tcontrol.willValidate\n\t\t\t\t) {\n\t\t\t\t\tfor (const message of readNativeMessages(control, this.#document.errors))\n\t\t\t\t\t\terrors.push({ field: field.name, message })\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor (const field of this.#document.schema.fields) {\n\t\t\tif (this.#destroyed) return\n\t\t\tconst messages = [\n\t\t\t\t...new Set(\n\t\t\t\t\terrors.filter((error) => error.field === field.name).map((error) => error.message),\n\t\t\t\t),\n\t\t\t]\n\t\t\tconst message = messages.join('\\n')\n\t\t\tconst visible =\n\t\t\t\tthis.#document.touched.has(field.name) && !this.#document.disabled.has(field.name)\n\t\t\tconst group = this.#controls.get(field.name) ?? []\n\t\t\tlet feedback = this.#feedback.get(field.name)\n\t\t\tif (\n\t\t\t\tfeedback === undefined &&\n\t\t\t\t(group.length > 0 || this.#options?.feedback?.has(field.name))\n\t\t\t) {\n\t\t\t\tfeedback = this.#element.ownerDocument.createElement('span')\n\t\t\t\tfeedback.id = `form-feedback-${crypto.randomUUID()}`\n\t\t\t\tfeedback.dataset.formFeedback = field.name\n\t\t\t\tconst destination = this.#options?.feedback?.get(field.name)\n\t\t\t\tif (destination !== undefined) destination.append(feedback)\n\t\t\t\telse (group.at(-1) ?? this.#element).insertAdjacentElement('afterend', feedback)\n\t\t\t\tthis.#feedback.set(field.name, feedback)\n\t\t\t}\n\t\t\tif (feedback !== undefined) {\n\t\t\t\tif (feedback.textContent !== message) {\n\t\t\t\t\tfeedback.textContent = message\n\t\t\t\t\tthis.#changed = true\n\t\t\t\t}\n\t\t\t\tif (feedback.hidden !== (!visible || message === '')) {\n\t\t\t\t\tfeedback.hidden = !visible || message === ''\n\t\t\t\t\tthis.#changed = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const control of group) {\n\t\t\t\tif (message !== '' && !control.validity.customError) {\n\t\t\t\t\tthis.#validity.set(control, { original: '', value: message })\n\t\t\t\t\tcontrol.setCustomValidity(message)\n\t\t\t\t}\n\t\t\t\tthis.#attribute(control, 'aria-invalid', visible && message !== '' ? 'true' : null)\n\t\t\t\tif (feedback !== undefined)\n\t\t\t\t\tthis.#description(control, feedback.id, visible && message !== '')\n\t\t\t\tconst presentation = this.#options?.presentations?.get(control)\n\t\t\t\tif (presentation !== undefined) {\n\t\t\t\t\tthis.#attribute(presentation, 'aria-invalid', visible && message !== '' ? 'true' : null)\n\t\t\t\t\tif (feedback !== undefined)\n\t\t\t\t\t\tthis.#description(presentation, feedback.id, visible && message !== '')\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.#paintSummary(\n\t\t\terrors.filter(\n\t\t\t\t(error) =>\n\t\t\t\t\tthis.#document.touched.has(error.field) && !this.#document.disabled.has(error.field),\n\t\t\t),\n\t\t)\n\t\tfor (const control of Array.from(this.#element.elements)) {\n\t\t\tif (\n\t\t\t\t(control instanceof HTMLButtonElement && control.type === 'submit') ||\n\t\t\t\t(control instanceof HTMLInputElement && ['submit', 'image'].includes(control.type))\n\t\t\t) {\n\t\t\t\tthis.#attribute(\n\t\t\t\t\tcontrol,\n\t\t\t\t\t'aria-busy',\n\t\t\t\t\tthis.#document.pending === undefined ? 'false' : 'true',\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t}\n\n\t#metadata(field: FormField, control: FormControl): void {\n\t\tif (\n\t\t\tfield.control === 'list' &&\n\t\t\tcontrol instanceof HTMLSelectElement &&\n\t\t\t!this.#lists.has(control)\n\t\t) {\n\t\t\tconst snapshot = control.cloneNode(true)\n\t\t\tif (snapshot instanceof HTMLSelectElement) {\n\t\t\t\tfor (const [index, option] of Array.from(snapshot.options).entries()) {\n\t\t\t\t\toption.selected = control.options[index]?.selected ?? false\n\t\t\t\t}\n\t\t\t\tthis.#lists.set(control, snapshot)\n\t\t\t}\n\t\t}\n\t\tif (this.#logical.has(field.name)) this.#attribute(control, 'disabled', '')\n\t\telse this.#releaseAttribute(control, 'disabled')\n\t\tif (\n\t\t\tfield.locked &&\n\t\t\t!(control instanceof HTMLSelectElement) &&\n\t\t\t!(\n\t\t\t\tcontrol instanceof HTMLInputElement &&\n\t\t\t\t['radio', 'checkbox', 'file', 'range', 'color'].includes(control.type)\n\t\t\t)\n\t\t)\n\t\t\tthis.#attribute(control, 'readonly', '')\n\t\tif (field.rule?.required && !['confirm', 'checkbox', 'file'].includes(field.control))\n\t\t\tthis.#attribute(control, 'required', '')\n\t\tif (\n\t\t\tfield.control === 'number' ||\n\t\t\tfield.control === 'date' ||\n\t\t\tfield.control === 'time' ||\n\t\t\tfield.control === 'datetime'\n\t\t) {\n\t\t\tif (field.rule?.minimum !== undefined && !control.hasAttribute('min'))\n\t\t\t\tthis.#attribute(control, 'min', String(field.rule.minimum))\n\t\t\tif (field.rule?.maximum !== undefined && !control.hasAttribute('max'))\n\t\t\t\tthis.#attribute(control, 'max', String(field.rule.maximum))\n\t\t\tif (\n\t\t\t\tfield.control === 'number' &&\n\t\t\t\tfield.rule?.step !== undefined &&\n\t\t\t\t!control.hasAttribute('step')\n\t\t\t)\n\t\t\t\tthis.#attribute(control, 'step', String(field.rule.step))\n\t\t}\n\t}\n\n\t#value(\n\t\tfield: FormField,\n\t\tcontrol: FormControl,\n\t\tvalue: FieldValue | undefined,\n\t\tpreserve: boolean,\n\t): void {\n\t\tif (\n\t\t\tpreserve &&\n\t\t\t!field.locked &&\n\t\t\tcontrol.ownerDocument.activeElement === control &&\n\t\t\tthis.#readings.has(control) &&\n\t\t\t(control instanceof HTMLTextAreaElement ||\n\t\t\t\t(control instanceof HTMLInputElement &&\n\t\t\t\t\t['text', 'search', 'email', 'url', 'tel', 'password'].includes(control.type))) &&\n\t\t\tcontrol.value !== this.#readings.get(control)\n\t\t)\n\t\t\treturn\n\t\tlet changed = false\n\t\tif (control instanceof HTMLInputElement && control.type === 'file') {\n\t\t\t// The browser alone owns bytes. A differing saved name cannot create a FileList.\n\t\t\tconst names = Array.from(control.files ?? [], (file) => file.name)\n\t\t\tif (names.length > 0 && (value === undefined || !matchesValue(names, value))) {\n\t\t\t\tcontrol.value = ''\n\t\t\t\tthis.#changed = true\n\t\t\t\tthis.#emitter.emit('write', control)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tif (\n\t\t\tcontrol instanceof HTMLInputElement &&\n\t\t\t(control.type === 'checkbox' || control.type === 'radio')\n\t\t) {\n\t\t\tconst checked =\n\t\t\t\tfield.control === 'confirm'\n\t\t\t\t\t? value === true\n\t\t\t\t\t: Array.isArray(value)\n\t\t\t\t\t\t? value.includes(control.value)\n\t\t\t\t\t\t: value === control.value\n\t\t\tif (control.checked !== checked) {\n\t\t\t\tcontrol.checked = checked\n\t\t\t\tchanged = true\n\t\t\t}\n\t\t} else if (control instanceof HTMLSelectElement && field.control === 'list') {\n\t\t\tconst remaining = Array.from(control.options).filter((option) => !option.matches(':disabled'))\n\t\t\tconst selected: HTMLOptionElement[] = []\n\t\t\tfor (const entry of Array.isArray(value) ? value : []) {\n\t\t\t\tconst index = remaining.findIndex((option) => option.value === entry)\n\t\t\t\tlet option = index < 0 ? undefined : remaining.splice(index, 1)[0]\n\t\t\t\tif (option === undefined) {\n\t\t\t\t\toption = control.ownerDocument.createElement('option')\n\t\t\t\t\toption.value = entry\n\t\t\t\t\toption.text = entry\n\t\t\t\t\tcontrol.append(option)\n\t\t\t\t\tchanged = true\n\t\t\t\t}\n\t\t\t\tif (!option.selected) changed = true\n\t\t\t\toption.selected = true\n\t\t\t\tselected.push(option)\n\t\t\t}\n\t\t\tfor (const option of remaining) {\n\t\t\t\tif (option.selected) changed = true\n\t\t\t\toption.selected = false\n\t\t\t}\n\t\t\tconst ordered = Array.from(control.selectedOptions).filter(\n\t\t\t\t(option) => !option.matches(':disabled'),\n\t\t\t)\n\t\t\tif (selected.some((option, index) => ordered[index] !== option)) {\n\t\t\t\tcontrol.append(...selected)\n\t\t\t\tchanged = true\n\t\t\t}\n\t\t} else if (control instanceof HTMLSelectElement && control.multiple) {\n\t\t\tfor (const option of Array.from(control.options)) {\n\t\t\t\tconst selected = Array.isArray(value) && value.includes(option.value)\n\t\t\t\tif (option.selected !== selected) {\n\t\t\t\t\toption.selected = selected\n\t\t\t\t\tchanged = true\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconst text = value === undefined ? '' : String(value)\n\t\t\tif (\n\t\t\t\tcontrol.value !== text ||\n\t\t\t\t(control instanceof HTMLInputElement && control.validity.badInput)\n\t\t\t) {\n\t\t\t\tconst before = control.value\n\t\t\t\tconst invalid = control.validity.badInput\n\t\t\t\tcontrol.value = text\n\t\t\t\tif (control.value !== before || invalid) changed = true\n\t\t\t}\n\t\t}\n\t\tthis.#readings.set(control, control.value)\n\t\tif (control instanceof HTMLSelectElement) {\n\t\t\tconst before = this.#resets.get(control)\n\t\t\tif (before !== undefined) {\n\t\t\t\tthis.#resets.delete(control)\n\t\t\t\tchanged = !matchesValue(\n\t\t\t\t\tbefore,\n\t\t\t\t\tArray.from(control.selectedOptions, (option) => option.value),\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\tif (changed) {\n\t\t\tthis.#changed = true\n\t\t\tthis.#emitter.emit('write', control)\n\t\t}\n\t}\n\n\t#attribute(element: Element, name: string, value: string | null): void {\n\t\tconst attributes = this.#attributes.get(element) ?? new Map<string, FormBindingAttribute>()\n\t\tconst previous = attributes.get(name)\n\t\tconst current = element.getAttribute(name)\n\t\tconst original =\n\t\t\tprevious === undefined || previous.value !== current ? current : previous.original\n\t\tif (current !== value) {\n\t\t\tif (value === null) element.removeAttribute(name)\n\t\t\telse element.setAttribute(name, value)\n\t\t\tthis.#changed = true\n\t\t}\n\t\tattributes.set(name, { original, value })\n\t\tthis.#attributes.set(element, attributes)\n\t}\n\n\t#description(control: HTMLElement, id: string, shown: boolean): void {\n\t\tconst tokens = (control.getAttribute('aria-describedby') ?? '')\n\t\t\t.split(/\\s+/)\n\t\t\t.filter((token) => token !== '' && token !== id)\n\t\tif (shown) tokens.push(id)\n\t\tthis.#attribute(control, 'aria-describedby', tokens.length === 0 ? null : tokens.join(' '))\n\t}\n\n\t#releaseAttribute(element: Element, name: string): void {\n\t\tconst attributes = this.#attributes.get(element)\n\t\tconst owned = attributes?.get(name)\n\t\tif (owned === undefined) return\n\t\tif (element.getAttribute(name) === owned.value) {\n\t\t\tif (owned.original === null) element.removeAttribute(name)\n\t\t\telse element.setAttribute(name, owned.original)\n\t\t\tthis.#changed = true\n\t\t}\n\t\tattributes?.delete(name)\n\t}\n\n\t#restore(element: Element): void {\n\t\tfor (const name of this.#attributes.get(element)?.keys() ?? [])\n\t\t\tthis.#releaseAttribute(element, name)\n\t\tconst ids = new Set([...this.#feedback.values()].map((feedback) => feedback.id))\n\t\tconst description = element.getAttribute('aria-describedby')\n\t\tif (description !== null) {\n\t\t\tconst tokens = description.split(/\\s+/).filter((token) => token !== '' && !ids.has(token))\n\t\t\tif (tokens.length === 0) element.removeAttribute('aria-describedby')\n\t\t\telse if (tokens.join(' ') !== description)\n\t\t\t\telement.setAttribute('aria-describedby', tokens.join(' '))\n\t\t}\n\t\tthis.#attributes.delete(element)\n\t}\n\n\t#restoreValidity(control: FormControl): void {\n\t\tconst owned = this.#validity.get(control)\n\t\tif (\n\t\t\towned !== undefined &&\n\t\t\tcontrol.validity.customError &&\n\t\t\tcontrol.validationMessage === owned.value\n\t\t)\n\t\t\tcontrol.setCustomValidity(owned.original)\n\t\tthis.#validity.delete(control)\n\t}\n\n\t#releaseRemoved(): void {\n\t\tconst live = new Set([...this.#controls.values()].flat())\n\t\tconst presentations = new Set<Element | undefined>(\n\t\t\t[...live].map((control) => this.#options?.presentations?.get(control)),\n\t\t)\n\t\tfor (const [control, name] of this.#names) {\n\t\t\tif (!live.has(control) || control.name !== name) {\n\t\t\t\tif (control instanceof HTMLSelectElement) {\n\t\t\t\t\tthis.#lists.delete(control)\n\t\t\t\t\tthis.#resets.delete(control)\n\t\t\t\t}\n\t\t\t\tconst presentation = this.#options?.presentations?.get(control)\n\t\t\t\tif (presentation !== undefined) this.#restore(presentation)\n\t\t\t\tthis.#restoreValidity(control)\n\t\t\t\tthis.#restore(control)\n\t\t\t\tthis.#names.delete(control)\n\t\t\t\tthis.#readings.delete(control)\n\t\t\t}\n\t\t}\n\t\tfor (const control of live) this.#names.set(control, control.name)\n\t\tfor (const element of this.#attributes.keys()) {\n\t\t\tif (\n\t\t\t\t!presentations.has(element) &&\n\t\t\t\t(isFormControl(element) || element instanceof HTMLButtonElement) &&\n\t\t\t\telement.form !== this.#element\n\t\t\t)\n\t\t\t\tthis.#restore(element)\n\t\t}\n\t\tfor (const [name, feedback] of this.#feedback) {\n\t\t\tif (!this.#controls.has(name) && !this.#options?.feedback?.has(name)) {\n\t\t\t\tfeedback.remove()\n\t\t\t\tthis.#feedback.delete(name)\n\t\t\t}\n\t\t}\n\t}\n\n\t#paintSummary(errors: readonly FieldError[]): void {\n\t\tconst destination = this.#options?.summary\n\t\tif (destination === undefined) return\n\t\tconst text = JSON.stringify(\n\t\t\terrors.map((error) => [error.field, error.message, this.#focusable(error.field)?.id]),\n\t\t)\n\t\tif (text === this.#summaryText) return\n\t\tthis.#summaryText = text\n\t\tthis.#changed = true\n\t\tthis.#summary?.remove()\n\t\tthis.#summary = this.#element.ownerDocument.createElement('ul')\n\t\tthis.#summary.dataset.formSummary = ''\n\t\tthis.#summary.hidden = errors.length === 0\n\t\tfor (const error of errors) {\n\t\t\tconst entry = this.#element.ownerDocument.createElement('li')\n\t\t\tconst target = this.#focusable(error.field)\n\t\t\tconst label = this.#document.field(error.field)?.label ?? error.field\n\t\t\tif (target === undefined) entry.textContent = `${label}: ${error.message}`\n\t\t\telse {\n\t\t\t\tif (target.id === '') this.#attribute(target, 'id', `form-control-${crypto.randomUUID()}`)\n\t\t\t\tconst link = this.#element.ownerDocument.createElement('a')\n\t\t\t\tlink.href = `#${target.id}`\n\t\t\t\tlink.textContent = `${label}: ${error.message}`\n\t\t\t\tlink.dataset.formField = error.field\n\t\t\t\tentry.append(link)\n\t\t\t}\n\t\t\tthis.#summary.append(entry)\n\t\t}\n\t\tdestination.append(this.#summary)\n\t}\n\n\t#focusable(name: string): HTMLElement | undefined {\n\t\treturn this.#controls\n\t\t\t.get(name)\n\t\t\t?.filter((control) => !control.matches(':disabled'))\n\t\t\t.map((control) => this.#options?.presentations?.get(control) ?? control)\n\t\t\t?.find(\n\t\t\t\t(control) =>\n\t\t\t\t\t!control.matches(':disabled') &&\n\t\t\t\t\tcontrol.closest('[inert]') === null &&\n\t\t\t\t\tcontrol.getClientRects().length > 0 &&\n\t\t\t\t\t!['hidden', 'collapse'].includes(getComputedStyle(control).visibility) &&\n\t\t\t\t\t!(control instanceof HTMLInputElement && control.type === 'hidden'),\n\t\t\t)\n\t}\n\n\t#onDocument(preserve = false): void {\n\t\tif (this.#destroyed) return\n\t\ttry {\n\t\t\tthis.#drain(preserve)\n\t\t} catch (error) {\n\t\t\tthis.#emitter.emit('error', error)\n\t\t}\n\t}\n\n\t#onFill(name: string): void {\n\t\tthis.#unreadable.delete(name)\n\t\tthis.#onState()\n\t}\n\n\t#onState(): void {\n\t\tthis.#notified = false\n\t\tthis.#onDocument()\n\t}\n\n\t#onDisable(name: string): void {\n\t\tif (this.#excluding !== name) this.#logical.add(name)\n\t\tthis.#onState()\n\t}\n\n\t#onEnable(name: string): void {\n\t\tif (this.#excluding !== name) {\n\t\t\tthis.#logical.delete(name)\n\t\t\tthis.#excluded.delete(name)\n\t\t}\n\t\tthis.#onState()\n\t}\n\n\t#onClear(): void {\n\t\tthis.#clearPress()\n\t\tthis.#logical.clear()\n\t\tthis.#excluded.clear()\n\t\tthis.#unreadable.clear()\n\t\tfor (const name of this.#document.disabled) this.#logical.add(name)\n\t\tthis.#onState()\n\t}\n\n\t#onInput(event: Event): void {\n\t\tconst control = event.target\n\t\tif (\n\t\t\t!isFormControl(control) ||\n\t\t\tcontrol.form !== this.#element ||\n\t\t\t!this.#document.field(control.name) ||\n\t\t\tthis.#destroyed\n\t\t)\n\t\t\treturn\n\t\ttry {\n\t\t\tthis.read()\n\t\t} catch (error) {\n\t\t\tthis.#emitter.emit('error', error)\n\t\t}\n\t}\n\n\t#onClick(event: MouseEvent): void {\n\t\tconst control = event.target\n\t\tif (control instanceof Element) {\n\t\t\tconst link = control.closest('a[data-form-field]')\n\t\t\tif (\n\t\t\t\tlink instanceof HTMLAnchorElement &&\n\t\t\t\tthis.#summary?.contains(link) &&\n\t\t\t\tlink.dataset.formField !== undefined\n\t\t\t) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tthis.#focusable(link.dataset.formField)?.focus()\n\t\t\t}\n\t\t}\n\t\tif (\n\t\t\tcontrol instanceof HTMLInputElement &&\n\t\t\tcontrol.form === this.#element &&\n\t\t\tthis.#document.field(control.name)?.locked &&\n\t\t\t['file', 'checkbox', 'radio', 'color'].includes(control.type)\n\t\t)\n\t\t\tevent.preventDefault()\n\t}\n\n\t#onBlur(event: FocusEvent): void {\n\t\tlet control = event.target\n\t\tfor (const [native, presentation] of this.#options?.presentations ?? []) {\n\t\t\tif (control === presentation) {\n\t\t\t\tcontrol = native\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif (\n\t\t\t!isFormControl(control) ||\n\t\t\tcontrol.form !== this.#element ||\n\t\t\t!this.#document.field(control.name) ||\n\t\t\tthis.#destroyed ||\n\t\t\tthis.#document.status !== 'editing'\n\t\t)\n\t\t\treturn\n\t\tif (event.relatedTarget === this.#options?.presentations?.get(control)) return\n\t\tif (this.#pointer !== undefined) {\n\t\t\tthis.#deferred.add(control.name)\n\t\t\treturn\n\t\t}\n\t\ttry {\n\t\t\tthis.#document.touch(control.name)\n\t\t\tthis.#drain()\n\t\t} catch (error) {\n\t\t\tthis.#emitter.emit('error', error)\n\t\t}\n\t}\n\n\t#onPress(event: PointerEvent): void {\n\t\tif (!event.isPrimary || event.button !== 0 || !(event.target instanceof Element)) return\n\t\tconst button = event.target.closest('button,input')\n\t\tif (\n\t\t\t!(\n\t\t\t\t(button instanceof HTMLButtonElement ||\n\t\t\t\t\t(button instanceof HTMLInputElement &&\n\t\t\t\t\t\t['button', 'submit', 'reset', 'image'].includes(button.type))) &&\n\t\t\t\tbutton.form === this.#element &&\n\t\t\t\t!button.matches(':disabled')\n\t\t\t)\n\t\t)\n\t\t\treturn\n\t\tthis.#finishPress()\n\t\tthis.#pointer = event.pointerId\n\t}\n\n\t#onRelease(event: PointerEvent): void {\n\t\tif (event.pointerId !== this.#pointer) return\n\t\t// A task keeps the pointerup-to-click sequence free of layout-changing feedback.\n\t\tif (this.#release !== undefined) clearTimeout(this.#release)\n\t\tthis.#release = setTimeout(() => this.#finishPress(), 0)\n\t}\n\n\t#finishPress(): void {\n\t\tconst names = [...this.#deferred]\n\t\tthis.#clearPress()\n\t\tif (this.#destroyed || this.#document.status !== 'editing') return\n\t\ttry {\n\t\t\tfor (const name of names) {\n\t\t\t\tif (this.#destroyed) break\n\t\t\t\tthis.#document.touch(name)\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.#emitter.emit('error', error)\n\t\t}\n\t}\n\n\t#clearPress(): void {\n\t\tif (this.#release !== undefined) clearTimeout(this.#release)\n\t\tthis.#release = undefined\n\t\tthis.#pointer = undefined\n\t\tthis.#deferred.clear()\n\t}\n\n\t#onSubmit(event: SubmitEvent): void {\n\t\tif (event.defaultPrevented || this.#destroyed) return\n\t\tevent.preventDefault()\n\t\tif (this.#submitting || this.#document.pending !== undefined) {\n\t\t\tthis.#emitter.emit(\n\t\t\t\t'error',\n\t\t\t\tnew FormBindingError('PENDING', 'A submission is already pending'),\n\t\t\t)\n\t\t\treturn\n\t\t}\n\t\tthis.#submitting = true\n\t\ttry {\n\t\t\tthis.read()\n\t\t\tif (this.#destroyed) return\n\t\t\tfor (const field of this.#document.schema.fields) {\n\t\t\t\tif (!this.#document.disabled.has(field.name)) this.#document.touch(field.name)\n\t\t\t\tif (this.#destroyed) return\n\t\t\t}\n\t\t\tthis.#drain()\n\t\t\tconst native = [...this.#controls].filter(\n\t\t\t\t([name, controls]) =>\n\t\t\t\t\t!this.#document.disabled.has(name) &&\n\t\t\t\t\tcontrols.some((control) => control.willValidate && !control.validity.valid),\n\t\t\t)\n\t\t\tif (native.length > 0) {\n\t\t\t\tfor (const [name] of native) {\n\t\t\t\t\tconst target = this.#focusable(name)\n\t\t\t\t\tif (target !== undefined) {\n\t\t\t\t\t\ttarget.focus()\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst result = this.#document.prepare()\n\t\t\tif (this.#destroyed) return\n\t\t\tthis.#drain()\n\t\t\tif (result.success) {\n\t\t\t\tif (!result.value.signal.aborted && this.#document.pending === result.value)\n\t\t\t\t\tthis.#emitter.emit('submit', result.value, event.submitter ?? undefined)\n\t\t\t} else {\n\t\t\t\tfor (const error of result.error) {\n\t\t\t\t\tconst target = this.#focusable(error.field)\n\t\t\t\t\tif (target !== undefined) {\n\t\t\t\t\t\ttarget.focus()\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.#emitter.emit('error', error)\n\t\t} finally {\n\t\t\tthis.#submitting = false\n\t\t}\n\t}\n\n\t#onReset(event: Event): void {\n\t\tif (event.defaultPrevented || this.#destroyed) return\n\t\tevent.preventDefault()\n\t\ttry {\n\t\t\tconst lists = new Map<HTMLSelectElement, HTMLSelectElement>()\n\t\t\tfor (const [control, snapshot] of this.#lists) {\n\t\t\t\tif (\n\t\t\t\t\tcontrol.form === this.#element &&\n\t\t\t\t\tcontrol.name === snapshot.name &&\n\t\t\t\t\tthis.#document.field(control.name)?.control === 'list'\n\t\t\t\t) {\n\t\t\t\t\tlists.set(control, snapshot)\n\t\t\t\t\tthis.#resets.set(\n\t\t\t\t\t\tcontrol,\n\t\t\t\t\t\tArray.from(control.selectedOptions, (option) => option.value),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.#reading = true\n\t\t\ttry {\n\t\t\t\tthis.#document.clear()\n\t\t\t\tfor (const [control, snapshot] of lists) {\n\t\t\t\t\tif (this.#destroyed) return\n\t\t\t\t\tif (control.form !== this.#element || control.name !== snapshot.name) continue\n\t\t\t\t\tcontrol.replaceChildren(\n\t\t\t\t\t\t...Array.from(snapshot.childNodes, (node) => node.cloneNode(true)),\n\t\t\t\t\t)\n\t\t\t\t\tfor (const [index, option] of Array.from(control.options).entries()) {\n\t\t\t\t\t\toption.selected = snapshot.options[index]?.selected ?? false\n\t\t\t\t\t}\n\t\t\t\t\tconst field = this.#document.field(control.name)\n\t\t\t\t\tif (field !== undefined)\n\t\t\t\t\t\tthis.#document.fill(field.name, readFormControls(field, [control]))\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tthis.#reading = false\n\t\t\t}\n\t\t\tthis.refresh()\n\t\t} catch (error) {\n\t\t\tthis.#emitter.emit('error', error)\n\t\t} finally {\n\t\t\tthis.#resets.clear()\n\t\t}\n\t}\n}\n","import type { FormInterface } from '@src/core'\nimport type { FormBindingInterface, FormBindingOptions } from './types.js'\nimport { FormBinding } from './FormBinding.js'\n\n/**\n * Creates a native form binding exposed through its lifecycle interface.\n * @param element - The native form.\n * @param document - The borrowed answer document.\n * @param options - Feedback destinations and listeners.\n * @returns The initialized native binding.\n * @example\n * ```ts\n * const binding = createFormBinding(element, document)\n * binding.refresh()\n * ```\n */\nexport function createFormBinding(\n\telement: HTMLFormElement,\n\tdocument: FormInterface,\n\toptions?: FormBindingOptions,\n): FormBindingInterface {\n\treturn new FormBinding(element, document, options)\n}\n"],"mappings":"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"}
|