Просмотр исходного кода

Merge pull request #6738 from weseek/support/106321-refactor-hackmd-routing

support: 106321 refactor hackmd routing
yuken 3 лет назад
Родитель
Сommit
88544c4c6b

+ 2 - 0
packages/app/package.json

@@ -45,6 +45,7 @@
     "swagger-jsdoc": "swagger-jsdoc -o tmp/swagger.json -d config/swagger-definition.js",
     "openapi:v3": "yarn cross-env API_VERSION=3 yarn swagger-jsdoc -- \"src/server/routes/apiv3/**/*.js\" \"src/server/models/**/*.js\"",
     "openapi:v1": "yarn cross-env API_VERSION=1 yarn swagger-jsdoc -- \"src/server/*/*.js\" \"src/server/models/**/*.js\"",
+    "resources:hackmd": "yarn lerna run build --scope=@growi/hackmd",
     "resources:dummy": "true",
     "// resources:plugin": "yarn ts-node bin/generate-plugin-definitions-source.ts",
     "// resources:dl-resources": "yarn ts-node bin/download-cdn-resources.ts",
@@ -66,6 +67,7 @@
     "@google-cloud/storage": "^5.8.5",
     "@growi/codemirror-textlint": "^6.0.0-RC.1",
     "@growi/core": "^6.0.0-RC.1",
+    "@growi/hackmd": "^6.0.0-RC.1",
     "@growi/plugin-attachment-refs": "^6.0.0-RC.1",
     "@growi/plugin-lsx": "^6.0.0-RC.1",
     "@growi/slack": "^6.0.0-RC.1",

+ 0 - 152
packages/app/src/client/hackmd-agent.js

@@ -1,152 +0,0 @@
-/**
- * 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.');
-}());

+ 0 - 42
packages/app/src/client/hackmd-styles.js

@@ -1,42 +0,0 @@
-/**
- * GROWI styles loader 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-styles"></script>
- *
- * @author Yuki Takei <yuki@weseek.co.jp>
- */
-
-/* eslint-disable no-console  */
-
-const styles = '{{styles}}'; // will be replaced by swig
-
-/**
- * Insert link tag to load style file
- */
-function insertStyle() {
-  const element = document.createElement('style');
-  element.type = 'text/css';
-  element.appendChild(document.createTextNode(unescape(styles)));
-  document.getElementsByTagName('head')[0].appendChild(element);
-}
-
-/**
- * main
- */
-(function() {
-  // check HackMD is in iframe
-  if (window === window.parent) {
-    console.log('[GROWI] Loading styles for HackMD is not processed because currently not in iframe');
-    return;
-  }
-
-  console.log('[HackMD] Loading GROWI styles for HackMD...');
-
-  insertStyle();
-
-  console.log('[HackMD] GROWI styles for HackMD has successfully loaded.');
-}());

+ 11 - 27
packages/app/src/server/routes/hackmd.js

@@ -1,12 +1,16 @@
+import { stylesCSS, stylesJS, agentJS } from '@growi/hackmd';
+
 import loggerFactory from '~/utils/logger';
 
 /* eslint-disable no-use-before-define */
 
 const logger = loggerFactory('growi:routes:hackmd');
 const path = require('path');
+
+const axios = require('axios');
+const ejs = require('ejs');
 const fs = require('graceful-fs');
 const swig = require('swig-templates');
-const axios = require('axios');
 
 const ApiResponse = require('../util/apiResponse');
 
