rsify / pico

Take browser screenshots in Javascript 📸
MIT License
1.96k stars 45 forks source link

Same origin `<iframe>` rendering #6

Open rsify opened 4 years ago

rsify commented 4 years ago

Some apps with micro frontends utilize tons of <iframe> elements to render out their UI.

This is yet to be tested, but as far as I know trying to embed any <iframe> into the exported image will result in a transparent box in place of its contents.

Possible solution would be either to clone the frame via contentWindow/contentDocument or we'd need to make users load a helper library inside the frame and communicate with it via iframe.postMessage.

rsify commented 4 years ago

Real world example: text editor in https://collabuml.com.

pauldijou commented 4 years ago

I tried to use Pico and ran into that issue (our whole app is running inside an iframe during development for some... valid reasons). So using Pico would only screenshot all the devtools we have around the iframe and not the app itself inside it.

I wanted to only screenshot the iframe itself next, since that's what I actually care about, doing something like:

pico.objectURL(document.querySelector("#myIframe").contentWindow).then(url => {})

But this crashed due to getWindowInfo checking the instanceof compared to the global ones. Can be solved by doing:

    if (!($html instanceof $window.HTMLHtmlElement)) {
        return left(err('Failed to get HTMLHtmlElement'))
    }

    if (!($body instanceof $window.HTMLBodyElement)) {
        return left(err('Failed to get HTMLBodyElement'))
    }

(there is a Typescript error but that's actually valid)

This will now screenshot the content of the iframe but without the correct rendering. Seems like most CSS (if not all) is missing.

That's how far I could go :-)