Without the option (in stencil.config.ts) 'cloneNodeFix' you will see double rendering of the contents of our non-shadow enabled component. If we enable the cloneNodeFix, it will on the initial run of the ng-if directive omit the slotted content.
First, run yarn
Then:
- To see the original double render issue, simply disable the
cloneNodeFix
flag in stencil.config.ts - To see the cloneNodeFix issue, enable the
cloneNodeFix
flag in stencil.config.ts - To apply the fix from the PR:
- run
yarn start
- in www/build, search for the snippet of the cloneNodeFix below
- replace it with my implementation of cloneNodeFix (see further below)
- run
The original cloneNodeFix snippet:
const cloneNodeFix = (HostElementPrototype) => {
const orgCloneNode = HostElementPrototype.cloneNode;
HostElementPrototype.cloneNode = function (deep) {
const srcNode = this;
const isShadowDom = BUILD.shadowDom ? srcNode.shadowRoot && supportsShadowDom : false;
const clonedNode = orgCloneNode.call(srcNode, isShadowDom ? deep : false);
if (BUILD.slot && !isShadowDom && deep) {
let i = 0;
let slotted;
for (; i < srcNode.childNodes.length; i++) {
slotted = srcNode.childNodes[i]['s-nr'];
if (slotted) {
if (BUILD.appendChildSlotFix && clonedNode.__appendChild) {
clonedNode.__appendChild(slotted.cloneNode(true));
}
else {
clonedNode.appendChild(slotted.cloneNode(true));
}
}
}
}
return clonedNode;
};
};
Patched cloneNodeFix snippet:
const cloneNodeFix = (HostElementPrototype) => {
const orgCloneNode = HostElementPrototype.cloneNode;
HostElementPrototype.cloneNode = function (deep) {
const srcNode = this;
const isShadowDom = BUILD.shadowDom ? srcNode.shadowRoot && supportsShadowDom : false;
const clonedNode = orgCloneNode.call(srcNode, isShadowDom ? deep : false);
if (BUILD.slot && !isShadowDom && deep) {
let i = 0;
let slotted, nonStencilNode;
const stencilPrivates = ['s-id', 's-cr', 's-lr', 's-rc', 's-sc', 's-p', 's-cn', 's-sr', 's-sn', 's-hn', 's-ol', 's-nr', 's-si'];
for (; i < srcNode.childNodes.length; i++) {
slotted = srcNode.childNodes[i]['s-nr'];
nonStencilNode = stencilPrivates.every((privateField) => !srcNode.childNodes[i][privateField]);
if (slotted) {
if (BUILD.appendChildSlotFix && clonedNode.__appendChild) {
clonedNode.__appendChild(slotted.cloneNode(true));
}
else {
clonedNode.appendChild(slotted.cloneNode(true));
}
}
if (nonStencilNode){
clonedNode.appendChild(srcNode.childNodes[i].cloneNode(true));
}
}
}
return clonedNode;
};
};