@@ -34,14 +38,6 @@ module.exports = function(crowi, app) {
   const Page = crowi.models.Page;
   const pageEvent = crowi.event('page');
 
-  // load GROWI agent script for HackMD
-  const manifest = require(path.join(crowi.publicDir, 'manifest.json'));
-  const agentScriptPath = path.join(crowi.publicDir, manifest['js/hackmd-agent.js']);
-  const stylesScriptPath = path.join(crowi.publicDir, manifest['js/hackmd-styles.js']);
-  // generate swig template
-  let agentScriptContentTpl;
-  let stylesScriptContentTpl;
-
   /**
    * GET /_hackmd/load-agent
    *
@@ -52,10 +48,6 @@ module.exports = function(crowi, app) {
    * @param {object} res
    */
   const loadAgent = function(req, res) {
-    // generate swig template
-    if (agentScriptContentTpl == null) {
-      agentScriptContentTpl = swig.compileFile(agentScriptPath);
-    }
 
     const origin = crowi.appService.getSiteUrl();
 
@@ -63,8 +55,9 @@ module.exports = function(crowi, app) {
     const definitions = {
       origin,
     };
-    // inject
-    const script = agentScriptContentTpl(definitions);
+
+    // inject origin to script
+    const script = ejs.render(agentJS, definitions);
 
     res.set('Content-Type', 'application/javascript');
     res.send(script);
@@ -80,22 +73,13 @@ module.exports = function(crowi, app) {
    * @param {object} res
    */
   const loadStyles = function(req, res) {
-    // generate swig template
-    if (stylesScriptContentTpl == null) {
-      stylesScriptContentTpl = swig.compileFile(stylesScriptPath);
-    }
-
-    const styleFilePath = path.join(crowi.publicDir, manifest['styles/style-hackmd.css']);
-    const styles = fs
-      .readFileSync(styleFilePath).toString()
-      .replace(/\s+/g, ' ');
 
     // generate definitions to replace
     const definitions = {
-      styles: escape(styles),
+      styles: stylesCSS,
     };
-    // inject
-    const script = stylesScriptContentTpl(definitions);
+    // inject styles to script
+    const script = ejs.render(stylesJS, definitions);
 
     res.set('Content-Type', 'application/javascript');
     res.send(script);

+ 6 - 8
packages/app/src/server/routes/index.js

@@ -48,8 +48,7 @@ module.exports = function(crowi, app) {
   const comment = require('./comment')(crowi, app);
   const tag = require('./tag')(crowi, app);
   const search = require('./search')(crowi, app);
-  // == TODO: Replace the code in hackmd.js getting the script path from manifest.json
-  // const hackmd = require('./hackmd')(crowi, app);
+  const hackmd = require('./hackmd')(crowi, app);
   const ogp = require('./ogp')(crowi);
 
   const next = nextFactory(crowi);
@@ -223,12 +222,11 @@ module.exports = function(crowi, app) {
   app.get('/trash/$'                  , loginRequired, (req, res) => res.redirect('/trash'));
   app.get('/trash/*/$'                , loginRequired, injectUserUISettings, page.deletedPageListShowWrapper);
 
-  // == TODO: Replace the code in hackmd.js getting the script path from manifest.json
-  // app.get('/_hackmd/load-agent'          , hackmd.loadAgent);
-  // app.get('/_hackmd/load-styles'         , hackmd.loadStyles);
-  // app.post('/_api/hackmd.integrate'      , accessTokenParser , loginRequiredStrictly , hackmd.validateForApi, hackmd.integrate);
-  // app.post('/_api/hackmd.discard'        , accessTokenParser , loginRequiredStrictly , hackmd.validateForApi, hackmd.discard);
-  // app.post('/_api/hackmd.saveOnHackmd'   , accessTokenParser , loginRequiredStrictly , hackmd.validateForApi, hackmd.saveOnHackmd);
+  app.get('/_hackmd/load-agent'          , hackmd.loadAgent);
+  app.get('/_hackmd/load-styles'         , hackmd.loadStyles);
+  app.post('/_api/hackmd.integrate'      , accessTokenParser , loginRequiredStrictly , hackmd.validateForApi, hackmd.integrate);
+  app.post('/_api/hackmd.discard'        , accessTokenParser , loginRequiredStrictly , hackmd.validateForApi, hackmd.discard);
+  app.post('/_api/hackmd.saveOnHackmd'   , accessTokenParser , loginRequiredStrictly , hackmd.validateForApi, hackmd.saveOnHackmd);
 
   app.use('/forgot-password', express.Router()
     .use(forgotPassword.checkForgotPasswordEnabledMiddlewareFactory(crowi))

+ 0 - 21
packages/app/src/styles-hackmd/style.scss

@@ -1,21 +0,0 @@
-.navbar-header {
-  .navbar-brand {
-    display: none;
-  }
-}
-
-.navbar-form {
-  margin-left: 15px;
-}
-
-.navbar-right {
-  .ui-new, .ui-publish {
-    display: none;
-  }
-}
-
-.CodeMirror pre.CodeMirror-line {
-  font-family: Osaka-Mono, 'MS Gothic', Monaco, Menlo, Consolas, 'Courier New', monospace;
-  font-size: 14px;
-  line-height: 20px;
-}

+ 1 - 1
packages/hackmd/src/hackmd-agent.js

@@ -16,7 +16,7 @@ const DEBUG_PENPAL = false;
 
 /* eslint-disable no-console  */
 
-const allowedOrigin = '{{origin}}'; // will be replaced by swig
+const allowedOrigin = '<%= origin %>'; // will be replaced by ejs
 
 
 /**

+ 1 - 1
packages/hackmd/src/hackmd-styles.js

@@ -12,7 +12,7 @@
 
 /* eslint-disable no-console  */
 
-const styles = '{{styles}}'; // will be replaced by swig
+const styles = '<%= styles %>'; // will be replaced by ejs
 
 /**
  * Insert link tag to load style file

+ 9 - 5
packages/hackmd/src/index.js

@@ -1,7 +1,11 @@
+const fs = require('fs');
+const path = require('path');
 
+const stylesJSFile = fs.readFileSync(path.resolve(__dirname, '../dist/assets/styles_bundle.js'));
+const agentJSFile = fs.readFileSync(path.resolve(__dirname, '../dist/assets/agent_bundle.js'));
+const stylesCSSFile = fs.readFileSync(path.resolve(__dirname, '../dist/assets/styles_bundle.css'));
 
-export * as styles from '../dist/assets/styles_bundle';
-
-export * as agent from '../dist/assets/agent_bundle';
-
-export * as stylesCSS from '../dist/assets/styles_bundle';
+// export to app as string
+export const stylesJS = stylesJSFile.toString();
+export const agentJS = agentJSFile.toString();
+export const stylesCSS = stylesCSSFile.toString();