Repository: nhn/tui.editor
Pull request #2622 (2022-07-26 10:15:33)

feat: add api for converting position to match editor mode
<!-- 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)
- [x] 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

* Added API for converting position to match editor mode

---
Thank you for your contribution to TOAST UI product. 🎉 😘 ✨



Patch:
diff --git a/apps/editor/src/editorCore.ts b/apps/editor/src/editorCore.ts
index 85e5ad1e..2b025790 100644
--- a/apps/editor/src/editorCore.ts
+++ b/apps/editor/src/editorCore.ts
@@ -43,6 +43,8 @@ import { sanitizeHTML } from './sanitizer/htmlSanitizer';
 import { createHTMLSchemaMap } from './wysiwyg/nodes/html';
 import { getHTMLRenderConvertors } from './markdown/htmlRenderConvertors';
 import { buildQuery } from './queries/queryManager';
+import { getEditorToMdPos, getMdToEditorPos } from './markdown/helper/pos';
+import { Pos } from '@t/toastmark';
 
 /**
  * ToastUIEditorCore
@@ -820,6 +822,33 @@ class ToastUIEditorCore {
       wwEditor: this.wwEditor.getElement(),
     };
   }
+
+  /**
+   * Convert position to match editor mode
+   * @param {number|Array.<number>} start - start position
+   * @param {number|Array.<number>} end - end position
+   * @param {string} mode - Editor mode name of want to match converted position to
+   */
+  convertPosToMatchEditorMode(start: EditorPos, end = start, mode = this.mode) {
+    const { doc } = this.mdEditor.view.state;
+    const isFromArray = Array.isArray(start);
+    const isToArray = Array.isArray(end);
+
+    let convertedFrom = start;
+    let convertedTo = end;
+
+    if (isFromArray !== isToArray) {
+      throw new Error('Types of arguments must be same');
+    }
+
+    if (mode === 'markdown' && !isFromArray && !isToArray) {
+      [convertedFrom, convertedTo] = getEditorToMdPos(doc, start as number, end as number);
+    } else if (mode === 'wysiwyg' && isFromArray && isToArray) {
+      [convertedFrom, convertedTo] = getMdToEditorPos(doc, start as Pos, end as Pos);
+    }
+
+    return [convertedFrom, convertedTo];
+  }
 }
 
 // // (Not an official API)


Test patch:
diff --git a/apps/editor/src/__test__/unit/editor.spec.ts b/apps/editor/src/__test__/unit/editor.spec.ts
index a33a9d1f..b6deace1 100644
--- a/apps/editor/src/__test__/unit/editor.spec.ts
+++ b/apps/editor/src/__test__/unit/editor.spec.ts
@@ -61,6 +61,27 @@ describe('editor', () => {
       document.body.removeChild(container);
     });
 
+    describe('convertPosToMatchEditorMode', () => {
+      const mdPos: [number, number] = [2, 1];
+      const wwPos = 14;
+
+      it('should convert position to match editor mode', () => {
+        editor.setMarkdown('Hello World\nwelcome to the world');
+
+        editor.changeMode('wysiwyg');
+        expect(editor.convertPosToMatchEditorMode(mdPos)).toEqual([wwPos, wwPos]);
+
+        editor.changeMode('markdown');
+        expect(editor.convertPosToMatchEditorMode(wwPos)).toEqual([mdPos, mdPos]);
+      });
+
+      it('should occurs error when types of parameters is not matched', () => {
+        expect(() => {
+          editor.convertPosToMatchEditorMode(mdPos, wwPos);
+        }).toThrowError();
+      });
+    });
+
     it('setPlaceholder()', () => {
       editor.setPlaceholder('Please input text');