Skip to content

Commit 62193a7

Browse files
authored
Merge pull request #38 from willtonkin/container-filter
Skip nested markup containers
2 parents 9d78582 + 0ddc616 commit 62193a7

File tree

5 files changed

+110
-2
lines changed

5 files changed

+110
-2
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ node_js:
44

55
script:
66
- yarn compile
7+
- yarn test
78
- yarn docz:build
89

910
deploy:

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"lint:ts": "tslint -c tslint.json './packages/**/*.ts*(x)'",
1616
"release": "lerna version prerelease",
1717
"pretest": "npm-run-all lint",
18-
"test": "echo \"Tests coming soon. I'm aware that's not ideal.\""
18+
"test": "jest"
1919
},
2020
"dependencies": {
2121
"react": "^16.5.0",
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`reactFromMarkupContainer E2E tests Should rehydrate a basic component 1`] = `
4+
"
5+
<div data-react-from-markup-container=\\"\\">
6+
<span>rehydrated component</span>
7+
</div>"
8+
`;
9+
10+
exports[`reactFromMarkupContainer E2E tests Should rehydrate valid HTML markup 1`] = `
11+
"
12+
<div data-react-from-markup-container=\\"\\">
13+
<p>paragraph</p>
14+
</div>"
15+
`;
16+
17+
exports[`reactFromMarkupContainer E2E tests Should work for nested markup containers 1`] = `
18+
"
19+
<div data-react-from-markup-container=\\"\\">
20+
<span>rehydrated component</span>
21+
<div data-react-from-markup-container=\\"\\">
22+
<span>rehydrated component</span>
23+
<span>rehydrated component</span>
24+
</div>
25+
</div>"
26+
`;
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/* eslint-env jest */
2+
import * as React from "react";
3+
import reactFromMarkupContainer from "..";
4+
5+
describe("reactFromMarkupContainer E2E tests", async () => {
6+
it("Should rehydrate a basic component", async () => {
7+
const componentName: string = "myComponent";
8+
9+
const rehydrator = async () => {
10+
return React.createElement("span", {}, "rehydrated component");
11+
};
12+
13+
const rehydrators = { [componentName]: rehydrator };
14+
const documentElement = document.createElement("div");
15+
16+
documentElement.innerHTML = `
17+
<div data-react-from-markup-container>
18+
<div data-rehydratable="${componentName}"></div>
19+
</div>`;
20+
21+
await reactFromMarkupContainer(documentElement, rehydrators, {
22+
extra: {}
23+
});
24+
25+
expect(documentElement.innerHTML).toMatchSnapshot();
26+
});
27+
28+
it("Should rehydrate valid HTML markup", async () => {
29+
const documentElement = document.createElement("div");
30+
31+
documentElement.innerHTML = `
32+
<div data-react-from-markup-container>
33+
<p>paragraph</p>
34+
</div>`;
35+
36+
await reactFromMarkupContainer(documentElement, {}, { extra: {} });
37+
38+
expect(documentElement.innerHTML).toMatchSnapshot();
39+
});
40+
41+
it("Should work for nested markup containers", async () => {
42+
const componentName: string = "mycomponentName";
43+
44+
const mockCall = jest.fn();
45+
const rehydrators = {
46+
[componentName]: async () => {
47+
mockCall();
48+
49+
return React.createElement("span", {}, "rehydrated component");
50+
}
51+
};
52+
53+
const documentElement = document.createElement("div");
54+
55+
documentElement.innerHTML = `
56+
<div data-react-from-markup-container>
57+
<div data-rehydratable="${componentName}"></div>
58+
<div data-react-from-markup-container>
59+
<div data-rehydratable="${componentName}">
60+
<div data-react-from-markup-container>
61+
<div data-rehydratable="${componentName}"></div>
62+
</div>
63+
</div>
64+
<div data-rehydratable="${componentName}"></div>
65+
</div>
66+
</div>`;
67+
68+
await reactFromMarkupContainer(documentElement, rehydrators, {
69+
extra: {}
70+
});
71+
72+
expect(documentElement.innerHTML).toMatchSnapshot();
73+
expect(mockCall).toBeCalledTimes(3);
74+
});
75+
});

packages/react-from-markup/src/rehydrator.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,13 @@ export default async (
7575
const roots = Array.from(
7676
// TODO: allow setting a container identifier so multiple rehydration instances can exist
7777
container.querySelectorAll("[data-react-from-markup-container]")
78-
);
78+
).reduce((acc: Element[], root: Element) => {
79+
// filter roots that are contained within other roots
80+
if (!acc.some(r => r.contains(root))) {
81+
acc.push(root);
82+
}
83+
return acc;
84+
}, []);
7985

8086
// TODO: solve race condition when a second rehydrate runs
8187

0 commit comments

Comments
 (0)