agent-for-hackmd.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /**
  2. * GROWI agent for HackMD
  3. *
  4. * This file will be transpiled as a single JS
  5. * and should be load from HackMD head via 'lib/routes/hackmd.js' route
  6. *
  7. * USAGE:
  8. * <script src="${hostname of GROWI}/_hackmd/load-agent"></script>
  9. *
  10. * @author Yuki Takei <yuki@weseek.co.jp>
  11. */
  12. import { debounce } from 'throttle-debounce';
  13. const JSON = window.JSON;
  14. /* eslint-disable no-console */
  15. const allowedOrigin = '{{origin}}'; // will be replaced by swig
  16. const styleFilePath = '{{styleFilePath}}'; // will be replaced by swig
  17. /**
  18. * Validate origin
  19. * @param {object} event
  20. */
  21. function validateOrigin(event) {
  22. if (event.origin !== allowedOrigin) {
  23. console.error('[HackMD] Message is rejected.', 'Cause: "event.origin" and "allowedOrigin" does not match');
  24. return;
  25. }
  26. }
  27. /**
  28. * Insert link tag to load style file
  29. */
  30. function insertStyle() {
  31. const element = document.createElement('link');
  32. element.href = styleFilePath;
  33. element.rel = 'stylesheet';
  34. document.getElementsByTagName('head')[0].appendChild(element);
  35. }
  36. function postMessageOnSave(body) {
  37. const data = {
  38. operation: 'notifyBodyChanges',
  39. body
  40. };
  41. window.parent.postMessage(JSON.stringify(data), allowedOrigin);
  42. }
  43. function addEventListenersToCodemirror() {
  44. // get CodeMirror instance
  45. const editor = window.editor;
  46. // generate debounced function
  47. const debouncedFunc = debounce(1500, postMessageOnSave);
  48. editor.on('change', (cm, change) => {
  49. debouncedFunc(cm.doc.getValue());
  50. });
  51. }
  52. function setValue(document) {
  53. // get CodeMirror instance
  54. const editor = window.editor;
  55. editor.doc.setValue(document);
  56. }
  57. /**
  58. * main
  59. */
  60. (function() {
  61. // check HackMD is in iframe
  62. if (window === window.parent) {
  63. console.log('[GROWI] Loading agent for HackMD is not processed because currently not in iframe');
  64. return;
  65. }
  66. console.log('[HackMD] Loading GROWI agent for HackMD...');
  67. insertStyle();
  68. // Add event listeners
  69. window.addEventListener('message', (event) => {
  70. validateOrigin(event);
  71. const data = JSON.parse(event.data);
  72. switch (data.operation) {
  73. case 'getValue':
  74. console.log('getValue called');
  75. break;
  76. case 'setValue':
  77. setValue(data.document);
  78. break;
  79. }
  80. });
  81. window.addEventListener('load', (event) => {
  82. console.log('loaded');
  83. addEventListenersToCodemirror();
  84. });
  85. console.log('[HackMD] GROWI agent for HackMD has successfully loaded.');
  86. }());