@b9g/crank 0.7.3 → 0.7.4
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 +26 -20
- package/_css.cjs.map +1 -1
- package/_css.js.map +1 -1
- package/_utils.cjs.map +1 -1
- package/_utils.js.map +1 -1
- package/async.cjs.map +1 -1
- package/async.js.map +1 -1
- package/crank.cjs +47 -32
- package/crank.cjs.map +1 -1
- package/crank.d.ts +8 -0
- package/crank.js +47 -32
- package/crank.js.map +1 -1
- package/dom.cjs +59 -32
- package/dom.cjs.map +1 -1
- package/dom.d.ts +1 -1
- package/dom.js +59 -32
- package/dom.js.map +1 -1
- package/event-target.cjs.map +1 -1
- package/event-target.js.map +1 -1
- package/html.cjs +14 -0
- package/html.cjs.map +1 -1
- package/html.d.ts +10 -3
- package/html.js +14 -0
- package/html.js.map +1 -1
- package/jsx-runtime.js.map +1 -1
- package/jsx-tag.cjs.map +1 -1
- package/jsx-tag.js.map +1 -1
- package/package.json +1 -1
- package/umd.js +120 -64
- package/umd.js.map +1 -1
package/umd.js
CHANGED
|
@@ -743,6 +743,7 @@
|
|
|
743
743
|
tagName: getTagName(Portal),
|
|
744
744
|
props: stripSpecialProps(ret.el.props),
|
|
745
745
|
scope: undefined,
|
|
746
|
+
root,
|
|
746
747
|
});
|
|
747
748
|
// remember that typeof null === "object"
|
|
748
749
|
if (typeof root === "object" && root !== null && children != null) {
|
|
@@ -765,32 +766,32 @@
|
|
|
765
766
|
const schedulePromises = [];
|
|
766
767
|
if (isPromiseLike(diff)) {
|
|
767
768
|
return diff.then(() => {
|
|
768
|
-
commit(adapter, ret, ret, ret.ctx, ret.scope, 0, schedulePromises, undefined);
|
|
769
|
+
commit(adapter, ret, ret, ret.ctx, ret.scope, root, 0, schedulePromises, undefined);
|
|
769
770
|
if (schedulePromises.length > 0) {
|
|
770
771
|
return Promise.all(schedulePromises).then(() => {
|
|
771
772
|
if (typeof root !== "object" || root === null) {
|
|
772
|
-
unmount(adapter, ret, ret.ctx, ret, false);
|
|
773
|
+
unmount(adapter, ret, ret.ctx, root, ret, false);
|
|
773
774
|
}
|
|
774
775
|
return adapter.read(unwrap(getChildValues(ret)));
|
|
775
776
|
});
|
|
776
777
|
}
|
|
777
778
|
if (typeof root !== "object" || root === null) {
|
|
778
|
-
unmount(adapter, ret, ret.ctx, ret, false);
|
|
779
|
+
unmount(adapter, ret, ret.ctx, root, ret, false);
|
|
779
780
|
}
|
|
780
781
|
return adapter.read(unwrap(getChildValues(ret)));
|
|
781
782
|
});
|
|
782
783
|
}
|
|
783
|
-
commit(adapter, ret, ret, ret.ctx, ret.scope, 0, schedulePromises, undefined);
|
|
784
|
+
commit(adapter, ret, ret, ret.ctx, ret.scope, root, 0, schedulePromises, undefined);
|
|
784
785
|
if (schedulePromises.length > 0) {
|
|
785
786
|
return Promise.all(schedulePromises).then(() => {
|
|
786
787
|
if (typeof root !== "object" || root === null) {
|
|
787
|
-
unmount(adapter, ret, ret.ctx, ret, false);
|
|
788
|
+
unmount(adapter, ret, ret.ctx, root, ret, false);
|
|
788
789
|
}
|
|
789
790
|
return adapter.read(unwrap(getChildValues(ret)));
|
|
790
791
|
});
|
|
791
792
|
}
|
|
792
793
|
if (typeof root !== "object" || root === null) {
|
|
793
|
-
unmount(adapter, ret, ret.ctx, ret, false);
|
|
794
|
+
unmount(adapter, ret, ret.ctx, root, ret, false);
|
|
794
795
|
}
|
|
795
796
|
return adapter.read(unwrap(getChildValues(ret)));
|
|
796
797
|
}
|
|
@@ -1040,11 +1041,12 @@
|
|
|
1040
1041
|
tagName: getTagName(tag),
|
|
1041
1042
|
props: el.props,
|
|
1042
1043
|
scope,
|
|
1044
|
+
root,
|
|
1043
1045
|
});
|
|
1044
1046
|
}
|
|
1045
1047
|
return diffChildren(adapter, root, ret, ctx, scope, ret, ret.el.props.children);
|
|
1046
1048
|
}
|
|
1047
|
-
function commit(adapter, host, ret, ctx, scope, index, schedulePromises, hydrationNodes) {
|
|
1049
|
+
function commit(adapter, host, ret, ctx, scope, root, index, schedulePromises, hydrationNodes) {
|
|
1048
1050
|
if (getFlag(ret, IsCopied) && getFlag(ret, DidCommit)) {
|
|
1049
1051
|
return getValue(ret);
|
|
1050
1052
|
}
|
|
@@ -1077,19 +1079,19 @@
|
|
|
1077
1079
|
}
|
|
1078
1080
|
else {
|
|
1079
1081
|
if (tag === Fragment) {
|
|
1080
|
-
value = commitChildren(adapter, host, ctx, scope, ret, index, schedulePromises, hydrationNodes);
|
|
1082
|
+
value = commitChildren(adapter, host, ctx, scope, root, ret, index, schedulePromises, hydrationNodes);
|
|
1081
1083
|
}
|
|
1082
1084
|
else if (tag === Text) {
|
|
1083
|
-
value = commitText(adapter, ret, el, scope, hydrationNodes);
|
|
1085
|
+
value = commitText(adapter, ret, el, scope, hydrationNodes, root);
|
|
1084
1086
|
}
|
|
1085
1087
|
else if (tag === Raw) {
|
|
1086
|
-
value = commitRaw(adapter, host, ret, scope, hydrationNodes);
|
|
1088
|
+
value = commitRaw(adapter, host, ret, scope, hydrationNodes, root);
|
|
1087
1089
|
}
|
|
1088
1090
|
else {
|
|
1089
|
-
value = commitHost(adapter, ret, ctx, schedulePromises, hydrationNodes);
|
|
1091
|
+
value = commitHost(adapter, ret, ctx, root, schedulePromises, hydrationNodes);
|
|
1090
1092
|
}
|
|
1091
1093
|
if (ret.fallback) {
|
|
1092
|
-
unmount(adapter, host, ctx, ret.fallback, false);
|
|
1094
|
+
unmount(adapter, host, ctx, root, ret.fallback, false);
|
|
1093
1095
|
ret.fallback = undefined;
|
|
1094
1096
|
}
|
|
1095
1097
|
}
|
|
@@ -1107,7 +1109,7 @@
|
|
|
1107
1109
|
}
|
|
1108
1110
|
return value;
|
|
1109
1111
|
}
|
|
1110
|
-
function commitChildren(adapter, host, ctx, scope, parent, index, schedulePromises, hydrationNodes) {
|
|
1112
|
+
function commitChildren(adapter, host, ctx, scope, root, parent, index, schedulePromises, hydrationNodes) {
|
|
1111
1113
|
let values = [];
|
|
1112
1114
|
for (let i = 0, children = wrap(parent.children); i < children.length; i++) {
|
|
1113
1115
|
let child = children[i];
|
|
@@ -1130,6 +1132,7 @@
|
|
|
1130
1132
|
node,
|
|
1131
1133
|
parentNode: host.value,
|
|
1132
1134
|
isNested: false,
|
|
1135
|
+
root,
|
|
1133
1136
|
});
|
|
1134
1137
|
}
|
|
1135
1138
|
}
|
|
@@ -1189,7 +1192,7 @@
|
|
|
1189
1192
|
schedulePromises.push(safeRace(schedulePromises1));
|
|
1190
1193
|
}
|
|
1191
1194
|
if (child) {
|
|
1192
|
-
const value = commit(adapter, host, child, ctx, scope, index, schedulePromises, hydrationNodes);
|
|
1195
|
+
const value = commit(adapter, host, child, ctx, scope, root, index, schedulePromises, hydrationNodes);
|
|
1193
1196
|
if (Array.isArray(value)) {
|
|
1194
1197
|
for (let j = 0; j < value.length; j++) {
|
|
1195
1198
|
values.push(value[j]);
|
|
@@ -1205,7 +1208,7 @@
|
|
|
1205
1208
|
if (parent.graveyard) {
|
|
1206
1209
|
for (let i = 0; i < parent.graveyard.length; i++) {
|
|
1207
1210
|
const child = parent.graveyard[i];
|
|
1208
|
-
unmount(adapter, host, ctx, child, false);
|
|
1211
|
+
unmount(adapter, host, ctx, root, child, false);
|
|
1209
1212
|
}
|
|
1210
1213
|
parent.graveyard = undefined;
|
|
1211
1214
|
}
|
|
@@ -1216,17 +1219,18 @@
|
|
|
1216
1219
|
}
|
|
1217
1220
|
return values;
|
|
1218
1221
|
}
|
|
1219
|
-
function commitText(adapter, ret, el, scope, hydrationNodes) {
|
|
1222
|
+
function commitText(adapter, ret, el, scope, hydrationNodes, root) {
|
|
1220
1223
|
const value = adapter.text({
|
|
1221
1224
|
value: el.props.value,
|
|
1222
1225
|
scope,
|
|
1223
1226
|
oldNode: ret.value,
|
|
1224
1227
|
hydrationNodes,
|
|
1228
|
+
root,
|
|
1225
1229
|
});
|
|
1226
1230
|
ret.value = value;
|
|
1227
1231
|
return value;
|
|
1228
1232
|
}
|
|
1229
|
-
function commitRaw(adapter, host, ret, scope, hydrationNodes) {
|
|
1233
|
+
function commitRaw(adapter, host, ret, scope, hydrationNodes, root) {
|
|
1230
1234
|
if (!ret.oldProps || ret.oldProps.value !== ret.el.props.value) {
|
|
1231
1235
|
const oldNodes = wrap(ret.value);
|
|
1232
1236
|
for (let i = 0; i < oldNodes.length; i++) {
|
|
@@ -1235,18 +1239,20 @@
|
|
|
1235
1239
|
node: oldNode,
|
|
1236
1240
|
parentNode: host.value,
|
|
1237
1241
|
isNested: false,
|
|
1242
|
+
root,
|
|
1238
1243
|
});
|
|
1239
1244
|
}
|
|
1240
1245
|
ret.value = adapter.raw({
|
|
1241
1246
|
value: ret.el.props.value,
|
|
1242
1247
|
scope,
|
|
1243
1248
|
hydrationNodes,
|
|
1249
|
+
root,
|
|
1244
1250
|
});
|
|
1245
1251
|
}
|
|
1246
1252
|
ret.oldProps = stripSpecialProps(ret.el.props);
|
|
1247
1253
|
return ret.value;
|
|
1248
1254
|
}
|
|
1249
|
-
function commitHost(adapter, ret, ctx, schedulePromises, hydrationNodes) {
|
|
1255
|
+
function commitHost(adapter, ret, ctx, root, schedulePromises, hydrationNodes) {
|
|
1250
1256
|
if (getFlag(ret, IsCopied) && getFlag(ret, DidCommit)) {
|
|
1251
1257
|
return getValue(ret);
|
|
1252
1258
|
}
|
|
@@ -1299,6 +1305,7 @@
|
|
|
1299
1305
|
node,
|
|
1300
1306
|
props,
|
|
1301
1307
|
scope,
|
|
1308
|
+
root,
|
|
1302
1309
|
});
|
|
1303
1310
|
if (childHydrationNodes) {
|
|
1304
1311
|
for (let i = 0; i < childHydrationNodes.length; i++) {
|
|
@@ -1306,6 +1313,7 @@
|
|
|
1306
1313
|
node: childHydrationNodes[i],
|
|
1307
1314
|
parentNode: node,
|
|
1308
1315
|
isNested: false,
|
|
1316
|
+
root,
|
|
1309
1317
|
});
|
|
1310
1318
|
}
|
|
1311
1319
|
}
|
|
@@ -1334,6 +1342,7 @@
|
|
|
1334
1342
|
node: nextChild,
|
|
1335
1343
|
props,
|
|
1336
1344
|
scope,
|
|
1345
|
+
root,
|
|
1337
1346
|
});
|
|
1338
1347
|
if (childHydrationNodes) {
|
|
1339
1348
|
node = nextChild;
|
|
@@ -1342,6 +1351,7 @@
|
|
|
1342
1351
|
node: childHydrationNodes[i],
|
|
1343
1352
|
parentNode: node,
|
|
1344
1353
|
isNested: false,
|
|
1354
|
+
root,
|
|
1345
1355
|
});
|
|
1346
1356
|
}
|
|
1347
1357
|
}
|
|
@@ -1356,6 +1366,7 @@
|
|
|
1356
1366
|
tagName: getTagName(tag),
|
|
1357
1367
|
props,
|
|
1358
1368
|
scope,
|
|
1369
|
+
root,
|
|
1359
1370
|
});
|
|
1360
1371
|
}
|
|
1361
1372
|
ret.value = node;
|
|
@@ -1369,13 +1380,14 @@
|
|
|
1369
1380
|
props,
|
|
1370
1381
|
oldProps,
|
|
1371
1382
|
scope,
|
|
1383
|
+
root,
|
|
1372
1384
|
copyProps,
|
|
1373
1385
|
isHydrating: !!childHydrationNodes,
|
|
1374
1386
|
quietProps,
|
|
1375
1387
|
});
|
|
1376
1388
|
}
|
|
1377
1389
|
if (!copyChildren) {
|
|
1378
|
-
const children = commitChildren(adapter, ret, ctx, scope, ret, 0, schedulePromises, hydrationMetaProp && !hydrationMetaProp.includes("children")
|
|
1390
|
+
const children = commitChildren(adapter, ret, ctx, scope, tag === Portal ? node : root, ret, 0, schedulePromises, hydrationMetaProp && !hydrationMetaProp.includes("children")
|
|
1379
1391
|
? undefined
|
|
1380
1392
|
: childHydrationNodes);
|
|
1381
1393
|
adapter.arrange({
|
|
@@ -1385,6 +1397,7 @@
|
|
|
1385
1397
|
props,
|
|
1386
1398
|
children,
|
|
1387
1399
|
oldProps,
|
|
1400
|
+
root,
|
|
1388
1401
|
});
|
|
1389
1402
|
}
|
|
1390
1403
|
ret.oldProps = props;
|
|
@@ -1485,10 +1498,10 @@
|
|
|
1485
1498
|
}
|
|
1486
1499
|
}
|
|
1487
1500
|
}
|
|
1488
|
-
function unmount(adapter, host, ctx, ret, isNested) {
|
|
1501
|
+
function unmount(adapter, host, ctx, root, ret, isNested) {
|
|
1489
1502
|
// TODO: set the IsUnmounted flag consistently for all retainers
|
|
1490
1503
|
if (ret.fallback) {
|
|
1491
|
-
unmount(adapter, host, ctx, ret.fallback, isNested);
|
|
1504
|
+
unmount(adapter, host, ctx, root, ret.fallback, isNested);
|
|
1492
1505
|
ret.fallback = undefined;
|
|
1493
1506
|
}
|
|
1494
1507
|
if (getFlag(ret, IsResurrecting)) {
|
|
@@ -1499,7 +1512,7 @@
|
|
|
1499
1512
|
const lingerers = ret.lingerers[i];
|
|
1500
1513
|
if (lingerers) {
|
|
1501
1514
|
for (const lingerer of lingerers) {
|
|
1502
|
-
unmount(adapter, host, ctx, lingerer, isNested);
|
|
1515
|
+
unmount(adapter, host, ctx, root, lingerer, isNested);
|
|
1503
1516
|
}
|
|
1504
1517
|
}
|
|
1505
1518
|
}
|
|
@@ -1509,16 +1522,16 @@
|
|
|
1509
1522
|
unmountComponent(ret.ctx, isNested);
|
|
1510
1523
|
}
|
|
1511
1524
|
else if (ret.el.tag === Fragment) {
|
|
1512
|
-
unmountChildren(adapter, host, ctx, ret, isNested);
|
|
1525
|
+
unmountChildren(adapter, host, ctx, root, ret, isNested);
|
|
1513
1526
|
}
|
|
1514
1527
|
else if (ret.el.tag === Portal) {
|
|
1515
|
-
unmountChildren(adapter, ret, ctx, ret, false);
|
|
1528
|
+
unmountChildren(adapter, ret, ctx, ret.value, ret, false);
|
|
1516
1529
|
if (ret.value != null) {
|
|
1517
1530
|
adapter.finalize(ret.value);
|
|
1518
1531
|
}
|
|
1519
1532
|
}
|
|
1520
1533
|
else {
|
|
1521
|
-
unmountChildren(adapter, ret, ctx, ret, true);
|
|
1534
|
+
unmountChildren(adapter, ret, ctx, root, ret, true);
|
|
1522
1535
|
if (getFlag(ret, DidCommit)) {
|
|
1523
1536
|
if (ctx) {
|
|
1524
1537
|
// Remove the value from every context which shares the same host.
|
|
@@ -1528,22 +1541,23 @@
|
|
|
1528
1541
|
node: ret.value,
|
|
1529
1542
|
parentNode: host.value,
|
|
1530
1543
|
isNested,
|
|
1544
|
+
root,
|
|
1531
1545
|
});
|
|
1532
1546
|
}
|
|
1533
1547
|
}
|
|
1534
1548
|
}
|
|
1535
|
-
function unmountChildren(adapter, host, ctx, ret, isNested) {
|
|
1549
|
+
function unmountChildren(adapter, host, ctx, root, ret, isNested) {
|
|
1536
1550
|
if (ret.graveyard) {
|
|
1537
1551
|
for (let i = 0; i < ret.graveyard.length; i++) {
|
|
1538
1552
|
const child = ret.graveyard[i];
|
|
1539
|
-
unmount(adapter, host, ctx, child, isNested);
|
|
1553
|
+
unmount(adapter, host, ctx, root, child, isNested);
|
|
1540
1554
|
}
|
|
1541
1555
|
ret.graveyard = undefined;
|
|
1542
1556
|
}
|
|
1543
1557
|
for (let i = 0, children = wrap(ret.children); i < children.length; i++) {
|
|
1544
1558
|
const child = children[i];
|
|
1545
1559
|
if (typeof child === "object") {
|
|
1546
|
-
unmount(adapter, host, ctx, child, isNested);
|
|
1560
|
+
unmount(adapter, host, ctx, root, child, isNested);
|
|
1547
1561
|
}
|
|
1548
1562
|
}
|
|
1549
1563
|
}
|
|
@@ -2337,7 +2351,7 @@
|
|
|
2337
2351
|
});
|
|
2338
2352
|
return getValue(ctx.ret);
|
|
2339
2353
|
}
|
|
2340
|
-
const values = commitChildren(ctx.adapter, ctx.host, ctx, ctx.scope, ctx.ret, ctx.index, schedulePromises, hydrationNodes);
|
|
2354
|
+
const values = commitChildren(ctx.adapter, ctx.host, ctx, ctx.scope, ctx.root, ctx.ret, ctx.index, schedulePromises, hydrationNodes);
|
|
2341
2355
|
if (getFlag(ctx.ret, IsUnmounted)) {
|
|
2342
2356
|
return;
|
|
2343
2357
|
}
|
|
@@ -2361,7 +2375,7 @@
|
|
|
2361
2375
|
setFlag(ctx.ret, IsScheduling, wasScheduling);
|
|
2362
2376
|
propagateComponent(ctx);
|
|
2363
2377
|
if (ctx.ret.fallback) {
|
|
2364
|
-
unmount(ctx.adapter, ctx.host, ctx.parent, ctx.ret.fallback, false);
|
|
2378
|
+
unmount(ctx.adapter, ctx.host, ctx.parent, ctx.root, ctx.ret.fallback, false);
|
|
2365
2379
|
}
|
|
2366
2380
|
ctx.ret.fallback = undefined;
|
|
2367
2381
|
});
|
|
@@ -2387,7 +2401,7 @@
|
|
|
2387
2401
|
propagateComponent(ctx);
|
|
2388
2402
|
}
|
|
2389
2403
|
if (ctx.ret.fallback) {
|
|
2390
|
-
unmount(ctx.adapter, ctx.host, ctx.parent, ctx.ret.fallback, false);
|
|
2404
|
+
unmount(ctx.adapter, ctx.host, ctx.parent, ctx.root, ctx.ret.fallback, false);
|
|
2391
2405
|
}
|
|
2392
2406
|
ctx.ret.fallback = undefined;
|
|
2393
2407
|
setFlag(ctx.ret, IsUpdating, false);
|
|
@@ -2453,6 +2467,7 @@
|
|
|
2453
2467
|
props,
|
|
2454
2468
|
oldProps: props,
|
|
2455
2469
|
children: hostChildren,
|
|
2470
|
+
root: ctx.root,
|
|
2456
2471
|
});
|
|
2457
2472
|
flush(ctx.adapter, ctx.root, ctx);
|
|
2458
2473
|
}
|
|
@@ -2507,7 +2522,7 @@
|
|
|
2507
2522
|
ctx.schedule = undefined;
|
|
2508
2523
|
}
|
|
2509
2524
|
clearEventListeners(ctx.ctx);
|
|
2510
|
-
unmountChildren(ctx.adapter, ctx.host, ctx, ctx.ret, isNested);
|
|
2525
|
+
unmountChildren(ctx.adapter, ctx.host, ctx, ctx.root, ctx.ret, isNested);
|
|
2511
2526
|
if (didLinger) {
|
|
2512
2527
|
// If we lingered, we call finalize to ensure rendering is finalized
|
|
2513
2528
|
if (ctx.root != null) {
|
|
@@ -2728,6 +2743,15 @@
|
|
|
2728
2743
|
|
|
2729
2744
|
const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
2730
2745
|
const MATHML_NAMESPACE = "http://www.w3.org/1998/Math/MathML";
|
|
2746
|
+
function getRootDocument(root) {
|
|
2747
|
+
if (root && root.ownerDocument) {
|
|
2748
|
+
return root.ownerDocument;
|
|
2749
|
+
}
|
|
2750
|
+
if (root && root.nodeType === Node.DOCUMENT_NODE) {
|
|
2751
|
+
return root;
|
|
2752
|
+
}
|
|
2753
|
+
return document;
|
|
2754
|
+
}
|
|
2731
2755
|
function isWritableProperty(element, name) {
|
|
2732
2756
|
// walk up the object's prototype chain to find the owner
|
|
2733
2757
|
let propOwner = element;
|
|
@@ -2758,11 +2782,18 @@
|
|
|
2758
2782
|
else if (expectedValue === true || expectedValue === "") {
|
|
2759
2783
|
console.warn(`Expected "${showName}" to be ${expectedValue === true ? "present" : '""'} but found ${String(actualValue)} while hydrating:`, element);
|
|
2760
2784
|
}
|
|
2761
|
-
else if (typeof window !== "undefined" &&
|
|
2762
|
-
window.location &&
|
|
2763
|
-
new URL(expectedValue, window.location.origin).href ===
|
|
2764
|
-
new URL(actualValue, window.location.origin).href) ;
|
|
2765
2785
|
else {
|
|
2786
|
+
// Check if this is a URL mismatch that's actually just resolution
|
|
2787
|
+
const win = element.ownerDocument.defaultView;
|
|
2788
|
+
if (win && win.location) {
|
|
2789
|
+
const origin = win.location.origin;
|
|
2790
|
+
if (new URL(expectedValue, origin).href ===
|
|
2791
|
+
new URL(actualValue, origin).href) {
|
|
2792
|
+
// attrs which are URLs will often be resolved to their full
|
|
2793
|
+
// href in the DOM, so we squash these errors
|
|
2794
|
+
return;
|
|
2795
|
+
}
|
|
2796
|
+
}
|
|
2766
2797
|
console.warn(`Expected "${showName}" to be "${String(expectedValue)}" but found ${String(actualValue)} while hydrating:`, element);
|
|
2767
2798
|
}
|
|
2768
2799
|
}
|
|
@@ -2783,7 +2814,7 @@
|
|
|
2783
2814
|
}
|
|
2784
2815
|
return props.xmlns || xmlns;
|
|
2785
2816
|
},
|
|
2786
|
-
create({ tag, tagName, scope: xmlns, }) {
|
|
2817
|
+
create({ tag, tagName, scope: xmlns, root, }) {
|
|
2787
2818
|
if (typeof tag !== "string") {
|
|
2788
2819
|
throw new Error(`Unknown tag: ${tagName}`);
|
|
2789
2820
|
}
|
|
@@ -2793,18 +2824,18 @@
|
|
|
2793
2824
|
else if (tag.toLowerCase() === "math") {
|
|
2794
2825
|
xmlns = MATHML_NAMESPACE;
|
|
2795
2826
|
}
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
: document.createElement(tag);
|
|
2827
|
+
const doc = getRootDocument(root);
|
|
2828
|
+
return xmlns ? doc.createElementNS(xmlns, tag) : doc.createElement(tag);
|
|
2799
2829
|
},
|
|
2800
|
-
adopt({ tag, tagName, node, }) {
|
|
2830
|
+
adopt({ tag, tagName, node, root, }) {
|
|
2801
2831
|
if (typeof tag !== "string" && tag !== Portal) {
|
|
2802
2832
|
throw new Error(`Unknown tag: ${tagName}`);
|
|
2803
2833
|
}
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
node ===
|
|
2807
|
-
node ===
|
|
2834
|
+
const doc = getRootDocument(root);
|
|
2835
|
+
if (node === doc.body ||
|
|
2836
|
+
node === doc.head ||
|
|
2837
|
+
node === doc.documentElement ||
|
|
2838
|
+
node === doc) {
|
|
2808
2839
|
console.warn(`Hydrating ${node.nodeName.toLowerCase()} is discouraged as it is destructive and may remove unknown nodes.`);
|
|
2809
2840
|
}
|
|
2810
2841
|
if (node == null ||
|
|
@@ -2962,19 +2993,28 @@
|
|
|
2962
2993
|
const hydratingClassName = isHydrating
|
|
2963
2994
|
? element.getAttribute("class")
|
|
2964
2995
|
: undefined;
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
shouldIssueWarning = true;
|
|
2974
|
-
}
|
|
2996
|
+
const allClassNames = { ...oldValue, ...value };
|
|
2997
|
+
// Two passes: removes first, then adds. This ensures that
|
|
2998
|
+
// overlapping classes in different keys are handled correctly.
|
|
2999
|
+
// e.g. {"a b": false, "b c": true} should result in "b c"
|
|
3000
|
+
for (const classNames in allClassNames) {
|
|
3001
|
+
if (!(value && value[classNames])) {
|
|
3002
|
+
const classes = classNames.split(/\s+/).filter(Boolean);
|
|
3003
|
+
element.classList.remove(...classes);
|
|
2975
3004
|
}
|
|
2976
|
-
|
|
2977
|
-
|
|
3005
|
+
}
|
|
3006
|
+
for (const classNames in allClassNames) {
|
|
3007
|
+
if (value && value[classNames]) {
|
|
3008
|
+
const classes = classNames.split(/\s+/).filter(Boolean);
|
|
3009
|
+
element.classList.add(...classes);
|
|
3010
|
+
for (const className of classes) {
|
|
3011
|
+
if (hydratingClasses && hydratingClasses.has(className)) {
|
|
3012
|
+
hydratingClasses.delete(className);
|
|
3013
|
+
}
|
|
3014
|
+
else if (isHydrating) {
|
|
3015
|
+
shouldIssueWarning = true;
|
|
3016
|
+
}
|
|
3017
|
+
}
|
|
2978
3018
|
}
|
|
2979
3019
|
}
|
|
2980
3020
|
if (shouldIssueWarning ||
|
|
@@ -3101,7 +3141,8 @@
|
|
|
3101
3141
|
parentNode.removeChild(node);
|
|
3102
3142
|
}
|
|
3103
3143
|
},
|
|
3104
|
-
text({ value, oldNode, hydrationNodes, }) {
|
|
3144
|
+
text({ value, oldNode, hydrationNodes, root, }) {
|
|
3145
|
+
const doc = getRootDocument(root);
|
|
3105
3146
|
if (hydrationNodes != null) {
|
|
3106
3147
|
let node = hydrationNodes.shift();
|
|
3107
3148
|
if (!node || node.nodeType !== Node.TEXT_NODE) {
|
|
@@ -3115,7 +3156,7 @@
|
|
|
3115
3156
|
// the text node is longer than the expected text, so we
|
|
3116
3157
|
// reuse the existing text node, but truncate it and unshift the rest
|
|
3117
3158
|
node.data = value;
|
|
3118
|
-
hydrationNodes.unshift(
|
|
3159
|
+
hydrationNodes.unshift(doc.createTextNode(textData.slice(value.length)));
|
|
3119
3160
|
return node;
|
|
3120
3161
|
}
|
|
3121
3162
|
}
|
|
@@ -3133,16 +3174,17 @@
|
|
|
3133
3174
|
}
|
|
3134
3175
|
return oldNode;
|
|
3135
3176
|
}
|
|
3136
|
-
return
|
|
3177
|
+
return doc.createTextNode(value);
|
|
3137
3178
|
},
|
|
3138
|
-
raw({ value, scope: xmlns, hydrationNodes, }) {
|
|
3179
|
+
raw({ value, scope: xmlns, hydrationNodes, root, }) {
|
|
3139
3180
|
let nodes;
|
|
3140
3181
|
if (typeof value === "string") {
|
|
3182
|
+
const doc = getRootDocument(root);
|
|
3141
3183
|
const el = xmlns == null
|
|
3142
|
-
?
|
|
3184
|
+
? doc.createElement("div")
|
|
3143
3185
|
: xmlns === SVG_NAMESPACE
|
|
3144
|
-
?
|
|
3145
|
-
:
|
|
3186
|
+
? doc.createElementNS(xmlns, "svg")
|
|
3187
|
+
: doc.createElementNS(xmlns, "math");
|
|
3146
3188
|
el.innerHTML = value;
|
|
3147
3189
|
nodes = Array.from(el.childNodes);
|
|
3148
3190
|
}
|
|
@@ -3270,6 +3312,20 @@
|
|
|
3270
3312
|
}
|
|
3271
3313
|
attrs.push(`class="${escape(value)}"`);
|
|
3272
3314
|
}
|
|
3315
|
+
else if (name === "class") {
|
|
3316
|
+
if (typeof value === "string") {
|
|
3317
|
+
attrs.push(`class="${escape(value)}"`);
|
|
3318
|
+
}
|
|
3319
|
+
else if (typeof value === "object" && value !== null) {
|
|
3320
|
+
// class={{"foo bar": true, "baz": false}} syntax
|
|
3321
|
+
const classes = Object.keys(value)
|
|
3322
|
+
.filter((k) => value[k])
|
|
3323
|
+
.join(" ");
|
|
3324
|
+
if (classes) {
|
|
3325
|
+
attrs.push(`class="${escape(classes)}"`);
|
|
3326
|
+
}
|
|
3327
|
+
}
|
|
3328
|
+
}
|
|
3273
3329
|
else {
|
|
3274
3330
|
if (name.startsWith("attr:")) {
|
|
3275
3331
|
name = name.slice("attr:".length);
|