diff --git a/package.json b/package.json
index 0f2bc367b48c..39c063466da0 100644
--- a/package.json
+++ b/package.json
@@ -135,6 +135,7 @@
"react-autosuggest": "^7.0.1",
"react-datetime": "^2.6.0",
"react-dom": "^15.1.0",
+ "react-frame-component": "^1.0.3",
"react-hot-loader": "^3.0.0-beta.2",
"react-immutable-proptypes": "^2.1.0",
"react-lazy-load": "^3.0.3",
diff --git a/src/components/PreviewPane/PreviewPane.js b/src/components/PreviewPane/PreviewPane.js
index 07c1fd72e542..88767f62eecc 100644
--- a/src/components/PreviewPane/PreviewPane.js
+++ b/src/components/PreviewPane/PreviewPane.js
@@ -1,7 +1,7 @@
import React, { PropTypes } from 'react';
-import ReactDOM from 'react-dom';
import { List, Map } from 'immutable';
import ImmutablePropTypes from 'react-immutable-proptypes';
+import Frame from 'react-frame-component';
import { ScrollSyncPane } from '../ScrollSync';
import registry from '../../lib/registry';
import { resolveWidget } from '../Widgets';
@@ -12,10 +12,6 @@ import styles from './PreviewPane.css';
export default class PreviewPane extends React.Component {
- componentDidUpdate() {
- this.renderPreview();
- }
-
getWidget = (field, value, props) => {
const { fieldsMetaData, getAsset } = props;
const widget = resolveWidget(field.get('widget'));
@@ -66,7 +62,7 @@ export default class PreviewPane extends React.Component {
const widgets = nestedFields && Map(nestedFields.map((f, i) => [f.get('name'),
{this.getWidget(f, val, this.props)}
]));
return Map({ data: val, widgets });
});
- }
+ };
return Map({
data: value,
@@ -74,27 +70,7 @@ export default class PreviewPane extends React.Component {
});
};
- handleIframeRef = (ref) => {
- if (ref) {
- registry.getPreviewStyles().forEach((style) => {
- const linkEl = document.createElement('link');
- linkEl.setAttribute('rel', 'stylesheet');
- linkEl.setAttribute('href', style);
- ref.contentDocument.head.appendChild(linkEl);
- });
-
- const base = document.createElement('base');
- base.setAttribute('target', '_blank');
- ref.contentDocument.head.appendChild(base);
-
- this.previewEl = document.createElement('div');
- this.iframeBody = ref.contentDocument.body;
- this.iframeBody.appendChild(this.previewEl);
- this.renderPreview();
- }
- };
-
- renderPreview() {
+ render() {
const { entry, collection } = this.props;
if (!entry || !entry.get('data')) return;
const component = registry.getPreviewTemplate(selectTemplateName(collection, entry.get('slug'))) || Preview;
@@ -107,22 +83,25 @@ export default class PreviewPane extends React.Component {
widgetsFor: this.widgetsFor,
};
- // We need to use this API in order to pass context to the iframe
- ReactDOM.unstable_renderSubtreeIntoContainer(
- this,
-
- {React.createElement(component, previewProps)}
-
- , this.previewEl);
- }
+ const styleEl = ;
- render() {
- const { collection } = this.props;
if (!collection) {
- return null;
+ return ;
}
- return ;
+ // We need to create a lightweight component here so that we can
+ // access the context within the Frame. This allows us to attach
+ // the ScrollSyncPane to the body.
+ const PreviewContent = (props, { document: iFrameDocument }) => (
+
+ {React.createElement(component, previewProps)}
+ );
+
+ PreviewContent.contextTypes = {
+ document: PropTypes.any,
+ };
+
+ return ();
}
}
diff --git a/yarn.lock b/yarn.lock
index a7688842d6a7..ba011dcc435e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6934,6 +6934,10 @@ react-dom@^15.1.0:
object-assign "^4.1.0"
prop-types "~15.5.7"
+react-frame-component@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/react-frame-component/-/react-frame-component-1.0.3.tgz#00a5deea81671927ea973954a0d8eb19ecc339de"
+
react-fuzzy@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/react-fuzzy/-/react-fuzzy-0.2.3.tgz#4fa08729524cd491e2b589509e8d2de7e3adfb9e"