HackmdEditor.jsx 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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. setValue(newValue) {
  44. this.hackmd.setValue(newValue);
  45. }
  46. notifyBodyChangesHandler(body) {
  47. // dispatch onChange()
  48. if (this.props.onChange != null) {
  49. this.props.onChange(body);
  50. }
  51. }
  52. saveWithShortcutHandler(document) {
  53. if (this.props.onSaveWithShortcut != null) {
  54. this.props.onSaveWithShortcut(document);
  55. }
  56. }
  57. render() {
  58. return (
  59. // will be rendered in componentDidMount
  60. <div id='iframe-hackmd-container' ref='iframeContainer'></div>
  61. );
  62. }
  63. }
  64. HackmdEditor.propTypes = {
  65. hackmdUri: PropTypes.string.isRequired,
  66. pageIdOnHackmd: PropTypes.string.isRequired,
  67. initializationMarkdown: PropTypes.string,
  68. onChange: PropTypes.func,
  69. onSaveWithShortcut: PropTypes.func,
  70. };