HackmdEditor.jsx 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. export default class HackmdEditor extends React.PureComponent {
  4. constructor(props) {
  5. super(props);
  6. this.state = {
  7. };
  8. this.listenMessages = this.listenMessages.bind(this);
  9. this.notifyBodyChangesHandler = this.notifyBodyChangesHandler.bind(this);
  10. this.loadHandler = this.loadHandler.bind(this);
  11. this.saveHandler = this.saveHandler.bind(this);
  12. }
  13. componentDidMount() {
  14. const contentWindow = this.refs.iframe.contentWindow;
  15. this.listenMessages(contentWindow);
  16. }
  17. setValue(newValue) {
  18. const data = { operation: 'setValue' };
  19. if (newValue != null) {
  20. data.document = newValue;
  21. }
  22. this.postMessageToHackmd(data);
  23. }
  24. /**
  25. *
  26. * @param {object} targetWindow
  27. */
  28. listenMessages(targetWindow) {
  29. window.addEventListener('message', (e) => {
  30. if (targetWindow !== e.source) {
  31. return;
  32. }
  33. const data = JSON.parse(e.data);
  34. const operation = data.operation;
  35. const body = data.body;
  36. switch (operation) {
  37. case 'notifyBodyChanges':
  38. this.notifyBodyChangesHandler(body);
  39. break;
  40. case 'save':
  41. this.saveHandler(body);
  42. break;
  43. }
  44. });
  45. }
  46. /**
  47. *
  48. * @param {object} data
  49. */
  50. postMessageToHackmd(data) {
  51. this.refs.iframe.contentWindow.postMessage(JSON.stringify(data), this.props.hackmdUri);
  52. }
  53. notifyBodyChangesHandler(body) {
  54. // dispatch onChange()
  55. if (this.props.onChange != null) {
  56. this.props.onChange(body);
  57. }
  58. }
  59. loadHandler() {
  60. this.setValue(this.props.initializationMarkdown);
  61. }
  62. saveHandler(document) {
  63. if (this.props.onSaveWithShortcut != null) {
  64. this.props.onSaveWithShortcut(document);
  65. }
  66. }
  67. render() {
  68. const src = `${this.props.hackmdUri}/${this.props.pageIdOnHackmd}?both`;
  69. return (
  70. <iframe id='iframe-hackmd'
  71. ref='iframe'
  72. src={src}
  73. onLoad={this.loadHandler}
  74. >
  75. </iframe>
  76. );
  77. }
  78. }
  79. HackmdEditor.propTypes = {
  80. hackmdUri: PropTypes.string.isRequired,
  81. pageIdOnHackmd: PropTypes.string.isRequired,
  82. initializationMarkdown: PropTypes.string,
  83. onChange: PropTypes.func,
  84. onSaveWithShortcut: PropTypes.func,
  85. };