Replace markup-it with Remark for rendering markdown in the editor preview
This commit is contained in:
parent
f3b7dc9e2e
commit
24c0a1bdb4
@ -101,6 +101,7 @@
|
||||
"dateformat": "^1.0.12",
|
||||
"deep-equal": "^1.0.1",
|
||||
"fuzzy": "^0.1.1",
|
||||
"hast-util-to-html": "^3.0.0",
|
||||
"history": "^2.1.2",
|
||||
"immutability-helper": "^2.0.0",
|
||||
"immutable": "^3.7.6",
|
||||
@ -112,6 +113,7 @@
|
||||
"lodash": "^4.13.1",
|
||||
"markup-it": "^2.0.0",
|
||||
"material-design-icons": "^3.0.1",
|
||||
"mdast-util-to-hast": "^2.4.0",
|
||||
"moment": "^2.11.2",
|
||||
"netlify-auth-js": "^0.5.5",
|
||||
"normalize.css": "^4.2.0",
|
||||
@ -157,6 +159,8 @@
|
||||
"redux-notifications": "^2.1.1",
|
||||
"redux-optimist": "^0.0.2",
|
||||
"redux-thunk": "^1.0.3",
|
||||
"remark": "6",
|
||||
"remark-html": "^6.0.0",
|
||||
"selection-position": "^1.0.0",
|
||||
"semaphore": "^1.0.5",
|
||||
"slate": "^0.14.14",
|
||||
|
@ -1,58 +1,14 @@
|
||||
/* eslint max-len:0 */
|
||||
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { padStart } from 'lodash';
|
||||
import { Map } from 'immutable';
|
||||
import MarkupIt from 'markup-it';
|
||||
import markdownSyntax from 'markup-it/syntaxes/markdown';
|
||||
import htmlSyntax from 'markup-it/syntaxes/html';
|
||||
import reInline from 'markup-it/syntaxes/markdown/re/inline';
|
||||
import MarkupItReactRenderer from '../';
|
||||
import React from "react";
|
||||
import { shallow } from "enzyme";
|
||||
import { padStart } from "lodash";
|
||||
import MarkupItReactRenderer from "../";
|
||||
|
||||
function getAsset(path) {
|
||||
return path;
|
||||
}
|
||||
|
||||
describe('MarkitupReactRenderer', () => {
|
||||
describe('basics', () => {
|
||||
it('should re-render properly after a value and syntax update', () => {
|
||||
const component = shallow(
|
||||
<MarkupItReactRenderer
|
||||
value="# Title"
|
||||
syntax={markdownSyntax}
|
||||
getAsset={getAsset}
|
||||
/>
|
||||
);
|
||||
const tree1 = component.html();
|
||||
component.setProps({
|
||||
value: '<h1>Title</h1>',
|
||||
syntax: htmlSyntax,
|
||||
});
|
||||
const tree2 = component.html();
|
||||
expect(tree1).toEqual(tree2);
|
||||
});
|
||||
|
||||
it('should not update the parser if syntax didn\'t change', () => {
|
||||
const component = shallow(
|
||||
<MarkupItReactRenderer
|
||||
value="# Title"
|
||||
syntax={markdownSyntax}
|
||||
getAsset={getAsset}
|
||||
/>
|
||||
);
|
||||
const syntax1 = component.instance().props.syntax;
|
||||
component.setProps({
|
||||
value: '## Title',
|
||||
});
|
||||
const syntax2 = component.instance().props.syntax;
|
||||
expect(syntax1).toEqual(syntax2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Markdown rendering', () => {
|
||||
describe('General', () => {
|
||||
it('should render markdown', () => {
|
||||
describe("MarkitupReactRenderer", () => {
|
||||
describe("Markdown rendering", () => {
|
||||
describe("General", () => {
|
||||
it("should render markdown", () => {
|
||||
const value = `
|
||||
# H1
|
||||
|
||||
@ -79,35 +35,23 @@ Text with **bold** & _em_ elements
|
||||
|
||||
###### H6
|
||||
`;
|
||||
const component = shallow(
|
||||
<MarkupItReactRenderer
|
||||
value={value}
|
||||
syntax={markdownSyntax}
|
||||
getAsset={getAsset}
|
||||
/>
|
||||
);
|
||||
const component = shallow(<MarkupItReactRenderer value={value} />);
|
||||
expect(component.html()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Headings', () => {
|
||||
describe("Headings", () => {
|
||||
for (const heading of [...Array(6).keys()]) {
|
||||
it(`should render Heading ${ heading + 1 }`, () => {
|
||||
const value = padStart(' Title', heading + 7, '#');
|
||||
const component = shallow(
|
||||
<MarkupItReactRenderer
|
||||
value={value}
|
||||
syntax={markdownSyntax}
|
||||
getAsset={getAsset}
|
||||
/>
|
||||
);
|
||||
const value = padStart(" Title", heading + 7, "#");
|
||||
const component = shallow(<MarkupItReactRenderer value={value} />);
|
||||
expect(component.html()).toMatchSnapshot();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('Lists', () => {
|
||||
it('should render lists', () => {
|
||||
describe("Lists", () => {
|
||||
it("should render lists", () => {
|
||||
const value = `
|
||||
1. ol item 1
|
||||
1. ol item 2
|
||||
@ -119,19 +63,13 @@ Text with **bold** & _em_ elements
|
||||
1. Sub-Sublist 3
|
||||
1. ol item 3
|
||||
`;
|
||||
const component = shallow(
|
||||
<MarkupItReactRenderer
|
||||
value={value}
|
||||
syntax={markdownSyntax}
|
||||
getAsset={getAsset}
|
||||
/>
|
||||
);
|
||||
const component = shallow(<MarkupItReactRenderer value={value} />);
|
||||
expect(component.html()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Links', () => {
|
||||
it('should render links', () => {
|
||||
describe("Links", () => {
|
||||
it("should render links", () => {
|
||||
const value = `
|
||||
I get 10 times more traffic from [Google] [1] than from [Yahoo] [2] or [MSN] [3].
|
||||
|
||||
@ -139,45 +77,27 @@ I get 10 times more traffic from [Google] [1] than from [Yahoo] [2] or [MSN] [3]
|
||||
[2]: http://search.yahoo.com/ "Yahoo Search"
|
||||
[3]: http://search.msn.com/ "MSN Search"
|
||||
`;
|
||||
const component = shallow(
|
||||
<MarkupItReactRenderer
|
||||
value={value}
|
||||
syntax={markdownSyntax}
|
||||
getAsset={getAsset}
|
||||
/>
|
||||
);
|
||||
const component = shallow(<MarkupItReactRenderer value={value} />);
|
||||
expect(component.html()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Code', () => {
|
||||
it('should render code', () => {
|
||||
const value = 'Use the `printf()` function.';
|
||||
const component = shallow(
|
||||
<MarkupItReactRenderer
|
||||
value={value}
|
||||
syntax={markdownSyntax}
|
||||
getAsset={getAsset}
|
||||
/>
|
||||
);
|
||||
describe("Code", () => {
|
||||
it("should render code", () => {
|
||||
const value = "Use the `printf()` function.";
|
||||
const component = shallow(<MarkupItReactRenderer value={value} />);
|
||||
expect(component.html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render code 2', () => {
|
||||
const value = '``There is a literal backtick (`) here.``';
|
||||
const component = shallow(
|
||||
<MarkupItReactRenderer
|
||||
value={value}
|
||||
syntax={markdownSyntax}
|
||||
getAsset={getAsset}
|
||||
/>
|
||||
);
|
||||
it("should render code 2", () => {
|
||||
const value = "``There is a literal backtick (`) here.``";
|
||||
const component = shallow(<MarkupItReactRenderer value={value} />);
|
||||
expect(component.html()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('HTML', () => {
|
||||
it('should render HTML as is when using Markdown', () => {
|
||||
describe("HTML", () => {
|
||||
it("should render HTML as is when using Markdown", () => {
|
||||
const value = `
|
||||
# Title
|
||||
|
||||
@ -193,71 +113,16 @@ I get 10 times more traffic from [Google] [1] than from [Yahoo] [2] or [MSN] [3]
|
||||
|
||||
<h1 style="display: block; border: 10px solid #f00; width: 100%">Test</h1>
|
||||
`;
|
||||
const component = shallow(
|
||||
<MarkupItReactRenderer
|
||||
value={value}
|
||||
syntax={markdownSyntax}
|
||||
getAsset={getAsset}
|
||||
/>
|
||||
);
|
||||
const component = shallow(<MarkupItReactRenderer value={value} />);
|
||||
expect(component.html()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('custom elements', () => {
|
||||
it('should extend default renderers with custom ones', () => {
|
||||
const myRule = MarkupIt.Rule('mediaproxy') // eslint-disable-line
|
||||
.regExp(reInline.link, (state, match) => {
|
||||
if (match[0].charAt(0) !== '!') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
data: Map({
|
||||
alt: match[1],
|
||||
src: match[2],
|
||||
title: match[3],
|
||||
}).filter(Boolean),
|
||||
};
|
||||
});
|
||||
|
||||
const myCustomSchema = {
|
||||
mediaproxy: ({ token }) => { //eslint-disable-line
|
||||
const src = token.getIn(['data', 'src']);
|
||||
const alt = token.getIn(['data', 'alt']);
|
||||
return <img src={src} alt={alt} />;
|
||||
},
|
||||
};
|
||||
|
||||
const myMarkdownSyntax = markdownSyntax.addInlineRules(myRule);
|
||||
const value = `
|
||||
## Title
|
||||
|
||||
![mediaproxy test](http://url.to.image)
|
||||
`;
|
||||
const component = shallow(
|
||||
<MarkupItReactRenderer
|
||||
value={value}
|
||||
syntax={myMarkdownSyntax}
|
||||
schema={myCustomSchema}
|
||||
getAsset={getAsset}
|
||||
/>
|
||||
);
|
||||
expect(component.html()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('HTML rendering', () => {
|
||||
it('should render HTML', () => {
|
||||
const value = '<p>Paragraph with <em>inline</em> element</p>';
|
||||
const component = shallow(
|
||||
<MarkupItReactRenderer
|
||||
value={value}
|
||||
syntax={htmlSyntax}
|
||||
getAsset={getAsset}
|
||||
/>
|
||||
);
|
||||
describe("HTML rendering", () => {
|
||||
it("should render HTML", () => {
|
||||
const value = "<p>Paragraph with <em>inline</em> element</p>";
|
||||
const component = shallow(<MarkupItReactRenderer value={value} />);
|
||||
expect(component.html()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
@ -1,15 +1,35 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`MarkitupReactRenderer HTML rendering should render HTML 1`] = `"<article><p>Paragraph with <em>inline</em> element</p></article>"`;
|
||||
exports[`MarkitupReactRenderer HTML rendering should render HTML 1`] = `"<div><p>Paragraph with <em>inline</em> element</p></div>"`;
|
||||
|
||||
exports[`MarkitupReactRenderer Markdown rendering Code should render code 1`] = `"<article><p>Use the <code>printf()</code> function.</p></article>"`;
|
||||
exports[`MarkitupReactRenderer Markdown rendering Code should render code 1`] = `"<div><p>Use the <code>printf()</code> function.</p></div>"`;
|
||||
|
||||
exports[`MarkitupReactRenderer Markdown rendering Code should render code 2 1`] = `"<article><p><code>There is a literal backtick (\`) here.</code></p></article>"`;
|
||||
exports[`MarkitupReactRenderer Markdown rendering Code should render code 2 1`] = `"<div><p><code>There is a literal backtick (\`) here.</code></p></div>"`;
|
||||
|
||||
exports[`MarkitupReactRenderer Markdown rendering General should render markdown 1`] = `"<article><h1>H1</h1><p>Text with <strong>bold</strong> & <em>em</em> elements</p><h2>H2</h2><ul><li>ul item 1</li><li>ul item 2</li></ul><h3>H3</h3><ol><li>ol item 1</li><li>ol item 2</li><li>ol item 3</li></ol><h4>H4</h4><p><a href=\\"http://google.com\\">link title</a></p><h5>H5</h5><p><img alt=\\"alt text\\" src=\\"https://pbs.twimg.com/profile_images/678903331176214528/TQTdqGwD.jpg\\"/></p><h6>H6</h6></article>"`;
|
||||
exports[`MarkitupReactRenderer Markdown rendering General should render markdown 1`] = `
|
||||
"<div><h1>H1</h1>
|
||||
<p>Text with <strong>bold</strong> & <em>em</em> elements</p>
|
||||
<h2>H2</h2>
|
||||
<ul>
|
||||
<li>ul item 1</li>
|
||||
<li>ul item 2</li>
|
||||
</ul>
|
||||
<h3>H3</h3>
|
||||
<ol>
|
||||
<li>ol item 1</li>
|
||||
<li>ol item 2</li>
|
||||
<li>ol item 3</li>
|
||||
</ol>
|
||||
<h4>H4</h4>
|
||||
<p><a href=\\"http://google.com\\">link title</a></p>
|
||||
<h5>H5</h5>
|
||||
<p><img src=\\"https://pbs.twimg.com/profile_images/678903331176214528/TQTdqGwD.jpg\\" alt=\\"alt text\\"></p>
|
||||
<h6>H6</h6></div>"
|
||||
`;
|
||||
|
||||
exports[`MarkitupReactRenderer Markdown rendering HTML should render HTML as is when using Markdown 1`] = `
|
||||
"<article><h1>Title</h1><div><form action=\\"test\\">
|
||||
"<div><h1>Title</h1>
|
||||
<form action=\\"test\\">
|
||||
<label for=\\"input\\">
|
||||
<input type=\\"checkbox\\" checked=\\"checked\\" id=\\"input\\"/> My label
|
||||
</label>
|
||||
@ -18,25 +38,41 @@ exports[`MarkitupReactRenderer Markdown rendering HTML should render HTML as is
|
||||
<dt>Testing HTML in Markdown</dt>
|
||||
</dl>
|
||||
</form>
|
||||
|
||||
</div><div><h1 style=\\"display: block; border: 10px solid #f00; width: 100%\\">Test</h1>
|
||||
</div></article>"
|
||||
<h1 style=\\"display: block; border: 10px solid #f00; width: 100%\\">Test</h1></div>"
|
||||
`;
|
||||
|
||||
exports[`MarkitupReactRenderer Markdown rendering Headings should render Heading 1 1`] = `"<article><h1>Title</h1></article>"`;
|
||||
exports[`MarkitupReactRenderer Markdown rendering Headings should render Heading 1 1`] = `"<div><h1>Title</h1></div>"`;
|
||||
|
||||
exports[`MarkitupReactRenderer Markdown rendering Headings should render Heading 2 1`] = `"<article><h2>Title</h2></article>"`;
|
||||
exports[`MarkitupReactRenderer Markdown rendering Headings should render Heading 2 1`] = `"<div><h2>Title</h2></div>"`;
|
||||
|
||||
exports[`MarkitupReactRenderer Markdown rendering Headings should render Heading 3 1`] = `"<article><h3>Title</h3></article>"`;
|
||||
exports[`MarkitupReactRenderer Markdown rendering Headings should render Heading 3 1`] = `"<div><h3>Title</h3></div>"`;
|
||||
|
||||
exports[`MarkitupReactRenderer Markdown rendering Headings should render Heading 4 1`] = `"<article><h4>Title</h4></article>"`;
|
||||
exports[`MarkitupReactRenderer Markdown rendering Headings should render Heading 4 1`] = `"<div><h4>Title</h4></div>"`;
|
||||
|
||||
exports[`MarkitupReactRenderer Markdown rendering Headings should render Heading 5 1`] = `"<article><h5>Title</h5></article>"`;
|
||||
exports[`MarkitupReactRenderer Markdown rendering Headings should render Heading 5 1`] = `"<div><h5>Title</h5></div>"`;
|
||||
|
||||
exports[`MarkitupReactRenderer Markdown rendering Headings should render Heading 6 1`] = `"<article><h6>Title</h6></article>"`;
|
||||
exports[`MarkitupReactRenderer Markdown rendering Headings should render Heading 6 1`] = `"<div><h6>Title</h6></div>"`;
|
||||
|
||||
exports[`MarkitupReactRenderer Markdown rendering Links should render links 1`] = `"<article><p>I get 10 times more traffic from <a href=\\"http://google.com/\\" title=\\"Google\\">Google</a> than from <a href=\\"http://search.yahoo.com/\\" title=\\"Yahoo Search\\">Yahoo</a> or <a href=\\"http://search.msn.com/\\" title=\\"MSN Search\\">MSN</a>.</p></article>"`;
|
||||
exports[`MarkitupReactRenderer Markdown rendering Links should render links 1`] = `"<div><p>I get 10 times more traffic from <a href=\\"http://google.com/\\" title=\\"Google\\">Google</a> than from <a href=\\"http://search.yahoo.com/\\" title=\\"Yahoo Search\\">Yahoo</a> or <a href=\\"http://search.msn.com/\\" title=\\"MSN Search\\">MSN</a>.</p></div>"`;
|
||||
|
||||
exports[`MarkitupReactRenderer Markdown rendering Lists should render lists 1`] = `"<article><ol><li>ol item 1</li><li>ol item 2<ul><li>Sublist 1</li><li>Sublist 2</li><li>Sublist 3<ol><li>Sub-Sublist 1</li><li>Sub-Sublist 2</li><li>Sub-Sublist 3</li></ol></li></ul></li><li>ol item 3</li></ol></article>"`;
|
||||
|
||||
exports[`MarkitupReactRenderer custom elements should extend default renderers with custom ones 1`] = `"<article><h2>Title</h2><p><img src=\\"http://url.to.image\\" alt=\\"mediaproxy test\\"/></p></article>"`;
|
||||
exports[`MarkitupReactRenderer Markdown rendering Lists should render lists 1`] = `
|
||||
"<div><ol>
|
||||
<li>ol item 1</li>
|
||||
<li>ol item 2</li>
|
||||
</ol>
|
||||
<ul>
|
||||
<li>Sublist 1</li>
|
||||
<li>Sublist 2</li>
|
||||
<li>
|
||||
<p>Sublist 3</p>
|
||||
<ol>
|
||||
<li>Sub-Sublist 1</li>
|
||||
<li>Sub-Sublist 2</li>
|
||||
<li>Sub-Sublist 3</li>
|
||||
</ol>
|
||||
</li>
|
||||
</ul>
|
||||
<ol>
|
||||
<li>ol item 3</li>
|
||||
</ol></div>"
|
||||
`;
|
||||
|
@ -1,130 +1,35 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
import MarkupIt, { Syntax, BLOCKS, STYLES, ENTITIES } from 'markup-it';
|
||||
import { omit } from 'lodash';
|
||||
import registry from '../../lib/registry';
|
||||
import React, { PropTypes } from "react";
|
||||
import Remark from "remark";
|
||||
import toHAST from "mdast-util-to-hast";
|
||||
import hastToHTML from "hast-util-to-html";
|
||||
import registry from "../../lib/registry";
|
||||
|
||||
const defaultSchema = {
|
||||
[BLOCKS.DOCUMENT]: 'article',
|
||||
[BLOCKS.TEXT]: null,
|
||||
[BLOCKS.CODE]: ({ token }) => {
|
||||
const className = token.getIn(['data', 'syntax']) && `language-${ token.getIn(['data', 'syntax']) }`;
|
||||
return <pre><code className={className} dangerouslySetInnerHTML={{ __html: token.get('tokens').map(token => token.text).join('') }} /></pre>;
|
||||
},
|
||||
[BLOCKS.BLOCKQUOTE]: 'blockquote',
|
||||
[BLOCKS.PARAGRAPH]: 'p',
|
||||
[BLOCKS.FOOTNOTE]: 'footnote',
|
||||
[BLOCKS.HTML]: ({ token }) => <div dangerouslySetInnerHTML={{ __html: token.get('raw') }} />,
|
||||
[BLOCKS.HR]: 'hr',
|
||||
[BLOCKS.HEADING_1]: 'h1',
|
||||
[BLOCKS.HEADING_2]: 'h2',
|
||||
[BLOCKS.HEADING_3]: 'h3',
|
||||
[BLOCKS.HEADING_4]: 'h4',
|
||||
[BLOCKS.HEADING_5]: 'h5',
|
||||
[BLOCKS.HEADING_6]: 'h6',
|
||||
[BLOCKS.TABLE]: 'table',
|
||||
[BLOCKS.TABLE_ROW]: 'tr',
|
||||
[BLOCKS.TABLE_CELL]: 'td',
|
||||
[BLOCKS.OL_LIST]: 'ol',
|
||||
[BLOCKS.UL_LIST]: 'ul',
|
||||
[BLOCKS.LIST_ITEM]: 'li',
|
||||
|
||||
[STYLES.TEXT]: null,
|
||||
[STYLES.BOLD]: 'strong',
|
||||
[STYLES.ITALIC]: 'em',
|
||||
[STYLES.CODE]: 'code',
|
||||
[STYLES.STRIKETHROUGH]: 'del',
|
||||
|
||||
[ENTITIES.LINK]: 'a',
|
||||
[ENTITIES.IMAGE]: 'img',
|
||||
[ENTITIES.FOOTNOTE_REF]: 'sup',
|
||||
[ENTITIES.HARD_BREAK]: 'br',
|
||||
};
|
||||
|
||||
const notAllowedAttributes = ['loose', 'image'];
|
||||
// Setup Remark.
|
||||
const remark = new Remark({
|
||||
commonmark: true,
|
||||
footnotes: true,
|
||||
pedantic: true,
|
||||
});
|
||||
|
||||
export default class MarkupItReactRenderer extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const { syntax } = props;
|
||||
this.parser = new MarkupIt(syntax);
|
||||
this.plugins = {};
|
||||
// TODO add back support for this.
|
||||
registry.getEditorComponents().forEach((component) => {
|
||||
this.plugins[component.get('id')] = component;
|
||||
this.plugins[component.get("id")] = component;
|
||||
});
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.syntax != this.props.syntax) {
|
||||
this.parser = new MarkupIt(nextProps.syntax);
|
||||
}
|
||||
}
|
||||
|
||||
sanitizeProps(props) {
|
||||
const { getAsset } = this.props;
|
||||
|
||||
if (props.image) {
|
||||
props = Object.assign({}, props, { src: getAsset(props.image).toString() });
|
||||
}
|
||||
|
||||
return omit(props, notAllowedAttributes);
|
||||
}
|
||||
|
||||
|
||||
renderToken(schema, token, index = 0, key = '0') {
|
||||
const type = token.get('type');
|
||||
const data = token.get('data');
|
||||
const text = token.get('text');
|
||||
const tokens = token.get('tokens');
|
||||
const nodeType = schema[type];
|
||||
key = `${ key }.${ index }`;
|
||||
|
||||
// Only render if type is registered as renderer
|
||||
if (typeof nodeType !== 'undefined') {
|
||||
let children = null;
|
||||
if (tokens.size) {
|
||||
children = tokens.map((token, idx) => this.renderToken(schema, token, idx, key));
|
||||
} else if (type === 'text') {
|
||||
children = text;
|
||||
}
|
||||
if (nodeType !== null) {
|
||||
let props = { key, token };
|
||||
if (typeof nodeType !== 'function') {
|
||||
props = { key, ...this.sanitizeProps(data.toJS()) };
|
||||
}
|
||||
// If this is a react element
|
||||
return React.createElement(nodeType, props, children);
|
||||
} else {
|
||||
// If this is a text node
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
const plugin = this.plugins[token.get('type')];
|
||||
if (plugin) {
|
||||
const output = plugin.toPreview(token.get('data').toJS());
|
||||
return typeof output === 'string' ?
|
||||
<span dangerouslySetInnerHTML={{ __html: output }} /> :
|
||||
output;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const { value, schema, getAsset } = this.props;
|
||||
const content = this.parser.toContent(value);
|
||||
return this.renderToken({ ...defaultSchema, ...schema }, content.get('token'));
|
||||
const { value } = this.props;
|
||||
const mast = remark.parse(value);
|
||||
const hast = toHAST(mast, { allowDangerousHTML: true });
|
||||
const html = hastToHTML(hast, { allowDangerousHTML: true });
|
||||
return <div dangerouslySetInnerHTML={{ __html: html }} />; // eslint-disable-line react/no-danger
|
||||
}
|
||||
}
|
||||
|
||||
MarkupItReactRenderer.propTypes = {
|
||||
value: PropTypes.string,
|
||||
syntax: PropTypes.instanceOf(Syntax).isRequired,
|
||||
schema: PropTypes.objectOf(PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.func,
|
||||
])),
|
||||
getAsset: PropTypes.func.isRequired,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user