octane 0.2.14 → 0.2.15
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/cjs/dom-binding-claims.cjs +28 -0
- package/dist/cjs/dom-bindings.cjs +35 -6
- package/dist/cjs/runtime.cjs +17 -2
- package/dist/cjs/version.cjs +1 -1
- package/dist/compiler/dom-binding-program.js +12 -1
- package/dist/compiler/dom-bindings.js +28 -4
- package/dist/dom-binding-claims.d.ts +1 -0
- package/dist/dom-binding-claims.js +4 -0
- package/dist/dom-bindings.d.ts +3 -2
- package/dist/dom-bindings.js +35 -6
- package/dist/runtime.js +17 -2
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var dom_binding_claims_exports = {};
|
|
20
|
+
__export(dom_binding_claims_exports, {
|
|
21
|
+
domBindingClaims: () => domBindingClaims
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(dom_binding_claims_exports);
|
|
24
|
+
const domBindingClaims = /* @__PURE__ */ new WeakMap();
|
|
25
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
26
|
+
0 && (module.exports = {
|
|
27
|
+
domBindingClaims
|
|
28
|
+
});
|
|
@@ -31,6 +31,7 @@ __export(dom_bindings_exports, {
|
|
|
31
31
|
});
|
|
32
32
|
module.exports = __toCommonJS(dom_bindings_exports);
|
|
33
33
|
var import_class_names = require("./class-names.cjs");
|
|
34
|
+
var import_dom_binding_claims = require("./dom-binding-claims.cjs");
|
|
34
35
|
var import_sanitize_url = require("./sanitize-url.cjs");
|
|
35
36
|
var import_stream_protocol = require("./stream-protocol.cjs");
|
|
36
37
|
var import_native_read_seeds = require("./signals/native-read-seeds.cjs");
|
|
@@ -91,6 +92,11 @@ function __releaseBinding(node, name) {
|
|
|
91
92
|
const channels = claims.get(node);
|
|
92
93
|
channels.delete(name);
|
|
93
94
|
if (channels.size === 0) claims.delete(node);
|
|
95
|
+
const published = import_dom_binding_claims.domBindingClaims.get(node);
|
|
96
|
+
if (published) {
|
|
97
|
+
published.delete(name);
|
|
98
|
+
if (published.size === 0) import_dom_binding_claims.domBindingClaims.delete(node);
|
|
99
|
+
}
|
|
94
100
|
}
|
|
95
101
|
function resolveNodes(root, descriptor) {
|
|
96
102
|
if (root?.nodeType !== 1 || root.getAttribute("data-octane-bindings") !== descriptor.id || descriptor.nodes.length === 0) {
|
|
@@ -100,9 +106,9 @@ function resolveNodes(root, descriptor) {
|
|
|
100
106
|
const nodes = [];
|
|
101
107
|
const childIndices = [];
|
|
102
108
|
for (let i = 0; i < descriptor.nodes.length; i++) {
|
|
103
|
-
const [parent, tag, namespace, children] = descriptor.nodes[i];
|
|
109
|
+
const [parent, tag, namespace, children, , text] = descriptor.nodes[i];
|
|
104
110
|
const node = i === 0 ? parent === -1 ? root : void 0 : parent >= 0 && parent < i && descriptor.nodes[parent][3] !== null ? nodes[parent]?.children[childIndices[parent]++] : void 0;
|
|
105
|
-
if (node === void 0 || descriptor.nodes[i][4] === true || node.localName !== tag || node.namespaceURI !== namespaces[namespace] || children !== null && (node.childNodes.length !== children || node.children.length !== children)) {
|
|
111
|
+
if (node === void 0 || descriptor.nodes[i][4] === true || node.localName !== tag || node.namespaceURI !== namespaces[namespace] || (text ? node.childNodes.length > 1 || node.firstChild !== null && node.firstChild.nodeType !== 3 : children !== null && (node.childNodes.length !== children || node.children.length !== children))) {
|
|
106
112
|
throw new Error("DOM bindings cannot adopt a mismatched static element topology.");
|
|
107
113
|
}
|
|
108
114
|
nodes.push(node);
|
|
@@ -143,9 +149,9 @@ function resolveAddressedNodes(root, descriptor) {
|
|
|
143
149
|
}
|
|
144
150
|
const childCounts = new Array(descriptor.nodes.length).fill(0);
|
|
145
151
|
for (let i = 0; i < descriptor.nodes.length; i++) {
|
|
146
|
-
const [parent, tag, namespace, children, openChildren] = descriptor.nodes[i];
|
|
152
|
+
const [parent, tag, namespace, children, openChildren, text] = descriptor.nodes[i];
|
|
147
153
|
const node = nodes[i];
|
|
148
|
-
if (node === void 0 || node.localName !== tag || node.namespaceURI !== namespaces[namespace] || (i === 0 ? parent !== -1 || node !== root : parent < 0 || parent >= i || descriptor.nodes[parent][3] === null || node.parentElement !== nodes[parent] || descriptor.nodes[parent][4] !== true && nodes[parent].children[childCounts[parent]] !== node) || openChildren && children === null || children !== null && !openChildren && (node.childNodes.length !== children || node.children.length !== children)) {
|
|
154
|
+
if (node === void 0 || node.localName !== tag || node.namespaceURI !== namespaces[namespace] || (i === 0 ? parent !== -1 || node !== root : parent < 0 || parent >= i || descriptor.nodes[parent][3] === null || node.parentElement !== nodes[parent] || descriptor.nodes[parent][4] !== true && nodes[parent].children[childCounts[parent]] !== node) || openChildren && children === null || (text ? node.childNodes.length > 1 || node.firstChild !== null && node.firstChild.nodeType !== 3 : children !== null && !openChildren && (node.childNodes.length !== children || node.children.length !== children))) {
|
|
149
155
|
throw new Error("DOM bindings cannot adopt a mismatched addressed element topology.");
|
|
150
156
|
}
|
|
151
157
|
if (parent !== -1) childCounts[parent]++;
|
|
@@ -160,6 +166,11 @@ function resolveAddressedNodes(root, descriptor) {
|
|
|
160
166
|
function normalize(binding, value) {
|
|
161
167
|
const type = typeof value;
|
|
162
168
|
switch (binding[1]) {
|
|
169
|
+
case "text":
|
|
170
|
+
if (value == null || value === false) return "";
|
|
171
|
+
if (type !== "string" && type !== "number" && type !== "bigint" && type !== "boolean")
|
|
172
|
+
throw new TypeError("DOM binding text must be a synchronous scalar.");
|
|
173
|
+
return String(value);
|
|
163
174
|
case "styleObject":
|
|
164
175
|
return value;
|
|
165
176
|
case "class":
|
|
@@ -187,7 +198,11 @@ function normalize(binding, value) {
|
|
|
187
198
|
}
|
|
188
199
|
function write(node, binding, value) {
|
|
189
200
|
const name = binding[2];
|
|
190
|
-
if (binding[1] === "
|
|
201
|
+
if (binding[1] === "text") {
|
|
202
|
+
const text = node.firstChild;
|
|
203
|
+
if (text === null) node.appendChild(node.ownerDocument.createTextNode(value));
|
|
204
|
+
else if (text.nodeValue !== value) text.nodeValue = value;
|
|
205
|
+
} else if (binding[1] === "classToken") {
|
|
191
206
|
node.classList.toggle(name, value !== null);
|
|
192
207
|
} else if (binding[1] === "url") {
|
|
193
208
|
if (value === "" && !(name === "href" && node.localName === "a")) value = null;
|
|
@@ -400,7 +415,21 @@ function __adoptBindings(root, descriptor, source, options) {
|
|
|
400
415
|
styles.set(i, style = __createBindingStyleRestoration(nodes[binding[0]], binding));
|
|
401
416
|
style.write(next[i]);
|
|
402
417
|
} else write(nodes[binding[0]], binding, next[i]);
|
|
403
|
-
if (!disposed)
|
|
418
|
+
if (!disposed) {
|
|
419
|
+
previous[i] = next[i];
|
|
420
|
+
if (binding[1] === "attr" || binding[1] === "boolean" || binding[1] === "aria" || binding[1] === "class" || binding[1] === "styleProperty" || binding[1] === "text") {
|
|
421
|
+
const [node, name] = owned[i];
|
|
422
|
+
let published2 = next[i];
|
|
423
|
+
if (binding[1] === "styleProperty") {
|
|
424
|
+
const style = node.style;
|
|
425
|
+
const value = style.getPropertyValue(binding[2]);
|
|
426
|
+
published2 = value === "" ? null : value + (style.getPropertyPriority(binding[2]) ? " !important" : "");
|
|
427
|
+
}
|
|
428
|
+
let claims2 = import_dom_binding_claims.domBindingClaims.get(node);
|
|
429
|
+
if (claims2 === void 0) import_dom_binding_claims.domBindingClaims.set(node, claims2 = /* @__PURE__ */ new Map());
|
|
430
|
+
claims2.set(name, published2);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
404
433
|
}
|
|
405
434
|
};
|
|
406
435
|
const drain = (preview = false) => {
|
package/dist/cjs/runtime.cjs
CHANGED
|
@@ -315,6 +315,7 @@ __export(runtime_exports, {
|
|
|
315
315
|
});
|
|
316
316
|
module.exports = __toCommonJS(runtime_exports);
|
|
317
317
|
var import_hook_slot_cache = require("./hook-slot-cache.cjs");
|
|
318
|
+
var import_dom_binding_claims = require("./dom-binding-claims.cjs");
|
|
318
319
|
var import_dom_stage = require("./dom-stage.cjs");
|
|
319
320
|
var import_dom_binding_styles = require("./dom-binding-styles.cjs");
|
|
320
321
|
var import_dom_binding_handoff = require("./dom-binding-handoff.cjs");
|
|
@@ -11583,7 +11584,7 @@ class HydrationCapability {
|
|
|
11583
11584
|
const first = getFirstChild(el);
|
|
11584
11585
|
if (first !== null && first.nodeType === 3) {
|
|
11585
11586
|
const server = (STAGED_DOM?.view(first) ?? first).nodeValue;
|
|
11586
|
-
if (server !== text && !isTextParserNormalizedMatch(server, text) && !isHydrationSuppressed(el)) {
|
|
11587
|
+
if (server !== text && import_dom_binding_claims.domBindingClaims.get(el)?.get("#text") !== server && !isTextParserNormalizedMatch(server, text) && !isHydrationSuppressed(el)) {
|
|
11587
11588
|
this.recordTextMismatch(first, loc || el.__oct_loc, server);
|
|
11588
11589
|
(STAGED_DOM?.view(first) ?? first).nodeValue = text;
|
|
11589
11590
|
}
|
|
@@ -11668,6 +11669,7 @@ class HydrationCapability {
|
|
|
11668
11669
|
name.indexOf(":") >= 0 ? name.slice(name.indexOf(":") + 1) : name
|
|
11669
11670
|
) : (STAGED_DOM?.view(el) ?? el).getAttribute(name);
|
|
11670
11671
|
if (server === next) return false;
|
|
11672
|
+
if (import_dom_binding_claims.domBindingClaims.get(el)?.get(name) === server) return false;
|
|
11671
11673
|
if (next !== null && isAttributeParserNormalizedMatch(server, next)) return false;
|
|
11672
11674
|
const mode = hydrationMismatchMode(el);
|
|
11673
11675
|
if (mode === 0) return true;
|
|
@@ -11678,10 +11680,11 @@ class HydrationCapability {
|
|
|
11678
11680
|
}
|
|
11679
11681
|
allowClass(el, next, absentIsEmpty = false) {
|
|
11680
11682
|
const mode = hydrationMismatchMode(el);
|
|
11681
|
-
if (mode === 0) return true;
|
|
11682
11683
|
const rawServer = (STAGED_DOM?.view(el) ?? el).getAttribute("class");
|
|
11683
11684
|
const server = absentIsEmpty && rawServer === null ? "" : rawServer;
|
|
11684
11685
|
if (server === next) return true;
|
|
11686
|
+
if (import_dom_binding_claims.domBindingClaims.get(el)?.get("class") === rawServer) return false;
|
|
11687
|
+
if (mode === 0) return true;
|
|
11685
11688
|
if (mode === 1) return false;
|
|
11686
11689
|
if (process.env.NODE_ENV !== "production")
|
|
11687
11690
|
warnHydrationValueMismatch(el.__oct_loc, "attribute `class`", server, next);
|
|
@@ -11723,6 +11726,18 @@ class HydrationCapability {
|
|
|
11723
11726
|
applyStyleProperty(el, expectedStyle, entries[i], entry);
|
|
11724
11727
|
}
|
|
11725
11728
|
}
|
|
11729
|
+
const claims = import_dom_binding_claims.domBindingClaims.get(el);
|
|
11730
|
+
if (claims !== void 0) {
|
|
11731
|
+
for (const [channel, published] of claims) {
|
|
11732
|
+
if (!channel.startsWith("style:")) continue;
|
|
11733
|
+
const property = channel.slice(6);
|
|
11734
|
+
const value2 = style.getPropertyValue(property);
|
|
11735
|
+
const priority = style.getPropertyPriority(property);
|
|
11736
|
+
if ((value2 === "" ? null : value2 + (priority ? " !important" : "")) !== published) continue;
|
|
11737
|
+
if (value2 === "") expectedStyle.removeProperty(property);
|
|
11738
|
+
else expectedStyle.setProperty(property, value2, priority);
|
|
11739
|
+
}
|
|
11740
|
+
}
|
|
11726
11741
|
const expected = expectedStyle.cssText;
|
|
11727
11742
|
const expectsStyleAttribute = expected !== "";
|
|
11728
11743
|
if (before === expected && hadStyleAttribute === expectsStyleAttribute) return true;
|
package/dist/cjs/version.cjs
CHANGED
|
@@ -21,7 +21,7 @@ __export(version_exports, {
|
|
|
21
21
|
version: () => version
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(version_exports);
|
|
24
|
-
const version = "0.2.
|
|
24
|
+
const version = "0.2.15";
|
|
25
25
|
// Annotate the CommonJS export names for ESM import in node:
|
|
26
26
|
0 && (module.exports = {
|
|
27
27
|
version
|
|
@@ -62,7 +62,18 @@ export function needsBindingProgram(node, isUnbound) {
|
|
|
62
62
|
)
|
|
63
63
|
return true;
|
|
64
64
|
if (tagOf(node) === 'textarea') return false;
|
|
65
|
-
|
|
65
|
+
const children = (node.children ?? []).filter(significant);
|
|
66
|
+
const child = children.length === 1 ? children[0] : null;
|
|
67
|
+
const expression = child?.type === 'JSXExpressionContainer' ? child.expression : null;
|
|
68
|
+
if (
|
|
69
|
+
child?.type === 'JSXText' ||
|
|
70
|
+
(expression?.type === 'Literal' && typeof expression.value === 'string') ||
|
|
71
|
+
(expression?.type === 'TSAsExpression' &&
|
|
72
|
+
(expression.typeAnnotation.type === 'TSStringKeyword' ||
|
|
73
|
+
expression.typeAnnotation.type === 'TSNumberKeyword'))
|
|
74
|
+
)
|
|
75
|
+
return false;
|
|
76
|
+
return children.some((child) => needsBindingProgram(child, isUnbound));
|
|
66
77
|
}
|
|
67
78
|
|
|
68
79
|
function data(value) {
|
|
@@ -901,6 +901,18 @@ function planView(fn, filename, source, imports, lexical, native = null) {
|
|
|
901
901
|
const expression = child.type === 'JSXExpressionContainer' ? child.expression : null;
|
|
902
902
|
return expression === null || !markUnbound(expression, true);
|
|
903
903
|
});
|
|
904
|
+
// A scalar leaf has one stable Text node (or no node for empty SSR).
|
|
905
|
+
// Structural or opaque children retain their existing compiler contract.
|
|
906
|
+
const child = children.length === 1 ? children[0] : null;
|
|
907
|
+
const expression = child?.type === 'JSXExpressionContainer' ? child.expression : null;
|
|
908
|
+
const text =
|
|
909
|
+
tag !== 'textarea' &&
|
|
910
|
+
authoredChildren.length === children.length &&
|
|
911
|
+
(child?.type === 'JSXText' ||
|
|
912
|
+
(expression?.type === 'Literal' && typeof expression.value === 'string') ||
|
|
913
|
+
(expression?.type === 'TSAsExpression' &&
|
|
914
|
+
(expression.typeAnnotation.type === 'TSStringKeyword' ||
|
|
915
|
+
expression.typeAnnotation.type === 'TSNumberKeyword')));
|
|
904
916
|
const opaqueChildren = authoredChildren.length !== children.length;
|
|
905
917
|
const openChildren = tag !== 'textarea' && opaqueChildren && children.length > 0;
|
|
906
918
|
if (tag === 'textarea' && children.some((child) => child.type !== 'JSXText'))
|
|
@@ -913,8 +925,8 @@ function planView(fn, filename, source, imports, lexical, native = null) {
|
|
|
913
925
|
parent,
|
|
914
926
|
tag,
|
|
915
927
|
ns,
|
|
916
|
-
(opaqueChildren && !openChildren) || tag === 'textarea' ? null : children.length,
|
|
917
|
-
...(openChildren ? [true] : []),
|
|
928
|
+
(opaqueChildren && !openChildren) || tag === 'textarea' ? null : text ? 0 : children.length,
|
|
929
|
+
...(text ? [null, 1] : openChildren ? [true] : []),
|
|
918
930
|
]);
|
|
919
931
|
elements.push(element);
|
|
920
932
|
const owned = new Set();
|
|
@@ -1157,7 +1169,9 @@ function planView(fn, filename, source, imports, lexical, native = null) {
|
|
|
1157
1169
|
add(index, kind, name, value, attr);
|
|
1158
1170
|
}
|
|
1159
1171
|
}
|
|
1160
|
-
if (
|
|
1172
|
+
if (text) {
|
|
1173
|
+
if (expression) add(index, 'text', '#text', expression, child);
|
|
1174
|
+
} else if (tag !== 'textarea') {
|
|
1161
1175
|
for (const child of children) visit(child, index, ns, [...ancestors, tag]);
|
|
1162
1176
|
}
|
|
1163
1177
|
};
|
|
@@ -1264,6 +1278,8 @@ function projectionDependencies(plan, lexical) {
|
|
|
1264
1278
|
}
|
|
1265
1279
|
});
|
|
1266
1280
|
collect(plan.expressions ?? plan.values);
|
|
1281
|
+
collect(plan.scalar?.values);
|
|
1282
|
+
collect(plan.scalar?.projections?.map((declaration) => declaration.declarations[0].init));
|
|
1267
1283
|
collect(plan.projections?.map((declaration) => declaration.declarations[0].init));
|
|
1268
1284
|
return needed;
|
|
1269
1285
|
}
|
|
@@ -1478,7 +1494,15 @@ function projectProgram(ast, plan, filename, lexical) {
|
|
|
1478
1494
|
b.object(
|
|
1479
1495
|
scalarProperties(
|
|
1480
1496
|
plan.scalar,
|
|
1481
|
-
|
|
1497
|
+
inheritHookMemoOrigin(
|
|
1498
|
+
b.arrow(
|
|
1499
|
+
plan.fn.params,
|
|
1500
|
+
plan.scalar.projections.length > 0
|
|
1501
|
+
? b.block([...plan.scalar.projections, b.return(b.array(plan.scalar.values))])
|
|
1502
|
+
: b.array(plan.scalar.values),
|
|
1503
|
+
),
|
|
1504
|
+
plan.fn,
|
|
1505
|
+
),
|
|
1482
1506
|
plan.scalar.bindings.some((binding) => binding[1] === 'classGroup')
|
|
1483
1507
|
? b.member(root, 'createClassGroup')
|
|
1484
1508
|
: null,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const domBindingClaims: WeakMap<Element, Map<string, string | null | undefined>>;
|
package/dist/dom-bindings.d.ts
CHANGED
|
@@ -45,12 +45,13 @@ export type BindingNode = readonly [
|
|
|
45
45
|
tag: string,
|
|
46
46
|
namespace: 0 | 1,
|
|
47
47
|
children: number | null,
|
|
48
|
-
openChildren?: true
|
|
48
|
+
openChildren?: true | null,
|
|
49
|
+
text?: 1
|
|
49
50
|
];
|
|
50
51
|
/** @internal Names and numeric CSS units are resolved by the compiler. */
|
|
51
52
|
export type BindingOperation = readonly [
|
|
52
53
|
node: number,
|
|
53
|
-
kind: 'attr' | 'boolean' | 'aria' | 'class' | 'classToken' | 'classGroup' | 'styleProperty' | 'styleAttribute' | 'styleObject' | 'control' | 'url',
|
|
54
|
+
kind: 'attr' | 'boolean' | 'aria' | 'class' | 'classToken' | 'classGroup' | 'styleProperty' | 'styleAttribute' | 'styleObject' | 'control' | 'url' | 'text',
|
|
54
55
|
name: string,
|
|
55
56
|
unitlessOrGroup?: boolean | number
|
|
56
57
|
];
|
package/dist/dom-bindings.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { normalizeClass } from "./class-names.js";
|
|
2
|
+
import { domBindingClaims } from "./dom-binding-claims.js";
|
|
2
3
|
import { sanitizeURL } from "./sanitize-url.js";
|
|
3
4
|
import { STREAM_SCRIPT_ATTR, SUSPENSE_SCRIPT_ATTR } from "./stream-protocol.js";
|
|
4
5
|
import { NATIVE_SIGNAL_SEED_ATTR } from "./signals/native-read-seeds.js";
|
|
@@ -62,6 +63,11 @@ function __releaseBinding(node, name) {
|
|
|
62
63
|
const channels = claims.get(node);
|
|
63
64
|
channels.delete(name);
|
|
64
65
|
if (channels.size === 0) claims.delete(node);
|
|
66
|
+
const published = domBindingClaims.get(node);
|
|
67
|
+
if (published) {
|
|
68
|
+
published.delete(name);
|
|
69
|
+
if (published.size === 0) domBindingClaims.delete(node);
|
|
70
|
+
}
|
|
65
71
|
}
|
|
66
72
|
function resolveNodes(root, descriptor) {
|
|
67
73
|
if (root?.nodeType !== 1 || root.getAttribute("data-octane-bindings") !== descriptor.id || descriptor.nodes.length === 0) {
|
|
@@ -71,9 +77,9 @@ function resolveNodes(root, descriptor) {
|
|
|
71
77
|
const nodes = [];
|
|
72
78
|
const childIndices = [];
|
|
73
79
|
for (let i = 0; i < descriptor.nodes.length; i++) {
|
|
74
|
-
const [parent, tag, namespace, children] = descriptor.nodes[i];
|
|
80
|
+
const [parent, tag, namespace, children, , text] = descriptor.nodes[i];
|
|
75
81
|
const node = i === 0 ? parent === -1 ? root : void 0 : parent >= 0 && parent < i && descriptor.nodes[parent][3] !== null ? nodes[parent]?.children[childIndices[parent]++] : void 0;
|
|
76
|
-
if (node === void 0 || descriptor.nodes[i][4] === true || node.localName !== tag || node.namespaceURI !== namespaces[namespace] || children !== null && (node.childNodes.length !== children || node.children.length !== children)) {
|
|
82
|
+
if (node === void 0 || descriptor.nodes[i][4] === true || node.localName !== tag || node.namespaceURI !== namespaces[namespace] || (text ? node.childNodes.length > 1 || node.firstChild !== null && node.firstChild.nodeType !== 3 : children !== null && (node.childNodes.length !== children || node.children.length !== children))) {
|
|
77
83
|
throw new Error("DOM bindings cannot adopt a mismatched static element topology.");
|
|
78
84
|
}
|
|
79
85
|
nodes.push(node);
|
|
@@ -114,9 +120,9 @@ function resolveAddressedNodes(root, descriptor) {
|
|
|
114
120
|
}
|
|
115
121
|
const childCounts = new Array(descriptor.nodes.length).fill(0);
|
|
116
122
|
for (let i = 0; i < descriptor.nodes.length; i++) {
|
|
117
|
-
const [parent, tag, namespace, children, openChildren] = descriptor.nodes[i];
|
|
123
|
+
const [parent, tag, namespace, children, openChildren, text] = descriptor.nodes[i];
|
|
118
124
|
const node = nodes[i];
|
|
119
|
-
if (node === void 0 || node.localName !== tag || node.namespaceURI !== namespaces[namespace] || (i === 0 ? parent !== -1 || node !== root : parent < 0 || parent >= i || descriptor.nodes[parent][3] === null || node.parentElement !== nodes[parent] || descriptor.nodes[parent][4] !== true && nodes[parent].children[childCounts[parent]] !== node) || openChildren && children === null || children !== null && !openChildren && (node.childNodes.length !== children || node.children.length !== children)) {
|
|
125
|
+
if (node === void 0 || node.localName !== tag || node.namespaceURI !== namespaces[namespace] || (i === 0 ? parent !== -1 || node !== root : parent < 0 || parent >= i || descriptor.nodes[parent][3] === null || node.parentElement !== nodes[parent] || descriptor.nodes[parent][4] !== true && nodes[parent].children[childCounts[parent]] !== node) || openChildren && children === null || (text ? node.childNodes.length > 1 || node.firstChild !== null && node.firstChild.nodeType !== 3 : children !== null && !openChildren && (node.childNodes.length !== children || node.children.length !== children))) {
|
|
120
126
|
throw new Error("DOM bindings cannot adopt a mismatched addressed element topology.");
|
|
121
127
|
}
|
|
122
128
|
if (parent !== -1) childCounts[parent]++;
|
|
@@ -131,6 +137,11 @@ function resolveAddressedNodes(root, descriptor) {
|
|
|
131
137
|
function normalize(binding, value) {
|
|
132
138
|
const type = typeof value;
|
|
133
139
|
switch (binding[1]) {
|
|
140
|
+
case "text":
|
|
141
|
+
if (value == null || value === false) return "";
|
|
142
|
+
if (type !== "string" && type !== "number" && type !== "bigint" && type !== "boolean")
|
|
143
|
+
throw new TypeError("DOM binding text must be a synchronous scalar.");
|
|
144
|
+
return String(value);
|
|
134
145
|
case "styleObject":
|
|
135
146
|
return value;
|
|
136
147
|
case "class":
|
|
@@ -158,7 +169,11 @@ function normalize(binding, value) {
|
|
|
158
169
|
}
|
|
159
170
|
function write(node, binding, value) {
|
|
160
171
|
const name = binding[2];
|
|
161
|
-
if (binding[1] === "
|
|
172
|
+
if (binding[1] === "text") {
|
|
173
|
+
const text = node.firstChild;
|
|
174
|
+
if (text === null) node.appendChild(node.ownerDocument.createTextNode(value));
|
|
175
|
+
else if (text.nodeValue !== value) text.nodeValue = value;
|
|
176
|
+
} else if (binding[1] === "classToken") {
|
|
162
177
|
node.classList.toggle(name, value !== null);
|
|
163
178
|
} else if (binding[1] === "url") {
|
|
164
179
|
if (value === "" && !(name === "href" && node.localName === "a")) value = null;
|
|
@@ -371,7 +386,21 @@ function __adoptBindings(root, descriptor, source, options) {
|
|
|
371
386
|
styles.set(i, style = __createBindingStyleRestoration(nodes[binding[0]], binding));
|
|
372
387
|
style.write(next[i]);
|
|
373
388
|
} else write(nodes[binding[0]], binding, next[i]);
|
|
374
|
-
if (!disposed)
|
|
389
|
+
if (!disposed) {
|
|
390
|
+
previous[i] = next[i];
|
|
391
|
+
if (binding[1] === "attr" || binding[1] === "boolean" || binding[1] === "aria" || binding[1] === "class" || binding[1] === "styleProperty" || binding[1] === "text") {
|
|
392
|
+
const [node, name] = owned[i];
|
|
393
|
+
let published2 = next[i];
|
|
394
|
+
if (binding[1] === "styleProperty") {
|
|
395
|
+
const style = node.style;
|
|
396
|
+
const value = style.getPropertyValue(binding[2]);
|
|
397
|
+
published2 = value === "" ? null : value + (style.getPropertyPriority(binding[2]) ? " !important" : "");
|
|
398
|
+
}
|
|
399
|
+
let claims2 = domBindingClaims.get(node);
|
|
400
|
+
if (claims2 === void 0) domBindingClaims.set(node, claims2 = /* @__PURE__ */ new Map());
|
|
401
|
+
claims2.set(name, published2);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
375
404
|
}
|
|
376
405
|
};
|
|
377
406
|
const drain = (preview = false) => {
|
package/dist/runtime.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { resolveHookPath } from "./hook-slot-cache.js";
|
|
2
|
+
import { domBindingClaims } from "./dom-binding-claims.js";
|
|
2
3
|
import { DOMStage } from "./dom-stage.js";
|
|
3
4
|
import { __normalizeBindingStyle } from "./dom-binding-styles.js";
|
|
4
5
|
import {
|
|
@@ -11417,7 +11418,7 @@ class HydrationCapability {
|
|
|
11417
11418
|
const first = getFirstChild(el);
|
|
11418
11419
|
if (first !== null && first.nodeType === 3) {
|
|
11419
11420
|
const server = (STAGED_DOM?.view(first) ?? first).nodeValue;
|
|
11420
|
-
if (server !== text && !isTextParserNormalizedMatch(server, text) && !isHydrationSuppressed(el)) {
|
|
11421
|
+
if (server !== text && domBindingClaims.get(el)?.get("#text") !== server && !isTextParserNormalizedMatch(server, text) && !isHydrationSuppressed(el)) {
|
|
11421
11422
|
this.recordTextMismatch(first, loc || el.__oct_loc, server);
|
|
11422
11423
|
(STAGED_DOM?.view(first) ?? first).nodeValue = text;
|
|
11423
11424
|
}
|
|
@@ -11502,6 +11503,7 @@ class HydrationCapability {
|
|
|
11502
11503
|
name.indexOf(":") >= 0 ? name.slice(name.indexOf(":") + 1) : name
|
|
11503
11504
|
) : (STAGED_DOM?.view(el) ?? el).getAttribute(name);
|
|
11504
11505
|
if (server === next) return false;
|
|
11506
|
+
if (domBindingClaims.get(el)?.get(name) === server) return false;
|
|
11505
11507
|
if (next !== null && isAttributeParserNormalizedMatch(server, next)) return false;
|
|
11506
11508
|
const mode = hydrationMismatchMode(el);
|
|
11507
11509
|
if (mode === 0) return true;
|
|
@@ -11512,10 +11514,11 @@ class HydrationCapability {
|
|
|
11512
11514
|
}
|
|
11513
11515
|
allowClass(el, next, absentIsEmpty = false) {
|
|
11514
11516
|
const mode = hydrationMismatchMode(el);
|
|
11515
|
-
if (mode === 0) return true;
|
|
11516
11517
|
const rawServer = (STAGED_DOM?.view(el) ?? el).getAttribute("class");
|
|
11517
11518
|
const server = absentIsEmpty && rawServer === null ? "" : rawServer;
|
|
11518
11519
|
if (server === next) return true;
|
|
11520
|
+
if (domBindingClaims.get(el)?.get("class") === rawServer) return false;
|
|
11521
|
+
if (mode === 0) return true;
|
|
11519
11522
|
if (mode === 1) return false;
|
|
11520
11523
|
if (process.env.NODE_ENV !== "production")
|
|
11521
11524
|
warnHydrationValueMismatch(el.__oct_loc, "attribute `class`", server, next);
|
|
@@ -11557,6 +11560,18 @@ class HydrationCapability {
|
|
|
11557
11560
|
applyStyleProperty(el, expectedStyle, entries[i], entry);
|
|
11558
11561
|
}
|
|
11559
11562
|
}
|
|
11563
|
+
const claims = domBindingClaims.get(el);
|
|
11564
|
+
if (claims !== void 0) {
|
|
11565
|
+
for (const [channel, published] of claims) {
|
|
11566
|
+
if (!channel.startsWith("style:")) continue;
|
|
11567
|
+
const property = channel.slice(6);
|
|
11568
|
+
const value2 = style.getPropertyValue(property);
|
|
11569
|
+
const priority = style.getPropertyPriority(property);
|
|
11570
|
+
if ((value2 === "" ? null : value2 + (priority ? " !important" : "")) !== published) continue;
|
|
11571
|
+
if (value2 === "") expectedStyle.removeProperty(property);
|
|
11572
|
+
else expectedStyle.setProperty(property, value2, priority);
|
|
11573
|
+
}
|
|
11574
|
+
}
|
|
11560
11575
|
const expected = expectedStyle.cssText;
|
|
11561
11576
|
const expectsStyleAttribute = expected !== "";
|
|
11562
11577
|
if (before === expected && hadStyleAttribute === expectsStyleAttribute) return true;
|
package/dist/version.js
CHANGED