ryanseddon / react-frame-component

Render your React app to an iFrame
http://ryanseddon.github.io/react-frame-component/
MIT License
1.75k stars 156 forks source link

Shadowing window globals #132

Closed bradbarrow closed 5 years ago

bradbarrow commented 5 years ago

This is similar to #40 I believe.

I'm trying to render an app that uses react-pose into a Frame. (actually, I'm using playroom which does this) but it's not able to work with it's refs properly.

It's got a number of instanceof checks like this:

https://github.com/Popmotion/popmotion/blob/master/packages/react-pose/src/components/PoseElement/index.tsx#L169

Basically, if ref instanceof Element.

In the case where this is rendered in the Frame though, the Element on ref's proto chain is the iFrame DOM Element, whereas Element in the condition is our browsers window.Element.

Naively, I wonder if there's a way to shadow the window globals with the iframe.contentWindow globals...or some sort of bind? (iframe n00b here).

Thanks for the hard work on this :)

More context:

https://github.com/seek-oss/playroom/issues/45

dominiczaq commented 5 years ago

I can share my experience with iframes and their context. Basically in one of our project we wanted to use emoji picker. Whole app is rendered inside of an iframe using react-frame-component. We used https://github.com/missive/emoji-mart (highly recommend it). Unfortunately we had an issue with firefox - it won't run window.requestAnimationFrame callbacks if they are used inside another window context (basically inside iframes). We ended up with passing context from react-frame-component (https://github.com/ryanseddon/react-frame-component#accessing-the-iframes-window-and-document) to emoji-mart in our fork https://github.com/dominiczaq/emoji-mart/commit/dd4b7889a30e9cb44d499dc0cc962dda297e307c

Maybe that's a possible solution for your problem.

bradbarrow commented 5 years ago

It certainly could be :) The context is passed through for use in Playroom - but I'd rather not fork the react-pose library. In their code, they check instanceof against globals...not directly against a window.

E.g they do:

ref instanceof Element

not

ref instanceof window.Element

So I was wondering if there was a way to shadow the globals?

Naively (not tested) I'm wondering if this could work:

const withFrameWindow = (props) => (
  <FameContextConsumer>
    {
      (context) => (function ({ window: frameWindow }) {
        Element = frameWindow.Element;

        return props.children;
      })(context)
    }
  </FameContextConsumer>
)

Edit Naively indeed. I'm not thinking straight. Of course the scope of react pose is outside of this execution 🤦‍♂️

Perhaps react-pose might consider taking a window context to use for it's checks

ryanseddon commented 5 years ago

Closing since this is a react-pose issue