HackmdEditor.jsx 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import Penpal from 'penpal';
  4. // Penpal.debug = true;
  5. export default class HackmdEditor extends React.PureComponent {
  6. constructor(props) {
  7. super(props);
  8. this.state = {
  9. };
  10. this.hackmd = null;
  11. this.initHackmdWithPenpal = this.initHackmdWithPenpal.bind(this);
  12. this.notifyBodyChangesHandler = this.notifyBodyChangesHandler.bind(this);
  13. this.saveWithShortcutHandler = this.saveWithShortcutHandler.bind(this);
  14. }
  15. componentDidMount() {
  16. // append iframe with penpal
  17. this.initHackmdWithPenpal();
  18. }
  19. initHackmdWithPenpal() {
  20. const _this = this; // for in methods scope
  21. const url = `${this.props.hackmdUri}/${this.props.pageIdOnHackmd}?both`;
  22. const connection = Penpal.connectToChild({
  23. url,
  24. appendTo: this.refs.iframeContainer,
  25. methods: { // expose methods to HackMD
  26. notifyBodyChanges(document) {
  27. _this.notifyBodyChangesHandler(document);
  28. },
  29. saveWithShortcut(document) {
  30. _this.saveWithShortcutHandler(document);
  31. }
  32. },
  33. });
  34. connection.promise.then(child => {
  35. this.hackmd = child;
  36. });
  37. connection.iframe.addEventListener('load', () => {
  38. if (this.props.initializationMarkdown != null) {
  39. this.setValue(this.props.initializationMarkdown);
  40. }
  41. });
  42. }
  43. /**
  44. * return markdown document of HackMD
  45. * @return {Promise<string>}
  46. */
  47. getValue() {
  48. return this.hackmd.getValue();
  49. }
  50. setValue(newValue) {
  51. this.hackmd.setValue(newValue);
  52. }
  53. notifyBodyChangesHandler(body) {
  54. // dispatch onChange()
  55. if (this.props.onChange != null) {
  56. this.props.onChange(body);
  57. }
  58. }
  59. saveWithShortcutHandler(document) {
  60. if (this.props.onSaveWithShortcut != null) {
  61. this.props.onSaveWithShortcut(document);
  62. }
  63. }
  64. render() {
  65. return (
  66. // will be rendered in componentDidMount
  67. <div id='iframe-hackmd-container' ref='iframeContainer'></div>
  68. );
  69. }
  70. }
  71. HackmdEditor.propTypes = {
  72. hackmdUri: PropTypes.string.isRequired,
  73. pageIdOnHackmd: PropTypes.string.isRequired,
  74. initializationMarkdown: PropTypes.string,
  75. onChange: PropTypes.func,
  76. onSaveWithShortcut: PropTypes.func,
  77. };