From 3b03cf82d95d1f1f5facaa6907cfd673e148b9e7 Mon Sep 17 00:00:00 2001 From: Andy Pye Date: Thu, 2 Nov 2023 13:41:31 +0200 Subject: [PATCH 1/4] Allow falling back to document.write() for initial frame population --- src/Frame.jsx | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) 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; From f12e134e138c74037843ae6c67d0724fb13f48aa Mon Sep 17 00:00:00 2001 From: Andy Pye Date: Thu, 2 Nov 2023 14:32:23 +0200 Subject: [PATCH 2/4] Add failing test for document.write fallback --- test/Frame.spec.jsx | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) 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 = + '
'; + const frame = ReactDOM.render( + { + const doc = ReactDOM.findDOMNode(frame).contentDocument; + expect(doc.documentElement.outerHTML).to.equal(renderedContent); + done(); + }} + />, + div + ); + }); + it('should allow setting mountTarget', done => { div = document.body.appendChild(document.createElement('div')); From 69ec5e83afb255c4be5a6dd3d218a4ba134998b9 Mon Sep 17 00:00:00 2001 From: Andy Pye Date: Thu, 2 Nov 2023 14:45:42 +0200 Subject: [PATCH 3/4] Add documentation for new prop --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) 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` From 710403eb198a4114bd2f17874af258ac299cbe8c Mon Sep 17 00:00:00 2001 From: Andy Pye Date: Mon, 5 May 2025 17:17:16 +0300 Subject: [PATCH 4/4] Try fixing failing test --- test/Frame.spec.jsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/Frame.spec.jsx b/test/Frame.spec.jsx index 271dd7f..f23d8de 100644 --- a/test/Frame.spec.jsx +++ b/test/Frame.spec.jsx @@ -253,7 +253,7 @@ describe('The Frame Component', () => { ); }); - it.only('should allow setting initialContent via document.write() when required', done => { + it('should allow setting initialContent via document.write() when required', () => { div = document.body.appendChild(document.createElement('div')); const initialContent = @@ -267,7 +267,6 @@ describe('The Frame Component', () => { contentDidMount={() => { const doc = ReactDOM.findDOMNode(frame).contentDocument; expect(doc.documentElement.outerHTML).to.equal(renderedContent); - done(); }} />, div