PageEditor.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import Editor from './PageEditor/Editor';
  4. import Preview from './PageEditor/Preview';
  5. export default class PageEditor extends React.Component {
  6. constructor(props) {
  7. super(props);
  8. this.state = {
  9. markdown: this.props.markdown,
  10. };
  11. // initial preview
  12. this.renderPreview();
  13. this.onMarkdownChanged = this.onMarkdownChanged.bind(this);
  14. }
  15. /**
  16. * the change event handler for `markdown` state
  17. * @param {string} value
  18. */
  19. onMarkdownChanged(value) {
  20. this.setState({
  21. markdown: value,
  22. html: '',
  23. });
  24. this.renderPreview();
  25. }
  26. renderPreview() {
  27. const config = this.props.crowi.config;
  28. // generate options obj
  29. const rendererOptions = {
  30. // see: https://www.npmjs.com/package/marked
  31. marked: {
  32. breaks: config.isEnabledLineBreaks,
  33. }
  34. };
  35. // render html
  36. var context = {
  37. markdown: this.state.markdown,
  38. dom: this.previewElement,
  39. currentPagePath: decodeURIComponent(location.pathname)
  40. };
  41. this.props.crowi.interceptorManager.process('preRenderPreview', context)
  42. .then(() => crowi.interceptorManager.process('prePreProcess', context))
  43. .then(() => {
  44. context.markdown = crowiRenderer.preProcess(context.markdown, context.dom);
  45. })
  46. .then(() => crowi.interceptorManager.process('postPreProcess', context))
  47. .then(() => {
  48. var parsedHTML = crowiRenderer.render(context.markdown, context.dom, rendererOptions);
  49. context['parsedHTML'] = parsedHTML;
  50. })
  51. .then(() => crowi.interceptorManager.process('postRenderPreview', context))
  52. .then(() => crowi.interceptorManager.process('preRenderPreviewHtml', context))
  53. .then(() => {
  54. this.setState({html: context.parsedHTML});
  55. // set html to the hidden input (for submitting to save)
  56. $('#form-body').val(this.state.markdown);
  57. })
  58. // process interceptors for post rendering
  59. .then(() => crowi.interceptorManager.process('postRenderPreviewHtml', context));
  60. }
  61. render() {
  62. return (
  63. <div className="row">
  64. <div className="col-md-6 col-sm-12 page-editor-editor-container">
  65. <Editor value={this.state.markdown} onChange={this.onMarkdownChanged} />
  66. </div>
  67. <div className="col-md-6 hidden-sm hidden-xs page-editor-preview-container">
  68. <Preview html={this.state.html} inputRef={el => this.previewElement = el} />
  69. </div>
  70. </div>
  71. )
  72. }
  73. }
  74. PageEditor.propTypes = {
  75. crowi: PropTypes.object.isRequired,
  76. markdown: PropTypes.string,
  77. };