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

Ensure to setup GrowiRenderer with originRenderer

* Plugins modify the main crowiRenderer, so GrowiRenderers that are generated later should inherit the settings of the main one
Yuki Takei 8 лет назад
Родитель
Сommit
95b7c9421b

+ 9 - 5
resource/js/app.js

@@ -64,10 +64,10 @@ if (isLoggedin) {
   crowi.fetchUsers();
 }
 
-const crowiRenderer = new GrowiRenderer(crowi, {
+const crowiRenderer = new GrowiRenderer(crowi, null, {
   mode: 'page',
-  // set function for rendering Table Of Contents
-  renderToc: crowi.getCrowiForJquery().renderTocContent,
+  isAutoSetup: false,                                     // manually setup because plugins may configure it
+  renderToc: crowi.getCrowiForJquery().renderTocContent,  // function for rendering Table Of Contents
 });
 window.crowiRenderer = crowiRenderer;
 
@@ -78,6 +78,9 @@ if (isEnabledPlugins) {
   crowiPlugin.installAll(crowi, crowiRenderer);
 }
 
+// configure renderer
+crowiRenderer.setup(crowi.config);
+
 /**
  * define components
  *  key: id of element
@@ -85,7 +88,7 @@ if (isEnabledPlugins) {
  */
 const componentMappings = {
   'search-top': <HeaderSearchBox crowi={crowi} />,
-  'search-page': <SearchPage crowi={crowi} />,
+  'search-page': <SearchPage crowi={crowi} crowiRenderer={crowiRenderer} />,
   'page-list-search': <PageListSearch crowi={crowi} />,
 
   //'revision-history': <PageHistory pageId={pageId} />,
@@ -139,7 +142,8 @@ if (pageEditorElem) {
   }
 
   pageEditor = ReactDOM.render(
-    <PageEditor crowi={crowi} pageId={pageId} revisionId={pageRevisionId} pagePath={pagePath}
+    <PageEditor crowi={crowi} crowiRenderer={crowiRenderer}
+        pageId={pageId} revisionId={pageRevisionId} pagePath={pagePath}
         markdown={markdown}
         editorOptions={editorOptions} previewOptions={previewOptions}
         onSaveSuccess={onSaveSuccess} />,

+ 2 - 1
resource/js/components/PageEditor.js

@@ -30,7 +30,7 @@ export default class PageEditor extends React.Component {
       previewOptions: this.props.previewOptions,
     };
 
-    this.growiRenderer = new GrowiRenderer(this.props.crowi, {mode: 'editor'});
+    this.growiRenderer = new GrowiRenderer(this.props.crowi, this.props.crowiRenderer, {mode: 'editor'});
 
     this.setCaretLine = this.setCaretLine.bind(this);
     this.focusToEditor = this.focusToEditor.bind(this);
@@ -325,6 +325,7 @@ export default class PageEditor extends React.Component {
 
 PageEditor.propTypes = {
   crowi: PropTypes.object.isRequired,
+  crowiRenderer: PropTypes.object.isRequired,
   markdown: PropTypes.string.isRequired,
   pageId: PropTypes.string,
   revisionId: PropTypes.string,

+ 2 - 1
resource/js/components/SearchPage.js

@@ -101,10 +101,10 @@ export default class SearchPage extends React.Component {
         </div>
 
         <SearchResult
+          crowi={this.props.crowi}  crowiRenderer={this.props.crowiRenderer}
           pages={this.state.searchedPages}
           searchingKeyword={this.state.searchingKeyword}
           searchResultMeta={this.state.searchResultMeta}
-          crowi={this.props.crowi}
           />
       </div>
     );
@@ -114,6 +114,7 @@ export default class SearchPage extends React.Component {
 SearchPage.propTypes = {
   query: PropTypes.object,
   crowi: PropTypes.object.isRequired,
+  crowiRenderer: PropTypes.object.isRequired,
 };
 SearchPage.defaultProps = {
   //pollInterval: 1000,

+ 2 - 1
resource/js/components/SearchPage/SearchResultList.js

@@ -10,7 +10,7 @@ export default class SearchResultList extends React.Component {
   constructor(props) {
     super(props);
 
-    this.growiRenderer = new GrowiRenderer(this.props.crowi, {mode: 'searchresult'});
+    this.growiRenderer = new GrowiRenderer(this.props.crowi, this.props.crowiRenderer, {mode: 'searchresult'});
   }
 
   render() {
@@ -42,6 +42,7 @@ export default class SearchResultList extends React.Component {
 
 SearchResultList.propTypes = {
   crowi: PropTypes.object.isRequired,
+  crowiRenderer: PropTypes.object.isRequired,
   pages: PropTypes.array.isRequired,
   searchingKeyword: PropTypes.string.isRequired,
 };

+ 1 - 1
resource/js/legacy/crowi.js

@@ -426,7 +426,7 @@ $(function() {
     var isShown = $('#view-timeline').data('shown');
 
     if (growiRendererForTimeline == null) {
-      growiRendererForTimeline = new GrowiRenderer(crowi, {mode: 'timeline'});
+      growiRendererForTimeline = new GrowiRenderer(crowi, crowiRenderer, {mode: 'timeline'});
     }
 
     if (isShown == 0) {

+ 62 - 42
resource/js/util/GrowiRenderer.js

@@ -18,37 +18,58 @@ import TocAndAnchorConfigurer from './markdown-it/toc-and-anchor';
 
 export default class GrowiRenderer {
 
-
-  constructor(crowi, option) {
+  /**
+   *
+   * @param {Crowi} crowi
+   * @param {GrowiRenderer} originRenderer may be customized by plugins
+   * @param {object} options
+   */
+  constructor(crowi, originRenderer, options) {
     this.crowi = crowi;
-
-    this.preProcessors = [
+    this.originRenderer = originRenderer || {};
+    this.options = Object.assign( // merge options
+      { isAutoSetup: true },      // default options
+      options || {});             // specified options
+
+    // initialize processors
+    //  that will be retrieved if originRenderer exists
+    this.preProcessors = this.originRenderer.preProcessors || [
       new Linker(crowi),
       new CsvToTable(crowi),
       new XssFilter(crowi),
     ];
-    this.postProcessors = [
+    this.postProcessors = this.originRenderer.postProcessors || [
     ];
 
-    this.langProcessors = {
+    this.langProcessors = this.originRenderer.langProcessors || {
       'template': new Template(crowi),
     };
 
-    this.configure = this.configure.bind(this);
-    this.configureMarkdownIt = this.configureMarkdownIt.bind(this);
+    this.initMarkdownItConfigurers = this.initMarkdownItConfigurers.bind(this);
+    this.setup = this.setup.bind(this);
     this.process = this.process.bind(this);
     this.codeRenderer = this.codeRenderer.bind(this);
 
-    this.md = new MarkdownIt();
-    this.configure(this.crowi.getConfig());
-    this.configureMarkdownIt(option);
+    // init markdown-it
+    this.md = new MarkdownIt({
+      html: true,
+      linkify: true,
+      highlight: this.codeRenderer,
+    });
+    this.initMarkdownItConfigurers(options);
 
+    // auto setup
+    if (this.options.isAutoSetup) {
+      this.setup(crowi.getConfig());
+    }
   }
 
-  configureMarkdownIt(option) {
+  initMarkdownItConfigurers(options) {
     const crowi = this.crowi;
 
-    let configurers = [
+    this.isMarkdownItConfigured = false;
+
+    this.markdownItConfigurers = [
       new CommonPluginsConfigurer(crowi),
       new HeaderConfigurer(crowi),
       new TableConfigurer(crowi),
@@ -57,43 +78,41 @@ export default class GrowiRenderer {
       new PlantUMLConfigurer(crowi),
     ];
 
-    if (option != null) {
-      const mode = option.mode;
-      switch (mode) {
-        case 'page':
-          configurers = configurers.concat([
-            new TocAndAnchorConfigurer(crowi, option.renderToc),
-            new HeaderLineNumberConfigurer(crowi),
-          ]);
-          break;
-        case 'editor':
-          configurers = configurers.concat([
-            new HeaderLineNumberConfigurer(crowi)
-          ]);
-          break;
-        case 'timeline':
-          break;
-        case 'searchresult':
-          break;
-      }
+    // add configurers according to mode
+    const mode = options.mode;
+    switch (mode) {
+      case 'page':
+        this.markdownItConfigurers = this.markdownItConfigurers.concat([
+          new TocAndAnchorConfigurer(crowi, options.renderToc),
+          new HeaderLineNumberConfigurer(crowi),
+        ]);
+        break;
+      case 'editor':
+        this.markdownItConfigurers = this.markdownItConfigurers.concat([
+          new HeaderLineNumberConfigurer(crowi)
+        ]);
+        break;
+      case 'timeline':
+        break;
+      case 'searchresult':
+        break;
     }
-
-    configurers.forEach((configurer) => {
-      configurer.configure(this.md);
-    });
   }
 
   /**
-   * configure with crowi config
-   * @param {any} config
+   * setup with crowi config
+   * @param {any} config crowi config
    */
-  configure(config) {
+  setup(config) {
     this.md.set({
-      html: true,
-      linkify: true,
       breaks: config.isEnabledLineBreaks,
-      highlight: this.codeRenderer,
     });
+
+    if (!this.isMarkdownItConfigured) {
+      this.markdownItConfigurers.forEach((configurer) => {
+        configurer.configure(this.md);
+      });
+    }
   }
 
   preProcess(markdown) {
@@ -103,6 +122,7 @@ export default class GrowiRenderer {
       }
       markdown = this.preProcessors[i].process(markdown);
     }
+
     return markdown;
   }