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

modify LsxPreProcessor to LsxPreRenderInterceptor

* use LsxContext and don't sotre context to sessionStorage
Yuki Takei 9 лет назад
Родитель
Сommit
aac1e17c28

+ 4 - 7
packages/growi-plugin-lsx/src/client-entry.js

@@ -1,16 +1,13 @@
-import { LsxPreProcessor } from './resource/js/util/PreProcessor/LsxPreProcessor';
+import { LsxPreRenderInterceptor } from './resource/js/util/Interceptor/LsxPreRenderInterceptor';
 import { LsxPostRenderInterceptor } from './resource/js/util/Interceptor/LsxPostRenderInterceptor';
 
 export default (crowi, crowiRenderer) => {
   // import css
   require('./resource/css/index.css');
 
-  // add preprocessor
-  crowiRenderer.preProcessors = crowiRenderer.preProcessors.concat([
-    new LsxPreProcessor(crowi),
-  ]);
-  // add interceptor
+  // add interceptors
   crowi.interceptorManager.addInterceptors([
-    new LsxPostRenderInterceptor(crowi)
+    new LsxPreRenderInterceptor(crowi),
+    new LsxPostRenderInterceptor(crowi),
   ]);
 }

+ 14 - 18
packages/growi-plugin-lsx/src/resource/js/util/Interceptor/LsxPostRenderInterceptor.js

@@ -4,13 +4,12 @@ import ReactDOM from 'react-dom';
 import BasicInterceptor from '../../../../lib/util/BasicInterceptor';
 
 import { Lsx } from '../../components/Lsx';
