attaform 0.30.1 → 0.31.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/abstract.d.mts +5 -5
- package/dist/abstract.mjs +4 -4
- package/dist/dev/abstract.mjs +4 -4
- package/dist/dev/chunks/devtools.mjs +3 -3
- package/dist/dev/directive.mjs +1 -1
- package/dist/dev/history.mjs +15 -2
- package/dist/dev/index.mjs +5 -5
- package/dist/dev/runtime/plugins/attaform.mjs +1 -1
- package/dist/dev/shared/{attaform-dev.zlvDr0WB.mjs → attaform-dev.04aupFBW.mjs} +3 -2
- package/dist/dev/shared/{attaform-dev.DxHdkkPG.mjs → attaform-dev.3uTCYwy8.mjs} +770 -254
- package/dist/dev/shared/{attaform-dev.BJK1kqHY.mjs → attaform-dev.BpVGFSFa.mjs} +88 -115
- package/dist/dev/shared/{attaform-dev.Chm4D6SJ.mjs → attaform-dev.Bu6wgrA5.mjs} +3 -3
- package/dist/dev/shared/{attaform-dev.BMQ3GcgD.mjs → attaform-dev.Cbx0AiQF.mjs} +476 -337
- package/dist/dev/shared/attaform-dev.CwYTWyPX.mjs +120 -0
- package/dist/dev/shared/{attaform-dev.DuEE4GU1.mjs → attaform-dev.D7lKyM_7.mjs} +4 -4
- package/dist/dev/shared/{attaform-dev.CT7MDjPy.mjs → attaform-dev.OceE0X3v.mjs} +154 -229
- package/dist/{shared/attaform.DRsANMok.mjs → dev/shared/attaform-dev.PTGM9KE1.mjs} +16 -15
- package/dist/{shared/attaform.8mfKZCwH.mjs → dev/shared/attaform-dev.n6n00owJ.mjs} +49 -128
- package/dist/dev/zod-v3.mjs +6 -6
- package/dist/dev/zod-v4.mjs +6 -6
- package/dist/dev/zod.mjs +5 -5
- package/dist/directive.d.mts +2 -2
- package/dist/directive.mjs +1 -1
- package/dist/history.d.mts +1 -1
- package/dist/history.mjs +15 -2
- package/dist/index.d.mts +16 -55
- package/dist/index.mjs +5 -5
- package/dist/runtime/components/AttaformDevtoolsPanel.vue +3 -3
- package/dist/runtime/plugins/attaform.mjs +1 -1
- package/dist/shared/{attaform.CO918TdU.mjs → attaform.B5b-HmhH.mjs} +88 -115
- package/dist/shared/{attaform.2FslhB9R.d.mts → attaform.B9PYKlhB.d.mts} +43 -19
- package/dist/shared/{attaform.D_f1WgYf.mjs → attaform.BPMOl562.mjs} +458 -319
- package/dist/{dev/shared/attaform-dev.CZz4GYZ6.mjs → shared/attaform.BPSqtU7a.mjs} +44 -156
- package/dist/shared/{attaform.CdZIEf7_.mjs → attaform.BhtAZysa.mjs} +3 -2
- package/dist/shared/{attaform.BcQwgWaq.d.mts → attaform.CYlF4P6X.d.mts} +58 -17
- package/dist/shared/{attaform.WiGdIqgx.mjs → attaform.CdA9bfRv.mjs} +3 -3
- package/dist/shared/{attaform.BIWicztt.mjs → attaform.DAf4ehIe.mjs} +765 -251
- package/dist/shared/{attaform.ZYn2ahzJ.mjs → attaform.DBCbxlyk.mjs} +59 -1
- package/dist/shared/{attaform.L0kUn3vL.d.mts → attaform.DZOynI6c.d.mts} +1 -1
- package/dist/shared/{attaform.B2iebkPA.mjs → attaform.KEfNRDot.mjs} +4 -4
- package/dist/shared/attaform._1Zp3mDG.mjs +96 -0
- package/dist/shared/{attaform.Br8EBn5B.d.mts → attaform.i13OEHJF.d.mts} +195 -38
- package/dist/{dev/shared/attaform-dev.BUIFcTYf.mjs → shared/attaform.j9xI_ObC.mjs} +16 -15
- package/dist/shared/{attaform.D_pt1gOj.mjs → attaform.u6jfHoed.mjs} +154 -229
- package/dist/transforms.mjs +1 -1
- package/dist/vite.mjs +1 -1
- package/dist/zod-v3.d.mts +4 -4
- package/dist/zod-v3.mjs +6 -6
- package/dist/zod-v4.d.mts +22 -16
- package/dist/zod-v4.mjs +6 -6
- package/dist/zod.d.mts +4 -4
- package/dist/zod.mjs +5 -5
- package/package.json +2 -1
- package/skills/attaform/SKILL.md +2 -1
- package/skills/attaform/references/custom-components.md +4 -0
|
@@ -1,9 +1,348 @@
|
|
|
1
|
-
import { reactive, markRaw, effectScope, watch, nextTick } from 'vue';
|
|
1
|
+
import { toRaw, reactive, markRaw, effectScope, watch, nextTick } from 'vue';
|
|
2
2
|
import { i as isRegisterValue, a as isTransforming, S as SSR_COMPONENT_HOST_MODIFIER, R as REGISTER_OWNER_MARKER, b as V_REGISTER_MARKER } from './attaform.KvlEedlF.mjs';
|
|
3
|
-
import { e as canonicalizePath } from './attaform.
|
|
3
|
+
import { e as canonicalizePath } from './attaform.BhtAZysa.mjs';
|
|
4
|
+
import { e as safeOwnHas } from './attaform._1Zp3mDG.mjs';
|
|
5
|
+
|
|
6
|
+
function activeElementOf(node) {
|
|
7
|
+
const rootNode = node.getRootNode();
|
|
8
|
+
return rootNode instanceof Document || rootNode instanceof ShadowRoot ? rootNode.activeElement : null;
|
|
9
|
+
}
|
|
4
10
|
|
|
5
11
|
const INTERACTIVE_TAG_NAMES = /* @__PURE__ */ new Set(["INPUT", "SELECT", "TEXTAREA"]);
|
|
6
12
|
|
|
13
|
+
const isArray = Array.isArray;
|
|
14
|
+
function isFunction(value) {
|
|
15
|
+
return typeof value === "function";
|
|
16
|
+
}
|
|
17
|
+
function toTypeString(value) {
|
|
18
|
+
return Object.prototype.toString.call(value);
|
|
19
|
+
}
|
|
20
|
+
function isSet(value) {
|
|
21
|
+
return toTypeString(value) === "[object Set]";
|
|
22
|
+
}
|
|
23
|
+
function isDate(value) {
|
|
24
|
+
return toTypeString(value) === "[object Date]";
|
|
25
|
+
}
|
|
26
|
+
function isSymbol(value) {
|
|
27
|
+
return typeof value === "symbol";
|
|
28
|
+
}
|
|
29
|
+
function isObject(value) {
|
|
30
|
+
return value !== null && typeof value === "object";
|
|
31
|
+
}
|
|
32
|
+
function looseToNumber(val) {
|
|
33
|
+
const n = parseFloat(val);
|
|
34
|
+
return isNaN(n) ? val : n;
|
|
35
|
+
}
|
|
36
|
+
function looseCompareArrays(a, b) {
|
|
37
|
+
if (a.length !== b.length) return false;
|
|
38
|
+
let equal = true;
|
|
39
|
+
for (let i = 0; equal && i < a.length; i++) {
|
|
40
|
+
equal = looseEqual(a[i], b[i]);
|
|
41
|
+
}
|
|
42
|
+
return equal;
|
|
43
|
+
}
|
|
44
|
+
function looseEqual(a, b) {
|
|
45
|
+
if (a === b) return true;
|
|
46
|
+
const aValidType = isDate(a);
|
|
47
|
+
const bValidType = isDate(b);
|
|
48
|
+
if (aValidType || bValidType) {
|
|
49
|
+
return aValidType && bValidType ? a.getTime() === b.getTime() : false;
|
|
50
|
+
}
|
|
51
|
+
const aSymbol = isSymbol(a);
|
|
52
|
+
const bSymbol = isSymbol(b);
|
|
53
|
+
if (aSymbol || bSymbol) return a === b;
|
|
54
|
+
const aIsArray = isArray(a);
|
|
55
|
+
const bIsArray = isArray(b);
|
|
56
|
+
if (aIsArray || bIsArray) {
|
|
57
|
+
return aIsArray && bIsArray ? looseCompareArrays(a, b) : false;
|
|
58
|
+
}
|
|
59
|
+
const aIsObject = isObject(a);
|
|
60
|
+
const bIsObject = isObject(b);
|
|
61
|
+
if (aIsObject !== bIsObject) return false;
|
|
62
|
+
if (aIsObject && bIsObject) {
|
|
63
|
+
const keysA = Object.keys(a);
|
|
64
|
+
if (keysA.length !== Object.keys(b).length) return false;
|
|
65
|
+
for (const key of keysA) {
|
|
66
|
+
const hasA = Object.prototype.hasOwnProperty.call(a, key);
|
|
67
|
+
const hasB = Object.prototype.hasOwnProperty.call(b, key);
|
|
68
|
+
if (!hasA || !hasB || !looseEqual(a[key], b[key])) return false;
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
return String(a) === String(b);
|
|
73
|
+
}
|
|
74
|
+
function looseIndexOf(arr, val) {
|
|
75
|
+
return arr.findIndex((item) => looseEqual(item, val));
|
|
76
|
+
}
|
|
77
|
+
function invokeArrayFns(fns, ...args) {
|
|
78
|
+
for (let i = 0; i < fns.length; i++) {
|
|
79
|
+
const fn = fns[i];
|
|
80
|
+
if (fn) fn(...args);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const assignKey = /* @__PURE__ */ Symbol.for("attaform:assign-key");
|
|
85
|
+
const DEFAULT_ASSIGNER_TAG = /* @__PURE__ */ Symbol.for("attaform:default-assigner-tag");
|
|
86
|
+
function isDefaultAssigner(fn) {
|
|
87
|
+
return typeof fn === "function" && fn[DEFAULT_ASSIGNER_TAG] === true;
|
|
88
|
+
}
|
|
89
|
+
const CONSUMER_WRAPPED_TAG = /* @__PURE__ */ Symbol.for("attaform:consumer-wrapped-assigner");
|
|
90
|
+
function isConsumerWrapped(fn) {
|
|
91
|
+
return typeof fn === "function" && fn[CONSUMER_WRAPPED_TAG] === true;
|
|
92
|
+
}
|
|
93
|
+
function fireAssigner(el, registerValue, value) {
|
|
94
|
+
const fn = el[assignKey];
|
|
95
|
+
if (fn === void 0) return void 0;
|
|
96
|
+
if (isDefaultAssigner(fn) || isConsumerWrapped(fn)) {
|
|
97
|
+
return fn(value);
|
|
98
|
+
}
|
|
99
|
+
if (!isRegisterValue(registerValue)) {
|
|
100
|
+
return fn(value, void 0);
|
|
101
|
+
}
|
|
102
|
+
return wrapWithTransforms(
|
|
103
|
+
value,
|
|
104
|
+
registerValue,
|
|
105
|
+
(coerced) => fn(coerced, registerValue),
|
|
106
|
+
void 0
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
function isThenable(x) {
|
|
110
|
+
return x !== null && (typeof x === "object" || typeof x === "function") && typeof x.then === "function";
|
|
111
|
+
}
|
|
112
|
+
function makeTransformContext() {
|
|
113
|
+
const holder = { controller: null, aborted: false };
|
|
114
|
+
const ctx = {
|
|
115
|
+
get signal() {
|
|
116
|
+
if (holder.controller === null) {
|
|
117
|
+
holder.controller = new AbortController();
|
|
118
|
+
if (holder.aborted) holder.controller.abort();
|
|
119
|
+
}
|
|
120
|
+
return holder.controller.signal;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
return { ctx, holder };
|
|
124
|
+
}
|
|
125
|
+
function runTransforms(initial, registerValue) {
|
|
126
|
+
const transforms = registerValue.transforms;
|
|
127
|
+
if (transforms === void 0 || transforms.length === 0) {
|
|
128
|
+
return { kind: "sync", ok: true, value: initial };
|
|
129
|
+
}
|
|
130
|
+
const { ctx, holder } = makeTransformContext();
|
|
131
|
+
let v = initial;
|
|
132
|
+
for (let i = 0; i < transforms.length; i++) {
|
|
133
|
+
const fn = transforms[i];
|
|
134
|
+
let out;
|
|
135
|
+
try {
|
|
136
|
+
out = fn(v, ctx);
|
|
137
|
+
} catch (err) {
|
|
138
|
+
logTransformFailure(registerValue.path);
|
|
139
|
+
return { kind: "sync", ok: false };
|
|
140
|
+
}
|
|
141
|
+
if (isThenable(out)) {
|
|
142
|
+
const rest = transforms.slice(i + 1);
|
|
143
|
+
const seed = out;
|
|
144
|
+
const run = () => rest.reduce(
|
|
145
|
+
(acc, next) => acc.then((value) => next(value, ctx)),
|
|
146
|
+
Promise.resolve(seed)
|
|
147
|
+
);
|
|
148
|
+
return { kind: "async", run, holder };
|
|
149
|
+
}
|
|
150
|
+
v = out;
|
|
151
|
+
}
|
|
152
|
+
return { kind: "sync", ok: true, value: v };
|
|
153
|
+
}
|
|
154
|
+
function kickoffAsyncTransform(rv, holder, run, commit, syncDom) {
|
|
155
|
+
const token = rv.beginTransform(holder);
|
|
156
|
+
void run().then(
|
|
157
|
+
(value) => {
|
|
158
|
+
const live = rv.isCurrentTransform(token);
|
|
159
|
+
rv.endTransform(token);
|
|
160
|
+
if (!live) return;
|
|
161
|
+
const coerced = applyCoerce(value, rv);
|
|
162
|
+
const wrote = commit(coerced);
|
|
163
|
+
if (wrote === false) rv.setTransformError(transformGateRejectedError(rv.path));
|
|
164
|
+
else syncDom?.();
|
|
165
|
+
},
|
|
166
|
+
(err) => {
|
|
167
|
+
if (rv.isCurrentTransform(token)) rv.setTransformError(toTransformError(err));
|
|
168
|
+
rv.endTransform(token);
|
|
169
|
+
}
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
function logTransformFailure(path, index, fn, err) {
|
|
173
|
+
{
|
|
174
|
+
console.error("[attaform] AF14 attaform.dev/e/af14");
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function applyCoerce(value, registerValue) {
|
|
178
|
+
return registerValue.coerce !== void 0 ? registerValue.coerce(value) : value;
|
|
179
|
+
}
|
|
180
|
+
function wrapWithTransforms(value, registerValue, commit, syncDom) {
|
|
181
|
+
const r = runTransforms(value, registerValue);
|
|
182
|
+
if (r.kind === "async") {
|
|
183
|
+
kickoffAsyncTransform(registerValue, r.holder, r.run, commit, syncDom);
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
if (!r.ok) return false;
|
|
187
|
+
const coerced = applyCoerce(r.value, registerValue);
|
|
188
|
+
return commit(coerced);
|
|
189
|
+
}
|
|
190
|
+
function toTransformError(value) {
|
|
191
|
+
if (value instanceof Error) return value;
|
|
192
|
+
const message = typeof value === "string" && value.length > 0 ? value : `Transform rejected with a non-Error value (${typeof value})`;
|
|
193
|
+
return new Error(message, { cause: value });
|
|
194
|
+
}
|
|
195
|
+
function transformGateRejectedError(path) {
|
|
196
|
+
return new Error(
|
|
197
|
+
`[attaform] transform result for path '${path}' was rejected by the field's type gate (the resolved value did not fit the schema slot).`
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
const getModelAssigner = (el, vnode, registerValue) => {
|
|
201
|
+
const fn = vnode.props?.["onUpdate:registerValue"] ?? vnode.props?.["on:update:registerValue"];
|
|
202
|
+
if (isArray(fn)) {
|
|
203
|
+
const fnArr = fn.filter((x) => isFunction(x));
|
|
204
|
+
const wrapped = (value) => {
|
|
205
|
+
return wrapWithTransforms(
|
|
206
|
+
value,
|
|
207
|
+
registerValue,
|
|
208
|
+
(coerced) => {
|
|
209
|
+
invokeArrayFns(fnArr, coerced, registerValue);
|
|
210
|
+
return void 0;
|
|
211
|
+
},
|
|
212
|
+
void 0
|
|
213
|
+
);
|
|
214
|
+
};
|
|
215
|
+
wrapped[CONSUMER_WRAPPED_TAG] = true;
|
|
216
|
+
return wrapped;
|
|
217
|
+
}
|
|
218
|
+
if (isFunction(fn)) {
|
|
219
|
+
const handler = fn;
|
|
220
|
+
const wrapped = (value) => {
|
|
221
|
+
return wrapWithTransforms(
|
|
222
|
+
value,
|
|
223
|
+
registerValue,
|
|
224
|
+
(coerced) => handler(coerced, registerValue),
|
|
225
|
+
void 0
|
|
226
|
+
);
|
|
227
|
+
};
|
|
228
|
+
wrapped[CONSUMER_WRAPPED_TAG] = true;
|
|
229
|
+
return wrapped;
|
|
230
|
+
}
|
|
231
|
+
const defaultAssigner = (value) => {
|
|
232
|
+
if (value === void 0 && registerValue.acceptsUndefined) {
|
|
233
|
+
return registerValue.setValueWithInternalPath(void 0);
|
|
234
|
+
}
|
|
235
|
+
return wrapWithTransforms(
|
|
236
|
+
value,
|
|
237
|
+
registerValue,
|
|
238
|
+
(coerced) => registerValue.setValueWithInternalPath(coerced),
|
|
239
|
+
el._syncFromStorage
|
|
240
|
+
);
|
|
241
|
+
};
|
|
242
|
+
defaultAssigner[DEFAULT_ASSIGNER_TAG] = true;
|
|
243
|
+
return defaultAssigner;
|
|
244
|
+
};
|
|
245
|
+
function makeNoopAssigner() {
|
|
246
|
+
const noop = (_) => void 0;
|
|
247
|
+
noop[DEFAULT_ASSIGNER_TAG] = true;
|
|
248
|
+
return noop;
|
|
249
|
+
}
|
|
250
|
+
function setAssignFunction(el, vnode, value) {
|
|
251
|
+
const current = el[assignKey];
|
|
252
|
+
if (current !== void 0 && !isDefaultAssigner(current) && !isConsumerWrapped(current)) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (value === void 0) {
|
|
256
|
+
el[assignKey] = makeNoopAssigner();
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (!isRegisterValue(value)) {
|
|
260
|
+
el[assignKey] = makeNoopAssigner();
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
el[assignKey] = getModelAssigner(el, vnode, value);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const inherited = /* @__PURE__ */ new WeakMap();
|
|
267
|
+
function recordInheritedModifiers(rv, modifiers) {
|
|
268
|
+
const lazy = modifiers.lazy === true;
|
|
269
|
+
const trim = modifiers.trim === true;
|
|
270
|
+
const number = modifiers.number === true;
|
|
271
|
+
if ((lazy || trim || number) && typeof rv === "object" && rv !== null) {
|
|
272
|
+
inherited.set(toRaw(rv), { lazy, trim, number });
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
function withInheritedModifiers(rv, own) {
|
|
276
|
+
const found = typeof rv === "object" && rv !== null ? inherited.get(toRaw(rv)) : void 0;
|
|
277
|
+
return found === void 0 ? own : { ...found, ...own };
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function commit(rv, raw, modifiers) {
|
|
281
|
+
let value = raw;
|
|
282
|
+
if (modifiers.number === true && typeof value === "string") {
|
|
283
|
+
const cast = looseToNumber(value);
|
|
284
|
+
if (typeof cast !== "number") return rv.markBlank();
|
|
285
|
+
if (!Number.isFinite(cast)) return false;
|
|
286
|
+
value = cast;
|
|
287
|
+
}
|
|
288
|
+
if (value == null || value === "" && !rv.acceptsString) return rv.commitFromHost(value);
|
|
289
|
+
return wrapWithTransforms(value, rv, (coerced) => rv.commitFromHost(coerced), void 0) !== false;
|
|
290
|
+
}
|
|
291
|
+
function createHostChannel() {
|
|
292
|
+
const editing = /* @__PURE__ */ new Set();
|
|
293
|
+
const pending = /* @__PURE__ */ new Map();
|
|
294
|
+
const heldDraft = (rv) => {
|
|
295
|
+
const draft = pending.get(rv.path);
|
|
296
|
+
return draft?.basis === rv.innerRef.value ? draft : void 0;
|
|
297
|
+
};
|
|
298
|
+
return {
|
|
299
|
+
write(rv, value, ownModifiers) {
|
|
300
|
+
const modifiers = withInheritedModifiers(rv, ownModifiers);
|
|
301
|
+
if (modifiers.lazy === true && editing.has(rv.path)) {
|
|
302
|
+
pending.set(rv.path, { value, basis: rv.innerRef.value });
|
|
303
|
+
return true;
|
|
304
|
+
}
|
|
305
|
+
return commit(rv, value, modifiers);
|
|
306
|
+
},
|
|
307
|
+
writeInput(rv, payload, modifiers) {
|
|
308
|
+
if (typeof payload !== "object" || payload === null || payload instanceof Event || !("value" in payload) || !safeOwnHas(payload, "value")) {
|
|
309
|
+
return false;
|
|
310
|
+
}
|
|
311
|
+
return rv.setValueFromHost(payload.value, modifiers);
|
|
312
|
+
},
|
|
313
|
+
markEditing(rv, isEditing, modifiers) {
|
|
314
|
+
if (isEditing) {
|
|
315
|
+
editing.add(rv.path);
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
editing.delete(rv.path);
|
|
319
|
+
const draft = heldDraft(rv);
|
|
320
|
+
if (pending.delete(rv.path)) {
|
|
321
|
+
if (draft !== void 0) {
|
|
322
|
+
const buffered = draft.value;
|
|
323
|
+
commit(
|
|
324
|
+
rv,
|
|
325
|
+
modifiers.trim === true && typeof buffered === "string" ? buffered.trim() : buffered,
|
|
326
|
+
modifiers
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
if (modifiers.trim === true) {
|
|
332
|
+
const current = rv.innerRef.value;
|
|
333
|
+
if (typeof current === "string" && current !== current.trim()) {
|
|
334
|
+
commit(rv, current.trim(), modifiers);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
},
|
|
338
|
+
holdsDraft: (rv) => heldDraft(rv) !== void 0,
|
|
339
|
+
release(rv) {
|
|
340
|
+
editing.delete(rv.path);
|
|
341
|
+
pending.delete(rv.path);
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
|
|
7
346
|
const attaformListenersSymbol = /* @__PURE__ */ Symbol.for("attaform:focus-listeners");
|
|
8
347
|
const HOST_FOCUS_TARGET_SELECTOR = [
|
|
9
348
|
'input:not([type="hidden"])',
|
|
@@ -33,9 +372,7 @@ function attachFocusListeners(kernel, segments, element, instanceMeta) {
|
|
|
33
372
|
element.addEventListener("focus", handleFocus);
|
|
34
373
|
element.addEventListener("blur", handleBlur);
|
|
35
374
|
target[attaformListenersSymbol] = { handleFocus, handleBlur };
|
|
36
|
-
|
|
37
|
-
const activeElement = rootNode instanceof Document || rootNode instanceof ShadowRoot ? rootNode.activeElement : null;
|
|
38
|
-
if (activeElement === element) {
|
|
375
|
+
if (activeElementOf(element) === element) {
|
|
39
376
|
kernel.markFocused(segments, true, focusMeta);
|
|
40
377
|
}
|
|
41
378
|
}
|
|
@@ -101,124 +438,54 @@ function createDomBinding(kernel) {
|
|
|
101
438
|
}
|
|
102
439
|
}
|
|
103
440
|
function rebuildSortedRegistrations() {
|
|
104
|
-
const flat = [];
|
|
105
|
-
for (const [, record] of elements) {
|
|
106
|
-
for (const el of record.elements) {
|
|
107
|
-
flat.push({
|
|
108
|
-
path: record.path,
|
|
109
|
-
element: el,
|
|
110
|
-
host: false,
|
|
111
|
-
formInstanceId: elementToFormInstance.get(el) ?? ""
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
for (const [key, target] of hostTargets) {
|
|
116
|
-
if (elements.has(key)) continue;
|
|
117
|
-
flat.push({
|
|
118
|
-
path: target.path,
|
|
119
|
-
element: target.hostRoot,
|
|
120
|
-
host: true,
|
|
121
|
-
formInstanceId: target.formInstanceId
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
flat.sort(
|
|
125
|
-
(a, b) => a.element.compareDocumentPosition(b.element) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1
|
|
126
|
-
);
|
|
127
|
-
return flat;
|
|
128
|
-
}
|
|
129
|
-
function getFirstErrorElement(formInstanceId) {
|
|
130
|
-
sortedRegistrationsCache ?? (sortedRegistrationsCache = rebuildSortedRegistrations());
|
|
131
|
-
for (const entry of sortedRegistrationsCache) {
|
|
132
|
-
if (entry.formInstanceId !== formInstanceId) continue;
|
|
133
|
-
if (!entry.element.isConnected) continue;
|
|
134
|
-
if (entry.element.offsetParent === null) continue;
|
|
135
|
-
if (kernel.getErrorsForPath(entry.path).length === 0) continue;
|
|
136
|
-
const element = entry.host ? resolveHostFocusTarget(entry.element) : entry.element;
|
|
137
|
-
return { path: entry.path, element };
|
|
138
|
-
}
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
return {
|
|
142
|
-
elements,
|
|
143
|
-
attach,
|
|
144
|
-
detach,
|
|
145
|
-
markHostConnected,
|
|
146
|
-
getFirstErrorElement
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
function armDomBinding(value) {
|
|
150
|
-
value.ensureDomBinding?.(createDomBinding);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const isArray = Array.isArray;
|
|
154
|
-
function isFunction(value) {
|
|
155
|
-
return typeof value === "function";
|
|
156
|
-
}
|
|
157
|
-
function toTypeString(value) {
|
|
158
|
-
return Object.prototype.toString.call(value);
|
|
159
|
-
}
|
|
160
|
-
function isSet(value) {
|
|
161
|
-
return toTypeString(value) === "[object Set]";
|
|
162
|
-
}
|
|
163
|
-
function isDate(value) {
|
|
164
|
-
return toTypeString(value) === "[object Date]";
|
|
165
|
-
}
|
|
166
|
-
function isSymbol(value) {
|
|
167
|
-
return typeof value === "symbol";
|
|
168
|
-
}
|
|
169
|
-
function isObject(value) {
|
|
170
|
-
return value !== null && typeof value === "object";
|
|
171
|
-
}
|
|
172
|
-
function looseToNumber(val) {
|
|
173
|
-
const n = parseFloat(val);
|
|
174
|
-
return isNaN(n) ? val : n;
|
|
175
|
-
}
|
|
176
|
-
function looseCompareArrays(a, b) {
|
|
177
|
-
if (a.length !== b.length) return false;
|
|
178
|
-
let equal = true;
|
|
179
|
-
for (let i = 0; equal && i < a.length; i++) {
|
|
180
|
-
equal = looseEqual(a[i], b[i]);
|
|
181
|
-
}
|
|
182
|
-
return equal;
|
|
183
|
-
}
|
|
184
|
-
function looseEqual(a, b) {
|
|
185
|
-
if (a === b) return true;
|
|
186
|
-
const aValidType = isDate(a);
|
|
187
|
-
const bValidType = isDate(b);
|
|
188
|
-
if (aValidType || bValidType) {
|
|
189
|
-
return aValidType && bValidType ? a.getTime() === b.getTime() : false;
|
|
190
|
-
}
|
|
191
|
-
const aSymbol = isSymbol(a);
|
|
192
|
-
const bSymbol = isSymbol(b);
|
|
193
|
-
if (aSymbol || bSymbol) return a === b;
|
|
194
|
-
const aIsArray = isArray(a);
|
|
195
|
-
const bIsArray = isArray(b);
|
|
196
|
-
if (aIsArray || bIsArray) {
|
|
197
|
-
return aIsArray && bIsArray ? looseCompareArrays(a, b) : false;
|
|
441
|
+
const flat = [];
|
|
442
|
+
for (const [, record] of elements) {
|
|
443
|
+
for (const el of record.elements) {
|
|
444
|
+
flat.push({
|
|
445
|
+
path: record.path,
|
|
446
|
+
element: el,
|
|
447
|
+
host: false,
|
|
448
|
+
formInstanceId: elementToFormInstance.get(el) ?? ""
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
for (const [key, target] of hostTargets) {
|
|
453
|
+
if (elements.has(key)) continue;
|
|
454
|
+
flat.push({
|
|
455
|
+
path: target.path,
|
|
456
|
+
element: target.hostRoot,
|
|
457
|
+
host: true,
|
|
458
|
+
formInstanceId: target.formInstanceId
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
flat.sort(
|
|
462
|
+
(a, b) => a.element.compareDocumentPosition(b.element) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1
|
|
463
|
+
);
|
|
464
|
+
return flat;
|
|
198
465
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
if (!hasA || !hasB || !looseEqual(a[key], b[key])) return false;
|
|
466
|
+
function getFirstErrorElement(formInstanceId) {
|
|
467
|
+
sortedRegistrationsCache ?? (sortedRegistrationsCache = rebuildSortedRegistrations());
|
|
468
|
+
for (const entry of sortedRegistrationsCache) {
|
|
469
|
+
if (entry.formInstanceId !== formInstanceId) continue;
|
|
470
|
+
if (!entry.element.isConnected) continue;
|
|
471
|
+
if (entry.element.offsetParent === null) continue;
|
|
472
|
+
if (kernel.getErrorsForPath(entry.path).length === 0) continue;
|
|
473
|
+
const element = entry.host ? resolveHostFocusTarget(entry.element) : entry.element;
|
|
474
|
+
return { path: entry.path, element };
|
|
209
475
|
}
|
|
210
|
-
return
|
|
476
|
+
return null;
|
|
211
477
|
}
|
|
212
|
-
return
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
478
|
+
return {
|
|
479
|
+
elements,
|
|
480
|
+
attach,
|
|
481
|
+
detach,
|
|
482
|
+
markHostConnected,
|
|
483
|
+
getFirstErrorElement,
|
|
484
|
+
hostChannel: createHostChannel()
|
|
485
|
+
};
|
|
216
486
|
}
|
|
217
|
-
function
|
|
218
|
-
|
|
219
|
-
const fn = fns[i];
|
|
220
|
-
if (fn) fn(...args);
|
|
221
|
-
}
|
|
487
|
+
function armDomBinding(value) {
|
|
488
|
+
return value.ensureDomBinding?.(createDomBinding);
|
|
222
489
|
}
|
|
223
490
|
|
|
224
491
|
const MANAGED_ARIA_ATTRS = [
|
|
@@ -369,188 +636,6 @@ function isRegisterValueLike(val) {
|
|
|
369
636
|
return typeof val === "object" && val !== null && "markInteracted" in val && typeof val.markInteracted === "function";
|
|
370
637
|
}
|
|
371
638
|
|
|
372
|
-
const assignKey = /* @__PURE__ */ Symbol.for("attaform:assign-key");
|
|
373
|
-
const DEFAULT_ASSIGNER_TAG = /* @__PURE__ */ Symbol.for("attaform:default-assigner-tag");
|
|
374
|
-
function isDefaultAssigner(fn) {
|
|
375
|
-
return typeof fn === "function" && fn[DEFAULT_ASSIGNER_TAG] === true;
|
|
376
|
-
}
|
|
377
|
-
const CONSUMER_WRAPPED_TAG = /* @__PURE__ */ Symbol.for("attaform:consumer-wrapped-assigner");
|
|
378
|
-
function isConsumerWrapped(fn) {
|
|
379
|
-
return typeof fn === "function" && fn[CONSUMER_WRAPPED_TAG] === true;
|
|
380
|
-
}
|
|
381
|
-
function fireAssigner(el, registerValue, value) {
|
|
382
|
-
const fn = el[assignKey];
|
|
383
|
-
if (fn === void 0) return void 0;
|
|
384
|
-
if (isDefaultAssigner(fn) || isConsumerWrapped(fn)) {
|
|
385
|
-
return fn(value);
|
|
386
|
-
}
|
|
387
|
-
if (!isRegisterValue(registerValue)) {
|
|
388
|
-
return fn(value, void 0);
|
|
389
|
-
}
|
|
390
|
-
return wrapWithTransforms(
|
|
391
|
-
value,
|
|
392
|
-
registerValue,
|
|
393
|
-
(coerced) => fn(coerced, registerValue),
|
|
394
|
-
void 0
|
|
395
|
-
);
|
|
396
|
-
}
|
|
397
|
-
function isThenable(x) {
|
|
398
|
-
return x !== null && (typeof x === "object" || typeof x === "function") && typeof x.then === "function";
|
|
399
|
-
}
|
|
400
|
-
function makeTransformContext() {
|
|
401
|
-
const holder = { controller: null, aborted: false };
|
|
402
|
-
const ctx = {
|
|
403
|
-
get signal() {
|
|
404
|
-
if (holder.controller === null) {
|
|
405
|
-
holder.controller = new AbortController();
|
|
406
|
-
if (holder.aborted) holder.controller.abort();
|
|
407
|
-
}
|
|
408
|
-
return holder.controller.signal;
|
|
409
|
-
}
|
|
410
|
-
};
|
|
411
|
-
return { ctx, holder };
|
|
412
|
-
}
|
|
413
|
-
function runTransforms(initial, registerValue) {
|
|
414
|
-
const transforms = registerValue.transforms;
|
|
415
|
-
if (transforms === void 0 || transforms.length === 0) {
|
|
416
|
-
return { kind: "sync", ok: true, value: initial };
|
|
417
|
-
}
|
|
418
|
-
const { ctx, holder } = makeTransformContext();
|
|
419
|
-
let v = initial;
|
|
420
|
-
for (let i = 0; i < transforms.length; i++) {
|
|
421
|
-
const fn = transforms[i];
|
|
422
|
-
let out;
|
|
423
|
-
try {
|
|
424
|
-
out = fn(v, ctx);
|
|
425
|
-
} catch (err) {
|
|
426
|
-
logTransformFailure(registerValue.path);
|
|
427
|
-
return { kind: "sync", ok: false };
|
|
428
|
-
}
|
|
429
|
-
if (isThenable(out)) {
|
|
430
|
-
const rest = transforms.slice(i + 1);
|
|
431
|
-
const seed = out;
|
|
432
|
-
const run = () => rest.reduce(
|
|
433
|
-
(acc, next) => acc.then((value) => next(value, ctx)),
|
|
434
|
-
Promise.resolve(seed)
|
|
435
|
-
);
|
|
436
|
-
return { kind: "async", run, holder };
|
|
437
|
-
}
|
|
438
|
-
v = out;
|
|
439
|
-
}
|
|
440
|
-
return { kind: "sync", ok: true, value: v };
|
|
441
|
-
}
|
|
442
|
-
function kickoffAsyncTransform(rv, holder, run, commit, syncDom) {
|
|
443
|
-
const token = rv.beginTransform(holder);
|
|
444
|
-
void run().then(
|
|
445
|
-
(value) => {
|
|
446
|
-
const live = rv.isCurrentTransform(token);
|
|
447
|
-
rv.endTransform(token);
|
|
448
|
-
if (!live) return;
|
|
449
|
-
const coerced = applyCoerce(value, rv);
|
|
450
|
-
const wrote = commit(coerced);
|
|
451
|
-
if (wrote === false) rv.setTransformError(transformGateRejectedError(rv.path));
|
|
452
|
-
else syncDom?.();
|
|
453
|
-
},
|
|
454
|
-
(err) => {
|
|
455
|
-
if (rv.isCurrentTransform(token)) rv.setTransformError(toTransformError(err));
|
|
456
|
-
rv.endTransform(token);
|
|
457
|
-
}
|
|
458
|
-
);
|
|
459
|
-
}
|
|
460
|
-
function logTransformFailure(path, index, fn, err) {
|
|
461
|
-
{
|
|
462
|
-
console.error("[attaform] AF14 attaform.dev/e/af14");
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
function applyCoerce(value, registerValue) {
|
|
466
|
-
return registerValue.coerce !== void 0 ? registerValue.coerce(value) : value;
|
|
467
|
-
}
|
|
468
|
-
function wrapWithTransforms(value, registerValue, commit, syncDom) {
|
|
469
|
-
const r = runTransforms(value, registerValue);
|
|
470
|
-
if (r.kind === "async") {
|
|
471
|
-
kickoffAsyncTransform(registerValue, r.holder, r.run, commit, syncDom);
|
|
472
|
-
return true;
|
|
473
|
-
}
|
|
474
|
-
if (!r.ok) return false;
|
|
475
|
-
const coerced = applyCoerce(r.value, registerValue);
|
|
476
|
-
return commit(coerced);
|
|
477
|
-
}
|
|
478
|
-
function toTransformError(value) {
|
|
479
|
-
if (value instanceof Error) return value;
|
|
480
|
-
const message = typeof value === "string" && value.length > 0 ? value : `Transform rejected with a non-Error value (${typeof value})`;
|
|
481
|
-
return new Error(message, { cause: value });
|
|
482
|
-
}
|
|
483
|
-
function transformGateRejectedError(path) {
|
|
484
|
-
return new Error(
|
|
485
|
-
`[attaform] transform result for path '${path}' was rejected by the field's type gate (the resolved value did not fit the schema slot).`
|
|
486
|
-
);
|
|
487
|
-
}
|
|
488
|
-
const getModelAssigner = (el, vnode, registerValue) => {
|
|
489
|
-
const fn = vnode.props?.["onUpdate:registerValue"] ?? vnode.props?.["on:update:registerValue"];
|
|
490
|
-
if (isArray(fn)) {
|
|
491
|
-
const fnArr = fn.filter((x) => isFunction(x));
|
|
492
|
-
const wrapped = (value) => {
|
|
493
|
-
return wrapWithTransforms(
|
|
494
|
-
value,
|
|
495
|
-
registerValue,
|
|
496
|
-
(coerced) => {
|
|
497
|
-
invokeArrayFns(fnArr, coerced, registerValue);
|
|
498
|
-
return void 0;
|
|
499
|
-
},
|
|
500
|
-
void 0
|
|
501
|
-
);
|
|
502
|
-
};
|
|
503
|
-
wrapped[CONSUMER_WRAPPED_TAG] = true;
|
|
504
|
-
return wrapped;
|
|
505
|
-
}
|
|
506
|
-
if (isFunction(fn)) {
|
|
507
|
-
const handler = fn;
|
|
508
|
-
const wrapped = (value) => {
|
|
509
|
-
return wrapWithTransforms(
|
|
510
|
-
value,
|
|
511
|
-
registerValue,
|
|
512
|
-
(coerced) => handler(coerced, registerValue),
|
|
513
|
-
void 0
|
|
514
|
-
);
|
|
515
|
-
};
|
|
516
|
-
wrapped[CONSUMER_WRAPPED_TAG] = true;
|
|
517
|
-
return wrapped;
|
|
518
|
-
}
|
|
519
|
-
const defaultAssigner = (value) => {
|
|
520
|
-
if (value === void 0 && registerValue.acceptsUndefined) {
|
|
521
|
-
return registerValue.setValueWithInternalPath(void 0);
|
|
522
|
-
}
|
|
523
|
-
return wrapWithTransforms(
|
|
524
|
-
value,
|
|
525
|
-
registerValue,
|
|
526
|
-
(coerced) => registerValue.setValueWithInternalPath(coerced),
|
|
527
|
-
el._syncFromStorage
|
|
528
|
-
);
|
|
529
|
-
};
|
|
530
|
-
defaultAssigner[DEFAULT_ASSIGNER_TAG] = true;
|
|
531
|
-
return defaultAssigner;
|
|
532
|
-
};
|
|
533
|
-
function makeNoopAssigner() {
|
|
534
|
-
const noop = (_) => void 0;
|
|
535
|
-
noop[DEFAULT_ASSIGNER_TAG] = true;
|
|
536
|
-
return noop;
|
|
537
|
-
}
|
|
538
|
-
function setAssignFunction(el, vnode, value) {
|
|
539
|
-
const current = el[assignKey];
|
|
540
|
-
if (current !== void 0 && !isDefaultAssigner(current) && !isConsumerWrapped(current)) {
|
|
541
|
-
return;
|
|
542
|
-
}
|
|
543
|
-
if (value === void 0) {
|
|
544
|
-
el[assignKey] = makeNoopAssigner();
|
|
545
|
-
return;
|
|
546
|
-
}
|
|
547
|
-
if (!isRegisterValue(value)) {
|
|
548
|
-
el[assignKey] = makeNoopAssigner();
|
|
549
|
-
return;
|
|
550
|
-
}
|
|
551
|
-
el[assignKey] = getModelAssigner(el, vnode, value);
|
|
552
|
-
}
|
|
553
|
-
|
|
554
639
|
function isBlankFileValue(value) {
|
|
555
640
|
if (value === null || value === void 0) return true;
|
|
556
641
|
if (Array.isArray(value) && value.length === 0) return true;
|
|
@@ -642,11 +727,6 @@ function syncElementRegistration(el, value, oldValue) {
|
|
|
642
727
|
}
|
|
643
728
|
|
|
644
729
|
const valueSyncScopeKey = /* @__PURE__ */ Symbol.for("attaform:value-sync-scope");
|
|
645
|
-
function isElementFocused(el) {
|
|
646
|
-
const rootNode = el.getRootNode();
|
|
647
|
-
const activeElement = rootNode instanceof Document || rootNode instanceof ShadowRoot ? rootNode.activeElement : null;
|
|
648
|
-
return activeElement === el;
|
|
649
|
-
}
|
|
650
730
|
function setupValueSync(el, source, apply, options = {}) {
|
|
651
731
|
const skipWhileFocused = options.skipWhileFocused === true;
|
|
652
732
|
const scope = effectScope(true);
|
|
@@ -655,7 +735,7 @@ function setupValueSync(el, source, apply, options = {}) {
|
|
|
655
735
|
source,
|
|
656
736
|
() => {
|
|
657
737
|
if (el.composing === true) return;
|
|
658
|
-
if (skipWhileFocused &&
|
|
738
|
+
if (skipWhileFocused && activeElementOf(el) === el) return;
|
|
659
739
|
apply();
|
|
660
740
|
},
|
|
661
741
|
{ flush: "post" }
|
|
@@ -714,6 +794,28 @@ function onCompositionEnd(e) {
|
|
|
714
794
|
target.dispatchEvent(new Event("input"));
|
|
715
795
|
}
|
|
716
796
|
}
|
|
797
|
+
const heldDrafts = /* @__PURE__ */ new WeakMap();
|
|
798
|
+
function holdDraft(owner, control, stale) {
|
|
799
|
+
heldDrafts.set(owner, {
|
|
800
|
+
control,
|
|
801
|
+
text: control.value,
|
|
802
|
+
stale,
|
|
803
|
+
start: control.selectionStart,
|
|
804
|
+
end: control.selectionEnd
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
function restoreDraft(owner) {
|
|
808
|
+
const held = heldDrafts.get(owner);
|
|
809
|
+
if (held === void 0) return;
|
|
810
|
+
heldDrafts.delete(owner);
|
|
811
|
+
const { control, text, stale, start, end } = held;
|
|
812
|
+
if (control.value !== stale || stale === text) return;
|
|
813
|
+
control.value = text;
|
|
814
|
+
if (start !== null && end !== null) control.setSelectionRange(start, end);
|
|
815
|
+
}
|
|
816
|
+
function textControl(node) {
|
|
817
|
+
return node instanceof HTMLInputElement || node instanceof HTMLTextAreaElement ? node : null;
|
|
818
|
+
}
|
|
717
819
|
const vRegisterText = {
|
|
718
820
|
created(el, { value, modifiers: { lazy, trim, number } }, vnode) {
|
|
719
821
|
const castToNumberAtCreated = number === true || vnode.props?.["type"] === "number";
|
|
@@ -836,12 +938,14 @@ const vRegisterText = {
|
|
|
836
938
|
mounted(el, { value }) {
|
|
837
939
|
if (!isRegisterValue(value)) return;
|
|
838
940
|
el.value = value.displayValue.value;
|
|
941
|
+
el._lastAppliedModel = value.innerRef.value;
|
|
839
942
|
setupValueSync(
|
|
840
943
|
el,
|
|
841
944
|
value.displayValue,
|
|
842
945
|
() => {
|
|
843
946
|
const next = value.displayValue.value;
|
|
844
947
|
if (el.value !== next) el.value = next;
|
|
948
|
+
el._lastAppliedModel = value.innerRef.value;
|
|
845
949
|
},
|
|
846
950
|
{ skipWhileFocused: true }
|
|
847
951
|
);
|
|
@@ -850,17 +954,16 @@ const vRegisterText = {
|
|
|
850
954
|
setAssignFunction(el, vnode, value);
|
|
851
955
|
if (el.composing === true) return;
|
|
852
956
|
if (!isRegisterValue(value)) return;
|
|
957
|
+
const model = value.innerRef.value;
|
|
958
|
+
const modelMoved = model !== el._lastAppliedModel || !isRegisterValue(oldValue) || oldValue.path !== value.path;
|
|
959
|
+
el._lastAppliedModel = model;
|
|
853
960
|
const target = value.displayValue.value;
|
|
854
961
|
if (el.value === target) {
|
|
855
962
|
return;
|
|
856
963
|
}
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
if (lazy === true && value.innerRef.value === oldValue) {
|
|
861
|
-
return;
|
|
862
|
-
}
|
|
863
|
-
if (trim === true && el.value.trim() === target) {
|
|
964
|
+
if (activeElementOf(el) === el && el.type !== "range") {
|
|
965
|
+
if (lazy === true && !modelMoved || trim === true && el.value.trim() === target) {
|
|
966
|
+
holdDraft(el, el, target);
|
|
864
967
|
return;
|
|
865
968
|
}
|
|
866
969
|
}
|
|
@@ -1217,6 +1320,29 @@ function observeForLateHostControl(el, rv) {
|
|
|
1217
1320
|
observer.observe(el, { childList: true, subtree: true });
|
|
1218
1321
|
hostHealObservers.set(el, observer);
|
|
1219
1322
|
}
|
|
1323
|
+
const hostEdits = /* @__PURE__ */ new WeakMap();
|
|
1324
|
+
function trackHostEdits(el, rv, modifiers) {
|
|
1325
|
+
if (modifiers.lazy !== true && modifiers.trim !== true) return;
|
|
1326
|
+
if (!INTERACTIVE_TAG_NAMES.has(el.tagName) && rv.hasRegisteredDescendant(el)) return;
|
|
1327
|
+
const channel = armDomBinding(rv)?.hostChannel;
|
|
1328
|
+
if (channel === void 0) return;
|
|
1329
|
+
const edits = { channel, rv, base: void 0 };
|
|
1330
|
+
const edge = (editing) => (event) => {
|
|
1331
|
+
if (editing && !channel.holdsDraft(rv)) edits.base = textControl(event.target)?.value;
|
|
1332
|
+
const other = event.relatedTarget;
|
|
1333
|
+
if (other instanceof Node && el.contains(other)) return;
|
|
1334
|
+
channel.markEditing(rv, editing, modifiers);
|
|
1335
|
+
};
|
|
1336
|
+
addTrackedListener(el, "focus", edge(true), { capture: true });
|
|
1337
|
+
addTrackedListener(el, "blur", edge(false), { capture: true });
|
|
1338
|
+
hostEdits.set(el, edits);
|
|
1339
|
+
}
|
|
1340
|
+
function holdHostDraft(el) {
|
|
1341
|
+
const edits = hostEdits.get(el);
|
|
1342
|
+
if (edits?.base === void 0 || !edits.channel.holdsDraft(edits.rv)) return;
|
|
1343
|
+
const control = textControl(activeElementOf(el));
|
|
1344
|
+
if (control !== null && el.contains(control)) holdDraft(el, control, edits.base);
|
|
1345
|
+
}
|
|
1220
1346
|
function activateComponentHost(el, rv) {
|
|
1221
1347
|
if (rv.hasRegisteredDescendant(el)) return;
|
|
1222
1348
|
el[REGISTER_OWNER_MARKER] = true;
|
|
@@ -1231,25 +1357,34 @@ function activateComponentHost(el, rv) {
|
|
|
1231
1357
|
setupNoLatchHost(el, rv);
|
|
1232
1358
|
scheduleHostSelfHeal(el, rv);
|
|
1233
1359
|
}
|
|
1360
|
+
function inheritModifiers(binding) {
|
|
1361
|
+
const modifiers = withInheritedModifiers(binding.value, binding.modifiers);
|
|
1362
|
+
return modifiers === binding.modifiers ? binding : { ...binding, modifiers };
|
|
1363
|
+
}
|
|
1234
1364
|
const vRegisterDynamic = {
|
|
1235
|
-
created(el,
|
|
1365
|
+
created(el, ownBinding, vnode) {
|
|
1366
|
+
const binding = inheritModifiers(ownBinding);
|
|
1236
1367
|
if (isRegisterValue(binding.value)) armDomBinding(binding.value);
|
|
1237
1368
|
callModelHook(el, binding, vnode, null, "created");
|
|
1238
1369
|
if (isRegisterValue(binding.value)) setupAria(el, binding.value, vnode);
|
|
1239
1370
|
},
|
|
1240
|
-
mounted(el,
|
|
1371
|
+
mounted(el, ownBinding, vnode) {
|
|
1372
|
+
const binding = inheritModifiers(ownBinding);
|
|
1241
1373
|
callModelHook(el, binding, vnode, null, "mounted");
|
|
1242
1374
|
if (isRegisterValue(binding.value) && INTERACTIVE_TAG_NAMES.has(el.tagName) && binding.modifiers[SSR_COMPONENT_HOST_MODIFIER] !== true && vnode.props?.["disabled"] === void 0) {
|
|
1243
1375
|
setupDisabledSync(el, binding.value.disabled);
|
|
1244
1376
|
}
|
|
1245
1377
|
if (binding.modifiers[SSR_COMPONENT_HOST_MODIFIER] === true && isRegisterValue(binding.value)) {
|
|
1378
|
+
trackHostEdits(el, binding.value, binding.modifiers);
|
|
1246
1379
|
activateComponentHost(el, binding.value);
|
|
1247
1380
|
}
|
|
1248
1381
|
},
|
|
1249
|
-
beforeUpdate(el,
|
|
1382
|
+
beforeUpdate(el, ownBinding, vnode, prevVNode) {
|
|
1383
|
+
const binding = inheritModifiers(ownBinding);
|
|
1250
1384
|
if (isRegisterValue(binding.value)) armDomBinding(binding.value);
|
|
1251
1385
|
syncElementRegistration(el, binding.value, binding.oldValue);
|
|
1252
1386
|
callModelHook(el, binding, vnode, prevVNode, "beforeUpdate");
|
|
1387
|
+
holdHostDraft(el);
|
|
1253
1388
|
const ariaEl = el;
|
|
1254
1389
|
const value = binding.value;
|
|
1255
1390
|
if (!isRegisterValue(value) || value.ariaDisplayState === void 0) {
|
|
@@ -1267,13 +1402,17 @@ const vRegisterDynamic = {
|
|
|
1267
1402
|
}
|
|
1268
1403
|
},
|
|
1269
1404
|
updated(el, binding, vnode, prevVNode) {
|
|
1270
|
-
callModelHook(el, binding, vnode, prevVNode, "updated");
|
|
1405
|
+
callModelHook(el, inheritModifiers(binding), vnode, prevVNode, "updated");
|
|
1406
|
+
restoreDraft(el);
|
|
1271
1407
|
},
|
|
1272
1408
|
beforeUnmount(el, { value }) {
|
|
1273
1409
|
removeTrackedListeners(el);
|
|
1274
1410
|
teardownAria(el);
|
|
1275
1411
|
teardownValueSync(el);
|
|
1276
1412
|
teardownDisabledSync(el);
|
|
1413
|
+
const edits = hostEdits.get(el);
|
|
1414
|
+
edits?.channel.release(edits.rv);
|
|
1415
|
+
hostEdits.delete(el);
|
|
1277
1416
|
if (!isRegisterValue(value)) return;
|
|
1278
1417
|
value.deregisterElement(el);
|
|
1279
1418
|
if (componentHostLatch.has(el)) {
|
|
@@ -1364,4 +1503,4 @@ function installVRegister(app) {
|
|
|
1364
1503
|
}
|
|
1365
1504
|
}
|
|
1366
1505
|
|
|
1367
|
-
export { assignKey as a, vRegisterFile as b, armDomBinding as c, installVRegister as i, vRegister as v };
|
|
1506
|
+
export { assignKey as a, vRegisterFile as b, armDomBinding as c, installVRegister as i, recordInheritedModifiers as r, vRegister as v, withInheritedModifiers as w };
|