diff --git a/README.md b/README.md index ace66f7..4ae0782 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,13 @@ The `mountTarget` props is a css selector (#target/.target) that specifies where ``` +###### dangerouslyUseDocWrite +`dangerouslyUseDocWrite: PropTypes.bool` + +Defaults to `false` + +The frame's initial content, as defined by the `initialContent` prop, is populated via the frame's `srcdoc` attribute by default. However, this can cause issues with some libraries such as Recaptcha and Google Maps that depend on the frame's location/origin. In these cases, setting this flag will cause `Frame` to use `document.write()` to populate the initial content. This is **unperformant and unrecommended**, but allows these libraries to be used inside a `Frame` instance. + ###### contentDidMount and contentDidUpdate `contentDidMount: PropTypes.func` `contentDidUpdate: PropTypes.func` diff --git a/src/Frame.jsx b/src/Frame.jsx index 8470f30..151fa4e 100644 --- a/src/Frame.jsx +++ b/src/Frame.jsx @@ -14,6 +14,7 @@ export class Frame extends Component { head: PropTypes.node, initialContent: PropTypes.string, mountTarget: PropTypes.string, + dangerouslyUseDocWrite: PropTypes.bool, contentDidMount: PropTypes.func, contentDidUpdate: PropTypes.func, children: PropTypes.oneOfType([ @@ -27,6 +28,7 @@ export class Frame extends Component { head: null, children: undefined, mountTarget: undefined, + dangerouslyUseDocWrite: false, contentDidMount: () => {}, contentDidUpdate: () => {}, initialContent: @@ -126,6 +128,12 @@ export class Frame extends Component { ); + if (this.props.dangerouslyUseDocWrite && doc.body.children.length < 1) { + doc.open('text/html', 'replace'); + doc.write(this.props.initialContent); + doc.close(); + } + const mountTarget = this.getMountTarget(); return [ @@ -137,12 +145,17 @@ export class Frame extends Component { render() { const props = { ...this.props, - srcDoc: this.props.initialContent, children: undefined // The iframe isn't ready so we drop children from props here. #12, #17 }; + + if (!this.props.dangerouslyUseDocWrite) { + props.srcDoc = this.props.initialContent; + } + delete props.head; delete props.initialContent; delete props.mountTarget; + delete props.dangerouslyUseDocWrite; delete props.contentDidMount; delete props.contentDidUpdate; delete props.forwardedRef; diff --git a/test/Frame.spec.jsx b/test/Frame.spec.jsx index c90242b..6e8b784 100644 --- a/test/Frame.spec.jsx +++ b/test/Frame.spec.jsx @@ -253,6 +253,27 @@ describe('The Frame Component', () => { ); }); + it.only('should allow setting initialContent via document.write() when required', done => { + div = document.body.appendChild(document.createElement('div')); + + const initialContent = + '
'; + const renderedContent = + '