Quellcode durchsuchen

Merge pull request #3314 from weseek/imprv/enable-auto-formatting-of-tables

Optionalizing feature of formatting Markdown tables
Yuki Takei vor 5 Jahren
Ursprung
Commit
f37fe2870e

+ 1 - 0
resource/locales/en_US/translation.json

@@ -308,6 +308,7 @@
   },
   "page_edit": {
     "Show active line": "Show active line",
+    "auto_format_table": "Auto format table",
     "overwrite_scopes": "{{operation}} and Overwrite scopes of all descendants",
     "notice": {
       "conflict": "Couldn't save the changes you made because someone else was editing this page. Please re-edit the affected section after reloading the page."

+ 1 - 0
resource/locales/ja_JP/translation.json

@@ -310,6 +310,7 @@
   },
   "page_edit": {
     "Show active line": "アクティブ行をハイライト",
+    "auto_format_table": "表の自動整形",
     "overwrite_scopes": "{{operation}}と同時に全ての配下ページのスコープを上書き",
     "notice": {
       "conflict": "すでに他の人がこのページを編集していたため保存できませんでした。ページを再読み込み後、自分の編集箇所のみ再度編集してください。"

+ 1 - 0
resource/locales/zh_CN/translation.json

@@ -286,6 +286,7 @@
 	},
 	"page_edit": {
 		"Show active line": "显示活动行",
+		"auto_format_table": "自动格式化表格",
 		"overwrite_scopes": "{{operation}和覆盖所有子体的作用域",
 		"notice": {
 			"conflict": "无法保存您所做的更改,因为其他人正在编辑此页。请在重新加载页面后重新编辑受影响的部分。"

+ 2 - 0
src/client/js/components/PageEditor/CodeMirrorEditor.jsx

@@ -441,6 +441,7 @@ export default class CodeMirrorEditor extends AbstractEditor {
     const context = {
       handlers: [], // list of handlers which process enter key
       editor: this,
+      editorOptions: this.props.editorOptions,
     };
 
     const interceptorManager = this.interceptorManager;
@@ -898,6 +899,7 @@ export default class CodeMirrorEditor extends AbstractEditor {
         <HandsontableModal
           ref={this.handsontableModal}
           onSave={(table) => { return mtu.replaceFocusedMarkdownTableWithEditor(this.getCodeMirror(), table) }}
+          ignoreAutoFormatting={this.props.editorOptions.ignoreMarkdownTableAutoFormatting}
         />
         <DrawioModal
           ref={this.drawioModal}

+ 9 - 1
src/client/js/components/PageEditor/HandsontableModal.jsx

@@ -158,7 +158,7 @@ export default class HandsontableModal extends React.PureComponent {
   save() {
     const markdownTable = new MarkdownTable(
       this.hotTable.hotInstance.getData(),
-      { align: [].concat(this.state.markdownTable.options.align) },
+      this.markdownTableOption,
     ).normalizeCells();
 
     if (this.props.onSave != null) {
@@ -398,6 +398,13 @@ export default class HandsontableModal extends React.PureComponent {
     }
   }
 
+  get markdownTableOption() {
+    return {
+      align: [].concat(this.state.markdownTable.options.align),
+      pad: this.props.ignoreAutoFormatting !== true,
+    };
+  }
+
   renderCloseButton() {
     return (
       <button type="button" className="close" onClick={this.cancel} aria-label="Close">
@@ -504,4 +511,5 @@ export default class HandsontableModal extends React.PureComponent {
 
 HandsontableModal.propTypes = {
   onSave: PropTypes.func,
+  ignoreAutoFormatting: PropTypes.bool,
 };

+ 4 - 2
src/client/js/components/PageEditor/MarkdownTableInterceptor.js

@@ -56,9 +56,11 @@ export default class MarkdownTableInterceptor extends BasicInterceptor {
   async process(contextName, ...args) {
     const context = Object.assign(args[0]); // clone
     const editor = context.editor; // AbstractEditor instance
+    // "ignoreMarkdownTableAutoFormatting" may be undefined, so it is compared to true and converted to bool.
+    const noIntercept = (context.editorOptions.ignoreMarkdownTableAutoFormatting === true);
 
-    // do nothing if editor is not a CodeMirrorEditor
-    if (editor == null || editor.getCodeMirror() == null) {
+    // do nothing if editor is not a CodeMirrorEditor or no intercept
+    if (editor == null || editor.getCodeMirror() == null || noIntercept) {
       return context;
     }
 

+ 35 - 0
src/client/js/components/PageEditor/OptionsSelector.jsx

@@ -49,6 +49,7 @@ class OptionsSelector extends React.Component {
     this.onChangeKeymapMode = this.onChangeKeymapMode.bind(this);
     this.onClickStyleActiveLine = this.onClickStyleActiveLine.bind(this);
     this.onClickRenderMathJaxInRealtime = this.onClickRenderMathJaxInRealtime.bind(this);
+    this.onClickMarkdownTableAutoFormatting = this.onClickMarkdownTableAutoFormatting.bind(this);
     this.onToggleConfigurationDropdown = this.onToggleConfigurationDropdown.bind(this);
   }
 
@@ -97,6 +98,17 @@ class OptionsSelector extends React.Component {
     editorContainer.saveOptsToLocalStorage();
   }
 
+  onClickMarkdownTableAutoFormatting(event) {
+    const { editorContainer } = this.props;
+
+    const newValue = !editorContainer.state.editorOptions.ignoreMarkdownTableAutoFormatting;
+    const newOpts = Object.assign(editorContainer.state.editorOptions, { ignoreMarkdownTableAutoFormatting: newValue });
+    editorContainer.setState({ editorOptions: newOpts });
+
+    // save to localStorage
+    editorContainer.saveOptsToLocalStorage();
+  }
+
   onToggleConfigurationDropdown(newValue) {
     this.setState({ isCddMenuOpened: !this.state.isCddMenuOpened });
   }
@@ -187,6 +199,7 @@ class OptionsSelector extends React.Component {
           <DropdownMenu>
             {this.renderActiveLineMenuItem()}
             {this.renderRealtimeMathJaxMenuItem()}
+            {this.renderMarkdownTableAutoFormattingMenuItem()}
             {/* <DropdownItem divider /> */}
           </DropdownMenu>
 
@@ -244,6 +257,28 @@ class OptionsSelector extends React.Component {
     );
   }
 
+  renderMarkdownTableAutoFormattingMenuItem() {
+    const { t, editorContainer } = this.props;
+    // Auto-formatting was enabled before optionalizing, so we made it a disabled option(ignoreMarkdownTableAutoFormatting).
+    const isActive = !editorContainer.state.editorOptions.ignoreMarkdownTableAutoFormatting;
+
+    const iconClasses = ['text-info'];
+    if (isActive) {
+      iconClasses.push('ti-check');
+    }
+    const iconClassName = iconClasses.join(' ');
+
+    return (
+      <DropdownItem toggle={false} onClick={this.onClickMarkdownTableAutoFormatting}>
+        <div className="d-flex justify-content-between">
+          <span className="icon-container"></span>
+          <span className="menuitem-label">{ t('page_edit.auto_format_table') }</span>
+          <span className="icon-container"><i className={iconClassName}></i></span>
+        </div>
+      </DropdownItem>
+    );
+  }
+
   render() {
     return (
       <div className="d-flex flex-row">