marko 6.1.12 → 6.1.14
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/common/errors.d.ts +5 -0
- package/dist/common/helpers.d.ts +1 -0
- package/dist/debug/dom.js +152 -55
- package/dist/debug/dom.mjs +152 -55
- package/dist/debug/html.js +176 -76
- package/dist/debug/html.mjs +176 -76
- package/dist/dom.js +24 -23
- package/dist/dom.mjs +24 -23
- package/dist/html/writer.d.ts +1 -1
- package/dist/html.js +51 -44
- package/dist/html.mjs +51 -44
- package/dist/translator/index.js +89 -9
- package/dist/translator/util/normalize-string-expression.d.ts +1 -0
- package/package.json +1 -1
package/dist/debug/html.js
CHANGED
|
@@ -21,7 +21,132 @@ function* attrTagIterator() {
|
|
|
21
21
|
yield* this[rest];
|
|
22
22
|
}
|
|
23
23
|
//#endregion
|
|
24
|
+
//#region src/common/helpers.ts
|
|
25
|
+
const htmlAttrNameReg = /^[^a-z_]|[^a-z0-9._:-]/i;
|
|
26
|
+
const knownWrongAttrs = {
|
|
27
|
+
className: "class",
|
|
28
|
+
classList: "class",
|
|
29
|
+
htmlFor: "for",
|
|
30
|
+
acceptCharset: "accept-charset",
|
|
31
|
+
httpEquiv: "http-equiv",
|
|
32
|
+
defaultValue: "value",
|
|
33
|
+
defaultChecked: "checked",
|
|
34
|
+
dangerouslySetInnerHTML: "$!{html}",
|
|
35
|
+
key: "<for by>",
|
|
36
|
+
ref: "<tag/ref>",
|
|
37
|
+
"v-if": "<if>",
|
|
38
|
+
"v-else": "<else>",
|
|
39
|
+
"v-else-if": "<else if>",
|
|
40
|
+
"v-for": "<for>",
|
|
41
|
+
"v-show": "<if>",
|
|
42
|
+
"v-model": "value:=state",
|
|
43
|
+
"v-bind": "...attrs",
|
|
44
|
+
"v-html": "$!{html}",
|
|
45
|
+
"v-text": "${text}"
|
|
46
|
+
};
|
|
47
|
+
function getWrongAttrSuggestion(name) {
|
|
48
|
+
const exact = knownWrongAttrs[name];
|
|
49
|
+
if (exact) return exact;
|
|
50
|
+
const colon = name.indexOf(":");
|
|
51
|
+
if (colon > 0) {
|
|
52
|
+
const rest = name.slice(colon + 1);
|
|
53
|
+
switch (name.slice(0, colon)) {
|
|
54
|
+
case "class": return `class={ ${rest}: condition }`;
|
|
55
|
+
case "style": return `style={ ${rest}: value }`;
|
|
56
|
+
case "on":
|
|
57
|
+
case "v-on": return `on${rest.charAt(0).toUpperCase()}${rest.slice(1)}`;
|
|
58
|
+
case "bind":
|
|
59
|
+
case "v-model": return `${rest}:=state`;
|
|
60
|
+
case "v-bind": return rest;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function stringifyClassObject(name, value) {
|
|
65
|
+
return value ? name : "";
|
|
66
|
+
}
|
|
67
|
+
function stringifyStyleObject(name, value) {
|
|
68
|
+
return value || value === 0 ? name + ":" + value : "";
|
|
69
|
+
}
|
|
70
|
+
const toDelimitedString = function toDelimitedString(val, delimiter, stringify) {
|
|
71
|
+
let str = "";
|
|
72
|
+
let sep = "";
|
|
73
|
+
let part;
|
|
74
|
+
if (val) if (typeof val !== "object") str += val;
|
|
75
|
+
else if (Array.isArray(val)) for (const v of val) {
|
|
76
|
+
part = toDelimitedString(v, delimiter, stringify);
|
|
77
|
+
if (part) {
|
|
78
|
+
str += sep + part;
|
|
79
|
+
sep = delimiter;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else for (const name in val) {
|
|
83
|
+
part = stringify(name, val[name]);
|
|
84
|
+
if (part) {
|
|
85
|
+
str += sep + part;
|
|
86
|
+
sep = delimiter;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return str;
|
|
90
|
+
};
|
|
91
|
+
function isEventHandler(name) {
|
|
92
|
+
return /^on[A-Z-]/.test(name);
|
|
93
|
+
}
|
|
94
|
+
function getEventHandlerName(name) {
|
|
95
|
+
return name[2] === "-" ? name.slice(3) : name.slice(2).toLowerCase();
|
|
96
|
+
}
|
|
97
|
+
function isVoid(value) {
|
|
98
|
+
return value == null || value === false;
|
|
99
|
+
}
|
|
100
|
+
function isNotVoid(value) {
|
|
101
|
+
return value != null && value !== false;
|
|
102
|
+
}
|
|
103
|
+
function normalizeDynamicRenderer(value) {
|
|
104
|
+
if (value) {
|
|
105
|
+
if (typeof value === "string") return value;
|
|
106
|
+
const normalized = value.content || value.default || value;
|
|
107
|
+
if ("id" in normalized) return normalized;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//#endregion
|
|
24
111
|
//#region src/common/errors.ts
|
|
112
|
+
const lowercaseEventHandlerReg = /^on[a-z]/;
|
|
113
|
+
function assertValidAttrValue(name, value) {
|
|
114
|
+
if (value && typeof value !== "string" && lowercaseEventHandlerReg.test(name)) throw new Error(`The \`${name}\` attribute must be a string or a falsey value (\`null\`, \`undefined\`, \`false\`, \`0\`, …), but received type "${typeof value}". To attach an event listener, use the \`on${name[2].toUpperCase()}${name.slice(3)}\` event handler instead.`);
|
|
115
|
+
if (typeof value === "function") {
|
|
116
|
+
if (name === "content" || /^on/i.test(name) || /Change$/.test(name)) return;
|
|
117
|
+
throw new Error(`The \`${name}\` attribute cannot be a function.`);
|
|
118
|
+
}
|
|
119
|
+
const unrenderable = describeUnrenderable(value);
|
|
120
|
+
if (unrenderable) throw new Error(`The \`${name}\` attribute cannot be ${unrenderable}.`);
|
|
121
|
+
}
|
|
122
|
+
function assertValidTextValue(value) {
|
|
123
|
+
const unrenderable = describeUnrenderable(value);
|
|
124
|
+
if (unrenderable) throw new Error(`Text content cannot be ${unrenderable}.`);
|
|
125
|
+
}
|
|
126
|
+
function describeUnrenderable(value) {
|
|
127
|
+
if (typeof value === "symbol") return "a symbol";
|
|
128
|
+
if (typeof value === "object" && value !== null) {
|
|
129
|
+
let stringified;
|
|
130
|
+
try {
|
|
131
|
+
stringified = `${value}`;
|
|
132
|
+
} catch {
|
|
133
|
+
stringified = "[object Object]";
|
|
134
|
+
}
|
|
135
|
+
if (/^\[object \w+\]$/.test(stringified)) return stringified === "[object Promise]" ? "a promise (use the `<await>` tag to render its resolved value)" : stringified === "[object Object]" ? "a plain object (it would render as `[object Object]`)" : `a value that renders as \`${stringified}\``;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function assertValidLoopKey(key, seenKeys) {
|
|
139
|
+
if (typeof key !== "string" && typeof key !== "number") throw new Error(`A \`<for>\` tag's \`by\` attribute must return a string or number for each item, but received ${key === null ? "null" : `type "${typeof key}"`}.`);
|
|
140
|
+
if (seenKeys) {
|
|
141
|
+
if (seenKeys.has(key)) throw new Error(`A \`<for>\` tag's \`by\` attribute must return a unique value for each item, but \`${key}\` was used more than once.`);
|
|
142
|
+
seenKeys.add(key);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function assertValidAttrName(name) {
|
|
146
|
+
if (htmlAttrNameReg.test(name)) throw new Error(`Invalid attribute name: ${JSON.stringify(name)}`);
|
|
147
|
+
const suggestion = getWrongAttrSuggestion(name);
|
|
148
|
+
if (suggestion) throw new Error(`\`${name}\` is not a valid attribute, did you mean \`${suggestion}\`?`);
|
|
149
|
+
}
|
|
25
150
|
function _el_read_error() {
|
|
26
151
|
throw new Error("Element references can only be read in scripts and event handlers.");
|
|
27
152
|
}
|
|
@@ -46,6 +171,9 @@ function assertExclusiveAttrs(attrs, onError = throwErr) {
|
|
|
46
171
|
if (exclusiveAttrs && exclusiveAttrs.length > 1) onError(`The attributes ${joinWithAnd(exclusiveAttrs)} are mutually exclusive.`);
|
|
47
172
|
}
|
|
48
173
|
}
|
|
174
|
+
function assertHandlerIsFunction(name, value) {
|
|
175
|
+
if (value && typeof value !== "function") throw new Error(`The \`${name}\` handler must be a function or a falsey value (\`null\`, \`undefined\`, \`false\`, \`0\`, …), but received type "${typeof value}".`);
|
|
176
|
+
}
|
|
49
177
|
function assertValidTagName(tagName) {
|
|
50
178
|
if (!/^[a-z][a-z0-9._-]*$/i.test(tagName)) throw new Error(`Invalid tag name: "${tagName}". Tag names must start with a letter and contain only letters, numbers, periods, hyphens, and underscores.`);
|
|
51
179
|
}
|
|
@@ -66,27 +194,32 @@ const DYNAMIC_TAG_SCRIPT_REGISTER_ID = "_dynamicTagScript";
|
|
|
66
194
|
//#endregion
|
|
67
195
|
//#region src/html/content.ts
|
|
68
196
|
function _unescaped(val) {
|
|
197
|
+
assertValidTextValue(val);
|
|
69
198
|
return val ? val + "" : val === 0 ? "0" : "";
|
|
70
199
|
}
|
|
71
200
|
const unsafeXMLReg = /[<&]/g;
|
|
72
201
|
const replaceUnsafeXML = (c) => c === "&" ? "&" : "<";
|
|
73
202
|
const escapeXMLStr = (str) => unsafeXMLReg.test(str) ? str.replace(unsafeXMLReg, replaceUnsafeXML) : str;
|
|
74
203
|
function _escape(val) {
|
|
204
|
+
assertValidTextValue(val);
|
|
75
205
|
return val ? escapeXMLStr(val + "") : val === 0 ? "0" : "";
|
|
76
206
|
}
|
|
77
207
|
const unsafeScriptReg = /<\/script/gi;
|
|
78
208
|
const escapeScriptStr = (str) => unsafeScriptReg.test(str) ? str.replace(unsafeScriptReg, "\\x3C/script") : str;
|
|
79
209
|
function _escape_script(val) {
|
|
210
|
+
assertValidTextValue(val);
|
|
80
211
|
return val ? escapeScriptStr(val + "") : val === 0 ? "0" : "";
|
|
81
212
|
}
|
|
82
213
|
const unsafeStyleReg = /<\/style/gi;
|
|
83
214
|
const escapeStyleStr = (str) => unsafeStyleReg.test(str) ? str.replace(unsafeStyleReg, "\\3C/style") : str;
|
|
84
215
|
function _escape_style(val) {
|
|
216
|
+
assertValidTextValue(val);
|
|
85
217
|
return val ? escapeStyleStr(val + "") : val === 0 ? "0" : "";
|
|
86
218
|
}
|
|
87
219
|
const unsafeCommentReg = />/g;
|
|
88
220
|
const escapeCommentStr = (str) => unsafeCommentReg.test(str) ? str.replace(unsafeCommentReg, ">") : str;
|
|
89
221
|
function _escape_comment(val) {
|
|
222
|
+
assertValidTextValue(val);
|
|
90
223
|
return val ? escapeCommentStr(val + "") : val === 0 ? "0" : "";
|
|
91
224
|
}
|
|
92
225
|
//#endregion
|
|
@@ -1152,6 +1285,7 @@ function isCircular(parent, ref) {
|
|
|
1152
1285
|
}
|
|
1153
1286
|
function toObjectKey(name) {
|
|
1154
1287
|
if (name === "") return "\"\"";
|
|
1288
|
+
if (name === "__proto__") return "[\"__proto__\"]";
|
|
1155
1289
|
const startChar = name[0];
|
|
1156
1290
|
if (isDigit(startChar)) {
|
|
1157
1291
|
if (startChar === "0") {
|
|
@@ -1164,7 +1298,7 @@ function toObjectKey(name) {
|
|
|
1164
1298
|
}
|
|
1165
1299
|
function toAccess(accessor) {
|
|
1166
1300
|
const start = accessor[0];
|
|
1167
|
-
return start === "\"" || start >= "0" && start <= "9" ? "[" + accessor + "]" : "." + accessor;
|
|
1301
|
+
return start === "[" ? accessor : start === "\"" || start >= "0" && start <= "9" ? "[" + accessor + "]" : "." + accessor;
|
|
1168
1302
|
}
|
|
1169
1303
|
function quote(str, startPos) {
|
|
1170
1304
|
let result = "";
|
|
@@ -1306,55 +1440,6 @@ function patchIteratorNext(proto) {
|
|
|
1306
1440
|
proto.next[kTouchedIterator] = true;
|
|
1307
1441
|
}
|
|
1308
1442
|
//#endregion
|
|
1309
|
-
//#region src/common/helpers.ts
|
|
1310
|
-
const htmlAttrNameReg = /^[^a-z_]|[^a-z0-9._:-]/i;
|
|
1311
|
-
function stringifyClassObject(name, value) {
|
|
1312
|
-
return value ? name : "";
|
|
1313
|
-
}
|
|
1314
|
-
function stringifyStyleObject(name, value) {
|
|
1315
|
-
return value || value === 0 ? name + ":" + value : "";
|
|
1316
|
-
}
|
|
1317
|
-
const toDelimitedString = function toDelimitedString(val, delimiter, stringify) {
|
|
1318
|
-
let str = "";
|
|
1319
|
-
let sep = "";
|
|
1320
|
-
let part;
|
|
1321
|
-
if (val) if (typeof val !== "object") str += val;
|
|
1322
|
-
else if (Array.isArray(val)) for (const v of val) {
|
|
1323
|
-
part = toDelimitedString(v, delimiter, stringify);
|
|
1324
|
-
if (part) {
|
|
1325
|
-
str += sep + part;
|
|
1326
|
-
sep = delimiter;
|
|
1327
|
-
}
|
|
1328
|
-
}
|
|
1329
|
-
else for (const name in val) {
|
|
1330
|
-
part = stringify(name, val[name]);
|
|
1331
|
-
if (part) {
|
|
1332
|
-
str += sep + part;
|
|
1333
|
-
sep = delimiter;
|
|
1334
|
-
}
|
|
1335
|
-
}
|
|
1336
|
-
return str;
|
|
1337
|
-
};
|
|
1338
|
-
function isEventHandler(name) {
|
|
1339
|
-
return /^on[A-Z-]/.test(name);
|
|
1340
|
-
}
|
|
1341
|
-
function getEventHandlerName(name) {
|
|
1342
|
-
return name[2] === "-" ? name.slice(3) : name.slice(2).toLowerCase();
|
|
1343
|
-
}
|
|
1344
|
-
function isVoid(value) {
|
|
1345
|
-
return value == null || value === false;
|
|
1346
|
-
}
|
|
1347
|
-
function isNotVoid(value) {
|
|
1348
|
-
return value != null && value !== false;
|
|
1349
|
-
}
|
|
1350
|
-
function normalizeDynamicRenderer(value) {
|
|
1351
|
-
if (value) {
|
|
1352
|
-
if (typeof value === "string") return value;
|
|
1353
|
-
const normalized = value.content || value.default || value;
|
|
1354
|
-
if ("id" in normalized) return normalized;
|
|
1355
|
-
}
|
|
1356
|
-
}
|
|
1357
|
-
//#endregion
|
|
1358
1443
|
//#region src/common/for.ts
|
|
1359
1444
|
function forIn(obj, cb) {
|
|
1360
1445
|
for (const key in obj) cb(key, obj[key]);
|
|
@@ -1397,19 +1482,13 @@ function concat(opt, other) {
|
|
|
1397
1482
|
//#endregion
|
|
1398
1483
|
//#region src/html/for.ts
|
|
1399
1484
|
function forOfBy(by, item, index) {
|
|
1400
|
-
|
|
1401
|
-
if (typeof by === "string") return item[by];
|
|
1402
|
-
return by(item, index);
|
|
1403
|
-
}
|
|
1404
|
-
return index;
|
|
1485
|
+
return by ? typeof by === "string" ? item[by] : by(item, index) : index;
|
|
1405
1486
|
}
|
|
1406
1487
|
function forInBy(by, name, value) {
|
|
1407
|
-
|
|
1408
|
-
return name;
|
|
1488
|
+
return by ? by(name, value) : name;
|
|
1409
1489
|
}
|
|
1410
1490
|
function forStepBy(by, index) {
|
|
1411
|
-
|
|
1412
|
-
return index;
|
|
1491
|
+
return by ? by(index) : index;
|
|
1413
1492
|
}
|
|
1414
1493
|
//#endregion
|
|
1415
1494
|
//#region src/html/inlined-runtimes.debug.ts
|
|
@@ -1670,20 +1749,31 @@ function _for_in(obj, cb, by, scopeId, accessor, serializeBranch, serializeMarke
|
|
|
1670
1749
|
}) : forIn(obj, cb), scopeId, accessor, serializeBranch, serializeMarker, serializeStateful, parentEndTag, singleNode);
|
|
1671
1750
|
}
|
|
1672
1751
|
function _for_to(to, from, step, cb, by, scopeId, accessor, serializeBranch, serializeMarker, serializeStateful, parentEndTag, singleNode) {
|
|
1673
|
-
forBranches(by, (each) =>
|
|
1674
|
-
|
|
1675
|
-
each(
|
|
1676
|
-
|
|
1752
|
+
forBranches(by, (each) => {
|
|
1753
|
+
let index = 0;
|
|
1754
|
+
return each ? forTo(to, from, step, (value) => {
|
|
1755
|
+
const itemKey = forStepBy(by, value);
|
|
1756
|
+
each(itemKey, itemKey === index++, () => cb(value));
|
|
1757
|
+
}) : forTo(to, from, step, cb);
|
|
1758
|
+
}, scopeId, accessor, serializeBranch, serializeMarker, serializeStateful, parentEndTag, singleNode);
|
|
1677
1759
|
}
|
|
1678
1760
|
function _for_until(to, from, step, cb, by, scopeId, accessor, serializeBranch, serializeMarker, serializeStateful, parentEndTag, singleNode) {
|
|
1679
|
-
forBranches(by, (each) =>
|
|
1680
|
-
|
|
1681
|
-
each(
|
|
1682
|
-
|
|
1761
|
+
forBranches(by, (each) => {
|
|
1762
|
+
let index = 0;
|
|
1763
|
+
return each ? forUntil(to, from, step, (value) => {
|
|
1764
|
+
const itemKey = forStepBy(by, value);
|
|
1765
|
+
each(itemKey, itemKey === index++, () => cb(value));
|
|
1766
|
+
}) : forUntil(to, from, step, cb);
|
|
1767
|
+
}, scopeId, accessor, serializeBranch, serializeMarker, serializeStateful, parentEndTag, singleNode);
|
|
1683
1768
|
}
|
|
1684
1769
|
function forBranches(by, iterate, scopeId, accessor, serializeBranch, serializeMarker, serializeStateful, parentEndTag, singleNode) {
|
|
1770
|
+
var seenKeys = /* @__PURE__ */ new Set();
|
|
1685
1771
|
if (serializeBranch === 0) {
|
|
1686
|
-
iterate(
|
|
1772
|
+
if (by) iterate((itemKey, _sameAsIndex, render) => {
|
|
1773
|
+
assertValidLoopKey(itemKey, seenKeys);
|
|
1774
|
+
render();
|
|
1775
|
+
});
|
|
1776
|
+
else iterate(0);
|
|
1687
1777
|
writeBranchEnd(scopeId, accessor, serializeStateful, serializeMarker, parentEndTag, singleNode, "");
|
|
1688
1778
|
return;
|
|
1689
1779
|
}
|
|
@@ -1692,13 +1782,9 @@ function forBranches(by, iterate, scopeId, accessor, serializeBranch, serializeM
|
|
|
1692
1782
|
const resumeMarker = serializeMarker !== 0 && (!parentEndTag || serializeStateful !== 0);
|
|
1693
1783
|
let flushBranchIds = "";
|
|
1694
1784
|
let loopScopes;
|
|
1695
|
-
var seenKeys = /* @__PURE__ */ new Set();
|
|
1696
1785
|
iterate((itemKey, sameAsIndex, render) => {
|
|
1697
1786
|
const branchId = _peek_scope_id();
|
|
1698
|
-
if (by)
|
|
1699
|
-
if (seenKeys.has(itemKey)) console.error(`A <for> tag's \`by\` attribute must return a unique value for each item, but a duplicate was found matching:`, itemKey);
|
|
1700
|
-
seenKeys.add(itemKey);
|
|
1701
|
-
}
|
|
1787
|
+
if (by) assertValidLoopKey(itemKey, seenKeys);
|
|
1702
1788
|
if (resumeMarker) if (singleNode) flushBranchIds = " " + branchId + flushBranchIds;
|
|
1703
1789
|
else {
|
|
1704
1790
|
$chunk.writeHTML(state.mark("[", flushBranchIds));
|
|
@@ -2370,12 +2456,24 @@ function _attr_style(value) {
|
|
|
2370
2456
|
}
|
|
2371
2457
|
function _attr_option_value(value) {
|
|
2372
2458
|
const valueAttr = _attr("value", value);
|
|
2373
|
-
|
|
2459
|
+
if (normalizedValueMatches(getContext(kSelectedValue), value)) {
|
|
2460
|
+
{
|
|
2461
|
+
const matched = getContext(kSelectedValueMatched);
|
|
2462
|
+
if (matched) matched.value = true;
|
|
2463
|
+
}
|
|
2464
|
+
return valueAttr + " selected";
|
|
2465
|
+
}
|
|
2466
|
+
return valueAttr;
|
|
2374
2467
|
}
|
|
2375
2468
|
const kSelectedValue = Symbol("selectedValue");
|
|
2469
|
+
const kSelectedValueMatched = Symbol("selectedValueMatched");
|
|
2376
2470
|
function _attr_select_value(scopeId, nodeAccessor, value, valueChange, content) {
|
|
2377
2471
|
if (valueChange) writeControlledScope(3, scopeId, nodeAccessor, void 0, valueChange);
|
|
2378
|
-
if (content)
|
|
2472
|
+
if (content) if (valueChange) {
|
|
2473
|
+
const matched = { value: false };
|
|
2474
|
+
withContext(kSelectedValue, value, () => withContext(kSelectedValueMatched, matched, content));
|
|
2475
|
+
if (!matched.value && (Array.isArray(value) ? value.some((v) => normalizeStrAttrValue(v) !== "") : normalizeStrAttrValue(value) !== "")) console.error("A controlled `<select>`'s `value` has no matching `<option>`:", value);
|
|
2476
|
+
} else withContext(kSelectedValue, value, content);
|
|
2379
2477
|
}
|
|
2380
2478
|
function _attr_textarea_value(scopeId, nodeAccessor, value, valueChange) {
|
|
2381
2479
|
if (valueChange) writeControlledScope(2, scopeId, nodeAccessor, void 0, valueChange);
|
|
@@ -2458,7 +2556,7 @@ function _attrs(data, nodeAccessor, scopeId, tagName) {
|
|
|
2458
2556
|
break;
|
|
2459
2557
|
default:
|
|
2460
2558
|
if (name && !(isVoid(value) || skip.test(name) || name === "content" && tagName !== "meta")) {
|
|
2461
|
-
|
|
2559
|
+
assertValidAttrName(name);
|
|
2462
2560
|
if (isEventHandler(name)) {
|
|
2463
2561
|
if (!events) {
|
|
2464
2562
|
events = {};
|
|
@@ -2489,6 +2587,7 @@ function _attrs_partial_content(data, skip, nodeAccessor, scopeId, tagName, seri
|
|
|
2489
2587
|
_attr_content(nodeAccessor, scopeId, data?.content, serializeReason);
|
|
2490
2588
|
}
|
|
2491
2589
|
function writeControlledScope(type, scopeId, nodeAccessor, value, valueChange) {
|
|
2590
|
+
assertHandlerIsFunction("valueChange", valueChange);
|
|
2492
2591
|
writeScope(scopeId, {
|
|
2493
2592
|
["ControlledType:" + nodeAccessor]: type,
|
|
2494
2593
|
["ControlledValue:" + nodeAccessor]: value,
|
|
@@ -2499,6 +2598,7 @@ function stringAttr(name, value) {
|
|
|
2499
2598
|
return value && " " + name + attrAssignment(value);
|
|
2500
2599
|
}
|
|
2501
2600
|
function nonVoidAttr(name, value) {
|
|
2601
|
+
assertValidAttrValue(name, value);
|
|
2502
2602
|
switch (typeof value) {
|
|
2503
2603
|
case "string": return " " + name + attrAssignment(value);
|
|
2504
2604
|
case "boolean": return " " + name;
|