|
|
@@ -0,0 +1,152 @@
|
|
|
+/**
|
|
|
+ * GROWI agent for HackMD
|
|
|
+ *
|
|
|
+ * This file will be transpiled as a single JS
|
|
|
+ * and should be load from HackMD head via 'routes/hackmd.js' route
|
|
|
+ *
|
|
|
+ * USAGE:
|
|
|
+ * <script src="${hostname of GROWI}/_hackmd/load-agent"></script>
|
|
|
+ *
|
|
|
+ * @author Yuki Takei <yuki@weseek.co.jp>
|
|
|
+ */
|
|
|
+import connectToParent from 'penpal/lib/connectToParent';
|
|
|
+import { debounce } from 'throttle-debounce';
|
|
|
+
|
|
|
+const DEBUG_PENPAL = false;
|
|
|
+
|
|
|
+/* eslint-disable no-console */
|
|
|
+
|
|
|
+const allowedOrigin = '{{origin}}'; // will be replaced by swig
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * return the value of CodeMirror
|
|
|
+ */
|
|
|
+function getValueOfCodemirror() {
|
|
|
+ // get CodeMirror instance
|
|
|
+ const editor = window.editor;
|
|
|
+ return editor.doc.getValue();
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * set the specified document to CodeMirror
|
|
|
+ * @param {string} value
|
|
|
+ */
|
|
|
+function setValueToCodemirror(value) {
|
|
|
+ // get CodeMirror instance
|
|
|
+ const editor = window.editor;
|
|
|
+ editor.doc.setValue(value);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * set the specified document to CodeMirror on window loaded
|
|
|
+ * @param {string} value
|
|
|
+ */
|
|
|
+function setValueToCodemirrorOnInit(newValue) {
|
|
|
+ if (window.cmClient != null) {
|
|
|
+ setValueToCodemirror(newValue);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const intervalId = setInterval(() => {
|
|
|
+ if (window.cmClient != null) {
|
|
|
+ clearInterval(intervalId);
|
|
|
+ setValueToCodemirror(newValue);
|
|
|
+ }
|
|
|
+ }, 250);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * postMessage to GROWI to notify body changes
|
|
|
+ * @param {string} body
|
|
|
+ */
|
|
|
+function postParentToNotifyBodyChanges(body) {
|
|
|
+ window.growi.notifyBodyChanges(body);
|
|
|
+}
|
|
|
+// generate debounced function
|
|
|
+const debouncedPostParentToNotifyBodyChanges = debounce(800, postParentToNotifyBodyChanges);
|
|
|
+
|
|
|
+/**
|
|
|
+ * postMessage to GROWI to save with shortcut
|
|
|
+ * @param {string} document
|
|
|
+ */
|
|
|
+function postParentToSaveWithShortcut(document) {
|
|
|
+ window.growi.saveWithShortcut(document);
|
|
|
+}
|
|
|
+
|
|
|
+function addEventListenersToCodemirror() {
|
|
|
+ // get CodeMirror instance
|
|
|
+ const codemirror = window.CodeMirror;
|
|
|
+ // get CodeMirror editor instance
|
|
|
+ const editor = window.editor;
|
|
|
+
|
|
|
+ // e.g. 404 not found
|
|
|
+ if (codemirror == null || editor == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // == change event
|
|
|
+ editor.on('change', (cm, change) => {
|
|
|
+ if (change.origin === 'ignoreHistory') {
|
|
|
+ // do nothing because this operation triggered by other user
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ debouncedPostParentToNotifyBodyChanges(cm.doc.getValue());
|
|
|
+ });
|
|
|
+
|
|
|
+ // == save event
|
|
|
+ // Reset save commands and Cmd-S/Ctrl-S shortcuts that initialized by HackMD
|
|
|
+ codemirror.commands.save = function(cm) {
|
|
|
+ postParentToSaveWithShortcut(cm.doc.getValue());
|
|
|
+ };
|
|
|
+ delete editor.options.extraKeys['Cmd-S'];
|
|
|
+ delete editor.options.extraKeys['Ctrl-S'];
|
|
|
+}
|
|
|
+
|
|
|
+function connectToParentWithPenpal() {
|
|
|
+ const connection = connectToParent({
|
|
|
+ parentOrigin: allowedOrigin,
|
|
|
+ // Methods child is exposing to parent
|
|
|
+ methods: {
|
|
|
+ getValue() {
|
|
|
+ return getValueOfCodemirror();
|
|
|
+ },
|
|
|
+ setValue(newValue) {
|
|
|
+ setValueToCodemirror(newValue);
|
|
|
+ },
|
|
|
+ setValueOnInit(newValue) {
|
|
|
+ setValueToCodemirrorOnInit(newValue);
|
|
|
+ },
|
|
|
+ },
|
|
|
+ debug: DEBUG_PENPAL,
|
|
|
+ });
|
|
|
+ connection.promise
|
|
|
+ .then((parent) => {
|
|
|
+ window.growi = parent;
|
|
|
+ })
|
|
|
+ .catch((err) => {
|
|
|
+ console.log(err);
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * main
|
|
|
+ */
|
|
|
+(function() {
|
|
|
+ // check HackMD is in iframe
|
|
|
+ if (window === window.parent) {
|
|
|
+ console.log('[GROWI] Loading agent for HackMD is not processed because currently not in iframe');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('[HackMD] Loading GROWI agent for HackMD...');
|
|
|
+
|
|
|
+ window.addEventListener('load', () => {
|
|
|
+ addEventListenersToCodemirror();
|
|
|
+ });
|
|
|
+
|
|
|
+ connectToParentWithPenpal();
|
|
|
+
|
|
|
+ console.log('[HackMD] GROWI agent for HackMD has successfully loaded.');
|
|
|
+}());
|