diff --git a/src/components/PreviewPane/Preview.js b/src/components/PreviewPane/Preview.js index 1875d1b1..e4409b5a 100644 --- a/src/components/PreviewPane/Preview.js +++ b/src/components/PreviewPane/Preview.js @@ -9,15 +9,18 @@ const style = { fontFamily: 'Roboto, "Helvetica Neue", HelveticaNeue, Helvetica, Arial, sans-serif', }; -export default function Preview({ collection, fields, widgetFor }) { - if (!collection || !fields) { - return null; +export default class Preview extends React.Component { + render() { + const { collection, fields, widgetFor } = this.props; + if (!collection || !fields) { + return null; + } + return ( +
+ {fields.filter(isVisible).map(field => widgetFor(field.get('name')))} +
+ ); } - return ( -
- {fields.filter(isVisible).map(field => widgetFor(field.get('name')))} -
- ); } Preview.propTypes = { diff --git a/src/components/PreviewPane/PreviewContent.js b/src/components/PreviewPane/PreviewContent.js new file mode 100644 index 00000000..dce067fe --- /dev/null +++ b/src/components/PreviewPane/PreviewContent.js @@ -0,0 +1,22 @@ +import React, { PropTypes } from 'react'; +import { ScrollSyncPane } from '../ScrollSync'; + +// 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. +class PreviewContent extends React.Component { + render() { + const { previewComponent, previewProps } = this.props; + return ( + + {React.createElement(previewComponent, previewProps)} + + ); + } +} + +PreviewContent.contextTypes = { + document: PropTypes.any, +}; + +export default PreviewContent; diff --git a/src/components/PreviewPane/PreviewPane.js b/src/components/PreviewPane/PreviewPane.js index 4117b597..c704b3fc 100644 --- a/src/components/PreviewPane/PreviewPane.js +++ b/src/components/PreviewPane/PreviewPane.js @@ -2,11 +2,12 @@ import React, { PropTypes } from 'react'; 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'; import { selectTemplateName, selectInferedField } from '../../reducers/collections'; import { INFERABLE_FIELDS } from '../../constants/fieldInference'; +import PreviewContent from './PreviewContent.js'; +import PreviewHOC from '../Widgets/PreviewHOC'; import Preview from './Preview'; import styles from './PreviewPane.css'; @@ -16,15 +17,18 @@ export default class PreviewPane extends React.Component { const { fieldsMetaData, getAsset, entry } = props; const widget = resolveWidget(field.get('widget')); - return !widget.preview ? null : React.createElement(widget.preview, { - field, - key: field.get('name'), - value: value && Map.isMap(value) ? value.get(field.get('name')) : value, - metadata: fieldsMetaData && fieldsMetaData.get(field.get('name')), - getAsset, - entry, - fieldsMetaData, - }); + return !widget.preview ? null : ( + + ); }; inferedFields = {}; @@ -118,7 +122,9 @@ export default class PreviewPane extends React.Component { return null; } - const component = registry.getPreviewTemplate(selectTemplateName(collection, entry.get('slug'))) || Preview; + const previewComponent = + registry.getPreviewTemplate(selectTemplateName(collection, entry.get('slug'))) || + Preview; this.inferFields(); @@ -135,18 +141,6 @@ export default class PreviewPane extends React.Component { 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/src/components/Widgets/ControlHOC.js b/src/components/Widgets/ControlHOC.js index 8e358905..40a7eeb0 100644 --- a/src/components/Widgets/ControlHOC.js +++ b/src/components/Widgets/ControlHOC.js @@ -22,6 +22,10 @@ class ControlHOC extends Component { getAsset: PropTypes.func.isRequired, }; + shouldComponentUpdate(nextProps) { + return nextProps.value !== this.props.value; + } + processInnerControlRef = (wrappedControl) => { if (!wrappedControl) return; this.wrappedControlValid = wrappedControl.isValid || truthy; diff --git a/src/components/Widgets/MarkdownControl/VisualEditor/index.js b/src/components/Widgets/MarkdownControl/VisualEditor/index.js index 97308c10..1239f369 100644 --- a/src/components/Widgets/MarkdownControl/VisualEditor/index.js +++ b/src/components/Widgets/MarkdownControl/VisualEditor/index.js @@ -166,6 +166,7 @@ const RULES = [ } }, }, + /* { // Special case for links, to grab their href. deserialize(el, next) { @@ -180,6 +181,7 @@ const RULES = [ } }, }, + */ ] const serializer = new SlateHtml({ rules: RULES }); diff --git a/src/components/Widgets/PreviewHOC.js b/src/components/Widgets/PreviewHOC.js new file mode 100644 index 00000000..dc25977a --- /dev/null +++ b/src/components/Widgets/PreviewHOC.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class PreviewHOC extends React.Component { + shouldComponentUpdate(nextProps) { + return nextProps.value !== this.props.value; + } + + render() { + const { previewComponent, ...props } = this.props; + return React.createElement(previewComponent, props); + } +} + +export default PreviewHOC;