@gyral/core 0.2.0 → 0.3.0
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/CHANGELOG.md +87 -0
- package/README.md +7 -5
- package/dist/children.d.ts +5 -2
- package/dist/children.js +8 -3
- package/dist/children.js.map +1 -1
- package/dist/command.js +6 -0
- package/dist/command.js.map +1 -1
- package/dist/compiler/ast.d.ts +21 -0
- package/dist/compiler/ast.js +145 -0
- package/dist/compiler/ast.js.map +1 -0
- package/dist/compiler/compile.d.ts +38 -0
- package/dist/compiler/compile.js +129 -0
- package/dist/compiler/compile.js.map +1 -0
- package/dist/compiler/hooks.d.ts +18 -0
- package/dist/compiler/hooks.js +186 -0
- package/dist/compiler/hooks.js.map +1 -0
- package/dist/compiler/parse5-check.d.ts +21 -0
- package/dist/compiler/parse5-check.js +55 -0
- package/dist/compiler/parse5-check.js.map +1 -0
- package/dist/compiler/scan.d.ts +31 -0
- package/dist/compiler/scan.js +152 -0
- package/dist/compiler/scan.js.map +1 -0
- package/dist/compiler/source.d.ts +34 -0
- package/dist/compiler/source.js +114 -0
- package/dist/compiler/source.js.map +1 -0
- package/dist/define.d.ts +2 -2
- package/dist/define.js +35 -327
- package/dist/define.js.map +1 -1
- package/dist/devtools-events.d.ts +5 -0
- package/dist/devtools-events.js.map +1 -1
- package/dist/devtools-off.d.ts +1 -0
- package/dist/devtools-off.js +1 -0
- package/dist/devtools-off.js.map +1 -1
- package/dist/devtools.d.ts +1 -0
- package/dist/devtools.js +3 -2
- package/dist/devtools.js.map +1 -1
- package/dist/drivers-scope.d.ts +1 -1
- package/dist/drivers-scope.js +1 -8
- package/dist/drivers-scope.js.map +1 -1
- package/dist/element-types.d.ts +5 -3
- package/dist/element-types.js.map +1 -1
- package/dist/element.d.ts +3 -0
- package/dist/element.js +269 -0
- package/dist/element.js.map +1 -0
- package/dist/eslint/imports.d.ts +24 -0
- package/dist/eslint/imports.js +78 -0
- package/dist/eslint/imports.js.map +1 -0
- package/dist/eslint/index.d.ts +15 -0
- package/dist/eslint/index.js +15 -0
- package/dist/eslint/index.js.map +1 -0
- package/dist/eslint/locate.d.ts +33 -0
- package/dist/eslint/locate.js +132 -0
- package/dist/eslint/locate.js.map +1 -0
- package/dist/eslint/row-purity-rule.d.ts +2 -0
- package/dist/eslint/row-purity-rule.js +103 -0
- package/dist/eslint/row-purity-rule.js.map +1 -0
- package/dist/eslint/template-rule.d.ts +5 -0
- package/dist/eslint/template-rule.js +66 -0
- package/dist/eslint/template-rule.js.map +1 -0
- package/dist/features.d.ts +39 -0
- package/dist/features.js +2 -0
- package/dist/features.js.map +1 -0
- package/dist/focus.d.ts +7 -12
- package/dist/focus.js +13 -10
- package/dist/focus.js.map +1 -1
- package/dist/hooks/invalid.d.ts +14 -0
- package/dist/hooks/invalid.js +72 -0
- package/dist/hooks/invalid.js.map +1 -0
- package/dist/hooks/labelled-by.d.ts +13 -0
- package/dist/hooks/labelled-by.js +51 -0
- package/dist/hooks/labelled-by.js.map +1 -0
- package/dist/host-model.d.ts +48 -0
- package/dist/host-model.js +155 -0
- package/dist/host-model.js.map +1 -0
- package/dist/hydration-client.d.ts +9 -0
- package/dist/hydration-client.js +35 -0
- package/dist/hydration-client.js.map +1 -0
- package/dist/hydration.d.ts +13 -19
- package/dist/hydration.js +45 -45
- package/dist/hydration.js.map +1 -1
- package/dist/index.d.ts +9 -17
- package/dist/index.js +9 -18
- package/dist/index.js.map +1 -1
- package/dist/intent.d.ts +31 -8
- package/dist/intent.js +82 -27
- package/dist/intent.js.map +1 -1
- package/dist/internal/interpreter.d.ts +7 -1
- package/dist/internal/interpreter.js +11 -4
- package/dist/internal/interpreter.js.map +1 -1
- package/dist/invokers-shim.d.ts +6 -0
- package/dist/invokers-shim.js +32 -0
- package/dist/invokers-shim.js.map +1 -0
- package/dist/invokers.d.ts +3 -5
- package/dist/invokers.js +11 -51
- package/dist/invokers.js.map +1 -1
- package/dist/islands.d.ts +0 -2
- package/dist/islands.js +4 -11
- package/dist/islands.js.map +1 -1
- package/dist/light-dom.d.ts +3 -52
- package/dist/light-dom.js +5 -100
- package/dist/light-dom.js.map +1 -1
- package/dist/prop.d.ts +66 -0
- package/dist/prop.js +22 -0
- package/dist/prop.js.map +1 -0
- package/dist/props.d.ts +52 -21
- package/dist/props.js +150 -34
- package/dist/props.js.map +1 -1
- package/dist/scheduler.d.ts +39 -0
- package/dist/scheduler.js +230 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/server-component.d.ts +10 -0
- package/dist/server-component.js +102 -0
- package/dist/server-component.js.map +1 -0
- package/dist/server-specs.d.ts +6 -0
- package/dist/server-specs.js +13 -0
- package/dist/server-specs.js.map +1 -0
- package/dist/server.d.ts +28 -0
- package/dist/server.js +50 -0
- package/dist/server.js.map +1 -0
- package/dist/settled.d.ts +10 -0
- package/dist/settled.js +40 -0
- package/dist/settled.js.map +1 -0
- package/dist/states.d.ts +3 -3
- package/dist/states.js +4 -7
- package/dist/states.js.map +1 -1
- package/dist/store-binding.d.ts +6 -3
- package/dist/store-binding.js +5 -6
- package/dist/store-binding.js.map +1 -1
- package/dist/store-scope.d.ts +6 -7
- package/dist/store-scope.js +11 -26
- package/dist/store-scope.js.map +1 -1
- package/dist/store.d.ts +3 -0
- package/dist/store.js +9 -2
- package/dist/store.js.map +1 -1
- package/dist/stores-provider.d.ts +2 -6
- package/dist/stores-provider.js +21 -55
- package/dist/stores-provider.js.map +1 -1
- package/dist/transitions.d.ts +5 -6
- package/dist/transitions.js +11 -20
- package/dist/transitions.js.map +1 -1
- package/dist/types.d.ts +19 -23
- package/dist/types.js.map +1 -1
- package/dist/view/attributes.d.ts +6 -0
- package/dist/view/attributes.js +10 -0
- package/dist/view/attributes.js.map +1 -0
- package/dist/view/compiled.d.ts +1 -0
- package/dist/view/compiled.js +6 -0
- package/dist/view/compiled.js.map +1 -0
- package/dist/view/dev-off.d.ts +1 -0
- package/dist/view/dev-off.js +4 -0
- package/dist/view/dev-off.js.map +1 -0
- package/dist/view/dev.d.ts +1 -0
- package/dist/view/dev.js +5 -0
- package/dist/view/dev.js.map +1 -0
- package/dist/view/flags.d.ts +1 -0
- package/dist/view/flags.js +4 -0
- package/dist/view/flags.js.map +1 -0
- package/dist/view/index.d.ts +21 -0
- package/dist/view/index.js +21 -0
- package/dist/view/index.js.map +1 -0
- package/dist/view/normalize/check.d.ts +20 -0
- package/dist/view/normalize/check.js +78 -0
- package/dist/view/normalize/check.js.map +1 -0
- package/dist/view/normalize/emit.d.ts +13 -0
- package/dist/view/normalize/emit.js +136 -0
- package/dist/view/normalize/emit.js.map +1 -0
- package/dist/view/normalize/entities.d.ts +4 -0
- package/dist/view/normalize/entities.js +38 -0
- package/dist/view/normalize/entities.js.map +1 -0
- package/dist/view/normalize/errors.d.ts +9 -0
- package/dist/view/normalize/errors.js +19 -0
- package/dist/view/normalize/errors.js.map +1 -0
- package/dist/view/normalize/id.d.ts +7 -0
- package/dist/view/normalize/id.js +48 -0
- package/dist/view/normalize/id.js.map +1 -0
- package/dist/view/normalize/normalize.d.ts +15 -0
- package/dist/view/normalize/normalize.js +36 -0
- package/dist/view/normalize/normalize.js.map +1 -0
- package/dist/view/normalize/repairs.d.ts +24 -0
- package/dist/view/normalize/repairs.js +166 -0
- package/dist/view/normalize/repairs.js.map +1 -0
- package/dist/view/normalize/rules.d.ts +30 -0
- package/dist/view/normalize/rules.js +90 -0
- package/dist/view/normalize/rules.js.map +1 -0
- package/dist/view/normalize/shape.d.ts +5 -0
- package/dist/view/normalize/shape.js +38 -0
- package/dist/view/normalize/shape.js.map +1 -0
- package/dist/view/normalize/source.d.ts +13 -0
- package/dist/view/normalize/source.js +34 -0
- package/dist/view/normalize/source.js.map +1 -0
- package/dist/view/normalize/tag-states.d.ts +23 -0
- package/dist/view/normalize/tag-states.js +192 -0
- package/dist/view/normalize/tag-states.js.map +1 -0
- package/dist/view/normalize/tokenizer.d.ts +5 -0
- package/dist/view/normalize/tokenizer.js +233 -0
- package/dist/view/normalize/tokenizer.js.map +1 -0
- package/dist/view/normalize/tokens.d.ts +51 -0
- package/dist/view/normalize/tokens.js +24 -0
- package/dist/view/normalize/tokens.js.map +1 -0
- package/dist/view/normalize/tree.d.ts +59 -0
- package/dist/view/normalize/tree.js +190 -0
- package/dist/view/normalize/tree.js.map +1 -0
- package/dist/view/normalize/types.d.ts +126 -0
- package/dist/view/normalize/types.js +26 -0
- package/dist/view/normalize/types.js.map +1 -0
- package/dist/view/normalize/whitespace.d.ts +2 -0
- package/dist/{template-whitespace.js → view/normalize/whitespace.js} +24 -34
- package/dist/view/normalize/whitespace.js.map +1 -0
- package/dist/view/prepare-stub.d.ts +3 -0
- package/dist/view/prepare-stub.js +7 -0
- package/dist/view/prepare-stub.js.map +1 -0
- package/dist/view/prepare.d.ts +8 -0
- package/dist/view/prepare.js +57 -0
- package/dist/view/prepare.js.map +1 -0
- package/dist/view/registry.d.ts +63 -0
- package/dist/view/registry.js +19 -0
- package/dist/view/registry.js.map +1 -0
- package/dist/view/render/adopt-attr.d.ts +14 -0
- package/dist/view/render/adopt-attr.js +77 -0
- package/dist/view/render/adopt-attr.js.map +1 -0
- package/dist/view/render/adopt-plan.d.ts +10 -0
- package/dist/view/render/adopt-plan.js +26 -0
- package/dist/view/render/adopt-plan.js.map +1 -0
- package/dist/view/render/adopt.d.ts +3 -0
- package/dist/view/render/adopt.js +269 -0
- package/dist/view/render/adopt.js.map +1 -0
- package/dist/view/render/attr-parts.d.ts +61 -0
- package/dist/view/render/attr-parts.js +229 -0
- package/dist/view/render/attr-parts.js.map +1 -0
- package/dist/view/render/child-part.d.ts +51 -0
- package/dist/view/render/child-part.js +170 -0
- package/dist/view/render/child-part.js.map +1 -0
- package/dist/view/render/dev-check.d.ts +12 -0
- package/dist/view/render/dev-check.js +122 -0
- package/dist/view/render/dev-check.js.map +1 -0
- package/dist/view/render/hook-part.d.ts +3 -0
- package/dist/view/render/hook-part.js +20 -0
- package/dist/view/render/hook-part.js.map +1 -0
- package/dist/view/render/hooks.d.ts +40 -0
- package/dist/view/render/hooks.js +46 -0
- package/dist/view/render/hooks.js.map +1 -0
- package/dist/view/render/hydrate.d.ts +10 -0
- package/dist/view/render/hydrate.js +33 -0
- package/dist/view/render/hydrate.js.map +1 -0
- package/dist/view/render/instance.d.ts +33 -0
- package/dist/view/render/instance.js +107 -0
- package/dist/view/render/instance.js.map +1 -0
- package/dist/view/render/list.d.ts +20 -0
- package/dist/view/render/list.js +156 -0
- package/dist/view/render/list.js.map +1 -0
- package/dist/view/render/mismatch.d.ts +10 -0
- package/dist/view/render/mismatch.js +53 -0
- package/dist/view/render/mismatch.js.map +1 -0
- package/dist/view/render/nodes.d.ts +10 -0
- package/dist/view/render/nodes.js +37 -0
- package/dist/view/render/nodes.js.map +1 -0
- package/dist/view/render/place.d.ts +18 -0
- package/dist/view/render/place.js +69 -0
- package/dist/view/render/place.js.map +1 -0
- package/dist/view/render/plan.d.ts +26 -0
- package/dist/view/render/plan.js +124 -0
- package/dist/view/render/plan.js.map +1 -0
- package/dist/view/render/raw.d.ts +18 -0
- package/dist/view/render/raw.js +68 -0
- package/dist/view/render/raw.js.map +1 -0
- package/dist/view/render/render.d.ts +12 -0
- package/dist/view/render/render.js +60 -0
- package/dist/view/render/render.js.map +1 -0
- package/dist/view/render/reorder.d.ts +4 -0
- package/dist/view/render/reorder.js +101 -0
- package/dist/view/render/reorder.js.map +1 -0
- package/dist/view/render/rows.d.ts +23 -0
- package/dist/view/render/rows.js +95 -0
- package/dist/view/render/rows.js.map +1 -0
- package/dist/view/render/seen.d.ts +11 -0
- package/dist/view/render/seen.js +17 -0
- package/dist/view/render/seen.js.map +1 -0
- package/dist/view/render/values.d.ts +29 -0
- package/dist/view/render/values.js +13 -0
- package/dist/view/render/values.js.map +1 -0
- package/dist/view/render/warn.d.ts +14 -0
- package/dist/view/render/warn.js +69 -0
- package/dist/view/render/warn.js.map +1 -0
- package/dist/view/server/component.d.ts +9 -0
- package/dist/view/server/component.js +42 -0
- package/dist/view/server/component.js.map +1 -0
- package/dist/view/server/escape.d.ts +10 -0
- package/dist/view/server/escape.js +34 -0
- package/dist/view/server/escape.js.map +1 -0
- package/dist/view/server/index.d.ts +28 -0
- package/dist/view/server/index.js +72 -0
- package/dist/view/server/index.js.map +1 -0
- package/dist/view/server/sha256.d.ts +2 -0
- package/dist/view/server/sha256.js +75 -0
- package/dist/view/server/sha256.js.map +1 -0
- package/dist/view/server/tags.d.ts +57 -0
- package/dist/view/server/tags.js +121 -0
- package/dist/view/server/tags.js.map +1 -0
- package/dist/view/server/values.d.ts +16 -0
- package/dist/view/server/values.js +86 -0
- package/dist/view/server/values.js.map +1 -0
- package/dist/view/server/writer.d.ts +16 -0
- package/dist/view/server/writer.js +155 -0
- package/dist/view/server/writer.js.map +1 -0
- package/dist/view/styles.d.ts +25 -0
- package/dist/view/styles.js +58 -0
- package/dist/view/styles.js.map +1 -0
- package/dist/view/template-element.d.ts +3 -0
- package/dist/view/template-element.js +25 -0
- package/dist/view/template-element.js.map +1 -0
- package/dist/view/template.d.ts +21 -0
- package/dist/view/template.js +30 -0
- package/dist/view/template.js.map +1 -0
- package/dist/vite.d.ts +45 -6
- package/dist/vite.js +150 -25
- package/dist/vite.js.map +1 -1
- package/package.json +39 -4
- package/dist/accessible-name.d.ts +0 -19
- package/dist/accessible-name.js +0 -56
- package/dist/accessible-name.js.map +0 -1
- package/dist/element-directive.d.ts +0 -20
- package/dist/element-directive.js +0 -31
- package/dist/element-directive.js.map +0 -1
- package/dist/invalid.d.ts +0 -21
- package/dist/invalid.js +0 -70
- package/dist/invalid.js.map +0 -1
- package/dist/lit-html-check.d.ts +0 -6
- package/dist/lit-html-check.js +0 -48
- package/dist/lit-html-check.js.map +0 -1
- package/dist/live-boolean.d.ts +0 -22
- package/dist/live-boolean.js +0 -34
- package/dist/live-boolean.js.map +0 -1
- package/dist/styles.d.ts +0 -12
- package/dist/styles.js +0 -11
- package/dist/styles.js.map +0 -1
- package/dist/template-whitespace.d.ts +0 -7
- package/dist/template-whitespace.js.map +0 -1
- package/dist/templates.d.ts +0 -5
- package/dist/templates.js +0 -15
- package/dist/templates.js.map +0 -1
- package/dist/textarea.d.ts +0 -26
- package/dist/textarea.js +0 -85
- package/dist/textarea.js.map +0 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { PartSpec, TemplateObject } from '../normalize/types.js';
|
|
2
|
+
import { type Plan } from './plan.js';
|
|
3
|
+
/** Per template: its element parts per static element, its child holes per parent node. */
|
|
4
|
+
export interface Adoption {
|
|
5
|
+
readonly plan: Plan;
|
|
6
|
+
readonly specs: readonly PartSpec[];
|
|
7
|
+
readonly attrs: Map<Node, number[]>;
|
|
8
|
+
readonly holes: Map<Node, number[]>;
|
|
9
|
+
}
|
|
10
|
+
export declare function adoptionOf(template: TemplateObject): Adoption;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { nodes, planOf, stack, walk } from './plan.js';
|
|
2
|
+
const adoptions = new WeakMap();
|
|
3
|
+
export function adoptionOf(template) {
|
|
4
|
+
let a = adoptions.get(template);
|
|
5
|
+
if (a !== undefined)
|
|
6
|
+
return a;
|
|
7
|
+
const plan = planOf(template);
|
|
8
|
+
// The plan's targets in the template's own content: where each part sits.
|
|
9
|
+
stack[0] = plan.content;
|
|
10
|
+
if (plan.single)
|
|
11
|
+
stack[1] = plan.content.firstChild;
|
|
12
|
+
walk(plan);
|
|
13
|
+
a = { plan, specs: template.parts, attrs: new Map(), holes: new Map() };
|
|
14
|
+
for (let i = 0; i < plan.kinds.length; i++) {
|
|
15
|
+
const node = nodes[plan.a[i]];
|
|
16
|
+
const map = plan.kinds[i] >= 0 ? a.attrs : a.holes;
|
|
17
|
+
const list = map.get(node);
|
|
18
|
+
if (list === undefined)
|
|
19
|
+
map.set(node, [i]);
|
|
20
|
+
else
|
|
21
|
+
list.push(i);
|
|
22
|
+
}
|
|
23
|
+
adoptions.set(template, a);
|
|
24
|
+
return a;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=adopt-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adopt-plan.js","sourceRoot":"","sources":["../../../src/view/render/adopt-plan.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAa,MAAM,WAAW,CAAC;AAUlE,MAAM,SAAS,GAAG,IAAI,OAAO,EAA4B,CAAC;AAE1D,MAAM,UAAU,UAAU,CAAC,QAAwB;IACjD,IAAI,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC9B,0EAA0E;IAC1E,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;IACxB,IAAI,IAAI,CAAC,MAAM;QAAE,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,UAAkB,CAAC;IAC5D,IAAI,CAAC,IAAI,CAAC,CAAC;IACX,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;IACxE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAW,CAAS,CAAC;QAChD,MAAM,GAAG,GAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAY,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAC/D,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,IAAI,KAAK,SAAS;YAAE,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;;YACtC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IACD,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC3B,OAAO,CAAC,CAAC;AACX,CAAC","sourcesContent":["// Per-template data for the hydration walk (adopt.ts, view/07-hydration.md \"The parallel\n// walk\"): which parts sit on each static element of the template's parsed content, and which\n// child holes sit in each parent node, in order. Computed once per template from its plan.\nimport type { PartSpec, TemplateObject } from '../normalize/types.js';\nimport { nodes, planOf, stack, walk, type Plan } from './plan.js';\n\n/** Per template: its element parts per static element, its child holes per parent node. */\nexport interface Adoption {\n readonly plan: Plan;\n readonly specs: readonly PartSpec[];\n readonly attrs: Map<Node, number[]>;\n readonly holes: Map<Node, number[]>;\n}\n\nconst adoptions = new WeakMap<TemplateObject, Adoption>();\n\nexport function adoptionOf(template: TemplateObject): Adoption {\n let a = adoptions.get(template);\n if (a !== undefined) return a;\n const plan = planOf(template);\n // The plan's targets in the template's own content: where each part sits.\n stack[0] = plan.content;\n if (plan.single) stack[1] = plan.content.firstChild as Node;\n walk(plan);\n a = { plan, specs: template.parts, attrs: new Map(), holes: new Map() };\n for (let i = 0; i < plan.kinds.length; i++) {\n const node = nodes[plan.a[i] as number] as Node;\n const map = (plan.kinds[i] as number) >= 0 ? a.attrs : a.holes;\n const list = map.get(node);\n if (list === undefined) map.set(node, [i]);\n else list.push(i);\n }\n adoptions.set(template, a);\n return a;\n}\n"]}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
// The parallel walk (view/07-hydration.md "The parallel walk"): visits a template's static
|
|
2
|
+
// structure (its parsed content) and the server DOM together, and builds the same parts the
|
|
3
|
+
// client renderer would, with this render's values as committed values. It writes nothing,
|
|
4
|
+
// except splitting merged text at known lengths (`splitText`), creating the empty Text node of
|
|
5
|
+
// an `''` value, joining text the parser split, and removing development markers. Nested
|
|
6
|
+
// templates, lists (rows one after another, no markers), arrays and `raw()` are walked in
|
|
7
|
+
// turn. Nested Gyral hosts: a shadow host's light children are the parent's content (slotted)
|
|
8
|
+
// and are walked; its shadow root never is; a light host (`data-gyral-light`) is opaque.
|
|
9
|
+
// Development checks every node, text and bound attribute, and the `<!--gyral:ID-->` markers
|
|
10
|
+
// when present; production checks node types, local names and text lengths.
|
|
11
|
+
import { DEV } from '#view-dev';
|
|
12
|
+
import { LIGHT_ATTRIBUTE } from '../attributes.js';
|
|
13
|
+
import { CHILD_BEFORE } from '../normalize/types.js';
|
|
14
|
+
import { isTemplateResult, sourceOf, templateOf } from '../template.js';
|
|
15
|
+
import { adoptionOf } from './adopt-plan.js';
|
|
16
|
+
import { adoptAttr, checkAttr } from './adopt-attr.js';
|
|
17
|
+
import { attrPart, TEXTAREA, TITLE } from './attr-parts.js';
|
|
18
|
+
import { ChildPart, INSTANCE, ITEMS, LIST, RAW, TEXT } from './child-part.js';
|
|
19
|
+
import { checkKeys } from './dev-check.js';
|
|
20
|
+
import { Instance } from './instance.js';
|
|
21
|
+
import { mismatch } from './mismatch.js';
|
|
22
|
+
import { ROOT, SOLE } from './plan.js';
|
|
23
|
+
import { parse, RawRange } from './raw.js';
|
|
24
|
+
import { report } from './seen.js';
|
|
25
|
+
import { List } from './rows.js';
|
|
26
|
+
import { isList, rawHtml } from './values.js';
|
|
27
|
+
/** The walk's position: the next DOM node; null at the end of `parent`'s children. */
|
|
28
|
+
let cur = null;
|
|
29
|
+
let parent;
|
|
30
|
+
/** For mismatch messages: the host's root, the component, the template being walked. */
|
|
31
|
+
let top;
|
|
32
|
+
let host = '';
|
|
33
|
+
let current;
|
|
34
|
+
const fail = (expected, found = cur, at = parent) => mismatch(expected, found, at, top, host, current?.loc);
|
|
35
|
+
/** Adopts the server DOM in `root` (a host's root) as `part`'s content for `value`. */
|
|
36
|
+
export function adopt(part, value, root, label) {
|
|
37
|
+
top = parent = root;
|
|
38
|
+
cur = root.firstChild;
|
|
39
|
+
host = label;
|
|
40
|
+
current = undefined;
|
|
41
|
+
content(part, value);
|
|
42
|
+
if (cur !== null)
|
|
43
|
+
fail('the end of the view');
|
|
44
|
+
}
|
|
45
|
+
/** A child value at the walk's position (view/02-bindings.md "Child values"). */
|
|
46
|
+
function content(part, v) {
|
|
47
|
+
switch (typeof v) {
|
|
48
|
+
case 'string':
|
|
49
|
+
case 'number': {
|
|
50
|
+
const data = typeof v === 'string' ? v : String(v);
|
|
51
|
+
part.kind = TEXT;
|
|
52
|
+
part.value = v;
|
|
53
|
+
if (data !== '')
|
|
54
|
+
part.content = text(data);
|
|
55
|
+
else
|
|
56
|
+
parent.insertBefore((part.content = document.createTextNode('')), cur);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
case 'object':
|
|
60
|
+
if (v === null)
|
|
61
|
+
return;
|
|
62
|
+
if (isTemplateResult(v)) {
|
|
63
|
+
part.kind = INSTANCE;
|
|
64
|
+
part.content = instance(v, part);
|
|
65
|
+
}
|
|
66
|
+
else if (isList(v))
|
|
67
|
+
rows(part, v.items, v);
|
|
68
|
+
else if (Array.isArray(v))
|
|
69
|
+
rows(part, v, undefined);
|
|
70
|
+
else {
|
|
71
|
+
const markup = rawHtml(v);
|
|
72
|
+
if (markup !== undefined)
|
|
73
|
+
raw(part, markup);
|
|
74
|
+
else if (DEV)
|
|
75
|
+
part.commit(v);
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
default:
|
|
79
|
+
// Development: a value no hole renders throws (or warns, for `true`) as on the client.
|
|
80
|
+
// Called through the part, so this chunk imports no development-only function.
|
|
81
|
+
if (DEV)
|
|
82
|
+
part.commit(v);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/** Static text or a text value: exactly `want`'s length, split off a longer Text node. */
|
|
86
|
+
function text(want) {
|
|
87
|
+
// The parser turns CR and CRLF into LF.
|
|
88
|
+
const data = want.includes('\r') ? want.replace(/\r\n?/g, '\n') : want;
|
|
89
|
+
const t = cur;
|
|
90
|
+
if (t !== null && t.nodeType === 3) {
|
|
91
|
+
// Join text the parser split (very long runs).
|
|
92
|
+
for (let n = t.nextSibling; t.length < data.length && n !== null && n.nodeType === 3;) {
|
|
93
|
+
t.appendData(n.data);
|
|
94
|
+
n.remove();
|
|
95
|
+
n = t.nextSibling;
|
|
96
|
+
}
|
|
97
|
+
if (t.length >= data.length && (!DEV || t.data.startsWith(data))) {
|
|
98
|
+
if (t.length > data.length)
|
|
99
|
+
t.splitText(data.length);
|
|
100
|
+
cur = t.nextSibling;
|
|
101
|
+
return t;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return fail(`text ${JSON.stringify(data.slice(0, 40))}`);
|
|
105
|
+
}
|
|
106
|
+
function instance(result, holder) {
|
|
107
|
+
const template = templateOf(result);
|
|
108
|
+
const a = adoptionOf(template);
|
|
109
|
+
// A development server's marker: checked when present (a production server writes none),
|
|
110
|
+
// against the id when the template has one (production client objects don't, 01).
|
|
111
|
+
const marker = cur;
|
|
112
|
+
if (marker !== null && marker.nodeType === 8 && marker.data.startsWith('gyral:')) {
|
|
113
|
+
const id = template.id;
|
|
114
|
+
if (DEV && id !== undefined && marker.data !== `gyral:${id}`)
|
|
115
|
+
fail(`<!--gyral:${id}-->`);
|
|
116
|
+
cur = marker.nextSibling;
|
|
117
|
+
marker.remove();
|
|
118
|
+
}
|
|
119
|
+
const outer = current;
|
|
120
|
+
current = template;
|
|
121
|
+
const inst = new Instance(template, sourceOf(result), holder, true);
|
|
122
|
+
children(a.plan.content, a, inst, result.values);
|
|
123
|
+
current = outer;
|
|
124
|
+
return inst;
|
|
125
|
+
}
|
|
126
|
+
/** The children of template node `t`, with the child holes between them. */
|
|
127
|
+
function children(t, a, inst, values) {
|
|
128
|
+
const holes = a.holes.get(t);
|
|
129
|
+
const root = t === a.plan.content;
|
|
130
|
+
let h = 0;
|
|
131
|
+
for (let n = t.firstChild, j = 0;; n = n.nextSibling, j++) {
|
|
132
|
+
if (holes !== undefined && h < holes.length) {
|
|
133
|
+
const i = holes[h];
|
|
134
|
+
const spec = a.specs[i];
|
|
135
|
+
const ref = spec[0] === CHILD_BEFORE ? spec[2] : null;
|
|
136
|
+
if (n === null ? ref === null : ref === j) {
|
|
137
|
+
hole(i, ref, a, inst, values);
|
|
138
|
+
h++;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (n === null)
|
|
142
|
+
return;
|
|
143
|
+
const dom = node(n, a, inst, values);
|
|
144
|
+
if (root) {
|
|
145
|
+
if (j === 0)
|
|
146
|
+
inst.start = dom;
|
|
147
|
+
inst.end = dom;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/** A child hole: its content, then its reference node (the DOM node the walk reached). */
|
|
152
|
+
function hole(i, ref, a, inst, values) {
|
|
153
|
+
const kind = a.plan.kinds[i];
|
|
154
|
+
const at = a.plan.at[i];
|
|
155
|
+
const part = kind === ROOT
|
|
156
|
+
? new ChildPart(null, null, null, 0, false, at)
|
|
157
|
+
: new ChildPart(parent, null, null, 0, kind === SOLE, at);
|
|
158
|
+
inst.parts[i] = part;
|
|
159
|
+
content(part, values[at]);
|
|
160
|
+
if (ref !== null) {
|
|
161
|
+
part.ref = cur;
|
|
162
|
+
if (kind === ROOT && ref === 0)
|
|
163
|
+
inst.head = part;
|
|
164
|
+
}
|
|
165
|
+
else if (kind === ROOT) {
|
|
166
|
+
part.owner = inst;
|
|
167
|
+
inst.tail = part;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function node(t, a, inst, values) {
|
|
171
|
+
if (t.nodeType === 3)
|
|
172
|
+
return text(t.data);
|
|
173
|
+
if (t.nodeType !== 8)
|
|
174
|
+
return element(t, a, inst, values);
|
|
175
|
+
const c = cur;
|
|
176
|
+
if (c === null || c.nodeType !== 8 || (DEV && c.data !== t.data)) {
|
|
177
|
+
return fail(`<!--${t.data}-->`);
|
|
178
|
+
}
|
|
179
|
+
cur = c.nextSibling;
|
|
180
|
+
return c;
|
|
181
|
+
}
|
|
182
|
+
const WHITESPACE_ONLY = /^[\t\n\f\r ]*$/;
|
|
183
|
+
function element(t, a, inst, values) {
|
|
184
|
+
const el = cur;
|
|
185
|
+
if (el === null || el.localName !== t.localName)
|
|
186
|
+
return fail(`<${t.localName}>`);
|
|
187
|
+
cur = el.nextSibling;
|
|
188
|
+
let whole = false;
|
|
189
|
+
for (const i of a.attrs.get(t) ?? []) {
|
|
190
|
+
const kind = a.plan.kinds[i];
|
|
191
|
+
const part = attrPart(el, kind, a.specs[i], a.plan.at[i]);
|
|
192
|
+
inst.parts[i] = part;
|
|
193
|
+
adoptAttr(part, values);
|
|
194
|
+
if (DEV)
|
|
195
|
+
checkAttr(part, fail);
|
|
196
|
+
if (kind === TEXTAREA || kind === TITLE)
|
|
197
|
+
whole = true; // the part owns the content
|
|
198
|
+
}
|
|
199
|
+
let holes = a.holes.has(t);
|
|
200
|
+
if (whole)
|
|
201
|
+
return el;
|
|
202
|
+
if (el.hasAttribute(LIGHT_ATTRIBUTE)) {
|
|
203
|
+
// A light host owns its children (ADR 0014): its parent writes none (06 "Components").
|
|
204
|
+
for (let c = t.firstChild; c !== null; c = c.nextSibling) {
|
|
205
|
+
if (c.nodeType !== 3 || !WHITESPACE_ONLY.test(c.data))
|
|
206
|
+
holes = true;
|
|
207
|
+
}
|
|
208
|
+
if (holes)
|
|
209
|
+
fail(`no children from the parent in light host <${t.localName}>`, el, el);
|
|
210
|
+
return el;
|
|
211
|
+
}
|
|
212
|
+
// A custom element without children in the template: what it holds is its own.
|
|
213
|
+
if (!holes && t.firstChild === null && t.localName.includes('-'))
|
|
214
|
+
return el;
|
|
215
|
+
const outer = cur;
|
|
216
|
+
const outerParent = parent;
|
|
217
|
+
parent = el;
|
|
218
|
+
cur = el.firstChild;
|
|
219
|
+
children(t, a, inst, values);
|
|
220
|
+
if (cur !== null)
|
|
221
|
+
fail(`the end of <${t.localName}>`);
|
|
222
|
+
cur = outer;
|
|
223
|
+
parent = outerParent;
|
|
224
|
+
return el;
|
|
225
|
+
}
|
|
226
|
+
/** Rows of `each` (keyed) or items of an array (`l` undefined), one after another. */
|
|
227
|
+
function rows(part, values, l) {
|
|
228
|
+
const list = new List(part);
|
|
229
|
+
part.kind = l === undefined ? ITEMS : LIST;
|
|
230
|
+
part.content = list;
|
|
231
|
+
if (DEV && l !== undefined)
|
|
232
|
+
checkKeys(values, l.key);
|
|
233
|
+
for (let i = 0; i < values.length; i++) {
|
|
234
|
+
const row = new ChildPart(null, null, list, i, false, -1);
|
|
235
|
+
list.rows.push(row);
|
|
236
|
+
if (l === undefined) {
|
|
237
|
+
content(row, values[i]);
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
const item = values[i];
|
|
241
|
+
row.key = l.key(item);
|
|
242
|
+
row.item = item;
|
|
243
|
+
row.picked = l.pick === undefined ? undefined : l.pick(item);
|
|
244
|
+
content(row, l.row(item, row.picked));
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/** `raw()`: its start anchor, then the nodes its markup parses to (texts by length). */
|
|
248
|
+
function raw(part, markup) {
|
|
249
|
+
report({ html: markup });
|
|
250
|
+
const start = cur;
|
|
251
|
+
if (start === null || start.nodeType !== 8)
|
|
252
|
+
return fail('the raw() start anchor <!---->');
|
|
253
|
+
cur = start.nextSibling;
|
|
254
|
+
let end = start;
|
|
255
|
+
for (let n = parse(markup).firstChild; n !== null; n = n.nextSibling) {
|
|
256
|
+
if (n.nodeType === 3)
|
|
257
|
+
end = text(n.data);
|
|
258
|
+
else {
|
|
259
|
+
const dom = cur;
|
|
260
|
+
if (dom === null || dom.nodeName !== n.nodeName)
|
|
261
|
+
return fail(`raw() markup's ${n.nodeName}`);
|
|
262
|
+
end = dom;
|
|
263
|
+
cur = dom.nextSibling;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
part.kind = RAW;
|
|
267
|
+
part.content = new RawRange(start, end, markup);
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=adopt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adopt.js","sourceRoot":"","sources":["../../../src/view/render/adopt.ts"],"names":[],"mappings":"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","sourcesContent":["// The parallel walk (view/07-hydration.md \"The parallel walk\"): visits a template's static\n// structure (its parsed content) and the server DOM together, and builds the same parts the\n// client renderer would, with this render's values as committed values. It writes nothing,\n// except splitting merged text at known lengths (`splitText`), creating the empty Text node of\n// an `''` value, joining text the parser split, and removing development markers. Nested\n// templates, lists (rows one after another, no markers), arrays and `raw()` are walked in\n// turn. Nested Gyral hosts: a shadow host's light children are the parent's content (slotted)\n// and are walked; its shadow root never is; a light host (`data-gyral-light`) is opaque.\n// Development checks every node, text and bound attribute, and the `<!--gyral:ID-->` markers\n// when present; production checks node types, local names and text lengths.\nimport { DEV } from '#view-dev';\nimport { LIGHT_ATTRIBUTE } from '../attributes.js';\nimport { CHILD_BEFORE, type PartSpec, type TemplateObject } from '../normalize/types.js';\nimport { isTemplateResult, sourceOf, templateOf, type TemplateResult } from '../template.js';\nimport { adoptionOf, type Adoption } from './adopt-plan.js';\nimport { adoptAttr, checkAttr } from './adopt-attr.js';\nimport { attrPart, TEXTAREA, TITLE } from './attr-parts.js';\nimport { ChildPart, INSTANCE, ITEMS, LIST, RAW, TEXT } from './child-part.js';\nimport { checkKeys } from './dev-check.js';\nimport { Instance } from './instance.js';\nimport { mismatch } from './mismatch.js';\nimport { ROOT, SOLE } from './plan.js';\nimport { parse, RawRange } from './raw.js';\nimport { report } from './seen.js';\nimport { List } from './rows.js';\nimport { isList, rawHtml, type ListResult } from './values.js';\n\n/** The walk's position: the next DOM node; null at the end of `parent`'s children. */\nlet cur: Node | null = null;\nlet parent: Node;\n/** For mismatch messages: the host's root, the component, the template being walked. */\nlet top: Node;\nlet host = '';\nlet current: TemplateObject | undefined;\n\nconst fail = (expected: string, found: Node | string | null = cur, at: Node = parent): never =>\n mismatch(expected, found, at, top, host, current?.loc);\n\n/** Adopts the server DOM in `root` (a host's root) as `part`'s content for `value`. */\nexport function adopt(part: ChildPart, value: unknown, root: Node, label: string): void {\n top = parent = root;\n cur = root.firstChild;\n host = label;\n current = undefined;\n content(part, value);\n if (cur !== null) fail('the end of the view');\n}\n\n/** A child value at the walk's position (view/02-bindings.md \"Child values\"). */\nfunction content(part: ChildPart, v: unknown): void {\n switch (typeof v) {\n case 'string':\n case 'number': {\n const data = typeof v === 'string' ? v : String(v);\n part.kind = TEXT;\n part.value = v;\n if (data !== '') part.content = text(data);\n else parent.insertBefore((part.content = document.createTextNode('')), cur);\n return;\n }\n case 'object':\n if (v === null) return;\n if (isTemplateResult(v)) {\n part.kind = INSTANCE;\n part.content = instance(v, part);\n } else if (isList(v)) rows(part, v.items, v);\n else if (Array.isArray(v)) rows(part, v, undefined);\n else {\n const markup = rawHtml(v);\n if (markup !== undefined) raw(part, markup);\n else if (DEV) part.commit(v);\n }\n return;\n default:\n // Development: a value no hole renders throws (or warns, for `true`) as on the client.\n // Called through the part, so this chunk imports no development-only function.\n if (DEV) part.commit(v);\n }\n}\n\n/** Static text or a text value: exactly `want`'s length, split off a longer Text node. */\nfunction text(want: string): Text {\n // The parser turns CR and CRLF into LF.\n const data = want.includes('\\r') ? want.replace(/\\r\\n?/g, '\\n') : want;\n const t = cur as Text | null;\n if (t !== null && t.nodeType === 3) {\n // Join text the parser split (very long runs).\n for (let n = t.nextSibling; t.length < data.length && n !== null && n.nodeType === 3;) {\n t.appendData((n as Text).data);\n (n as Text).remove();\n n = t.nextSibling;\n }\n if (t.length >= data.length && (!DEV || t.data.startsWith(data))) {\n if (t.length > data.length) t.splitText(data.length);\n cur = t.nextSibling;\n return t;\n }\n }\n return fail(`text ${JSON.stringify(data.slice(0, 40))}`);\n}\n\nfunction instance(result: TemplateResult, holder: ChildPart): Instance {\n const template = templateOf(result);\n const a = adoptionOf(template);\n // A development server's marker: checked when present (a production server writes none),\n // against the id when the template has one (production client objects don't, 01).\n const marker = cur as Comment | null;\n if (marker !== null && marker.nodeType === 8 && marker.data.startsWith('gyral:')) {\n const id = template.id;\n if (DEV && id !== undefined && marker.data !== `gyral:${id}`) fail(`<!--gyral:${id}-->`);\n cur = marker.nextSibling;\n marker.remove();\n }\n const outer = current;\n current = template;\n const inst = new Instance(template, sourceOf(result), holder, true);\n children(a.plan.content, a, inst, result.values);\n current = outer;\n return inst;\n}\n\n/** The children of template node `t`, with the child holes between them. */\nfunction children(t: Node, a: Adoption, inst: Instance, values: readonly unknown[]): void {\n const holes = a.holes.get(t);\n const root = t === a.plan.content;\n let h = 0;\n for (let n = t.firstChild, j = 0; ; n = n.nextSibling, j++) {\n if (holes !== undefined && h < holes.length) {\n const i = holes[h] as number;\n const spec = a.specs[i] as PartSpec;\n const ref = spec[0] === CHILD_BEFORE ? spec[2] : null;\n if (n === null ? ref === null : ref === j) {\n hole(i, ref, a, inst, values);\n h++;\n }\n }\n if (n === null) return;\n const dom = node(n, a, inst, values);\n if (root) {\n if (j === 0) inst.start = dom;\n inst.end = dom;\n }\n }\n}\n\n/** A child hole: its content, then its reference node (the DOM node the walk reached). */\nfunction hole(\n i: number,\n ref: number | null,\n a: Adoption,\n inst: Instance,\n values: readonly unknown[],\n): void {\n const kind = a.plan.kinds[i] as number;\n const at = a.plan.at[i] as number;\n const part =\n kind === ROOT\n ? new ChildPart(null, null, null, 0, false, at)\n : new ChildPart(parent, null, null, 0, kind === SOLE, at);\n inst.parts[i] = part;\n content(part, values[at]);\n if (ref !== null) {\n part.ref = cur;\n if (kind === ROOT && ref === 0) inst.head = part;\n } else if (kind === ROOT) {\n part.owner = inst;\n inst.tail = part;\n }\n}\n\nfunction node(t: Node, a: Adoption, inst: Instance, values: readonly unknown[]): Node {\n if (t.nodeType === 3) return text((t as Text).data);\n if (t.nodeType !== 8) return element(t as Element, a, inst, values);\n const c = cur as Comment | null;\n if (c === null || c.nodeType !== 8 || (DEV && c.data !== (t as Comment).data)) {\n return fail(`<!--${(t as Comment).data}-->`);\n }\n cur = c.nextSibling;\n return c;\n}\n\nconst WHITESPACE_ONLY = /^[\\t\\n\\f\\r ]*$/;\n\nfunction element(t: Element, a: Adoption, inst: Instance, values: readonly unknown[]): Element {\n const el = cur as Element | null;\n if (el === null || el.localName !== t.localName) return fail(`<${t.localName}>`);\n cur = el.nextSibling;\n let whole = false;\n for (const i of a.attrs.get(t) ?? []) {\n const kind = a.plan.kinds[i] as number;\n const part = attrPart(el, kind, a.specs[i] as PartSpec, a.plan.at[i] as number);\n inst.parts[i] = part;\n adoptAttr(part, values);\n if (DEV) checkAttr(part, fail);\n if (kind === TEXTAREA || kind === TITLE) whole = true; // the part owns the content\n }\n let holes = a.holes.has(t);\n if (whole) return el;\n if (el.hasAttribute(LIGHT_ATTRIBUTE)) {\n // A light host owns its children (ADR 0014): its parent writes none (06 \"Components\").\n for (let c = t.firstChild; c !== null; c = c.nextSibling) {\n if (c.nodeType !== 3 || !WHITESPACE_ONLY.test((c as Text).data)) holes = true;\n }\n if (holes) fail(`no children from the parent in light host <${t.localName}>`, el, el);\n return el;\n }\n // A custom element without children in the template: what it holds is its own.\n if (!holes && t.firstChild === null && t.localName.includes('-')) return el;\n const outer = cur;\n const outerParent = parent;\n parent = el;\n cur = el.firstChild;\n children(t, a, inst, values);\n if (cur !== null) fail(`the end of <${t.localName}>`);\n cur = outer;\n parent = outerParent;\n return el;\n}\n\n/** Rows of `each` (keyed) or items of an array (`l` undefined), one after another. */\nfunction rows(part: ChildPart, values: readonly unknown[], l: ListResult | undefined): void {\n const list = new List(part);\n part.kind = l === undefined ? ITEMS : LIST;\n part.content = list;\n if (DEV && l !== undefined) checkKeys(values, l.key);\n for (let i = 0; i < values.length; i++) {\n const row = new ChildPart(null, null, list, i, false, -1);\n list.rows.push(row);\n if (l === undefined) {\n content(row, values[i]);\n continue;\n }\n const item = values[i];\n row.key = l.key(item);\n row.item = item;\n row.picked = l.pick === undefined ? undefined : l.pick(item);\n content(row, l.row(item, row.picked));\n }\n}\n\n/** `raw()`: its start anchor, then the nodes its markup parses to (texts by length). */\nfunction raw(part: ChildPart, markup: string): void {\n report({ html: markup });\n const start = cur as Comment | null;\n if (start === null || start.nodeType !== 8) return fail('the raw() start anchor <!---->');\n cur = start.nextSibling;\n let end: Node = start;\n for (let n = parse(markup).firstChild; n !== null; n = n.nextSibling) {\n if (n.nodeType === 3) end = text((n as Text).data);\n else {\n const dom = cur;\n if (dom === null || dom.nodeName !== n.nodeName) return fail(`raw() markup's ${n.nodeName}`);\n end = dom;\n cur = dom.nextSibling;\n }\n }\n part.kind = RAW;\n part.content = new RawRange(start, end, markup);\n}\n"]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { PartSpec } from '../normalize/types.js';
|
|
2
|
+
import { type HookSpec } from './hooks.js';
|
|
3
|
+
/** What every part of an instance implements: commit its value(s) from this render's values. */
|
|
4
|
+
export interface Part {
|
|
5
|
+
set(values: readonly unknown[]): void;
|
|
6
|
+
}
|
|
7
|
+
/** `name=${v}`; `value=${v}` on a non-text input becomes this after its first commit. */
|
|
8
|
+
export declare const ATTR = 0;
|
|
9
|
+
/** `name="a ${x} b"`. */
|
|
10
|
+
export declare const MULTI = 1;
|
|
11
|
+
/** `?name=${v}`. */
|
|
12
|
+
export declare const BOOL = 2;
|
|
13
|
+
/** `.name=${v}`. */
|
|
14
|
+
export declare const PROP = 3;
|
|
15
|
+
/** `value=${v}` on `<input>`: live `.value`. */
|
|
16
|
+
export declare const VALUE = 4;
|
|
17
|
+
/** `?checked` on `<input>`, `?selected` on `<option>`: attribute first, then the live property. */
|
|
18
|
+
export declare const CHECKED = 5;
|
|
19
|
+
/** `?indeterminate` on `<input>`: the property only. */
|
|
20
|
+
export declare const STATE = 6;
|
|
21
|
+
/** `?open` on `<details>`/`<dialog>`: the attribute, compared with its live presence. */
|
|
22
|
+
export declare const OPEN = 7;
|
|
23
|
+
/** `<title>${v}</title>`: text content. */
|
|
24
|
+
export declare const TITLE = 8;
|
|
25
|
+
/** `<textarea>${v}</textarea>`: text content first, then the live `.value`. */
|
|
26
|
+
export declare const TEXTAREA = 9;
|
|
27
|
+
/** `${hook(…)}` in a start tag. */
|
|
28
|
+
export declare const HOOK = 10;
|
|
29
|
+
/** Input types whose `value` is a submitted value, not state the user edits. */
|
|
30
|
+
export declare const PLAIN: RegExp;
|
|
31
|
+
export declare const absent: (v: unknown) => boolean;
|
|
32
|
+
export declare const truthy: (v: unknown) => boolean;
|
|
33
|
+
/** The text of a `<textarea>`/`<title>` value: child-hole rules, as one string. */
|
|
34
|
+
export declare function textOf(part: object, v: unknown): string;
|
|
35
|
+
/** The kind of a bound attribute (`?name` when `bool`) on `el`. */
|
|
36
|
+
export declare function attrKind(el: Element, name: string, bool: boolean): number;
|
|
37
|
+
/** The element part for part table entry `spec`: `[kind, path, name?, strings?]` (01). */
|
|
38
|
+
export declare function attrPart(el: Element, kind: number, spec: PartSpec, at: number): AttrPart;
|
|
39
|
+
export declare class AttrPart implements Part {
|
|
40
|
+
readonly el: Element;
|
|
41
|
+
kind: number;
|
|
42
|
+
readonly name: string;
|
|
43
|
+
readonly at: number;
|
|
44
|
+
/** The committed value: raw (ATTR, PROP, VALUE), boolean, string (MULTI, text), or UNSET. */
|
|
45
|
+
value: unknown;
|
|
46
|
+
/** MULTI: the static strings and the committed pieces. */
|
|
47
|
+
readonly strings: readonly string[] | undefined;
|
|
48
|
+
readonly pieces: unknown[] | undefined;
|
|
49
|
+
/** HOOK: the hook, its committed arguments and the ones before. */
|
|
50
|
+
spec: HookSpec<readonly unknown[]> | null;
|
|
51
|
+
args: readonly unknown[] | undefined;
|
|
52
|
+
prev: readonly unknown[] | undefined;
|
|
53
|
+
constructor(el: Element, kind: number, name: string, at: number, strings?: readonly string[]);
|
|
54
|
+
set(values: readonly unknown[]): void;
|
|
55
|
+
/** MULTI: pieces joined with the static strings; `nothing` in any piece removes. */
|
|
56
|
+
private multi;
|
|
57
|
+
/** The joined value of `pieces`, or null when one is `nothing`. */
|
|
58
|
+
join(pieces: readonly unknown[]): string | null;
|
|
59
|
+
/** HOOK: the result commits itself (hook-part.ts); an absent value forgets the hook. */
|
|
60
|
+
hook(v: unknown): void;
|
|
61
|
+
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
// Element parts (view/02-bindings.md "Attribute values", "Boolean attributes", "Properties",
|
|
2
|
+
// "Live form state", "Element hooks"): every hole on or inside one element that isn't a child
|
|
3
|
+
// hole, as one class with a kind, so an instance's update loop sees only two part shapes.
|
|
4
|
+
// Every part compares with its committed value and writes only on change. Live form state
|
|
5
|
+
// sets the attribute too on first creation (the default, so `form.reset()` returns to the
|
|
6
|
+
// model's first value); when the model's value changes it compares with the element's live
|
|
7
|
+
// state and writes only on a difference, so the change lands even over a user's edit, and an
|
|
8
|
+
// unchanged model never touches the control. Constructors only record nodes; hydration
|
|
9
|
+
// (view/07-hydration.md) builds the same parts over server DOM and adopts this render's values
|
|
10
|
+
// as committed (adopt-attr.ts), so edits made before scripts ran stay by the same rule.
|
|
11
|
+
import { DEV } from '#view-dev';
|
|
12
|
+
import { COMMIT_HOOK, isHook } from './hooks.js';
|
|
13
|
+
import { nothing, UNSET } from './values.js';
|
|
14
|
+
import { badHook, warnTrue, warnValue } from './warn.js';
|
|
15
|
+
/** `name=${v}`; `value=${v}` on a non-text input becomes this after its first commit. */
|
|
16
|
+
export const ATTR = 0;
|
|
17
|
+
/** `name="a ${x} b"`. */
|
|
18
|
+
export const MULTI = 1;
|
|
19
|
+
/** `?name=${v}`. */
|
|
20
|
+
export const BOOL = 2;
|
|
21
|
+
/** `.name=${v}`. */
|
|
22
|
+
export const PROP = 3;
|
|
23
|
+
/** `value=${v}` on `<input>`: live `.value`. */
|
|
24
|
+
export const VALUE = 4;
|
|
25
|
+
/** `?checked` on `<input>`, `?selected` on `<option>`: attribute first, then the live property. */
|
|
26
|
+
export const CHECKED = 5;
|
|
27
|
+
/** `?indeterminate` on `<input>`: the property only. */
|
|
28
|
+
export const STATE = 6;
|
|
29
|
+
/** `?open` on `<details>`/`<dialog>`: the attribute, compared with its live presence. */
|
|
30
|
+
export const OPEN = 7;
|
|
31
|
+
/** `<title>${v}</title>`: text content. */
|
|
32
|
+
export const TITLE = 8;
|
|
33
|
+
/** `<textarea>${v}</textarea>`: text content first, then the live `.value`. */
|
|
34
|
+
export const TEXTAREA = 9;
|
|
35
|
+
/** `${hook(…)}` in a start tag. */
|
|
36
|
+
export const HOOK = 10;
|
|
37
|
+
/** Input types whose `value` is a submitted value, not state the user edits. */
|
|
38
|
+
export const PLAIN = /^(checkbox|radio|hidden|button|submit|reset|image|file)$/;
|
|
39
|
+
/** `String(v)`: numbers and booleans as text (objects warn in development first). */
|
|
40
|
+
const text = String;
|
|
41
|
+
export const absent = (v) => v === null || v === undefined || v === nothing;
|
|
42
|
+
export const truthy = (v) => v !== nothing && !!v;
|
|
43
|
+
const isObject = (v) => (typeof v === 'object' && v !== null) || typeof v === 'function';
|
|
44
|
+
/** The text of a `<textarea>`/`<title>` value: child-hole rules, as one string. */
|
|
45
|
+
export function textOf(part, v) {
|
|
46
|
+
if (typeof v === 'string')
|
|
47
|
+
return v;
|
|
48
|
+
if (typeof v === 'number')
|
|
49
|
+
return String(v);
|
|
50
|
+
if (DEV) {
|
|
51
|
+
if (v === true)
|
|
52
|
+
warnTrue(part);
|
|
53
|
+
else if (isObject(v))
|
|
54
|
+
warnValue(part, v, 'the text content');
|
|
55
|
+
}
|
|
56
|
+
return absent(v) || typeof v === 'boolean' ? '' : text(v);
|
|
57
|
+
}
|
|
58
|
+
/** The kind of a bound attribute (`?name` when `bool`) on `el`. */
|
|
59
|
+
export function attrKind(el, name, bool) {
|
|
60
|
+
const tag = el.localName;
|
|
61
|
+
if (!bool)
|
|
62
|
+
return name === 'value' && tag === 'input' ? VALUE : ATTR;
|
|
63
|
+
if (tag === 'input')
|
|
64
|
+
return name === 'checked' ? CHECKED : name === 'indeterminate' ? STATE : BOOL;
|
|
65
|
+
if (tag === 'option' && name === 'selected')
|
|
66
|
+
return CHECKED;
|
|
67
|
+
return name === 'open' && (tag === 'details' || tag === 'dialog') ? OPEN : BOOL;
|
|
68
|
+
}
|
|
69
|
+
/** The element part for part table entry `spec`: `[kind, path, name?, strings?]` (01). */
|
|
70
|
+
export function attrPart(el, kind, spec, at) {
|
|
71
|
+
const s = spec;
|
|
72
|
+
return new AttrPart(el, kind, s[2] ?? '', at, s[3]);
|
|
73
|
+
}
|
|
74
|
+
export class AttrPart {
|
|
75
|
+
constructor(el, kind, name, at, strings) {
|
|
76
|
+
this.el = el;
|
|
77
|
+
this.kind = kind;
|
|
78
|
+
this.name = name;
|
|
79
|
+
this.at = at;
|
|
80
|
+
this.value = UNSET;
|
|
81
|
+
this.strings = strings;
|
|
82
|
+
this.pieces =
|
|
83
|
+
strings === undefined ? undefined : new Array(strings.length - 1).fill(UNSET);
|
|
84
|
+
this.spec = null;
|
|
85
|
+
this.args = undefined;
|
|
86
|
+
this.prev = undefined;
|
|
87
|
+
}
|
|
88
|
+
set(values) {
|
|
89
|
+
const v = values[this.at];
|
|
90
|
+
const el = this.el;
|
|
91
|
+
const live = el;
|
|
92
|
+
switch (this.kind) {
|
|
93
|
+
case ATTR:
|
|
94
|
+
if (v === this.value)
|
|
95
|
+
return;
|
|
96
|
+
this.value = v;
|
|
97
|
+
if (absent(v))
|
|
98
|
+
el.removeAttribute(this.name);
|
|
99
|
+
else {
|
|
100
|
+
if (DEV && isObject(v))
|
|
101
|
+
warnValue(this, v, `the attribute ${this.name}`);
|
|
102
|
+
el.setAttribute(this.name, typeof v === 'string' ? v : text(v));
|
|
103
|
+
}
|
|
104
|
+
return;
|
|
105
|
+
case MULTI:
|
|
106
|
+
this.multi(values);
|
|
107
|
+
return;
|
|
108
|
+
case BOOL: {
|
|
109
|
+
const on = truthy(v);
|
|
110
|
+
if (on === this.value)
|
|
111
|
+
return;
|
|
112
|
+
this.value = on;
|
|
113
|
+
el.toggleAttribute(this.name, on);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
case PROP:
|
|
117
|
+
if (Object.is(v, this.value))
|
|
118
|
+
return;
|
|
119
|
+
this.value = v;
|
|
120
|
+
live[this.name] = v;
|
|
121
|
+
return;
|
|
122
|
+
case VALUE: {
|
|
123
|
+
if (v === this.value)
|
|
124
|
+
return;
|
|
125
|
+
const s = absent(v) ? '' : text(v);
|
|
126
|
+
if (this.value === UNSET) {
|
|
127
|
+
// First creation: the attribute (the default), then the live value.
|
|
128
|
+
if (absent(v))
|
|
129
|
+
el.removeAttribute('value');
|
|
130
|
+
else
|
|
131
|
+
el.setAttribute('value', s);
|
|
132
|
+
if (PLAIN.test(el.type))
|
|
133
|
+
this.kind = ATTR;
|
|
134
|
+
}
|
|
135
|
+
this.value = v;
|
|
136
|
+
if (this.kind === VALUE && live.value !== s)
|
|
137
|
+
live.value = s;
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
case CHECKED:
|
|
141
|
+
case STATE: {
|
|
142
|
+
const on = truthy(v);
|
|
143
|
+
if (on === this.value)
|
|
144
|
+
return;
|
|
145
|
+
if (this.kind === CHECKED && this.value === UNSET)
|
|
146
|
+
el.toggleAttribute(this.name, on);
|
|
147
|
+
this.value = on;
|
|
148
|
+
if (live[this.name] !== on)
|
|
149
|
+
live[this.name] = on;
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
case OPEN: {
|
|
153
|
+
const on = truthy(v);
|
|
154
|
+
if (on === this.value)
|
|
155
|
+
return;
|
|
156
|
+
this.value = on;
|
|
157
|
+
if (el.hasAttribute('open') !== on)
|
|
158
|
+
el.toggleAttribute('open', on);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
case TITLE:
|
|
162
|
+
case TEXTAREA: {
|
|
163
|
+
const s = textOf(this, v);
|
|
164
|
+
if (s === this.value)
|
|
165
|
+
return;
|
|
166
|
+
if (this.kind === TEXTAREA && this.value !== UNSET) {
|
|
167
|
+
if (live.value !== s)
|
|
168
|
+
live.value = s;
|
|
169
|
+
}
|
|
170
|
+
else
|
|
171
|
+
el.textContent = s;
|
|
172
|
+
this.value = s;
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
default:
|
|
176
|
+
this.hook(v);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/** MULTI: pieces joined with the static strings; `nothing` in any piece removes. */
|
|
180
|
+
multi(values) {
|
|
181
|
+
const pieces = this.pieces;
|
|
182
|
+
let changed = false;
|
|
183
|
+
for (let i = 0; i < pieces.length; i++) {
|
|
184
|
+
const v = values[this.at + i];
|
|
185
|
+
if (v !== pieces[i]) {
|
|
186
|
+
pieces[i] = v;
|
|
187
|
+
changed = true;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (!changed)
|
|
191
|
+
return;
|
|
192
|
+
const joined = this.join(pieces);
|
|
193
|
+
if (joined === this.value)
|
|
194
|
+
return;
|
|
195
|
+
this.value = joined;
|
|
196
|
+
if (joined === null)
|
|
197
|
+
this.el.removeAttribute(this.name);
|
|
198
|
+
else
|
|
199
|
+
this.el.setAttribute(this.name, joined);
|
|
200
|
+
}
|
|
201
|
+
/** The joined value of `pieces`, or null when one is `nothing`. */
|
|
202
|
+
join(pieces) {
|
|
203
|
+
const strings = this.strings;
|
|
204
|
+
let joined = strings[0];
|
|
205
|
+
for (let i = 0; i < pieces.length; i++) {
|
|
206
|
+
const v = pieces[i];
|
|
207
|
+
if (v === nothing)
|
|
208
|
+
return null;
|
|
209
|
+
if (DEV && isObject(v))
|
|
210
|
+
warnValue(this, v, `the attribute ${this.name}`);
|
|
211
|
+
joined += (v === null || v === undefined ? '' : text(v)) + strings[i + 1];
|
|
212
|
+
}
|
|
213
|
+
return joined;
|
|
214
|
+
}
|
|
215
|
+
/** HOOK: the result commits itself (hook-part.ts); an absent value forgets the hook. */
|
|
216
|
+
hook(v) {
|
|
217
|
+
if (absent(v)) {
|
|
218
|
+
this.spec = null;
|
|
219
|
+
this.args = undefined;
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const commit = isHook(v) ? v[COMMIT_HOOK] : undefined;
|
|
223
|
+
if (commit !== undefined)
|
|
224
|
+
commit(this, v);
|
|
225
|
+
else if (DEV)
|
|
226
|
+
badHook(v);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=attr-parts.js.map
|