From c5f66d8c70a2b7a546feab192016927929791b55 Mon Sep 17 00:00:00 2001 From: Amir Harel Date: Fri, 20 Apr 2018 14:37:41 +0200 Subject: [PATCH 1/2] Added getDocument prop --- src/preact-portal.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/preact-portal.js b/src/preact-portal.js index 642ab0d..90eae04 100644 --- a/src/preact-portal.js +++ b/src/preact-portal.js @@ -28,7 +28,14 @@ export default class Portal extends Component { } findNode(node) { - return typeof node==='string' ? document.querySelector(node) : node; + return typeof node==='string' ? this.getDocument().querySelector(node) : node; + } + + getDocument() { + if (this.props.getDocument) { + return this.props.getDocument(); + } + return document; } renderLayer(show=true) { From 7fd5ecffb5e28909ae5d0b957a3a4d8c06637ace Mon Sep 17 00:00:00 2001 From: Amir Harel Date: Fri, 20 Apr 2018 14:40:36 +0200 Subject: [PATCH 2/2] Update README.md --- README.md | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/README.md b/README.md index 502f648..b0b1fa7 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,80 @@ class Form extends Component { } ``` +### iframes & document context +In cases were you need to render the portal inside of an `iframe`, you need to provide +the prop `getDocument` which is a method that return the `document` as the context of the portal. + +Here is an example: + +```js + +const INITIAL_CONTENT = '
'; + +class Iframe extends React.Component { + node = null; + initialContentRendered = false; + + getDocument = () => this.node.contentDocument; + + componentDidMount() { + const doc = this.getDocument(); + if (doc && doc.readyState === 'complete') { + this.forceUpdate(); + } else { + this.node.addEventListener('load', this.handleLoad); + } + } + + componentWillUnmount() { + this.node.removeEventListener('load', this.handleLoad); + } + + handleLoad = () => { + this.forceUpdate(); + }; + + + renderContent() { + if (!this.isMounted()) { + return null; + } + + const doc = this.getDocument(); + + if (!this.initialContentRendered) { + doc.open('text/html', 'replace'); + doc.write(INITIAL_CONTENT); + doc.close(); + this.initialContentRendered = true; + } + + return ( + + {this.props.children} + + ); + } + + render() { + return ( + + ); + } +} + +class App extends React.Component { + render() { + return ( + + ); + } +} +``` [preact]: https://github.com/developit/preact [Demo #1]: http://jsfiddle.net/developit/bsr7gmdd/