Skip to content

Commit a31632f

Browse files
authored
Update logic for enumerated attribute hydration markers, add view hydration as export (#7125)
# Pull Request ## 📖 Description This change: - Fixes an issue where if the number on an attribute binding marker did not start at `0` the binding would not be detected accurately. - Adds the view template hydration script as an export as this will be used in FAST HTML to automatically include the `HydratableElementController` ## ✅ Checklist ### General <!--- Review the list and put an x in the boxes that apply. --> - [x] I have included a change request file using `$ npm run change` - [x] I have added tests for my changes. - [x] I have tested my changes. - [ ] I have updated the project documentation to reflect my changes. - [x] I have read the [CONTRIBUTING](https://github.com/microsoft/fast/blob/main/CONTRIBUTING.md) documentation and followed the [standards](https://github.com/microsoft/fast/blob/main/CODE_OF_CONDUCT.md#our-standards) for this project.
1 parent fee3c1e commit a31632f

File tree

4 files changed

+38
-5
lines changed

4 files changed

+38
-5
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Update logic for enumerated attribute hydration markers, add view hydration as export",
4+
"packageName": "@microsoft/fast-element",
5+
"email": "[email protected]",
6+
"dependentChangeType": "none"
7+
}

packages/web-components/fast-element/package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@
7474
"types": "./dist/dts/components/install-hydration.d.ts",
7575
"default": "./dist/esm/components/install-hydration.js"
7676
},
77+
"./install-hydratable-view-templates.js": {
78+
"types": "./dist/dts/templating/install-hydratable-view-templates.d.ts",
79+
"default": "./dist/esm/templating/install-hydratable-view-templates.js"
80+
},
7781
"./pending-task.js": {
7882
"types": "./dist/dts/pending-task.d.ts",
7983
"default": "./dist/esm/pending-task.js"
@@ -88,7 +92,8 @@
8892
"sideEffects": [
8993
"./dist/esm/debug.js",
9094
"./dist/esm/polyfills.js",
91-
"./dist/esm/components/install-hydration.js"
95+
"./dist/esm/components/install-hydration.js",
96+
"./dist/esm/templating/install-hydratable-view-templates.js"
9297
],
9398
"scripts": {
9499
"benchmark": "npm run clean:dist && npm run build && node ./scripts/run-benchmarks",

packages/web-components/fast-element/src/components/hydration.spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,17 @@ describe("HydrationMarkup", () => {
245245
el.setAttribute(`${HydrationMarkup.attributeMarkerName}-2`, "");
246246
expect(HydrationMarkup.parseEnumeratedAttributeBinding(el)).to.eql([0, 1, 2]);
247247
});
248+
it("should return the binding ids as numbers when assigned enumerated marker attributes on multiple elements", () => {
249+
const el = document.createElement("div");
250+
const el2 = document.createElement("div");
251+
const el3 = document.createElement("div");
252+
el.setAttribute(`${HydrationMarkup.attributeMarkerName}-0`, "");
253+
el2.setAttribute(`${HydrationMarkup.attributeMarkerName}-1`, "");
254+
el3.setAttribute(`${HydrationMarkup.attributeMarkerName}-2`, "");
255+
expect(HydrationMarkup.parseEnumeratedAttributeBinding(el)).to.eql([0]);
256+
expect(HydrationMarkup.parseEnumeratedAttributeBinding(el2)).to.eql([1]);
257+
expect(HydrationMarkup.parseEnumeratedAttributeBinding(el3)).to.eql([2]);
258+
});
248259
});
249260

250261
describe("repeat parser", () => {

packages/web-components/fast-element/src/components/hydration.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,23 @@ export const HydrationMarkup = Object.freeze({
7777
*/
7878
parseEnumeratedAttributeBinding(node: Element): null | number[] {
7979
const attrs: number[] = [];
80-
let count = 0;
80+
const prefixLength = this.attributeMarkerName.length + 1;
81+
const prefix = `${this.attributeMarkerName}-`;
8182

82-
while (node.hasAttribute(`${this.attributeMarkerName}-${count}`)) {
83-
attrs.push(count++);
83+
for (const attr of node.getAttributeNames()) {
84+
if (attr.startsWith(prefix)) {
85+
const count = Number(attr.slice(prefixLength));
86+
if (!Number.isNaN(count)) {
87+
attrs.push(count);
88+
} else {
89+
throw new Error(
90+
`Invalid attribute marker name: ${attr}. Expected format is ${prefix}<number>.`
91+
);
92+
}
93+
}
8494
}
8595

86-
return count === 0 ? null : attrs;
96+
return attrs.length === 0 ? null : attrs;
8797
},
8898
/**
8999
* Parses the ViewBehaviorFactory index from string data. Returns

0 commit comments

Comments
 (0)