Expected Behavior
When cloning an iframe on the page, I'd expect to see its content cloned a single time.
Current Behavior
Instead, I'm seeing two copies of the iframe content.
Possible Solution
The problem appears to be in clone-node.ts. The pipeline for cloning each node is cloneSingleNode() -> cloneChildren() -> etc. Both cloneSingleNode() and cloneChildren() have special casing for iframes which result in a separate clone of the contents. cloneSingleNode() calls cloneIframeElement(), which calls cloneNode() again on the iframe's body:
return (await cloneNode(
iframe.contentDocument.body,
options,
true,
)) as HTMLBodyElement
cloneChildren() sets the children to the iframe body's children:
} else if (
isInstanceOfElement(nativeNode, HTMLIFrameElement) &&
nativeNode.contentDocument?.body
) {
children = toArray<T>(nativeNode.contentDocument.body.childNodes)
}
It seems the best solution is to return no children from cloneChildren() when the target element is an iframe. The children will still be cloned by the call to cloneNode() on the iframe's body.
Steps To Reproduce
- Call one of the various
htmlToImage functions on an <iframe> that has any content
- Observe the duplication of content in the resulting image
Expected Behavior
When cloning an iframe on the page, I'd expect to see its content cloned a single time.
Current Behavior
Instead, I'm seeing two copies of the iframe content.
Possible Solution
The problem appears to be in
clone-node.ts. The pipeline for cloning each node iscloneSingleNode()->cloneChildren()-> etc. BothcloneSingleNode()andcloneChildren()have special casing for iframes which result in a separate clone of the contents.cloneSingleNode()callscloneIframeElement(), which callscloneNode()again on the iframe's body:cloneChildren()sets the children to the iframe body's children:It seems the best solution is to return no children from
cloneChildren()when the target element is an iframe. The children will still be cloned by the call tocloneNode()on the iframe's body.Steps To Reproduce
htmlToImagefunctions on an<iframe>that has any content