UNPKG

@readme/markdown

Version:

ReadMe's React-based Markdown parser

70 lines (56 loc) 1.68 kB
/* eslint-disable no-eval */ const escape = require('lodash.escape'); const PropTypes = require('prop-types'); const React = require('react'); const MATCH_SCRIPT_TAGS = /<script\b[^>]*>([\s\S]*?)<\/script *>\n?/gim; const extractScripts = (html = '') => { const scripts = []; let match; while ((match = MATCH_SCRIPT_TAGS.exec(html)) !== null) { scripts.push(match[1]); } const cleaned = html.replace(MATCH_SCRIPT_TAGS, ''); return [cleaned, () => scripts.map(js => window.eval(js))]; }; class HTMLBlock extends React.PureComponent { constructor(props) { super(props); [this.html, this.exec] = extractScripts(this.props.html); } componentDidMount() { const { runScripts } = this.props; if (typeof window !== 'undefined' && (runScripts === '' || runScripts)) this.exec(); } render() { const { html, safeMode } = this.props; if (safeMode) { return ( <pre className="html-unsafe"> <code dangerouslySetInnerHTML={{ __html: escape(html) }} /> </pre> ); } return <div className="rdmd-html" dangerouslySetInnerHTML={{ __html: this.html }} />; } } HTMLBlock.defaultProps = { runScripts: false, safeMode: false, }; HTMLBlock.propTypes = { html: PropTypes.string, runScripts: PropTypes.any, safeMode: PropTypes.bool, }; const CreateHtmlBlock = ({ safeMode }) => // eslint-disable-next-line react/display-name props => <HTMLBlock {...props} safeMode={safeMode} />; CreateHtmlBlock.sanitize = schema => { schema.tagNames.push('html-block'); schema.attributes['html-block'] = ['html', 'runScripts']; return schema; }; module.exports = CreateHtmlBlock;