dom-expressions 0.40.8 → 0.40.11
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/package.json +7 -7
- package/src/client.js +42 -20
- package/src/server.js +10 -1
- package/src/universal.js +2 -2
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dom-expressions",
|
|
3
3
|
"description": "A Fine-Grained Runtime for Performant DOM Rendering",
|
|
4
|
-
"version": "0.40.
|
|
4
|
+
"version": "0.40.11",
|
|
5
5
|
"author": "Ryan Carniato",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -20,14 +20,14 @@
|
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
22
|
"csstype": "^3.0",
|
|
23
|
-
"seroval": "~1.
|
|
24
|
-
"seroval-plugins": "~1.
|
|
23
|
+
"seroval": "~1.6.8",
|
|
24
|
+
"seroval-plugins": "~1.6.8"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"babel-plugin-jsx-dom-expressions": "^0.40.
|
|
27
|
+
"babel-plugin-jsx-dom-expressions": "^0.40.11",
|
|
28
28
|
"csstype": "^3.1",
|
|
29
|
-
"seroval": "~1.
|
|
30
|
-
"seroval-plugins": "~1.
|
|
29
|
+
"seroval": "~1.6.8",
|
|
30
|
+
"seroval-plugins": "~1.6.8"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "3eba17b37754abaae2346c0237a4a65de802a316"
|
|
33
33
|
}
|
package/src/client.js
CHANGED
|
@@ -54,9 +54,10 @@ export function render(code, element, init, options = {}) {
|
|
|
54
54
|
let disposer;
|
|
55
55
|
root(dispose => {
|
|
56
56
|
disposer = dispose;
|
|
57
|
+
// Hydration owns the whole container, including nodes streamed in after init.
|
|
57
58
|
element === document
|
|
58
59
|
? code()
|
|
59
|
-
: insert(element, code(), element.firstChild ? null : undefined, init);
|
|
60
|
+
: insert(element, code(), !init && element.firstChild ? null : undefined, init);
|
|
60
61
|
}, options.owner);
|
|
61
62
|
return () => {
|
|
62
63
|
disposer();
|
|
@@ -107,7 +108,14 @@ export function clearDelegatedEvents(document = window.document) {
|
|
|
107
108
|
|
|
108
109
|
export function setProperty(node, name, value) {
|
|
109
110
|
if (isHydrating(node)) return;
|
|
110
|
-
|
|
111
|
+
// Compiler on next emits `el.value = v ?? ""` for input/textarea. 0.40.x
|
|
112
|
+
// still goes through setProperty, so apply the same rule here (#2957).
|
|
113
|
+
if (
|
|
114
|
+
(name === "value" || name === "defaultValue") &&
|
|
115
|
+
(node.nodeName === "INPUT" || node.nodeName === "TEXTAREA")
|
|
116
|
+
)
|
|
117
|
+
node[name] = value ?? "";
|
|
118
|
+
else node[name] = value;
|
|
111
119
|
}
|
|
112
120
|
|
|
113
121
|
export function setAttribute(node, name, value) {
|
|
@@ -384,6 +392,12 @@ function assignProp(node, prop, value, prev, isSVG, skipRef, props) {
|
|
|
384
392
|
} else if (isHydrating(node)) return value;
|
|
385
393
|
if (prop === "class" || prop === "className") className(node, value);
|
|
386
394
|
else if (isCE && !isProp && !isChildProp) node[toPropertyName(prop)] = value;
|
|
395
|
+
else if (
|
|
396
|
+
(prop === "value" || prop === "defaultValue") &&
|
|
397
|
+
(node.nodeName === "INPUT" || node.nodeName === "TEXTAREA")
|
|
398
|
+
)
|
|
399
|
+
// Spread path assigned raw, so value={undefined} painted "undefined" (#2957).
|
|
400
|
+
node[propAlias || prop] = value ?? "";
|
|
387
401
|
else node[propAlias || prop] = value;
|
|
388
402
|
} else {
|
|
389
403
|
const ns = isSVG && prop.indexOf(":") > -1 && SVGNamespace[prop.split(":")[0]];
|
|
@@ -435,27 +449,35 @@ function eventHandler(e) {
|
|
|
435
449
|
// cancel hydration
|
|
436
450
|
if (sharedConfig.registry && !sharedConfig.done) sharedConfig.done = _$HY.done = true;
|
|
437
451
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
+
try {
|
|
453
|
+
if (e.composedPath) {
|
|
454
|
+
const path = e.composedPath();
|
|
455
|
+
retarget(path[0]);
|
|
456
|
+
for (let i = 0; i < path.length - 2; i++) {
|
|
457
|
+
node = path[i];
|
|
458
|
+
if (!handleNode()) break;
|
|
459
|
+
if (node._$host) {
|
|
460
|
+
node = node._$host;
|
|
461
|
+
// bubble up from portal mount instead of composedPath
|
|
462
|
+
walkUpTree();
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
if (node.parentNode === oriCurrentTarget) {
|
|
466
|
+
break; // don't bubble above root of event delegation
|
|
467
|
+
}
|
|
452
468
|
}
|
|
453
469
|
}
|
|
470
|
+
// fallback for browsers that don't support composedPath
|
|
471
|
+
else walkUpTree();
|
|
472
|
+
// Mixing portals and shadow dom can lead to a nonstandard target, so reset here.
|
|
473
|
+
retarget(oriTarget);
|
|
474
|
+
} finally {
|
|
475
|
+
// The currentTarget getter shares this closure scope. Chromium keeps the
|
|
476
|
+
// getter from the first event of each event interface reachable for the
|
|
477
|
+
// page's lifetime (via the interface's shared map descriptors), so release
|
|
478
|
+
// the event and the last walked node to not pin a detached DOM tree.
|
|
479
|
+
e = node = null;
|
|
454
480
|
}
|
|
455
|
-
// fallback for browsers that don't support composedPath
|
|
456
|
-
else walkUpTree();
|
|
457
|
-
// Mixing portals and shadow dom can lead to a nonstandard target, so reset here.
|
|
458
|
-
retarget(oriTarget);
|
|
459
481
|
}
|
|
460
482
|
|
|
461
483
|
function insertExpression(parent, value, current, marker, unwrapArray) {
|
package/src/server.js
CHANGED
|
@@ -432,7 +432,16 @@ export function escape(s, attr) {
|
|
|
432
432
|
for (let i = 0; i < s.length; i++) s[i] = escape(s[i]);
|
|
433
433
|
return s;
|
|
434
434
|
}
|
|
435
|
-
if (attr
|
|
435
|
+
if (attr) {
|
|
436
|
+
if (t === "boolean") return String(s);
|
|
437
|
+
// Nullish values pass through so callers can omit the attribute, and
|
|
438
|
+
// numbers can never contain `&` or `"`. Everything else (arrays,
|
|
439
|
+
// objects) would be stringified by the surrounding template literal
|
|
440
|
+
// anyway, so coerce to the final string here first — matching what the
|
|
441
|
+
// client DOM receives — and run it through the normal string path.
|
|
442
|
+
if (s == null || t === "number") return s;
|
|
443
|
+
return escape(String(s), attr);
|
|
444
|
+
}
|
|
436
445
|
return s;
|
|
437
446
|
}
|
|
438
447
|
const delim = attr ? '"' : "<";
|
package/src/universal.js
CHANGED
|
@@ -63,7 +63,7 @@ export function createRenderer({
|
|
|
63
63
|
if (current.length === 0) {
|
|
64
64
|
appendNodes(parent, array, marker);
|
|
65
65
|
} else reconcileArrays(parent, current, array);
|
|
66
|
-
} else if (current == null ||
|
|
66
|
+
} else if (current == null || !getFirstChild(parent)) {
|
|
67
67
|
appendNodes(parent, array);
|
|
68
68
|
} else {
|
|
69
69
|
reconcileArrays(parent, (multi && current) || [getFirstChild(parent)], array);
|
|
@@ -74,7 +74,7 @@ export function createRenderer({
|
|
|
74
74
|
if (Array.isArray(current)) {
|
|
75
75
|
if (multi) return (current = cleanChildren(parent, current, marker, value));
|
|
76
76
|
cleanChildren(parent, current, null, value);
|
|
77
|
-
} else if (current == null ||
|
|
77
|
+
} else if (current == null || !getFirstChild(parent)) {
|
|
78
78
|
insertNode(parent, value);
|
|
79
79
|
} else replaceNode(parent, value, getFirstChild(parent));
|
|
80
80
|
current = value;
|