Make editor plugins work in preview
This commit is contained in:
parent
378be79a76
commit
aca88ef441
@ -1,6 +1,7 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
import MarkupIt, { Syntax, BLOCKS, STYLES, ENTITIES } from 'markup-it';
|
||||
import { omit } from 'lodash';
|
||||
import registry from '../../lib/registry';
|
||||
|
||||
const defaultSchema = {
|
||||
[BLOCKS.DOCUMENT]: 'article',
|
||||
@ -44,7 +45,25 @@ function sanitizeProps(props) {
|
||||
return omit(props, notAllowedAttributes);
|
||||
}
|
||||
|
||||
function renderToken(schema, token, index = 0, key = '0') {
|
||||
export default class MarkupItReactRenderer extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const { syntax } = props;
|
||||
this.parser = new MarkupIt(syntax);
|
||||
this.plugins = {};
|
||||
registry.getEditorComponents().forEach((component) => {
|
||||
this.plugins[component.get('id')] = component;
|
||||
});
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.syntax != this.props.syntax) {
|
||||
this.parser = new MarkupIt(nextProps.syntax);
|
||||
}
|
||||
}
|
||||
|
||||
renderToken(schema, token, index = 0, key = '0') {
|
||||
const type = token.get('type');
|
||||
const data = token.get('data');
|
||||
const text = token.get('text');
|
||||
@ -56,7 +75,7 @@ function renderToken(schema, token, index = 0, key = '0') {
|
||||
if (typeof nodeType !== 'undefined') {
|
||||
let children = null;
|
||||
if (tokens.size) {
|
||||
children = tokens.map((token, idx) => renderToken(schema, token, idx, key));
|
||||
children = tokens.map((token, idx) => this.renderToken(schema, token, idx, key));
|
||||
} else if (type === 'text') {
|
||||
children = text;
|
||||
}
|
||||
@ -72,27 +91,23 @@ function renderToken(schema, token, index = 0, key = '0') {
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
const plugin = this.plugins[token.get('type')];
|
||||
if (plugin) {
|
||||
const output = plugin.toPreview(token.get('data').toJS());
|
||||
return output instanceof React.Component ?
|
||||
output :
|
||||
<span dangerouslySetInnerHTML={{ __html: output}} />;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export default class MarkupItReactRenderer extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const { syntax } = props;
|
||||
this.parser = new MarkupIt(syntax);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.syntax != this.props.syntax) {
|
||||
this.parser = new MarkupIt(nextProps.syntax);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { value, schema } = this.props;
|
||||
const content = this.parser.toContent(value);
|
||||
return renderToken({ ...defaultSchema, ...schema }, content.get('token'));
|
||||
return this.renderToken({ ...defaultSchema, ...schema }, content.get('token'));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
left: -18px;
|
||||
display: none;
|
||||
width: 100%;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.visible {
|
||||
|
@ -65,18 +65,17 @@ function getCleanPaste(e) {
|
||||
});
|
||||
}
|
||||
|
||||
const buildtInPlugins = fromJS([{
|
||||
const buildtInPlugins = [{
|
||||
label: 'Image',
|
||||
id: 'image',
|
||||
fromBlock: (data) => {
|
||||
const m = data.match(/^!\[([^\]]+)\]\(([^\)]+)\)$/);
|
||||
return m && {
|
||||
image: m[2],
|
||||
alt: m[1],
|
||||
};
|
||||
fromBlock: match => match && {
|
||||
image: match[2],
|
||||
alt: match[1],
|
||||
},
|
||||
toBlock: data => ``,
|
||||
toPreview: data => `<img src="${ data.image }" alt="${ data.alt }" />`,
|
||||
toPreview: (data) => {
|
||||
return <img src={data.image} alt={data.alt} />;
|
||||
},
|
||||
pattern: /^!\[([^\]]+)\]\(([^\)]+)\)$/,
|
||||
fields: [{
|
||||
label: 'Image',
|
||||
@ -86,14 +85,15 @@ const buildtInPlugins = fromJS([{
|
||||
label: 'Alt Text',
|
||||
name: 'alt',
|
||||
}],
|
||||
}]);
|
||||
}];
|
||||
buildtInPlugins.forEach(plugin => registry.registerEditorComponent(plugin));
|
||||
|
||||
export default class RawEditor extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const plugins = registry.getEditorComponents();
|
||||
this.state = {
|
||||
plugins: buildtInPlugins.concat(plugins),
|
||||
plugins: plugins,
|
||||
};
|
||||
this.shortcuts = {
|
||||
meta: {
|
||||
@ -161,7 +161,7 @@ export default class RawEditor extends React.Component {
|
||||
}
|
||||
|
||||
replaceSelection(chars) {
|
||||
const { value } = this.props;
|
||||
const value = this.props.value || '';
|
||||
const selection = this.getSelection();
|
||||
const newSelection = Object.assign({}, selection);
|
||||
const beforeSelection = value.substr(0, selection.start);
|
||||
@ -172,7 +172,7 @@ export default class RawEditor extends React.Component {
|
||||
}
|
||||
|
||||
toggleHeader(header) {
|
||||
const { value } = this.props;
|
||||
const value = this.props.value || '';
|
||||
const selection = this.getSelection();
|
||||
const newSelection = Object.assign({}, selection);
|
||||
const lastNewline = value.lastIndexOf('\n', selection.start);
|
||||
@ -234,7 +234,7 @@ export default class RawEditor extends React.Component {
|
||||
};
|
||||
|
||||
handleSelection = () => {
|
||||
const { value } = this.props;
|
||||
const value = this.props.value || '';
|
||||
const selection = this.getSelection();
|
||||
if (selection.start !== selection.end && !HAS_LINE_BREAK.test(selection.selected)) {
|
||||
try {
|
||||
|
Loading…
x
Reference in New Issue
Block a user