-import { LsxLoadingContext } from '../LsxLoadingContext';
+import { LsxContext } from '../LsxContext';
 
 /**
  * The interceptor for lsx
  *
- *  replace lsx tag to HTML codes
- *  when contextName is 'postRenderPreview' and '...' <- TODO
+ *  render React DOM
  */
 export class LsxPostRenderInterceptor extends BasicInterceptor {
 
@@ -33,37 +32,34 @@ export class LsxPostRenderInterceptor extends BasicInterceptor {
    * @inheritdoc
    */
   process(contextName, ...args) {
+    const context = Object.assign(args[0]);   // clone
+
     let contexts = JSON.parse(sessionStorage.getItem('lsx-loading-contexts')) || {};
 
     let keysToBeRemoved = [];
 
     // forEach keys of contexts
-    Object.keys(contexts).forEach((key) => {
-      const elem = document.getElementById(key);
+    Object.keys(context.lsxContextMap).forEach((renderId) => {
+      const elem = document.getElementById(renderId);
 
       if (elem) {
-        const contextObj = contexts[key]
-        // remove from context regardless of rendering success or failure
-        delete contexts[key];
+        // get LsxContext
+        const lsxContext = context.lsxContextMap[renderId];
         // render
-        this.renderReactDOM(contextObj, elem);
+        this.renderReactDOM(lsxContext, elem);
       }
     });
 
-    // store contexts to sessionStorage
-    sessionStorage.setItem('lsx-loading-contexts', JSON.stringify(contexts));
-
     return Promise.resolve();
   }
 
-  renderReactDOM(contextObj, elem) {
-    const context = new LsxLoadingContext(contextObj);
+  renderReactDOM(lsxContext, elem) {
     ReactDOM.render(
       <Lsx crowi={this.crowi}
-          currentPagePath={context.currentPagePath}
-          tagExpression={context.tagExpression}
-          fromPagePath={context.fromPagePath}
-          lsxArgs={context.lsxArgs} />,
+          currentPagePath={lsxContext.currentPagePath}
+          tagExpression={lsxContext.tagExpression}
+          fromPagePath={lsxContext.fromPagePath}
+          lsxArgs={lsxContext.lsxArgs} />,
       elem
     );
   }

+ 99 - 0
packages/growi-plugin-lsx/src/resource/js/util/Interceptor/LsxPreRenderInterceptor.js

@@ -0,0 +1,99 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+
+import BasicInterceptor from '../../../../lib/util/BasicInterceptor';
+
+import { Lsx } from '../../components/Lsx';
+import { LsxContext } from '../LsxContext';
+
+/**
+ * The interceptor for lsx
+ *
+ *  replace lsx tag to a React target element
+ */
+export class LsxPreRenderInterceptor extends BasicInterceptor {
+
+  constructor(crowi) {
+    super();
+    this.crowi = crowi;
+    this.crowiForJquery = crowi.getCrowiForJquery();
+  }
+
+  /**
+   * @inheritdoc
+   */
+  isInterceptWhen(contextName) {
+    return (
+      contextName === 'preRender' ||
+      contextName === 'preRenderPreview'
+    );
+  }
+
+  /**
+   * @inheritdoc
+   */
+  process(contextName, ...args) {
+    const context = Object.assign(args[0]);   // clone
+    const markdown = context.markdown;
+    const parsedHTML = context.parsedHTML;
+    const currentPagePath = context.currentPagePath;
+
+    context.lsxContextMap = {};
+
+    // TODO retrieve from args for interceptor
+    const fromPagePath = currentPagePath;
+
+    // see: https://regex101.com/r/NQq3s9/2
+    context.parsedHTML = parsedHTML.replace(/\$lsx\((.*)\)/g, (all, group1) => {
+      const tagExpression = all;
+      const lsxArgs = group1.trim();
+
+      // create contexts
+      let lsxContext = new LsxContext();
+      lsxContext.currentPagePath = currentPagePath;
+      lsxContext.tagExpression = tagExpression;
+      lsxContext.fromPagePath = fromPagePath;
+      lsxContext.lsxArgs = lsxArgs;
+
+      // get cache container obj from sessionStorage
+      // let lsxCache = JSON.parse(sessionStorage.getItem('lsx-cache'));
+      // if (lsxCache) {
+      //   lsxCache = Object.create(LsxCache, lsxCache);
+      //   const cache = lsxCache.getItem(tagExpression);
+      //   // check cache exists
+      //   if (cache) {
+      //     return cache;
+      //   }
+      // }
+
+      const renderId = 'lsx-' + this.createRandomStr(8);
+      lsxContext.renderId = renderId;
+
+      context.lsxContextMap[renderId] = lsxContext;
+
+      // return replace strings
+      return this.createReactTargetDom(renderId, tagExpression);
+    });
+
+    // resolve
+    return Promise.resolve(context);
+  }
+
+  createReactTargetDom(renderId, tagExpression) {
+    return `<div id="${renderId}" />`;
+  }
+
+  /**
+   * @see http://qiita.com/ryounagaoka/items/4736c225bdd86a74d59c
+   * @param {number} length
+   * @return random strings
+   */
+  createRandomStr(length) {
+    const bag = "abcdefghijklmnopqrstuvwxyz0123456789";
+    let generated = "";
+    for (var i = 0; i < length; i++) {
+      generated += bag[Math.floor(Math.random() * bag.length)];
+    }
+    return generated;
+  }
+}

+ 0 - 16
packages/growi-plugin-lsx/src/resource/js/util/LsxCache.js

@@ -1,16 +0,0 @@
-/**
- * for storing cache to sessionStorage
- */
-export class LsxCache {
-
-  cache = {};
-
-  getItem(tagExpression) {
-    return cache[tagExpression];
-  }
-
-  setItem(tagExpression, html) {
-    cache[tagExpression] = html;
-  }
-
-}

+ 21 - 0
packages/growi-plugin-lsx/src/resource/js/util/LsxContext.js

@@ -0,0 +1,21 @@
+export class LsxContext {
+
+  renderId;
+  isCache;
+  currentPagePath;
+  tagExpression;
+  fromPagePath;
+  lsxArgs;
+  html;
+
+  static fronJson(json) {
+    let context = Object.create(LsxContext, JSON.parse(json));
+    context.isCache = true;
+
+    return contest;
+  }
+
+  generateCacheKey() {
+    return `${this.fromPagePath}__${this.lsxArgs}`;
+  }
+}

+ 0 - 18
packages/growi-plugin-lsx/src/resource/js/util/LsxLoadingContext.js

@@ -1,18 +0,0 @@
-/**
- * for storing loading context to sessionStorage
- */
-export class LsxLoadingContext {
-
-  currentPagePath;
-  tagExpression;
-  fromPagePath;
-  lsxArgs;
-
-  constructor(obj) {
-    this.currentPagePath = obj.currentPagePath;
-    this.tagExpression = obj.tagExpression;
-    this.fromPagePath = obj.fromPagePath;
-    this.lsxArgs = obj.lsxArgs;
-  }
-
-}

+ 0 - 63
packages/growi-plugin-lsx/src/resource/js/util/PreProcessor/LsxPreProcessor.js

@@ -1,63 +0,0 @@
-import { LsxCache } from '../LsxCache';
-import { LsxLoadingContext } from '../LsxLoadingContext';
-
-// TODO change to PreInterceptor
-export class LsxPreProcessor {
-
-  constructor(crowi) {
-    this.crowi = crowi;
-    this.crowiForJquery = crowi.getCrowiForJquery();
-  }
-
-  process(markdown) {
-    // get current path from window.location
-    const currentPagePath = window.location.pathname;
-    // TODO retrieve from args for interceptor
-    const fromPagePath = currentPagePath;
-
-    return markdown
-      // see: https://regex101.com/r/NQq3s9/2
-      .replace(/\$lsx\((.*)\)/g, (all, group1) => {
-        const tagExpression = all;
-        const lsxArgs = group1.trim();
-
-        // get cache container obj from sessionStorage
-        let lsxCache = JSON.parse(sessionStorage.getItem('lsx-cache'));
-        if (lsxCache) {
-          lsxCache = Object.create(LsxCache, lsxCache);
-          const cache = lsxCache.getItem(tagExpression);
-          // check cache exists
-          if (cache) {
-            return cache;
-          }
-        }
-
-        const renderId = 'lsx-' + this.createRandomStr(8);
-
-        // store contexts
-        let contexts = JSON.parse(sessionStorage.getItem('lsx-loading-contexts')) || {};
-        contexts[renderId] = new LsxLoadingContext({currentPagePath, tagExpression, fromPagePath, lsxArgs});
-        sessionStorage.setItem('lsx-loading-contexts', JSON.stringify(contexts));
-
-        return this.createReactTargetDom(renderId, tagExpression);
-      });
-  }
-
-  createReactTargetDom(renderId, tagExpression) {
-    return `<div id="${renderId}" />`;
-  }
-
-  /**
-   * @see http://qiita.com/ryounagaoka/items/4736c225bdd86a74d59c
-   * @param {number} length
-   * @return random strings
-   */
-  createRandomStr(length) {
-    const bag = "abcdefghijklmnopqrstuvwxyz0123456789";
-    let generated = "";
-    for (var i = 0; i < length; i++) {
-      generated += bag[Math.floor(Math.random() * bag.length)];
-    }
-    return generated;
-  }
-}