Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set the document clone iframe container's size via the style attribute #3097

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

15joeybloom
Copy link

@15joeybloom 15joeybloom commented Jul 25, 2023

Summary

This PR fixes/implements the following bugs/features

  • Bug: CSS rules can override the iframe's size which compromises the screenshot

Some sites I used html2canvas on have a CSS rule like

body>iframe {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
}

This CSS rule takes precedence over the the width and height attributes of the html2canvas iframe container. As a result, the document clone is rendered with a width and height of 0, so I get a blank, all-white screenshot.

This PR also sets the width and height of the iframe within the style attribute. The style attribute will take precedence over any CSS rules.

Test plan (required)

When I tried to run npm test locally I got this error:

Traceback (most recent call last):
  File "/Users/joey/.nvm/versions/node/v12.13.1/lib/node_modules/npm/node_modules/node-gyp/gyp/pylib/gyp/common.py", line 499, in <module>
    class OrderedSet(collections.MutableSet):                                           
AttributeError: module 'collections' has no attribute 'MutableSet'

I'm on macos Ventura 13.4.1 using npm 6.12.1 and node v12.13.1

This prevents CSS rules from overriding the iframe's size which would
compromise the screenshot
@15joeybloom
Copy link
Author

15joeybloom commented Jul 25, 2023

For anyone else who might have come across this issue - a good workaround is to use the onclone callback:

      const canvas = await html2canvas(document.body, {
        x: window.scrollX,
        y: window.scrollY,
        width: document.documentElement.clientWidth,
        height: document.documentElement.clientHeight,
        onclone: (clonedDocument, _element) => {
...
          // This is a hack to fix a bug with html2canvas. When html2canvas is
          // rendering the element to screenshot, it actually adds the element
          // to the DOM inside an invisible iframe. The bug is that the
          // html2canvas iframe container uses the width and height attributes
          // instead of the style attribute to set the iframe's size.  Some
          // sites have a CSS rule that sets iframes' width and height to zero,
          // which takes precedence over the width and height attributes. To fix
          // this bug, we just copy the html2canvas iframe container's width and
          // height attributes into the style attribute.
          const container = document.querySelector('iframe.html2canvas-container');
          container.style.width = container.width + 'px';
          container.style.height = container.height + 'px';
...
        },
...
      });

@Sharcoux
Copy link

Can be tested in @cantoo/html2canvas

nangelina added a commit to artificialonlinesao/html2canvas that referenced this pull request Feb 9, 2024
Squashed commit of the following:

commit d2d83ad
Author: Joey Bloom <15joeybloom@gmail.com>
Date:   Tue Jul 25 16:34:13 2023 -0500

    Set the document clone iframe container's size via the style attribute

    This prevents CSS rules from overriding the iframe's size which would
    compromise the screenshot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants