@solidjs/babel-plugin 2.0.0-rc.6 → 2.0.0-rc.7
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +8 -0
- package/index.js +57 -377
- package/package.json +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -7,4 +7,4 @@ src/shared/transform.ts -> src/ssr/element.ts -> src/shared/transform.ts
|
|
|
7
7
|
src/shared/transform.ts -> src/universal/element.ts -> src/shared/transform.ts
|
|
8
8
|
src/shared/transform.ts -> src/shared/component.ts -> src/shared/transform.ts
|
|
9
9
|
src/shared/transform.ts -> src/shared/fragment.ts -> src/shared/transform.ts
|
|
10
|
-
[32mcreated [1mindex.js[22m in [
|
|
10
|
+
[32mcreated [1mindex.js[22m in [1m2s[22m[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @solidjs/babel-plugin
|
|
2
2
|
|
|
3
|
+
## 2.0.0-rc.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ead7b1a: Keep hydration IDs aligned when an intrinsic element has a ref and one reactive spread.
|
|
8
|
+
- b3586e8: Validate document-shell templates in the document context (#3259). The `validate` pass round-trips templates through a body-context fragment parse, which strips `<html>`/`<head>`/`<body>` wrappers no matter how well-formed the markup — so once #3099 made validate failures compile errors, a root component owning the document shell failed to compile in plain client mode, and merely importing it (the jsdom component-test configuration) was fatal. Shell-rooted templates now parse as a document and the shell element is compared back — the analogue of the synthetic `<table>` wrap for table partials, in both the Babel plugin and the native compiler. Genuine restructuring (an implied `<head>`, flow content in `<head>`, a `<p>` split in `<body>`) still errors. Since `<template>` parsing flattens shells, actually client-creating one now throws a descriptive dev-mode error from `template()` pointing at `hydrate()` — the failure moved from every import to the one broken act.
|
|
9
|
+
- d601119: Remove the experimental patch channel and patch-mode list driver (always opt-in, never default). Graph-native regions own value delivery and the unified-For design owns list structure, so the channel's parallel delivery machinery is retired: `patch.ts`/`patch-driver.ts` deleted, the compiler-contract exports (`registerPatch`/`registerRowOps`/`registerSlotPatch`/`patchableRaw`, `patchDriver`/`rowProof`/`driveList`) removed, the `patchDriver` compiler option dropped from both compilers, the insert `$ll` seam stripped, and the write-side channel struct dieted to the single written-keys bound (`t.wk`) the core fold/notify paths actually use. Store-family app bundles reclaim up to ~900 B brotli; every measured tier shrinks.
|
|
10
|
+
|
|
3
11
|
## 2.0.0-rc.6
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
package/index.js
CHANGED
|
@@ -2821,170 +2821,6 @@ attributes,
|
|
|
2821
2821
|
|
|
2822
2822
|
}
|
|
2823
2823
|
|
|
2824
|
-
/**
|
|
2825
|
-
* Patch-mode eligibility + emission (DESIGN-PATCH-CHANNEL.md, PR-C).
|
|
2826
|
-
*
|
|
2827
|
-
* A template scope qualifies for patch mode when EVERY dynamic binding's
|
|
2828
|
-
* value is a pure expression over member reads of ONE stable subject
|
|
2829
|
-
* identifier (Tier 1: bare member chains; Tier 2: ternary/binary/logical/
|
|
2830
|
-
* template-literal/unary compositions of Tier-1 reads and literals).
|
|
2831
|
-
* Anything else — calls, assignments, functions, foreign identifiers —
|
|
2832
|
-
* disqualifies the SCOPE (per-binding islands remain future work; v1 is
|
|
2833
|
-
* all-or-nothing per template scope, matching the fixture shape).
|
|
2834
|
-
*
|
|
2835
|
-
* Emission (dual driver, shared body):
|
|
2836
|
-
*
|
|
2837
|
-
* _$patchDriver(subject, (_n$, _p$, _f$) => {
|
|
2838
|
-
* let _v$;
|
|
2839
|
-
* if (_f$ || (_v$ = <expr(_n$)>) !== <expr(_p$)>) <setAttr(..., _v$)>;
|
|
2840
|
-
* ...
|
|
2841
|
-
* });
|
|
2842
|
-
*
|
|
2843
|
-
* The runtime driver registers on the store's patch channel when the
|
|
2844
|
-
* subject is a patchable record, else falls back to a tracked force-mode
|
|
2845
|
-
* effect running the same body (reads through the subject track; force
|
|
2846
|
-
* short-circuits every compare, so `prev` is never dereferenced there).
|
|
2847
|
-
* Semantics are therefore IDENTICAL either way; patch mode only changes
|
|
2848
|
-
* who dispatches.
|
|
2849
|
-
*/
|
|
2850
|
-
|
|
2851
|
-
// Node types allowed inside an eligible binding expression (Tier 1+2).
|
|
2852
|
-
function isEligibleExpr(node, subject) {
|
|
2853
|
-
switch (node.type) {
|
|
2854
|
-
case "Identifier":
|
|
2855
|
-
return node.name === subject || node.name === "undefined";
|
|
2856
|
-
case "MemberExpression":{
|
|
2857
|
-
const m = node;
|
|
2858
|
-
if (m.computed) {
|
|
2859
|
-
if (!t__namespace.isStringLiteral(m.property) && !t__namespace.isNumericLiteral(m.property)) return false;
|
|
2860
|
-
} else if (!t__namespace.isIdentifier(m.property)) {
|
|
2861
|
-
return false;
|
|
2862
|
-
}
|
|
2863
|
-
return isEligibleExpr(m.object, subject);
|
|
2864
|
-
}
|
|
2865
|
-
case "StringLiteral":
|
|
2866
|
-
case "NumericLiteral":
|
|
2867
|
-
case "BooleanLiteral":
|
|
2868
|
-
case "NullLiteral":
|
|
2869
|
-
case "BigIntLiteral":
|
|
2870
|
-
return true;
|
|
2871
|
-
case "ConditionalExpression":{
|
|
2872
|
-
const c = node;
|
|
2873
|
-
return (
|
|
2874
|
-
isEligibleExpr(c.test, subject) &&
|
|
2875
|
-
isEligibleExpr(c.consequent, subject) &&
|
|
2876
|
-
isEligibleExpr(c.alternate, subject));
|
|
2877
|
-
|
|
2878
|
-
}
|
|
2879
|
-
case "BinaryExpression":{
|
|
2880
|
-
const b = node;
|
|
2881
|
-
if (b.operator === "in" || b.operator === "instanceof") return false;
|
|
2882
|
-
return isEligibleExpr(b.left, subject) && isEligibleExpr(b.right, subject);
|
|
2883
|
-
}
|
|
2884
|
-
case "LogicalExpression":{
|
|
2885
|
-
const l = node;
|
|
2886
|
-
return isEligibleExpr(l.left, subject) && isEligibleExpr(l.right, subject);
|
|
2887
|
-
}
|
|
2888
|
-
case "UnaryExpression":{
|
|
2889
|
-
const u = node;
|
|
2890
|
-
if (u.operator === "delete" || u.operator === "throw") return false;
|
|
2891
|
-
return isEligibleExpr(u.argument, subject);
|
|
2892
|
-
}
|
|
2893
|
-
case "TemplateLiteral":
|
|
2894
|
-
return node.expressions.every((e) =>
|
|
2895
|
-
t__namespace.isExpression(e) ? isEligibleExpr(e, subject) : false
|
|
2896
|
-
);
|
|
2897
|
-
case "ParenthesizedExpression":
|
|
2898
|
-
return isEligibleExpr(node.expression, subject);
|
|
2899
|
-
default:
|
|
2900
|
-
return false;
|
|
2901
|
-
}
|
|
2902
|
-
}
|
|
2903
|
-
|
|
2904
|
-
/** Find the single subject: the root identifier of the FIRST member chain
|
|
2905
|
-
* encountered. Every other read must root at the same name. */
|
|
2906
|
-
function findSubject(node) {
|
|
2907
|
-
switch (node.type) {
|
|
2908
|
-
case "MemberExpression":
|
|
2909
|
-
return findSubject(node.object);
|
|
2910
|
-
case "Identifier":
|
|
2911
|
-
return node.name === "undefined" ? null : node.name;
|
|
2912
|
-
case "ConditionalExpression":
|
|
2913
|
-
return (
|
|
2914
|
-
findSubject(node.test) ??
|
|
2915
|
-
findSubject(node.consequent) ??
|
|
2916
|
-
findSubject(node.alternate));
|
|
2917
|
-
|
|
2918
|
-
case "BinaryExpression":
|
|
2919
|
-
case "LogicalExpression":
|
|
2920
|
-
return (
|
|
2921
|
-
findSubject(node.left) ?? findSubject(node.right));
|
|
2922
|
-
|
|
2923
|
-
case "UnaryExpression":
|
|
2924
|
-
return findSubject(node.argument);
|
|
2925
|
-
case "TemplateLiteral":{
|
|
2926
|
-
for (const e of node.expressions) {
|
|
2927
|
-
const s = findSubject(e);
|
|
2928
|
-
if (s) return s;
|
|
2929
|
-
}
|
|
2930
|
-
return null;
|
|
2931
|
-
}
|
|
2932
|
-
case "ParenthesizedExpression":
|
|
2933
|
-
return findSubject(node.expression);
|
|
2934
|
-
default:
|
|
2935
|
-
return null;
|
|
2936
|
-
}
|
|
2937
|
-
}
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
/** Analyze a template scope's dynamic binding values. Returns the subject
|
|
2944
|
-
* when EVERY value is an eligible pure expression over it, else null. */
|
|
2945
|
-
function analyzePatchEligibility(values) {
|
|
2946
|
-
if (values.length === 0) return null;
|
|
2947
|
-
let subject = null;
|
|
2948
|
-
for (const v of values) {
|
|
2949
|
-
const s = findSubject(v);
|
|
2950
|
-
if (s === null) return null; // static-only binding: no dispatch source
|
|
2951
|
-
if (subject === null) subject = s;else
|
|
2952
|
-
if (subject !== s) return null; // multi-subject: Q3 territory, bail in v1
|
|
2953
|
-
}
|
|
2954
|
-
if (subject === null) return null;
|
|
2955
|
-
for (const v of values) {
|
|
2956
|
-
if (!isEligibleExpr(v, subject)) return null;
|
|
2957
|
-
}
|
|
2958
|
-
return { subject };
|
|
2959
|
-
}
|
|
2960
|
-
|
|
2961
|
-
/** Clone `expr` substituting the subject identifier with `replacement`.
|
|
2962
|
-
* Safe because eligibility rejected functions/shadowing constructs. */
|
|
2963
|
-
function substituteSubject(
|
|
2964
|
-
expr,
|
|
2965
|
-
subject,
|
|
2966
|
-
replacement)
|
|
2967
|
-
{
|
|
2968
|
-
const clone = t__namespace.cloneNode(expr, true);
|
|
2969
|
-
const rewrite = (node) => {
|
|
2970
|
-
if (t__namespace.isIdentifier(node) && node.name === subject) return t__namespace.cloneNode(replacement);
|
|
2971
|
-
for (const key of Object.keys(node)) {
|
|
2972
|
-
const value = node[key];
|
|
2973
|
-
if (Array.isArray(value)) {
|
|
2974
|
-
for (let i = 0; i < value.length; i++) {
|
|
2975
|
-
if (value[i] && typeof value[i].type === "string") value[i] = rewrite(value[i]);
|
|
2976
|
-
}
|
|
2977
|
-
} else if (value && typeof value.type === "string") {
|
|
2978
|
-
// Never rewrite non-computed member PROPERTY positions.
|
|
2979
|
-
if (t__namespace.isMemberExpression(node) && key === "property" && !node.computed) continue;
|
|
2980
|
-
node[key] = rewrite(value);
|
|
2981
|
-
}
|
|
2982
|
-
}
|
|
2983
|
-
return node;
|
|
2984
|
-
};
|
|
2985
|
-
return rewrite(clone);
|
|
2986
|
-
}
|
|
2987
|
-
|
|
2988
2824
|
function createTemplate$2(
|
|
2989
2825
|
path,
|
|
2990
2826
|
result,
|
|
@@ -2998,16 +2834,9 @@ wrap)
|
|
|
2998
2834
|
!(result.exprs.length || result.dynamics.length || result.postExprs?.length) &&
|
|
2999
2835
|
decl.declarations.length === 1)
|
|
3000
2836
|
{
|
|
3001
|
-
// Static single-root template: a candidate row function returning it is
|
|
3002
|
-
// trivially pure (no reactive work at all).
|
|
3003
|
-
if (config.patchDriver) recordPureRow(path, result, null);
|
|
3004
2837
|
return decl.declarations[0].init;
|
|
3005
2838
|
} else {
|
|
3006
|
-
const
|
|
3007
|
-
const dynamicsStmt = patched ? patched.stmt : wrapDynamics$1(path, result.dynamics);
|
|
3008
|
-
if (config.patchDriver && (result.dynamics.length === 0 || patched)) {
|
|
3009
|
-
recordPureRow(path, result, patched ? patched.subject : null);
|
|
3010
|
-
}
|
|
2839
|
+
const dynamicsStmt = wrapDynamics$1(path, result.dynamics);
|
|
3011
2840
|
const stmts = [
|
|
3012
2841
|
decl,
|
|
3013
2842
|
...result.exprs,
|
|
@@ -3123,179 +2952,6 @@ function registerTemplate(path, results) {
|
|
|
3123
2952
|
results.decl = t__namespace.variableDeclaration("var", results.declarations);
|
|
3124
2953
|
}
|
|
3125
2954
|
|
|
3126
|
-
/**
|
|
3127
|
-
* Row-proof analysis (DESIGN-PATCH-CHANNEL §3c). A function qualifies as a
|
|
3128
|
-
* PURE ROW — buildable with no per-row owner, so the patch-mode list driver
|
|
3129
|
-
* may engage — when ALL of:
|
|
3130
|
-
*
|
|
3131
|
-
* - it is a single-parameter function (plain Identifier param, not
|
|
3132
|
-
* destructured; not async/generator) whose body is exactly this compiled
|
|
3133
|
-
* template: an expression body, or a block whose ONLY statement returns
|
|
3134
|
-
* it (checked before the flat-statement emission inserts our own);
|
|
3135
|
-
* - the template has a single root element (`result.id` — fragments never
|
|
3136
|
-
* reach here) and emitted NO reactive or owned work: dynamics either
|
|
3137
|
-
* absent or all landed in ONE patchDriver body, and `result.exprs` holds
|
|
3138
|
-
* only inert DOM wiring (member-target assignments like `_el$.$$click =
|
|
3139
|
-
* fn` / `_el$.style.cssText = v`, and `_el$.addEventListener(...)`) —
|
|
3140
|
-
* any `insert`/`createComponent`/`memo`/`use`/ref/spread emission is a
|
|
3141
|
-
* call or conditional shape and fails the walk (default-deny);
|
|
3142
|
-
* - the patch subject IS the row parameter. A pure template patching an
|
|
3143
|
-
* OUTER subject would register once per created row on a long-lived
|
|
3144
|
-
* record with no per-row disposal — the foreign-subject leak the runtime
|
|
3145
|
-
* probe never caught.
|
|
3146
|
-
*
|
|
3147
|
-
* Handler/attribute VALUE expressions may be arbitrary user code: stamped
|
|
3148
|
-
* rows are only ever built for real mounts (never speculatively), so their
|
|
3149
|
-
* evaluation timing is identical to the classic path. Event handlers are
|
|
3150
|
-
* not reactive bindings — values evaluate exactly once at build — so the
|
|
3151
|
-
* only ownership divergence is a factory creating owned work in value
|
|
3152
|
-
* position (`onClick={makeHandler(row)}` calling onCleanup), which is not
|
|
3153
|
-
* a supported pattern (owned work belongs in effects/refs; ruled
|
|
3154
|
-
* non-responsibility). Denying evaluation-position calls would cost
|
|
3155
|
-
* legitimate currying to guard it; instead the runtime dev-asserts that a
|
|
3156
|
-
* stamped row's build attaches nothing to the list owner.
|
|
3157
|
-
*
|
|
3158
|
-
* Qualifying functions are recorded and wrapped with `rowProof` at program
|
|
3159
|
-
* exit (postprocess) — the stamp travels with the function object, so
|
|
3160
|
-
* extracted row functions prove at their DEFINITION site and work across
|
|
3161
|
-
* modules, which the runtime probe could never see.
|
|
3162
|
-
*/
|
|
3163
|
-
function recordPureRow(path, result, subject) {
|
|
3164
|
-
const parent = path.parentPath;
|
|
3165
|
-
if (!parent) return;
|
|
3166
|
-
let fn;
|
|
3167
|
-
if (
|
|
3168
|
-
(t__namespace.isArrowFunctionExpression(parent.node) || t__namespace.isFunctionExpression(parent.node)) &&
|
|
3169
|
-
parent.node.body === path.node)
|
|
3170
|
-
{
|
|
3171
|
-
fn = parent.node;
|
|
3172
|
-
} else if (
|
|
3173
|
-
t__namespace.isReturnStatement(parent.node) &&
|
|
3174
|
-
parent.node.argument === path.node &&
|
|
3175
|
-
parent.parentPath &&
|
|
3176
|
-
t__namespace.isBlockStatement(parent.parentPath.node) &&
|
|
3177
|
-
parent.parentPath.node.body.length === 1 &&
|
|
3178
|
-
parent.parentPath.parentPath && (
|
|
3179
|
-
t__namespace.isArrowFunctionExpression(parent.parentPath.parentPath.node) ||
|
|
3180
|
-
t__namespace.isFunctionExpression(parent.parentPath.parentPath.node)) &&
|
|
3181
|
-
parent.parentPath.parentPath.node.body === parent.parentPath.node)
|
|
3182
|
-
{
|
|
3183
|
-
fn = parent.parentPath.parentPath.node;
|
|
3184
|
-
}
|
|
3185
|
-
if (!fn || fn.async || fn.generator) return;
|
|
3186
|
-
if (fn.params.length !== 1 || !t__namespace.isIdentifier(fn.params[0])) return;
|
|
3187
|
-
const param = fn.params[0].name;
|
|
3188
|
-
if (subject !== null && subject !== param) return;
|
|
3189
|
-
|
|
3190
|
-
const isLocalMemberTarget = (n) => {
|
|
3191
|
-
if (!t__namespace.isMemberExpression(n) || n.computed) return false;
|
|
3192
|
-
let obj = n.object;
|
|
3193
|
-
while (t__namespace.isMemberExpression(obj) && !obj.computed) obj = obj.object;
|
|
3194
|
-
return t__namespace.isIdentifier(obj);
|
|
3195
|
-
};
|
|
3196
|
-
for (const stmt of result.exprs) {
|
|
3197
|
-
if (!t__namespace.isExpressionStatement(stmt)) return;
|
|
3198
|
-
const e = stmt.expression;
|
|
3199
|
-
if (t__namespace.isAssignmentExpression(e) && e.operator === "=" && isLocalMemberTarget(e.left)) continue;
|
|
3200
|
-
if (
|
|
3201
|
-
t__namespace.isCallExpression(e) &&
|
|
3202
|
-
t__namespace.isMemberExpression(e.callee) &&
|
|
3203
|
-
!e.callee.computed &&
|
|
3204
|
-
t__namespace.isIdentifier(e.callee.property) &&
|
|
3205
|
-
e.callee.property.name === "addEventListener")
|
|
3206
|
-
|
|
3207
|
-
continue;
|
|
3208
|
-
return;
|
|
3209
|
-
}
|
|
3210
|
-
if (result.postExprs?.length) {
|
|
3211
|
-
const data = path.scope.getProgramParent().data;
|
|
3212
|
-
const moduleName = getRendererConfig(path, "dom").moduleName;
|
|
3213
|
-
const rheUid = data.imports?.get(`${moduleName}:runHydrationEvents`);
|
|
3214
|
-
for (const stmt of result.postExprs) {
|
|
3215
|
-
if (
|
|
3216
|
-
!t__namespace.isExpressionStatement(stmt) ||
|
|
3217
|
-
!t__namespace.isCallExpression(stmt.expression) ||
|
|
3218
|
-
!t__namespace.isIdentifier(stmt.expression.callee) ||
|
|
3219
|
-
!rheUid ||
|
|
3220
|
-
stmt.expression.callee.name !== rheUid.name)
|
|
3221
|
-
|
|
3222
|
-
return;
|
|
3223
|
-
}
|
|
3224
|
-
}
|
|
3225
|
-
|
|
3226
|
-
const data = path.scope.getProgramParent().data;
|
|
3227
|
-
(data.pureRows || (data.pureRows = new Set())).add(fn);
|
|
3228
|
-
}
|
|
3229
|
-
|
|
3230
|
-
/** Patch-mode emission (shared/patch.ts): one compiled body doing inline
|
|
3231
|
-
* compares + setAttr writes, handed to the runtime driver which registers
|
|
3232
|
-
* on the store patch channel (patchable subject) or falls back to a
|
|
3233
|
-
* tracked force-mode effect running the SAME body. Returns undefined when
|
|
3234
|
-
* the scope is ineligible — caller falls through to the effect shapes.
|
|
3235
|
-
* The subject rides along for row-proof analysis (recordPureRow). */
|
|
3236
|
-
function wrapPatchMode(
|
|
3237
|
-
path,
|
|
3238
|
-
dynamics)
|
|
3239
|
-
{
|
|
3240
|
-
const config = getConfig(path);
|
|
3241
|
-
if (dynamics.length === 0) return;
|
|
3242
|
-
const eligibility = analyzePatchEligibility(dynamics.map((d) => d.value));
|
|
3243
|
-
if (!eligibility) return;
|
|
3244
|
-
const subject = eligibility.subject;
|
|
3245
|
-
// The subject must be a stable local binding (not reassigned): row params
|
|
3246
|
-
// and const destructures qualify; anything else falls back to effects.
|
|
3247
|
-
const binding = path.scope.getBinding(subject);
|
|
3248
|
-
if (!binding || !binding.constant) return;
|
|
3249
|
-
// Fixed `$`-suffixed locals, matching wrapDynamics' `_v$`/`_p$` convention
|
|
3250
|
-
// (and byte-parity with the Oxc compiler's emission): substitution only
|
|
3251
|
-
// rewrites subject references, so nothing else in an eligible expression
|
|
3252
|
-
// can collide with these.
|
|
3253
|
-
const nId = t__namespace.identifier("_n$");
|
|
3254
|
-
const pId = t__namespace.identifier("_p$");
|
|
3255
|
-
const fId = t__namespace.identifier("_f$");
|
|
3256
|
-
const stmts = [];
|
|
3257
|
-
let vIndex = 0;
|
|
3258
|
-
for (const d of dynamics) {
|
|
3259
|
-
let value = d.value;
|
|
3260
|
-
if (d.classProperty && !t__namespace.isBooleanLiteral(value) && !t__namespace.isUnaryExpression(value)) {
|
|
3261
|
-
value = t__namespace.unaryExpression("!", t__namespace.unaryExpression("!", value));
|
|
3262
|
-
}
|
|
3263
|
-
const vId = t__namespace.identifier(++vIndex === 1 ? "_v$" : `_v$${vIndex}`);
|
|
3264
|
-
stmts.push(
|
|
3265
|
-
t__namespace.variableDeclaration("const", [
|
|
3266
|
-
t__namespace.variableDeclarator(vId, substituteSubject(value, subject, nId))]
|
|
3267
|
-
)
|
|
3268
|
-
);
|
|
3269
|
-
stmts.push(
|
|
3270
|
-
t__namespace.ifStatement(
|
|
3271
|
-
t__namespace.logicalExpression(
|
|
3272
|
-
"||",
|
|
3273
|
-
t__namespace.cloneNode(fId),
|
|
3274
|
-
t__namespace.binaryExpression("!==", t__namespace.cloneNode(vId), substituteSubject(value, subject, pId))
|
|
3275
|
-
),
|
|
3276
|
-
t__namespace.expressionStatement(
|
|
3277
|
-
setAttr$2(path, d.elem, d.key, t__namespace.cloneNode(vId), {
|
|
3278
|
-
tagName: d.tagName,
|
|
3279
|
-
dynamic: true,
|
|
3280
|
-
styleProperty: d.styleProperty,
|
|
3281
|
-
classProperty: d.classProperty
|
|
3282
|
-
})
|
|
3283
|
-
)
|
|
3284
|
-
)
|
|
3285
|
-
);
|
|
3286
|
-
}
|
|
3287
|
-
const driverId = registerImportMethod(path, config.patchDriver, undefined);
|
|
3288
|
-
return {
|
|
3289
|
-
stmt: t__namespace.expressionStatement(
|
|
3290
|
-
t__namespace.callExpression(driverId, [
|
|
3291
|
-
t__namespace.identifier(subject),
|
|
3292
|
-
t__namespace.arrowFunctionExpression([nId, pId, fId], t__namespace.blockStatement(stmts))]
|
|
3293
|
-
)
|
|
3294
|
-
),
|
|
3295
|
-
subject
|
|
3296
|
-
};
|
|
3297
|
-
}
|
|
3298
|
-
|
|
3299
2955
|
function wrapDynamics$1(path, dynamics) {
|
|
3300
2956
|
if (!dynamics.length) return;
|
|
3301
2957
|
const config = getConfig(path);
|
|
@@ -4382,9 +4038,15 @@ path,
|
|
|
4382
4038
|
return memo;
|
|
4383
4039
|
}, []);
|
|
4384
4040
|
|
|
4041
|
+
// The DOM transform handles `ref` outside its spread prop sources.
|
|
4042
|
+
const propAttributes = attributes.filter((attribute) => {
|
|
4043
|
+
const node = attribute.node;
|
|
4044
|
+
return !(t.isJSXAttribute(node) && t.isJSXIdentifier(node.name) && node.name.name === "ref");
|
|
4045
|
+
});
|
|
4046
|
+
|
|
4385
4047
|
let props;
|
|
4386
|
-
if (
|
|
4387
|
-
props = [
|
|
4048
|
+
if (propAttributes.length === 1 && t.isJSXSpreadAttribute(propAttributes[0].node)) {
|
|
4049
|
+
props = [propAttributes[0].node.argument];
|
|
4388
4050
|
} else {
|
|
4389
4051
|
props = [];
|
|
4390
4052
|
let runningObject = [],
|
|
@@ -14283,6 +13945,29 @@ function serialize(node, options) {
|
|
|
14283
13945
|
}
|
|
14284
13946
|
return serializeChildNodes(node, opts);
|
|
14285
13947
|
}
|
|
13948
|
+
/**
|
|
13949
|
+
* Serializes an AST element node to an HTML string, including the element node.
|
|
13950
|
+
*
|
|
13951
|
+
* @example
|
|
13952
|
+
*
|
|
13953
|
+
* ```js
|
|
13954
|
+
* const parse5 = require('parse5');
|
|
13955
|
+
*
|
|
13956
|
+
* const document = parse5.parseFragment('<div>Hello, <b>world</b>!</div>');
|
|
13957
|
+
*
|
|
13958
|
+
* // Serializes the <div> element.
|
|
13959
|
+
* const str = parse5.serializeOuter(document.childNodes[0]);
|
|
13960
|
+
*
|
|
13961
|
+
* console.log(str); //> '<div>Hello, <b>world</b>!</div>'
|
|
13962
|
+
* ```
|
|
13963
|
+
*
|
|
13964
|
+
* @param node Node to serialize.
|
|
13965
|
+
* @param options Serialization options.
|
|
13966
|
+
*/
|
|
13967
|
+
function serializeOuter(node, options) {
|
|
13968
|
+
const opts = { ...defaultOpts, ...options };
|
|
13969
|
+
return serializeNode(node, opts);
|
|
13970
|
+
}
|
|
14286
13971
|
function serializeChildNodes(parentNode, options) {
|
|
14287
13972
|
let html = '';
|
|
14288
13973
|
// Get container of the child nodes
|
|
@@ -14416,6 +14101,29 @@ function innerHTML(htmlFragment) {
|
|
|
14416
14101
|
return serialize(parsedFragment);
|
|
14417
14102
|
}
|
|
14418
14103
|
|
|
14104
|
+
/**
|
|
14105
|
+
* A document shell (`<html>`/`<head>`/`<body>` root) can never round-trip a
|
|
14106
|
+
* body-context fragment parse — the parser strips those wrappers no matter
|
|
14107
|
+
* how well-formed the markup is — so it is parsed as a DOCUMENT instead and
|
|
14108
|
+
* the shell element serialized back out (#3259). The same "used in the right
|
|
14109
|
+
* place" assumption the synthetic `<table>` makes for table partials: a
|
|
14110
|
+
* shell template is hydrated against a real document, not client-created.
|
|
14111
|
+
* Restructuring inside the shell still mismatches — an implied `<head>`,
|
|
14112
|
+
* flow content hoisted out of `<head>`, a `<p>` split in `<body>` — so the
|
|
14113
|
+
* #3099 guarantee holds for markup a browser would actually rebuild.
|
|
14114
|
+
*/
|
|
14115
|
+
function documentShell(html, tag) {
|
|
14116
|
+
const document = parse(html);
|
|
14117
|
+
const htmlElement = document.childNodes.find(
|
|
14118
|
+
(node) => node.tagName === "html"
|
|
14119
|
+
);
|
|
14120
|
+
const shell =
|
|
14121
|
+
tag === "html" ?
|
|
14122
|
+
htmlElement :
|
|
14123
|
+
htmlElement.childNodes.find((node) => node.tagName === tag);
|
|
14124
|
+
return serializeOuter(shell);
|
|
14125
|
+
}
|
|
14126
|
+
|
|
14419
14127
|
/**
|
|
14420
14128
|
* Returns an object with information when the markup is invalid
|
|
14421
14129
|
*
|
|
@@ -14486,7 +14194,8 @@ function isInvalidMarkup(html) {
|
|
|
14486
14194
|
}
|
|
14487
14195
|
|
|
14488
14196
|
/** Parse HTML. `browser` is a string with the supposed resulting html of a real `innerHTML` call */
|
|
14489
|
-
const
|
|
14197
|
+
const shell = /^<(html|head|body)>/.exec(html);
|
|
14198
|
+
const browser = shell ? documentShell(html, shell[1]) : innerHTML(html);
|
|
14490
14199
|
|
|
14491
14200
|
if (html.toLowerCase() !== browser.toLowerCase()) {
|
|
14492
14201
|
return {
|
|
@@ -14547,31 +14256,6 @@ var postprocess = (path, state) => {
|
|
|
14547
14256
|
domTemplates.length > 0 && appendTemplates$1(path, domTemplates);
|
|
14548
14257
|
ssrTemplates.length > 0 && appendTemplates(path, ssrTemplates);
|
|
14549
14258
|
}
|
|
14550
|
-
|
|
14551
|
-
// Compile-time row proofs (DESIGN-PATCH-CHANNEL §3c): wrap each function
|
|
14552
|
-
// recorded by recordPureRow with the runtime's `rowProof` marker so the
|
|
14553
|
-
// patch-mode list driver can engage on proven-pure rows — admission is
|
|
14554
|
-
// decided here, statically; there is no runtime purity probe. The stamp
|
|
14555
|
-
// travels with the function object, so extracted row functions qualify at
|
|
14556
|
-
// their definition site.
|
|
14557
|
-
if (data.pureRows?.size) {
|
|
14558
|
-
const rowProofId = registerImportMethod(
|
|
14559
|
-
path,
|
|
14560
|
-
"rowProof",
|
|
14561
|
-
getRendererConfig(path, "dom").moduleName
|
|
14562
|
-
);
|
|
14563
|
-
const pureRows = data.pureRows;
|
|
14564
|
-
path.traverse({
|
|
14565
|
-
"ArrowFunctionExpression|FunctionExpression"(fnPath) {
|
|
14566
|
-
if (!pureRows.has(fnPath.node)) return;
|
|
14567
|
-
pureRows.delete(fnPath.node);
|
|
14568
|
-
fnPath.replaceWith(
|
|
14569
|
-
t__namespace.callExpression(t__namespace.cloneNode(rowProofId), [fnPath.node])
|
|
14570
|
-
);
|
|
14571
|
-
fnPath.skip();
|
|
14572
|
-
}
|
|
14573
|
-
});
|
|
14574
|
-
}
|
|
14575
14259
|
};
|
|
14576
14260
|
|
|
14577
14261
|
const config = {
|
|
@@ -14603,7 +14287,6 @@ const config = {
|
|
|
14603
14287
|
contextToCustomElements: true,
|
|
14604
14288
|
staticMarker: "@static",
|
|
14605
14289
|
effectWrapper: "effect",
|
|
14606
|
-
patchDriver: false,
|
|
14607
14290
|
memoWrapper: "memo",
|
|
14608
14291
|
validate: true,
|
|
14609
14292
|
inlineStyles: true,
|
|
@@ -14619,9 +14302,6 @@ var preprocess = (path, state) => {
|
|
|
14619
14302
|
delete file.ast.tsrxStyle;
|
|
14620
14303
|
}
|
|
14621
14304
|
const merged = file.metadata.config = Object.assign({}, config, state.opts);
|
|
14622
|
-
// Boolean opt-in parity with the native loader: `patchDriver: true` means
|
|
14623
|
-
// the default import name (downstream code uses the value AS the name).
|
|
14624
|
-
if (merged.patchDriver === true) merged.patchDriver = "patchDriver";
|
|
14625
14305
|
const lib = merged.requireImportSource;
|
|
14626
14306
|
if (lib) {
|
|
14627
14307
|
const comments = file.ast.comments ?? [];
|