Skip to content

Commit d089161

Browse files
committed
Fix: Rendering for multiple nested head and body nodes (dojo#812)
* failing unit test for nested body and head tags * skip head or body node when finding insert before node
1 parent 1a76f5b commit d089161

File tree

2 files changed

+140
-0
lines changed

2 files changed

+140
-0
lines changed

src/core/vdom.ts

+4
Original file line numberDiff line numberDiff line change
@@ -1393,6 +1393,10 @@ export function renderer(renderer: () => RenderResult): Renderer {
13931393
while (!insertBefore) {
13941394
const nextSibling = _wrapperSiblingMap.get(searchNode);
13951395
if (nextSibling) {
1396+
if (isBodyWrapper(nextSibling) || isHeadWrapper(nextSibling)) {
1397+
searchNode = nextSibling;
1398+
continue;
1399+
}
13961400
let domNode = nextSibling.domNode;
13971401
if (isWNodeWrapper(nextSibling) || isVirtualWrapper(nextSibling)) {
13981402
if (!nextSibling.childDomWrapperId) {

tests/core/unit/vdom.tsx

+136
Original file line numberDiff line numberDiff line change
@@ -4848,6 +4848,74 @@ jsdomDescribe('vdom', () => {
48484848
results = document.querySelectorAll('.body-span');
48494849
assert.lengthOf(results, 0);
48504850
});
4851+
4852+
it('should support attaching body nodes in nested widgets', () => {
4853+
const factory = create({ icache }).properties<any>();
4854+
4855+
const Foo = factory(function Foo() {
4856+
return (
4857+
<div id="wrapper-2">
4858+
<body>
4859+
<div id="body-2" />
4860+
</body>
4861+
</div>
4862+
);
4863+
});
4864+
4865+
const Bar = factory(function Bar({ properties }) {
4866+
return (
4867+
<div id="wrapper-1">
4868+
<Foo close={() => properties().close()} />
4869+
<body>
4870+
<div id="body-1" />
4871+
</body>
4872+
</div>
4873+
);
4874+
});
4875+
4876+
const App = factory(function App({ middleware: { icache } }) {
4877+
const show = icache.getOrSet('show', false);
4878+
return (
4879+
<div>
4880+
<button
4881+
onclick={() => {
4882+
icache.set('show', (current) => !current);
4883+
}}
4884+
>
4885+
Open/Close
4886+
</button>
4887+
{show && (
4888+
<Bar
4889+
close={() => {
4890+
icache.set('show', false);
4891+
}}
4892+
/>
4893+
)}
4894+
<h2>Start editing to see some magic happen</h2>
4895+
</div>
4896+
);
4897+
});
4898+
4899+
const r = renderer(() => w(App, {}));
4900+
r.mount({ domNode: root });
4901+
(root.children[0].children[0] as any).click();
4902+
resolvers.resolve();
4903+
assert.strictEqual(
4904+
root.innerHTML,
4905+
'<div><button>Open/Close</button><div id="wrapper-1"><div id="wrapper-2"></div></div><h2>Start editing to see some magic happen</h2></div>'
4906+
);
4907+
assert.lengthOf(document.querySelectorAll('#body-1'), 1);
4908+
assert.lengthOf(document.querySelectorAll('#body-2'), 1);
4909+
(root.children[0].children[0] as any).click();
4910+
resolvers.resolve();
4911+
resolvers.resolve();
4912+
assert.strictEqual(
4913+
root.innerHTML,
4914+
'<div><button>Open/Close</button><h2>Start editing to see some magic happen</h2></div>'
4915+
);
4916+
assert.lengthOf(document.querySelectorAll('#body-1'), 0);
4917+
assert.lengthOf(document.querySelectorAll('#body-2'), 0);
4918+
});
48514919
});
48524920

48534921
describe('head node', () => {
@@ -5100,6 +5168,74 @@ jsdomDescribe('vdom', () => {
51005168
results = document.querySelectorAll('.head-span');
51015169
assert.lengthOf(results, 0);
51025170
});
5171+
5172+
it('should support attaching head nodes in nested widgets', () => {
5173+
const factory = create({ icache }).properties<any>();
5174+
5175+
const Foo = factory(function Foo() {
5176+
return (
5177+
<div id="wrapper-2">
5178+
<head>
5179+
<div id="head-2" />
5180+
</head>
5181+
</div>
5182+
);
5183+
});
5184+
5185+
const Bar = factory(function Bar({ properties }) {
5186+
return (
5187+
<div id="wrapper-1">
5188+
<Foo close={() => properties().close()} />
5189+
<head>
5190+
<div id="head-1" />
5191+
</head>
5192+
</div>
5193+
);
5194+
});
5195+
5196+
const App = factory(function App({ middleware: { icache } }) {
5197+
const show = icache.getOrSet('show', false);
5198+
return (
5199+
<div>
5200+
<button
5201+
onclick={() => {
5202+
icache.set('show', (current) => !current);
5203+
}}
5204+
>
5205+
Open/Close
5206+
</button>
5207+
{show && (
5208+
<Bar
5209+
close={() => {
5210+
icache.set('show', false);
5211+
}}
5212+
/>
5213+
)}
5214+
<h2>Start editing to see some magic happen</h2>
5215+
</div>
5216+
);
5217+
});
5218+
5219+
const r = renderer(() => w(App, {}));
5220+
r.mount({ domNode: root });
5221+
(root.children[0].children[0] as any).click();
5222+
resolvers.resolve();
5223+
assert.strictEqual(
5224+
root.innerHTML,
5225+
'<div><button>Open/Close</button><div id="wrapper-1"><div id="wrapper-2"></div></div><h2>Start editing to see some magic happen</h2></div>'
5226+
);
5227+
assert.lengthOf(document.querySelectorAll('#head-1'), 1);
5228+
assert.lengthOf(document.querySelectorAll('#head-2'), 1);
5229+
(root.children[0].children[0] as any).click();
5230+
resolvers.resolve();
5231+
resolvers.resolve();
5232+
assert.strictEqual(
5233+
root.innerHTML,
5234+
'<div><button>Open/Close</button><h2>Start editing to see some magic happen</h2></div>'
5235+
);
5236+
assert.lengthOf(document.querySelectorAll('#head-1'), 0);
5237+
assert.lengthOf(document.querySelectorAll('#head-2'), 0);
5238+
});
51035239
});
51045240

51055241
describe('virtual node', () => {

0 commit comments

Comments
 (0)