Repository: nhn/tui.editor
Pull request #2104 (2021-12-09 12:22:21)

fix: editor fails to render content if table syntax is wrong
<!-- EDIT TITLE PLEASE -->
<!-- It should be one of them
  <ISSUE TYPE>: Short Description (<CLOSING TYPE> #<ISSUE NUMBERS>)
  ex)
  feat: add new feature (close #111)
  fix: wrong behavior (fix #111)
  chore: change build tool (ref #111)
-->

<!-- SPECIFY A ISSUE TYPE AT HEAD
  feat: A new feature
  fix: A bug fix
  docs: Documentation only changes
  style: Changes that do not affect the meaning of the code (white-space, formatting etc)
  refactor: A code change that neither fixes a bug or adds a feature
  perf: A code change that improves performance
  test: Adding missing tests
  chore: Changes to the build process or auxiliary tools and libraries such as documentation generation
-->

<!-- ADD CLOSING TYPE AND ISSUE NUMBER AT TAIL
  (<CLOSING TYPE> #<ISSUE NUMBERS>)
  close: resolve not a bug(feature, docs, etc) completely
  fix: resolve a bug completely
  ref: not fully resolved or related to
-->

### Please check if the PR fulfills these requirements
- [x] It's the right issue type on the title
- [ ] When resolving a specific issue, it's referenced in the PR's title (e.g. `fix #xxx[,#xxx]`, where "xxx" is the issue number)
- [x] The commit message follows our guidelines
- [x] Tests for the changes have been added (for bug fixes/features)
- [ ] Docs have been added/updated (for bug fixes/features)
- [ ] It does not introduce a breaking change or has a description of the breaking change

### Description
* related issue(#2050)


---
Thank you for your contribution to TOAST UI product. 🎉 😘 ✨



Patch:
diff --git a/apps/editor/src/convertors/toWysiwyg/toWwConvertors.ts b/apps/editor/src/convertors/toWysiwyg/toWwConvertors.ts
index 5cfdc38b..738eafa9 100644
--- a/apps/editor/src/convertors/toWysiwyg/toWwConvertors.ts
+++ b/apps/editor/src/convertors/toWysiwyg/toWwConvertors.ts
@@ -233,35 +233,40 @@ const toWwConvertors: ToWwConvertorMap = {
   },
 
   tableCell(state, node, { entering }) {
-    if (!(node as TableCellMdNode).ignored) {
-      const hasParaNode = (childNode: MdNode | null) =>
-        childNode && (isInlineNode(childNode) || isCustomHTMLInlineNode(state, childNode));
+    const { tableHeadCell, tableBodyCell, paragraph } = state.schema.nodes;
+    const tablePart = node.parent!.parent!;
+    const cell = tablePart.type === 'tableHead' ? tableHeadCell : tableBodyCell;
+    const hasParaNode = (childNode: MdNode | null) =>
+      childNode && (isInlineNode(childNode) || isCustomHTMLInlineNode(state, childNode));
 
-      if (entering) {
-        const { tableHeadCell, tableBodyCell, paragraph } = state.schema.nodes;
-        const tablePart = node.parent!.parent!;
-        const cell = tablePart.type === 'tableHead' ? tableHeadCell : tableBodyCell;
+    if (entering) {
+      let attrs: Record<string, string | number> | null = null;
 
+      if (!(node as TableCellMdNode).ignored) {
         const table = tablePart.parent as TableMdNode;
-        const { align } = table.columns[(node as TableCellMdNode).startIdx];
-        const attrs: Record<string, string | number> = { ...(node as TableCellMdNode).attrs };
+        const { startIdx } = node as TableCellMdNode;
 
-        if (align) {
-          attrs.align = align;
-        }
+        if (table.columns.length > startIdx) {
+          const { align } = table.columns[startIdx];
 
-        state.openNode(cell, attrs);
+          attrs = (node as TableCellMdNode).attrs ?? {};
 
-        if (hasParaNode(node.firstChild)) {
-          state.openNode(paragraph);
-        }
-      } else {
-        if (hasParaNode(node.lastChild)) {
-          state.closeNode();
+          if (align) {
+            attrs.align = align;
+          }
         }
+      }
 
+      state.openNode(cell, attrs);
+
+      if (hasParaNode(node.firstChild)) {
+        state.openNode(paragraph);
+      }
+    } else {
+      if (hasParaNode(node.lastChild)) {
         state.closeNode();
       }
+      state.closeNode();
     }
   },
 


Test patch:
diff --git a/apps/editor/src/__test__/unit/convertor.spec.ts b/apps/editor/src/__test__/unit/convertor.spec.ts
index f3060b17..58003af1 100644
--- a/apps/editor/src/__test__/unit/convertor.spec.ts
+++ b/apps/editor/src/__test__/unit/convertor.spec.ts
@@ -284,6 +284,21 @@ describe('Convertor', () => {
       assertConverting(markdown, `${expected}\n`);
     });
 
+    it('should normalize wrong table syntax when converting', () => {
+      const markdown = source`
+        | col1 | col2 | col3 |
+        | --- | --- |
+        | cell1 | cell2 | cell3 |
+      `;
+      const expected = source`
+        | col1 | col2 | col3 |
+        | ---- | ---- | ---- |
+        | cell1 | cell2 |  |
+      `;
+
+      assertConverting(markdown, `${expected}\n`);
+    });
+
     it('task', () => {
       const markdown = source`
         * [ ] foo
diff --git a/apps/editor/src/__test__/unit/wysiwyg/wwCommand.spec.ts b/apps/editor/src/__test__/unit/wysiwyg/wwCommand.spec.ts
index 016985cc..3766e8ca 100644
--- a/apps/editor/src/__test__/unit/wysiwyg/wwCommand.spec.ts
+++ b/apps/editor/src/__test__/unit/wysiwyg/wwCommand.spec.ts
@@ -92,7 +92,7 @@ describe('wysiwyg commands', () => {
       cmd.exec('selectAll');
       cmd.exec('heading', { level: 0 });
 
-      expect(wwe.getHTML()).toBe('foo');
+      expect(wwe.getHTML()).toBe('<p>foo</p>');
     });
   });