Skip to content

Commit

Permalink
Use react-frame-component for preview pane
Browse files Browse the repository at this point in the history
This fixes the preview pane not working in Firefox
  • Loading branch information
Benaiah authored and calavera committed May 8, 2017
1 parent c086dca commit ab47c3c
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 39 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
67 changes: 28 additions & 39 deletions src/components/PreviewPane/PreviewPane.js
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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'));
Expand Down Expand Up @@ -66,35 +62,15 @@ export default class PreviewPane extends React.Component {
const widgets = nestedFields && Map(nestedFields.map((f, i) => [f.get('name'), <div key={i}>{this.getWidget(f, val, this.props)}</div>]));
return Map({ data: val, widgets });
});
}
};

return Map({
data: value,
widgets: nestedFields && Map(nestedFields.map(f => [f.get('name'), this.getWidget(f, value, this.props)])),
});
};

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;
Expand All @@ -107,22 +83,35 @@ 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,
<ScrollSyncPane attachTo={this.iframeBody}>
{React.createElement(component, previewProps)}
</ScrollSyncPane>
, this.previewEl);
}
const styleEls = registry.getPreviewStyles()
.map(style => <link href={style} type="text/css" rel="stylesheet" />);

render() {
const { collection } = this.props;
if (!collection) {
return null;
return <Frame className={styles.frame} head={styleEl} />;
}

return <iframe className={styles.frame} ref={this.handleIframeRef} />;
// 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 }) => (
<ScrollSyncPane attachTo={iFrameDocument.scrollingElement}>
{React.createElement(component, previewProps)}
</ScrollSyncPane>);

PreviewContent.contextTypes = {
document: PropTypes.any,
};

return (<Frame
className={styles.frame}
head={styleEls}
initialContent={`
<!DOCTYPE html>
<html>
<head><base target="_blank"/></head>
<body><div></div></body>
</html>`}
><PreviewContent /></Frame>);
}
}

Expand Down
4 changes: 4 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit ab47c3c

Please sign in to comment.