@microsoft/fast-element 2.10.4 → 3.0.0-rc.2
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 +52 -2
- package/README.md +244 -1
- package/dist/arrays/arrays.api.json +2621 -0
- package/dist/context/context.api.json +13 -13
- package/dist/declarative/declarative.api.json +8483 -0
- package/dist/di/di.api.json +16 -16
- package/dist/dts/__test__/helpers.d.ts +6 -0
- package/dist/dts/array-observer.d.ts +2 -0
- package/dist/dts/arrays.d.ts +2 -0
- package/dist/dts/attr.d.ts +1 -0
- package/dist/dts/binding/binding.d.ts +15 -5
- package/dist/dts/binding/one-time.d.ts +1 -1
- package/dist/dts/binding/one-way.d.ts +1 -1
- package/dist/dts/binding/signal.d.ts +6 -6
- package/dist/dts/binding/two-way.d.ts +2 -1
- package/dist/dts/binding.d.ts +7 -0
- package/dist/dts/components/attributes.d.ts +1 -4
- package/dist/dts/components/definition-schema-transforms.d.ts +9 -0
- package/dist/dts/components/element-controller.d.ts +80 -114
- package/dist/dts/components/element-hydration.d.ts +1 -1
- package/dist/dts/components/enable-hydration.d.ts +54 -0
- package/dist/dts/components/fast-definitions.d.ts +98 -46
- package/dist/dts/components/fast-element.d.ts +43 -16
- package/dist/dts/components/hydration-tracker.d.ts +83 -0
- package/dist/dts/components/hydration.d.ts +23 -53
- package/dist/dts/components/schema.d.ts +205 -0
- package/dist/dts/context.d.ts +13 -13
- package/dist/dts/css.d.ts +3 -0
- package/dist/dts/debug.d.ts +5 -1
- package/dist/dts/declarative/attribute-map.d.ts +58 -0
- package/dist/dts/declarative/debug.d.ts +4 -0
- package/dist/dts/declarative/index.d.ts +14 -0
- package/dist/dts/declarative/interfaces.d.ts +8 -0
- package/dist/dts/declarative/observer-map-utilities.d.ts +58 -0
- package/dist/dts/declarative/observer-map.d.ts +89 -0
- package/dist/dts/declarative/runtime.d.ts +5 -0
- package/dist/dts/declarative/syntax.d.ts +21 -0
- package/dist/dts/declarative/template-bridge.d.ts +33 -0
- package/dist/dts/declarative/template-parser.d.ts +98 -0
- package/dist/dts/declarative/template.d.ts +10 -0
- package/dist/dts/declarative/utilities.d.ts +358 -0
- package/dist/dts/di/di.d.ts +7 -7
- package/dist/dts/directives/children.d.ts +2 -0
- package/dist/dts/directives/node-observation.d.ts +2 -0
- package/dist/dts/directives/ref.d.ts +2 -0
- package/dist/dts/directives/repeat.d.ts +4 -0
- package/dist/dts/directives/slotted.d.ts +2 -0
- package/dist/dts/directives/when.d.ts +3 -0
- package/dist/dts/dom-policy.d.ts +23 -5
- package/dist/dts/dom.d.ts +4 -16
- package/dist/dts/html.d.ts +5 -0
- package/dist/dts/hydration/diagnostics.d.ts +93 -0
- package/dist/dts/hydration/hydration-debugger.d.ts +35 -0
- package/dist/dts/hydration/messages.d.ts +62 -0
- package/dist/dts/hydration/runtime.d.ts +7 -0
- package/dist/dts/hydration/target-builder.d.ts +40 -12
- package/dist/dts/hydration.d.ts +18 -0
- package/dist/dts/index.d.ts +42 -42
- package/dist/dts/index.debug.d.ts +0 -1
- package/dist/dts/index.rollup.debug.d.ts +0 -1
- package/dist/dts/interfaces.d.ts +2 -49
- package/dist/dts/observable.d.ts +3 -6
- package/dist/dts/observation/arrays.d.ts +1 -1
- package/dist/dts/observation/observable.d.ts +3 -3
- package/dist/dts/observation/update-queue.d.ts +1 -1
- package/dist/dts/platform.d.ts +45 -8
- package/dist/dts/registry.d.ts +1 -0
- package/dist/dts/render.d.ts +7 -0
- package/dist/dts/schema.d.ts +1 -0
- package/dist/dts/state/exports.d.ts +1 -1
- package/dist/dts/state/state.d.ts +2 -2
- package/dist/dts/styles/css-directive.d.ts +5 -12
- package/dist/dts/styles/css.d.ts +5 -7
- package/dist/dts/styles/element-styles.d.ts +0 -10
- package/dist/dts/styles.d.ts +6 -0
- package/dist/dts/templating/compiler.d.ts +1 -1
- package/dist/dts/templating/html-binding-directive.d.ts +10 -2
- package/dist/dts/templating/html-directive.d.ts +19 -1
- package/dist/dts/templating/hydration-view.d.ts +130 -0
- package/dist/dts/templating/render.d.ts +1 -1
- package/dist/dts/templating/repeat.d.ts +1 -1
- package/dist/dts/templating/template.d.ts +15 -7
- package/dist/dts/templating/view.d.ts +25 -102
- package/dist/dts/templating.d.ts +10 -0
- package/dist/dts/testing/exports.d.ts +2 -2
- package/dist/dts/testing/fakes.d.ts +4 -4
- package/dist/dts/updates.d.ts +1 -0
- package/dist/dts/volatile.d.ts +2 -0
- package/dist/esm/__test__/helpers.js +22 -0
- package/dist/esm/__test__/setup-node.js +18 -0
- package/dist/esm/array-observer.js +1 -0
- package/dist/esm/arrays.js +1 -0
- package/dist/esm/attr.js +1 -0
- package/dist/esm/binding/normalize.js +1 -1
- package/dist/esm/binding/signal.js +4 -4
- package/dist/esm/binding/two-way.js +3 -3
- package/dist/esm/binding.js +4 -0
- package/dist/esm/components/attributes.js +18 -11
- package/dist/esm/components/definition-schema-transforms.js +23 -0
- package/dist/esm/components/element-controller.js +206 -270
- package/dist/esm/components/element-hydration.js +1 -1
- package/dist/esm/components/enable-hydration.js +124 -0
- package/dist/esm/components/fast-definitions.js +219 -56
- package/dist/esm/components/fast-element.js +18 -27
- package/dist/esm/components/hydration-tracker.js +122 -0
- package/dist/esm/components/hydration.js +137 -140
- package/dist/esm/components/schema.js +253 -0
- package/dist/esm/context.js +6 -6
- package/dist/esm/css.js +3 -0
- package/dist/esm/debug.js +27 -26
- package/dist/esm/declarative/attribute-map.js +122 -0
- package/dist/esm/declarative/debug.js +4 -0
- package/dist/esm/declarative/index.js +4 -0
- package/dist/esm/declarative/interfaces.js +9 -0
- package/dist/esm/declarative/observer-map-utilities.js +565 -0
- package/dist/esm/declarative/observer-map.js +216 -0
- package/dist/esm/declarative/runtime.js +14 -0
- package/dist/esm/declarative/syntax.js +36 -0
- package/dist/esm/declarative/template-bridge.js +160 -0
- package/dist/esm/declarative/template-parser.js +306 -0
- package/dist/esm/declarative/template.js +143 -0
- package/dist/esm/declarative/utilities.js +1069 -0
- package/dist/esm/di/di.js +8 -9
- package/dist/esm/directives/children.js +1 -0
- package/dist/esm/directives/node-observation.js +1 -0
- package/dist/esm/directives/ref.js +1 -0
- package/dist/esm/directives/repeat.js +1 -0
- package/dist/esm/directives/slotted.js +1 -0
- package/dist/esm/directives/when.js +1 -0
- package/dist/esm/dom-policy.js +35 -6
- package/dist/esm/dom.js +1 -1
- package/dist/esm/html.js +2 -0
- package/dist/esm/hydration/diagnostics.js +50 -0
- package/dist/esm/hydration/hydration-debugger.js +112 -0
- package/dist/esm/hydration/messages.js +84 -0
- package/dist/esm/hydration/runtime.js +33 -0
- package/dist/esm/hydration/target-builder.js +144 -91
- package/dist/esm/hydration.js +6 -0
- package/dist/esm/index.debug.js +2 -1
- package/dist/esm/index.js +38 -29
- package/dist/esm/index.rollup.debug.js +3 -2
- package/dist/esm/index.rollup.js +1 -1
- package/dist/esm/interfaces.js +2 -45
- package/dist/esm/metadata.js +2 -8
- package/dist/esm/observable.js +1 -4
- package/dist/esm/observation/arrays.js +1 -1
- package/dist/esm/observation/notifier.js +2 -4
- package/dist/esm/observation/observable.js +5 -5
- package/dist/esm/observation/update-queue.js +47 -58
- package/dist/esm/platform.js +31 -30
- package/dist/esm/registry.js +1 -0
- package/dist/esm/render.js +1 -0
- package/dist/esm/schema.js +1 -0
- package/dist/esm/state/exports.js +1 -1
- package/dist/esm/styles/css-directive.js +1 -2
- package/dist/esm/styles/css.js +15 -56
- package/dist/esm/styles/element-styles.js +69 -15
- package/dist/esm/styles.js +2 -0
- package/dist/esm/templating/html-binding-directive.js +11 -9
- package/dist/esm/templating/hydration-view.js +228 -0
- package/dist/esm/templating/render.js +39 -18
- package/dist/esm/templating/repeat.js +69 -33
- package/dist/esm/templating/template.js +7 -7
- package/dist/esm/templating/view.js +25 -234
- package/dist/esm/templating.js +7 -0
- package/dist/esm/testing/exports.js +2 -2
- package/dist/esm/testing/fixture.js +2 -2
- package/dist/esm/testing/timeout.js +2 -2
- package/dist/esm/updates.js +1 -0
- package/dist/esm/volatile.js +1 -0
- package/dist/fast-element.api.json +14389 -11138
- package/dist/fast-element.d.ts +3651 -809
- package/dist/fast-element.debug.js +5666 -4722
- package/dist/fast-element.debug.min.js +2 -2
- package/dist/fast-element.js +5394 -4381
- package/dist/fast-element.min.js +2 -2
- package/dist/fast-element.untrimmed.d.ts +923 -472
- package/dist/hydration/hydration.api.json +6460 -0
- package/dist/styles/styles.api.json +2672 -0
- package/package.json +165 -45
- package/ARCHITECTURE_FASTELEMENT.md +0 -63
- package/ARCHITECTURE_HTML_TAGGED_TEMPLATE_LITERAL.md +0 -36
- package/ARCHITECTURE_INTRO.md +0 -10
- package/ARCHITECTURE_OVERVIEW.md +0 -52
- package/ARCHITECTURE_UPDATES.md +0 -11
- package/CHANGELOG.json +0 -2275
- package/DESIGN.md +0 -510
- package/api-extractor.context.json +0 -14
- package/api-extractor.di.json +0 -14
- package/biome.json +0 -4
- package/dist/dts/components/install-hydration.d.ts +0 -1
- package/dist/dts/pending-task.d.ts +0 -32
- package/dist/dts/styles/css-binding-directive.d.ts +0 -60
- package/dist/dts/templating/install-hydratable-view-templates.d.ts +0 -1
- package/dist/esm/components/install-hydration.js +0 -3
- package/dist/esm/pending-task.js +0 -28
- package/dist/esm/polyfills.js +0 -60
- package/dist/esm/styles/css-binding-directive.js +0 -76
- package/dist/esm/templating/install-hydratable-view-templates.js +0 -23
- package/docs/ACKNOWLEDGEMENTS.md +0 -12
- package/docs/api-report.api.md +0 -1122
- package/docs/context/api-report.api.md +0 -69
- package/docs/di/api-report.api.md +0 -315
- package/docs/fast-element-2-changes.md +0 -15
- package/playwright.config.ts +0 -26
- package/scripts/run-api-extractor.js +0 -51
- package/test/index.html +0 -11
- package/test/main.ts +0 -104
- package/test/vite.config.ts +0 -19
- package/tsconfig.api-extractor.json +0 -6
- /package/dist/dts/{polyfills.d.ts → __test__/setup-node.d.ts} +0 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { HydrationMarkup } from "../components/hydration.js";
|
|
2
|
+
import { getHostName, getHydrationDiagnostic, } from "./diagnostics.js";
|
|
3
|
+
import { expectedContentAfterStartMarker, expectedContentEndMarker, expectedElementBoundaryEndMarker, formatNoMoreAttributeBindings, formatNoMoreContentBindings, } from "./messages.js";
|
|
2
4
|
export class HydrationTargetElementError extends Error {
|
|
3
5
|
constructor(
|
|
4
6
|
/**
|
|
@@ -12,10 +14,24 @@ export class HydrationTargetElementError extends Error {
|
|
|
12
14
|
/**
|
|
13
15
|
* The node to target factory.
|
|
14
16
|
*/
|
|
15
|
-
node
|
|
17
|
+
node,
|
|
18
|
+
/**
|
|
19
|
+
* Structured description of the binding the hydration walk was
|
|
20
|
+
* attempting to apply when the mismatch was detected. Free-form
|
|
21
|
+
* string for structural errors that do not correspond to a single
|
|
22
|
+
* binding factory.
|
|
23
|
+
*/
|
|
24
|
+
expected,
|
|
25
|
+
/**
|
|
26
|
+
* Structured description of the server-rendered DOM that was
|
|
27
|
+
* encountered at the mismatch point.
|
|
28
|
+
*/
|
|
29
|
+
received) {
|
|
16
30
|
super(message);
|
|
17
31
|
this.factories = factories;
|
|
18
32
|
this.node = node;
|
|
33
|
+
this.expected = expected;
|
|
34
|
+
this.received = received;
|
|
19
35
|
}
|
|
20
36
|
}
|
|
21
37
|
function isComment(node) {
|
|
@@ -39,26 +55,24 @@ export function createRangeForNodes(first, last) {
|
|
|
39
55
|
range.setEnd(last, isComment(last) || isText(last) ? last.data.length : last.childNodes.length);
|
|
40
56
|
return range;
|
|
41
57
|
}
|
|
42
|
-
function isShadowRoot(node) {
|
|
43
|
-
return node instanceof DocumentFragment && "mode" in node;
|
|
44
|
-
}
|
|
45
58
|
/**
|
|
46
59
|
* Maps compiled ViewBehaviorFactory IDs to their corresponding DOM nodes in the
|
|
47
60
|
* server-rendered shadow root. Uses a TreeWalker to scan the existing DOM between
|
|
48
|
-
* firstNode and lastNode,
|
|
61
|
+
* firstNode and lastNode, processing data-free sequential hydration markers.
|
|
49
62
|
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
63
|
+
* A sequential factory pointer advances through the factories array in DFS order.
|
|
64
|
+
* Since the template compiler and hydration walker both traverse the DOM in
|
|
65
|
+
* identical depth-first order, no embedded indices are needed in markers.
|
|
52
66
|
*
|
|
53
|
-
* For
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
67
|
+
* For element nodes: parses `data-fe="N"` to determine the count of attribute
|
|
68
|
+
* binding factories, then consumes N factories sequentially.
|
|
69
|
+
*
|
|
70
|
+
* For comment nodes: `fe:b` markers consume the next factory for content bindings,
|
|
71
|
+
* using balanced depth counting for nested marker pairing. `fe:e` markers cause
|
|
72
|
+
* the walker to skip nested custom element subtrees.
|
|
58
73
|
*
|
|
59
74
|
* Host bindings (targetNodeId='h') appear at the start of the factories array but
|
|
60
|
-
* have no SSR markers — getHydrationIndexOffset() computes
|
|
61
|
-
* marker indices align with the correct non-host factories.
|
|
75
|
+
* have no SSR markers — getHydrationIndexOffset() computes the initial pointer value.
|
|
62
76
|
*
|
|
63
77
|
* @param firstNode - The first node of the view.
|
|
64
78
|
* @param lastNode - The last node of the view.
|
|
@@ -68,7 +82,6 @@ function isShadowRoot(node) {
|
|
|
68
82
|
export function buildViewBindingTargets(firstNode, lastNode, factories) {
|
|
69
83
|
const range = createRangeForNodes(firstNode, lastNode);
|
|
70
84
|
const treeRoot = range.commonAncestorContainer;
|
|
71
|
-
const hydrationIndexOffset = getHydrationIndexOffset(factories);
|
|
72
85
|
const walker = document.createTreeWalker(treeRoot, NodeFilter.SHOW_ELEMENT + NodeFilter.SHOW_COMMENT + NodeFilter.SHOW_TEXT, {
|
|
73
86
|
acceptNode(node) {
|
|
74
87
|
return range.comparePoint(node, 0) === 0
|
|
@@ -78,15 +91,67 @@ export function buildViewBindingTargets(firstNode, lastNode, factories) {
|
|
|
78
91
|
});
|
|
79
92
|
const targets = {};
|
|
80
93
|
const boundaries = {};
|
|
94
|
+
// Sequential factory pointer — skip host bindings at the start
|
|
95
|
+
const hydrationIndexOffset = getHydrationIndexOffset(factories);
|
|
96
|
+
let factoryPointer = hydrationIndexOffset;
|
|
81
97
|
let node = (walker.currentNode = firstNode);
|
|
82
98
|
while (node !== null) {
|
|
83
99
|
switch (node.nodeType) {
|
|
84
100
|
case Node.ELEMENT_NODE: {
|
|
85
|
-
|
|
101
|
+
const element = node;
|
|
102
|
+
const legacyIndices = HydrationMarkup.parseLegacyAttributeBindingIndices(element);
|
|
103
|
+
if (legacyIndices !== null) {
|
|
104
|
+
for (const index of legacyIndices) {
|
|
105
|
+
const factoryIndex = index + hydrationIndexOffset;
|
|
106
|
+
const factory = factories[factoryIndex];
|
|
107
|
+
if (!factory) {
|
|
108
|
+
const expected = formatNoMoreAttributeBindings(factories.length);
|
|
109
|
+
const result = getHydrationDiagnostic().formatStructuralError(node, getHostName(node), expected);
|
|
110
|
+
throw new HydrationTargetElementError(result.message, factories, element, result.expected, result.received);
|
|
111
|
+
}
|
|
112
|
+
targetFactory(factory, node, targets);
|
|
113
|
+
factoryPointer = Math.max(factoryPointer, factoryIndex + 1);
|
|
114
|
+
}
|
|
115
|
+
HydrationMarkup.removeLegacyAttributeBindingMarkers(element);
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
const count = HydrationMarkup.parseAttributeBindingCount(element);
|
|
119
|
+
if (count !== null) {
|
|
120
|
+
for (let i = 0; i < count; i++) {
|
|
121
|
+
const factory = factories[factoryPointer++];
|
|
122
|
+
if (!factory) {
|
|
123
|
+
const expected = formatNoMoreAttributeBindings(factories.length);
|
|
124
|
+
const result = getHydrationDiagnostic().formatStructuralError(node, getHostName(node), expected);
|
|
125
|
+
throw new HydrationTargetElementError(result.message, factories, node, result.expected, result.received);
|
|
126
|
+
}
|
|
127
|
+
targetFactory(factory, node, targets);
|
|
128
|
+
}
|
|
129
|
+
element.removeAttribute(HydrationMarkup.attributeMarkerName);
|
|
130
|
+
}
|
|
86
131
|
break;
|
|
87
132
|
}
|
|
88
133
|
case Node.COMMENT_NODE: {
|
|
89
|
-
|
|
134
|
+
const data = node.data;
|
|
135
|
+
if (HydrationMarkup.isElementBoundaryStartMarker(node)) {
|
|
136
|
+
// Element boundary — clear start marker and skip subtree
|
|
137
|
+
node.data = "";
|
|
138
|
+
skipToElementBoundaryEnd(walker, factories, node);
|
|
139
|
+
}
|
|
140
|
+
else if (HydrationMarkup.isContentBindingStartMarker(data)) {
|
|
141
|
+
// Content binding — consume next factory
|
|
142
|
+
const legacyIndex = HydrationMarkup.parseLegacyContentBindingStartIndex(data);
|
|
143
|
+
const factoryIndex = legacyIndex === null
|
|
144
|
+
? factoryPointer++
|
|
145
|
+
: legacyIndex + hydrationIndexOffset;
|
|
146
|
+
const factory = factories[factoryIndex];
|
|
147
|
+
factoryPointer = Math.max(factoryPointer, factoryIndex + 1);
|
|
148
|
+
if (!factory) {
|
|
149
|
+
const expected = formatNoMoreContentBindings(factories.length);
|
|
150
|
+
const result = getHydrationDiagnostic().formatStructuralError(node, getHostName(node), expected);
|
|
151
|
+
throw new HydrationTargetElementError(result.message, factories, node, result.expected, result.received);
|
|
152
|
+
}
|
|
153
|
+
targetContentBinding(node, walker, factory, factories, targets, boundaries);
|
|
154
|
+
}
|
|
90
155
|
break;
|
|
91
156
|
}
|
|
92
157
|
}
|
|
@@ -95,100 +160,88 @@ export function buildViewBindingTargets(firstNode, lastNode, factories) {
|
|
|
95
160
|
range.detach();
|
|
96
161
|
return { targets, boundaries };
|
|
97
162
|
}
|
|
98
|
-
function
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
throw new HydrationTargetElementError(`HydrationView was unable to successfully target factory on ${node.nodeName} inside ${node.getRootNode().host.nodeName}. This likely indicates a template mismatch between SSR rendering and hydration.`, factories, node);
|
|
107
|
-
}
|
|
108
|
-
targetFactory(factory, node, targets);
|
|
109
|
-
}
|
|
110
|
-
node.removeAttribute(HydrationMarkup.attributeMarkerName);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
function targetComment(node, walker, factories, targets, boundaries, hydrationIndexOffset) {
|
|
114
|
-
if (HydrationMarkup.isElementBoundaryStartMarker(node)) {
|
|
115
|
-
skipToElementBoundaryEndMarker(node, walker);
|
|
116
|
-
return;
|
|
163
|
+
function targetContentBinding(node, walker, factory, factories, targets, boundaries) {
|
|
164
|
+
const nodes = [];
|
|
165
|
+
let current = walker.nextSibling();
|
|
166
|
+
node.data = "";
|
|
167
|
+
if (current === null) {
|
|
168
|
+
const expected = expectedContentAfterStartMarker;
|
|
169
|
+
const result = getHydrationDiagnostic().formatStructuralError(node, getHostName(node), expected);
|
|
170
|
+
throw new HydrationTargetElementError(result.message, factories, node, result.expected, result.received);
|
|
117
171
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const first = current;
|
|
129
|
-
// Search for the binding end marker that closes the binding.
|
|
130
|
-
while (current !== null) {
|
|
131
|
-
if (isComment(current)) {
|
|
132
|
-
const parsed = HydrationMarkup.parseContentBindingEndMarker(current.data);
|
|
133
|
-
if (parsed && parsed[1] === id) {
|
|
172
|
+
const first = current;
|
|
173
|
+
// Balanced depth counting for nested content markers
|
|
174
|
+
let depth = 0;
|
|
175
|
+
while (current !== null) {
|
|
176
|
+
if (isComment(current)) {
|
|
177
|
+
if (HydrationMarkup.isContentBindingStartMarker(current.data)) {
|
|
178
|
+
depth++;
|
|
179
|
+
}
|
|
180
|
+
else if (HydrationMarkup.isContentBindingEndMarker(current.data)) {
|
|
181
|
+
if (depth === 0)
|
|
134
182
|
break;
|
|
135
|
-
|
|
183
|
+
depth--;
|
|
136
184
|
}
|
|
137
|
-
nodes.push(current);
|
|
138
|
-
current = walker.nextSibling();
|
|
139
|
-
}
|
|
140
|
-
if (current === null) {
|
|
141
|
-
const root = node.getRootNode();
|
|
142
|
-
throw new Error(`Error hydrating Comment node inside "${isShadowRoot(root) ? root.host.nodeName : root.nodeName}".`);
|
|
143
185
|
}
|
|
144
|
-
current
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
const dummyTextNode = current.parentNode.insertBefore(document.createTextNode(""), current);
|
|
166
|
-
targetFactory(factory, dummyTextNode, targets);
|
|
186
|
+
nodes.push(current);
|
|
187
|
+
current = walker.nextSibling();
|
|
188
|
+
}
|
|
189
|
+
if (current === null) {
|
|
190
|
+
const expected = expectedContentEndMarker;
|
|
191
|
+
const result = getHydrationDiagnostic().formatStructuralError(node, getHostName(node), expected);
|
|
192
|
+
throw new HydrationTargetElementError(result.message, factories, node, result.expected, result.received);
|
|
193
|
+
}
|
|
194
|
+
current.data = "";
|
|
195
|
+
if (nodes.length === 1 && isText(nodes[0])) {
|
|
196
|
+
targetFactory(factory, nodes[0], targets);
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
// If current === first, it means there is no content in
|
|
200
|
+
// the view. This happens when a `when` directive evaluates false,
|
|
201
|
+
// or whenever a content binding returns null or undefined.
|
|
202
|
+
if (current !== first && current.previousSibling !== null) {
|
|
203
|
+
boundaries[factory.targetNodeId] = {
|
|
204
|
+
first,
|
|
205
|
+
last: current.previousSibling,
|
|
206
|
+
};
|
|
167
207
|
}
|
|
208
|
+
// Insert a text node so text content binding targets it
|
|
209
|
+
const dummyTextNode = current.parentNode.insertBefore(document.createTextNode(""), current);
|
|
210
|
+
targetFactory(factory, dummyTextNode, targets);
|
|
168
211
|
}
|
|
169
212
|
}
|
|
170
213
|
/**
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
* @param walker - tree walker
|
|
214
|
+
* Skips past a nested custom element's shadow content using balanced
|
|
215
|
+
* depth counting to handle nested element boundaries correctly.
|
|
174
216
|
*/
|
|
175
|
-
function
|
|
176
|
-
|
|
217
|
+
function skipToElementBoundaryEnd(walker, factories, startNode) {
|
|
218
|
+
let depth = 0;
|
|
177
219
|
let current = walker.nextSibling();
|
|
178
220
|
while (current !== null) {
|
|
179
221
|
if (isComment(current)) {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
222
|
+
if (HydrationMarkup.isElementBoundaryStartMarker(current)) {
|
|
223
|
+
current.data = "";
|
|
224
|
+
depth++;
|
|
225
|
+
}
|
|
226
|
+
else if (HydrationMarkup.isElementBoundaryEndMarker(current)) {
|
|
227
|
+
if (depth === 0) {
|
|
228
|
+
current.data = "";
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
current.data = "";
|
|
232
|
+
depth--;
|
|
183
233
|
}
|
|
184
234
|
}
|
|
185
235
|
current = walker.nextSibling();
|
|
186
236
|
}
|
|
237
|
+
const expected = expectedElementBoundaryEndMarker;
|
|
238
|
+
const result = getHydrationDiagnostic().formatStructuralError(startNode, getHostName(startNode), expected);
|
|
239
|
+
throw new HydrationTargetElementError(result.message, factories, startNode, result.expected, result.received);
|
|
187
240
|
}
|
|
188
241
|
/**
|
|
189
242
|
* Counts how many factories at the start of the array are host bindings (targetNodeId='h').
|
|
190
243
|
* Host bindings target the custom element itself and are not represented by SSR markers,
|
|
191
|
-
* so the
|
|
244
|
+
* so the factory pointer must start past them.
|
|
192
245
|
*/
|
|
193
246
|
function getHydrationIndexOffset(factories) {
|
|
194
247
|
let offset = 0;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { deferHydrationAttribute, enableHydration, StopHydration, } from "./components/enable-hydration.js";
|
|
2
|
+
export { isHydratable } from "./components/hydration.js";
|
|
3
|
+
export { HydrationTracker } from "./components/hydration-tracker.js";
|
|
4
|
+
export { DOMPolicy, } from "./dom-policy.js";
|
|
5
|
+
export { hydrationDebugger } from "./hydration/hydration-debugger.js";
|
|
6
|
+
export { HydrationBindingError, HydrationStage, } from "./templating/hydration-view.js";
|
package/dist/esm/index.debug.js
CHANGED
package/dist/esm/index.js
CHANGED
|
@@ -1,39 +1,48 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export {
|
|
8
|
-
export { Updates } from "./observation/update-queue.js";
|
|
1
|
+
/**
|
|
2
|
+
* Core APIs for building standards-based Web Components with FAST Element.
|
|
3
|
+
* @packageDocumentation
|
|
4
|
+
*/
|
|
5
|
+
// Kernel
|
|
6
|
+
// Components
|
|
7
|
+
export { AttributeConfiguration, AttributeDefinition, attr, booleanConverter, nullableBooleanConverter, nullableNumberConverter, } from "./attr.js";
|
|
9
8
|
// Binding
|
|
10
9
|
export { Binding } from "./binding/binding.js";
|
|
11
10
|
export { normalizeBinding } from "./binding/normalize.js";
|
|
12
11
|
export { oneTime } from "./binding/one-time.js";
|
|
13
12
|
export { listener, oneWay } from "./binding/one-way.js";
|
|
13
|
+
export { Signal, signal } from "./binding/signal.js";
|
|
14
|
+
export { TwoWaySettings, twoWay, } from "./binding/two-way.js";
|
|
15
|
+
export { ElementController, Stages, } from "./components/element-controller.js";
|
|
16
|
+
export { FASTElementDefinition, fastElementRegistry, } from "./components/fast-definitions.js";
|
|
17
|
+
export { customElement, FASTElement, } from "./components/fast-element.js";
|
|
18
|
+
export { enableDebug } from "./debug.js";
|
|
19
|
+
// Directives
|
|
20
|
+
export { ChildrenDirective, children, } from "./directives/children.js";
|
|
21
|
+
export { elements, NodeObservationDirective, } from "./directives/node-observation.js";
|
|
22
|
+
export { RefDirective, ref } from "./directives/ref.js";
|
|
23
|
+
export { RepeatBehavior, RepeatDirective, repeat, } from "./directives/repeat.js";
|
|
24
|
+
export { SlottedDirective, slotted, } from "./directives/slotted.js";
|
|
25
|
+
export { when } from "./directives/when.js";
|
|
26
|
+
export { DOM, DOMAspect } from "./dom.js";
|
|
27
|
+
export { DOMPolicy, } from "./dom-policy.js";
|
|
28
|
+
export { ArrayObserver, lengthOf, Sort, Splice, SpliceStrategy, SpliceStrategySupport, sortedCount, } from "./observation/arrays.js";
|
|
29
|
+
// Observation
|
|
30
|
+
export { PropertyChangeNotifier, SubscriberSet, } from "./observation/notifier.js";
|
|
31
|
+
export { ExecutionContext, Observable, observable, SourceLifetime, volatile, } from "./observation/observable.js";
|
|
32
|
+
export { Updates } from "./observation/update-queue.js";
|
|
33
|
+
export { emptyArray, FAST } from "./platform.js";
|
|
34
|
+
export { Schema, schemaRegistry, } from "./schema.js";
|
|
35
|
+
export * from "./state/exports.js";
|
|
14
36
|
// Styles
|
|
15
|
-
export { CSSBindingDirective } from "./styles/css-binding-directive.js";
|
|
16
|
-
export { cssDirective, CSSDirective, } from "./styles/css-directive.js";
|
|
17
37
|
export { css } from "./styles/css.js";
|
|
18
|
-
export {
|
|
19
|
-
export {} from "./styles/
|
|
38
|
+
export { CSSDirective, cssDirective, } from "./styles/css-directive.js";
|
|
39
|
+
export { ElementStyles } from "./styles/element-styles.js";
|
|
20
40
|
// Templating
|
|
21
|
-
export { children, ChildrenDirective } from "./templating/children.js";
|
|
22
41
|
export { Compiler } from "./templating/compiler.js";
|
|
23
|
-
export { HTMLBindingDirective } from "./templating/html-binding-directive.js";
|
|
24
|
-
export {
|
|
42
|
+
export { HTMLBindingDirective, } from "./templating/html-binding-directive.js";
|
|
43
|
+
export { HTMLDirective, htmlDirective, StatelessAttachedAttributeDirective, } from "./templating/html-directive.js";
|
|
25
44
|
export { Markup, Parser } from "./templating/markup.js";
|
|
26
|
-
export {
|
|
27
|
-
export {
|
|
28
|
-
export {
|
|
29
|
-
export
|
|
30
|
-
export { slotted, SlottedDirective } from "./templating/slotted.js";
|
|
31
|
-
export { html, InlineTemplateDirective, ViewTemplate } from "./templating/template.js";
|
|
32
|
-
export { HTMLView, HydrationBindingError } from "./templating/view.js";
|
|
33
|
-
export { when } from "./templating/when.js";
|
|
34
|
-
// Components
|
|
35
|
-
export { attr, AttributeConfiguration, AttributeDefinition, booleanConverter, nullableBooleanConverter, nullableNumberConverter, } from "./components/attributes.js";
|
|
36
|
-
export { ElementController, HydratableElementController, needsHydrationAttribute, Stages, } from "./components/element-controller.js";
|
|
37
|
-
export { FASTElementDefinition, fastElementRegistry, TemplateOptions, } from "./components/fast-definitions.js";
|
|
38
|
-
export { customElement, FASTElement } from "./components/fast-element.js";
|
|
39
|
-
export { deferHydrationAttribute, isHydratable } from "./components/hydration.js";
|
|
45
|
+
export { RenderBehavior, RenderDirective, render } from "./templating/render.js";
|
|
46
|
+
export { html, InlineTemplateDirective, ViewTemplate, } from "./templating/template.js";
|
|
47
|
+
export { DefaultExecutionContext, HTMLView, } from "./templating/view.js";
|
|
48
|
+
export * from "./utilities.js";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import "./debug.js";
|
|
2
|
-
import { DOMPolicy } from "./dom-policy.js";
|
|
1
|
+
import { enableDebug } from "./debug.js";
|
|
3
2
|
import { DOM } from "./dom.js";
|
|
3
|
+
import { DOMPolicy } from "./dom-policy.js";
|
|
4
|
+
enableDebug();
|
|
4
5
|
export * from "./index.js";
|
|
5
6
|
DOM.setPolicy(DOMPolicy.create());
|
package/dist/esm/index.rollup.js
CHANGED
package/dist/esm/interfaces.js
CHANGED
|
@@ -1,48 +1,3 @@
|
|
|
1
|
-
let kernelMode;
|
|
2
|
-
const kernelAttr = "fast-kernel";
|
|
3
|
-
try {
|
|
4
|
-
if (document.currentScript) {
|
|
5
|
-
kernelMode = document.currentScript.getAttribute(kernelAttr);
|
|
6
|
-
}
|
|
7
|
-
else {
|
|
8
|
-
const scripts = document.getElementsByTagName("script");
|
|
9
|
-
const currentScript = scripts[scripts.length - 1];
|
|
10
|
-
kernelMode = currentScript.getAttribute(kernelAttr);
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
catch (e) {
|
|
14
|
-
kernelMode = "isolate";
|
|
15
|
-
}
|
|
16
|
-
let KernelServiceId;
|
|
17
|
-
switch (kernelMode) {
|
|
18
|
-
case "share": // share the kernel across major versions
|
|
19
|
-
KernelServiceId = Object.freeze({
|
|
20
|
-
updateQueue: 1,
|
|
21
|
-
observable: 2,
|
|
22
|
-
contextEvent: 3,
|
|
23
|
-
elementRegistry: 4,
|
|
24
|
-
});
|
|
25
|
-
break;
|
|
26
|
-
case "share-v2": // only share the kernel with other v2 instances
|
|
27
|
-
KernelServiceId = Object.freeze({
|
|
28
|
-
updateQueue: 1.2,
|
|
29
|
-
observable: 2.2,
|
|
30
|
-
contextEvent: 3.2,
|
|
31
|
-
elementRegistry: 4.2,
|
|
32
|
-
});
|
|
33
|
-
break;
|
|
34
|
-
default:
|
|
35
|
-
// fully isolate the kernel from all other FAST instances
|
|
36
|
-
const postfix = `-${Math.random().toString(36).substring(2, 8)}`;
|
|
37
|
-
KernelServiceId = Object.freeze({
|
|
38
|
-
updateQueue: `1.2${postfix}`,
|
|
39
|
-
observable: `2.2${postfix}`,
|
|
40
|
-
contextEvent: `3.2${postfix}`,
|
|
41
|
-
elementRegistry: `4.2${postfix}`,
|
|
42
|
-
});
|
|
43
|
-
break;
|
|
44
|
-
}
|
|
45
|
-
export { KernelServiceId };
|
|
46
1
|
/**
|
|
47
2
|
* Warning and error messages.
|
|
48
3
|
* @internal
|
|
@@ -62,6 +17,8 @@ export var Message;
|
|
|
62
17
|
Message[Message["onlySetTemplatePolicyOnce"] = 1207] = "onlySetTemplatePolicyOnce";
|
|
63
18
|
Message[Message["cannotSetTemplatePolicyAfterCompilation"] = 1208] = "cannotSetTemplatePolicyAfterCompilation";
|
|
64
19
|
Message[Message["blockedByDOMPolicy"] = 1209] = "blockedByDOMPolicy";
|
|
20
|
+
Message[Message["invalidHydrationAttributeMarker"] = 1210] = "invalidHydrationAttributeMarker";
|
|
21
|
+
Message[Message["duplicateRenderInstruction"] = 1211] = "duplicateRenderInstruction";
|
|
65
22
|
// 1301 - 1400 Styles
|
|
66
23
|
// 1401 - 1500 Components
|
|
67
24
|
Message[Message["missingElementDefinition"] = 1401] = "missingElementDefinition";
|
package/dist/esm/metadata.js
CHANGED
|
@@ -34,19 +34,13 @@ export const Metadata = Object.freeze({
|
|
|
34
34
|
* @param Type - The type to get the metadata for.
|
|
35
35
|
* @returns The metadata array or a frozen empty array if no metadata is found.
|
|
36
36
|
*/
|
|
37
|
-
getDesignParamTypes: (Type) => {
|
|
38
|
-
var _a;
|
|
39
|
-
return ((_a = Reflect.getOwnMetadata(designParamTypesKey, Type)) !== null && _a !== void 0 ? _a : emptyArray);
|
|
40
|
-
},
|
|
37
|
+
getDesignParamTypes: (Type) => { var _a; return ((_a = Reflect.getOwnMetadata(designParamTypesKey, Type)) !== null && _a !== void 0 ? _a : emptyArray); },
|
|
41
38
|
/**
|
|
42
39
|
* Gets the "annotation:paramtypes" metadata for the specified type.
|
|
43
40
|
* @param Type - The type to get the metadata for.
|
|
44
41
|
* @returns The metadata array or a frozen empty array if no metadata is found.
|
|
45
42
|
*/
|
|
46
|
-
getAnnotationParamTypes: (Type) => {
|
|
47
|
-
var _a;
|
|
48
|
-
return ((_a = Reflect.getOwnMetadata(annotationParamTypesKey, Type)) !== null && _a !== void 0 ? _a : emptyArray);
|
|
49
|
-
},
|
|
43
|
+
getAnnotationParamTypes: (Type) => { var _a; return ((_a = Reflect.getOwnMetadata(annotationParamTypesKey, Type)) !== null && _a !== void 0 ? _a : emptyArray); },
|
|
50
44
|
/**
|
|
51
45
|
* Gets the "annotation:paramtypes" metadata for the specified type. If none is found,
|
|
52
46
|
* an empty, mutable metadata array is created and added.
|
package/dist/esm/observable.js
CHANGED
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Observable exports for easy access to the Observable API
|
|
3
|
-
*/
|
|
4
|
-
export { ExecutionContext, Observable, observable, SourceLifetime, volatile, } from "./observation/observable.js";
|
|
5
1
|
export { PropertyChangeNotifier, SubscriberSet } from "./observation/notifier.js";
|
|
2
|
+
export { ExecutionContext, Observable, observable, SourceLifetime, } from "./observation/observable.js";
|
|
@@ -589,7 +589,7 @@ export const ArrayObserver = Object.freeze({
|
|
|
589
589
|
* Enables the array observation mechanism.
|
|
590
590
|
* @remarks
|
|
591
591
|
* Array observation is enabled automatically when using the
|
|
592
|
-
*
|
|
592
|
+
* `RepeatDirective`, so calling this API manually is
|
|
593
593
|
* not typically necessary.
|
|
594
594
|
*/
|
|
595
595
|
enable() {
|
|
@@ -138,12 +138,10 @@ export class PropertyChangeNotifier {
|
|
|
138
138
|
var _a, _b;
|
|
139
139
|
let subscribers;
|
|
140
140
|
if (propertyToWatch) {
|
|
141
|
-
subscribers =
|
|
142
|
-
(_a = this.subscribers[propertyToWatch]) !== null && _a !== void 0 ? _a : (this.subscribers[propertyToWatch] = new SubscriberSet(this.subject));
|
|
141
|
+
subscribers = (_a = this.subscribers[propertyToWatch]) !== null && _a !== void 0 ? _a : (this.subscribers[propertyToWatch] = new SubscriberSet(this.subject));
|
|
143
142
|
}
|
|
144
143
|
else {
|
|
145
|
-
subscribers =
|
|
146
|
-
(_b = this.subjectSubscribers) !== null && _b !== void 0 ? _b : (this.subjectSubscribers = new SubscriberSet(this.subject));
|
|
144
|
+
subscribers = (_b = this.subjectSubscribers) !== null && _b !== void 0 ? _b : (this.subjectSubscribers = new SubscriberSet(this.subject));
|
|
147
145
|
}
|
|
148
146
|
subscribers.subscribe(subscriber);
|
|
149
147
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isFunction, isString,
|
|
1
|
+
import { isFunction, isString, Message, } from "../interfaces.js";
|
|
2
2
|
import { createMetadataLocator, FAST, makeSerializationNoop } from "../platform.js";
|
|
3
3
|
import { PropertyChangeNotifier, SubscriberSet } from "./notifier.js";
|
|
4
4
|
import { Updates } from "./update-queue.js";
|
|
@@ -21,7 +21,7 @@ export const SourceLifetime = Object.freeze({
|
|
|
21
21
|
* Common Observable APIs.
|
|
22
22
|
* @public
|
|
23
23
|
*/
|
|
24
|
-
export const Observable =
|
|
24
|
+
export const Observable = (() => {
|
|
25
25
|
const queueUpdate = Updates.enqueue;
|
|
26
26
|
const volatileRegex = /(:|&&|\|\||if|\?\.)/;
|
|
27
27
|
const notifierLookup = new WeakMap();
|
|
@@ -264,7 +264,7 @@ export const Observable = FAST.getById(KernelServiceId.observable, () => {
|
|
|
264
264
|
return volatileRegex.test(expression.toString());
|
|
265
265
|
},
|
|
266
266
|
});
|
|
267
|
-
});
|
|
267
|
+
})();
|
|
268
268
|
/**
|
|
269
269
|
* Decorator: Defines an observable property on the target.
|
|
270
270
|
* @param target - The target to define the observable on.
|
|
@@ -289,7 +289,7 @@ export function volatile(target, name, descriptor) {
|
|
|
289
289
|
},
|
|
290
290
|
});
|
|
291
291
|
}
|
|
292
|
-
const contextEvent =
|
|
292
|
+
const contextEvent = (() => {
|
|
293
293
|
let current = null;
|
|
294
294
|
return {
|
|
295
295
|
get() {
|
|
@@ -299,7 +299,7 @@ const contextEvent = FAST.getById(KernelServiceId.contextEvent, () => {
|
|
|
299
299
|
current = event;
|
|
300
300
|
},
|
|
301
301
|
};
|
|
302
|
-
});
|
|
302
|
+
})();
|
|
303
303
|
/**
|
|
304
304
|
* Provides additional contextual information available to behaviors and expressions.
|
|
305
305
|
* @public
|