From 65c4983a2721729d36e1986d05b17ad30ab87e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8C=80=EC=97=B0?= Date: Fri, 5 Aug 2022 15:40:49 +0900 Subject: [PATCH] env: update prosemirror versions (fix #2631) (#2648) * env: update prosemirror versions * chore: fix types according to prosemirror updates * chore: remove something added to DOM by prosemirror * test: fix tests following prosemirror updates * chore: fix type errors * chore: apply code reviews test: fix failing tests chore: implement method that was not chore: remove unused utility function * chore: change npm ci to npm install in ci test workflows --- .github/workflows/plugin-test.yml | 2 +- .github/workflows/test.yml | 2 +- apps/editor/package.json | 15 +- .../integration/widget/widgetNode.spec.ts | 196 +++++++----------- .../__test__/unit/markdown/mdEditor.spec.ts | 4 +- .../__test__/unit/wysiwyg/wwEditor.spec.ts | 4 +- .../toMarkdown/toMdConvertorState.ts | 2 +- .../toWysiwyg/toWwConvertorState.ts | 8 +- apps/editor/src/editorCore.ts | 4 +- apps/editor/src/markdown/marks/blockQuote.ts | 4 +- apps/editor/src/markdown/marks/code.ts | 4 +- apps/editor/src/markdown/marks/codeBlock.ts | 4 +- apps/editor/src/markdown/marks/customBlock.ts | 4 +- apps/editor/src/markdown/marks/emph.ts | 4 +- apps/editor/src/markdown/marks/heading.ts | 4 +- apps/editor/src/markdown/marks/html.ts | 4 +- apps/editor/src/markdown/marks/link.ts | 4 +- apps/editor/src/markdown/marks/listItem.ts | 4 +- apps/editor/src/markdown/marks/simpleMark.ts | 12 +- apps/editor/src/markdown/marks/strike.ts | 4 +- apps/editor/src/markdown/marks/strong.ts | 4 +- apps/editor/src/markdown/marks/table.ts | 4 +- .../src/markdown/marks/thematicBreak.ts | 4 +- apps/editor/src/markdown/mdPreview.ts | 10 +- apps/editor/src/markdown/nodes/paragraph.ts | 6 +- apps/editor/src/utils/dom.ts | 12 ++ apps/editor/src/widget/widgetNode.ts | 4 +- .../src/wysiwyg/adaptor/wwToDOMAdaptor.ts | 2 +- apps/editor/src/wysiwyg/command/list.ts | 8 +- apps/editor/src/wysiwyg/helper/node.ts | 2 +- apps/editor/src/wysiwyg/marks/code.ts | 4 +- apps/editor/src/wysiwyg/marks/emph.ts | 4 +- apps/editor/src/wysiwyg/marks/link.ts | 7 +- apps/editor/src/wysiwyg/marks/strike.ts | 4 +- apps/editor/src/wysiwyg/marks/strong.ts | 4 +- apps/editor/src/wysiwyg/nodes/blockQuote.ts | 4 +- apps/editor/src/wysiwyg/nodes/bulletList.ts | 4 +- apps/editor/src/wysiwyg/nodes/codeBlock.ts | 6 +- apps/editor/src/wysiwyg/nodes/customBlock.ts | 4 +- apps/editor/src/wysiwyg/nodes/frontMatter.ts | 4 +- apps/editor/src/wysiwyg/nodes/heading.ts | 4 +- apps/editor/src/wysiwyg/nodes/html.ts | 8 +- apps/editor/src/wysiwyg/nodes/htmlComment.ts | 4 +- apps/editor/src/wysiwyg/nodes/image.ts | 4 +- apps/editor/src/wysiwyg/nodes/listItem.ts | 4 +- apps/editor/src/wysiwyg/nodes/orderedList.ts | 4 +- apps/editor/src/wysiwyg/nodes/paragraph.ts | 4 +- apps/editor/src/wysiwyg/nodes/table.ts | 4 +- apps/editor/src/wysiwyg/nodes/tableBody.ts | 4 +- .../editor/src/wysiwyg/nodes/tableBodyCell.ts | 4 +- apps/editor/src/wysiwyg/nodes/tableHead.ts | 4 +- .../editor/src/wysiwyg/nodes/tableHeadCell.ts | 4 +- apps/editor/src/wysiwyg/nodes/tableRow.ts | 4 +- .../editor/src/wysiwyg/nodes/thematicBreak.ts | 4 +- .../src/wysiwyg/nodeview/codeBlockView.ts | 4 +- .../src/wysiwyg/nodeview/customBlockView.ts | 2 +- .../plugins/selection/cellSelection.ts | 5 + .../src/wysiwyg/plugins/toolbarState.ts | 2 +- apps/editor/src/wysiwyg/wwEditor.ts | 8 +- apps/editor/types/convertor.d.ts | 2 +- apps/editor/types/prosemirror-commands.d.ts | 15 ++ apps/editor/types/prosemirror-model.d.ts | 11 +- package-lock.json | 146 +++++++------ .../src/nodeViews/codeSyntaxHighlightView.ts | 2 +- .../integration/colorSyntaxPlugin.spec.ts | 5 +- plugins/color-syntax/src/utils/dom.ts | 12 ++ .../integration/wysiwyg/addRow.spec.ts | 20 +- .../wysiwyg/helper/cellSelection.ts | 5 + .../integration/wysiwyg/helper/utils.ts | 15 +- 69 files changed, 360 insertions(+), 344 deletions(-) create mode 100644 apps/editor/types/prosemirror-commands.d.ts diff --git a/.github/workflows/plugin-test.yml b/.github/workflows/plugin-test.yml index 44af6b718b..5695d64208 100644 --- a/.github/workflows/plugin-test.yml +++ b/.github/workflows/plugin-test.yml @@ -13,7 +13,7 @@ jobs: node-version: '15.x' - name: Install run: | - npm ci + npm install - name: build toastmark run: | npm run build toastmark diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b7dd036a4f..23551d23e3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,7 @@ jobs: node-version: '15.x' - name: Install run: | - npm ci + npm install - name: build toastmark run: | npm run build toastmark diff --git a/apps/editor/package.json b/apps/editor/package.json index 769feac50a..fed6b52ca5 100644 --- a/apps/editor/package.json +++ b/apps/editor/package.json @@ -83,13 +83,12 @@ }, "dependencies": { "dompurify": "^2.3.3", - "prosemirror-commands": "~1.1.9", - "prosemirror-history": "~1.1.3", - "prosemirror-inputrules": "~1.1.3", - "prosemirror-keymap": "~1.1.4", - "prosemirror-model": "~1.14.1", - "prosemirror-state": "~1.3.4", - "prosemirror-view": "~1.18.7", - "prosemirror-transform": "~1.3.0" + "prosemirror-commands": "^1.1.9", + "prosemirror-history": "^1.1.3", + "prosemirror-inputrules": "^1.1.3", + "prosemirror-keymap": "^1.1.4", + "prosemirror-model": "^1.14.1", + "prosemirror-state": "^1.3.4", + "prosemirror-view": "^1.18.7" } } diff --git a/apps/editor/src/__test__/integration/widget/widgetNode.spec.ts b/apps/editor/src/__test__/integration/widget/widgetNode.spec.ts index 5fdc9c6490..bb6db2c81b 100644 --- a/apps/editor/src/__test__/integration/widget/widgetNode.spec.ts +++ b/apps/editor/src/__test__/integration/widget/widgetNode.spec.ts @@ -92,17 +92,14 @@ describe('widgetNode', () => { editor.setMarkdown('@test1 @test2'); const expectedEditor = oneLineTrim` -
- - @test1 - - - - @test2 - + + @test1 + + + + @test2 -
-
+ `; const expectedPreview = oneLineTrim`

@@ -125,17 +122,14 @@ describe('widgetNode', () => { editor.insertText('@test1 @test2'); const expectedEditor = oneLineTrim` -

- - @test1 - - - - @test2 - + + @test1 + + + + @test2 -
-
+ `; const expectedPreview = oneLineTrim`

@@ -158,12 +152,9 @@ describe('widgetNode', () => { editor.replaceWithWidget([1, 1], [1, 1], '[#toast](ui.toast.com)'); const expectedEditor = oneLineTrim` -

- - #toast - -
-
+ + #toast + `; const expectedPreview = oneLineTrim`

@@ -181,20 +172,17 @@ describe('widgetNode', () => { editor.insertText('@test1 [#toast](ui.toast.com) @test2'); const expectedEditor = oneLineTrim` -

- - @test1 - - - #toast - - - - @test2 - + + @test1 + + + #toast + + + + @test2 -
-
+ `; const expectedPreview = oneLineTrim`

@@ -221,17 +209,14 @@ describe('widgetNode', () => { editor.changeMode('wysiwyg'); const expectedEditor = oneLineTrim` -

- - @test1 - - - - @test2 - + + @test1 + + + + @test2 -
-

+ `; expect(wwEditor).toContainHTML(expectedEditor); @@ -241,18 +226,15 @@ describe('widgetNode', () => { editor.setMarkdown('@test1 $$myText @test2'); const expectedEditor = oneLineTrim` -
- - @test1 - - $$myText - - - @test2 - + + @test1 + + $$myText + + + @test2 -
-
+ `; const expectedPreview = oneLineTrim`

@@ -278,19 +260,16 @@ describe('widgetNode', () => { editor.replaceSelection('@test1 @test2', [1, 1], [1, 13]); const expectedEditor = oneLineTrim` -

- - - @test1 - - - - - @test2 - + + + @test1 -
-
+ + + + @test2 + + `; const expectedPreview = oneLineTrim`

@@ -329,12 +308,9 @@ describe('widgetNode', () => { editor.replaceWithWidget(1, 1, '@test'); const expectedEditor = oneLineTrim` -

- - @test - -
-

+ + @test + `; expect(wwEditor).toContainHTML(expectedEditor); @@ -345,12 +321,9 @@ describe('widgetNode', () => { editor.replaceWithWidget(1, 1, '[#toast](ui.toast.com)'); const expectedEditor = oneLineTrim` -

- - #toast - -
-

+ + #toast + `; expect(wwEditor).toContainHTML(expectedEditor); @@ -362,17 +335,14 @@ describe('widgetNode', () => { editor.changeMode('markdown'); const expectedEditor = oneLineTrim` -
- - @test1 - - - - @test2 - + + @test1 + + + + @test2 -
-
+ `; const expectedPreview = oneLineTrim`

@@ -398,19 +368,16 @@ describe('widgetNode', () => { editor.replaceSelection('@test1 @test2', 1, 12); const expectedEditor = oneLineTrim` -

- - - @test1 - - - - - @test2 - + + + @test1 -
-

+ + + + @test2 + + `; expect(wwEditor).toContainHTML(expectedEditor); @@ -422,17 +389,14 @@ describe('widgetNode', () => { editor.insertText('@test1 @test2'); const expectedEditor = oneLineTrim` -

- - @test1 - - - - @test2 - + + @test1 + + + + @test2 -
-

+ `; expect(wwEditor).toContainHTML(expectedEditor); diff --git a/apps/editor/src/__test__/unit/markdown/mdEditor.spec.ts b/apps/editor/src/__test__/unit/markdown/mdEditor.spec.ts index 8e6a9c1401..341693e2d0 100644 --- a/apps/editor/src/__test__/unit/markdown/mdEditor.spec.ts +++ b/apps/editor/src/__test__/unit/markdown/mdEditor.spec.ts @@ -79,8 +79,8 @@ describe('MarkdownEditor', () => { it('setPlaceholder API', () => { mde.setPlaceholder('Write something'); - expect(getEditorHTML(mde)).toBe( - '
Write something
' + expect(getEditorHTML(mde)).toContain( + 'Write something' ); }); diff --git a/apps/editor/src/__test__/unit/wysiwyg/wwEditor.spec.ts b/apps/editor/src/__test__/unit/wysiwyg/wwEditor.spec.ts index 724e6ec623..8b2e5fc341 100644 --- a/apps/editor/src/__test__/unit/wysiwyg/wwEditor.spec.ts +++ b/apps/editor/src/__test__/unit/wysiwyg/wwEditor.spec.ts @@ -86,10 +86,8 @@ describe('WysiwygEditor', () => { wwe.setPlaceholder('placeholder text'); assertToContainHTML(oneLineTrim` -

+ placeholder text -
-

`); }); diff --git a/apps/editor/src/convertors/toMarkdown/toMdConvertorState.ts b/apps/editor/src/convertors/toMarkdown/toMdConvertorState.ts index b402f79753..86fd701a05 100644 --- a/apps/editor/src/convertors/toMarkdown/toMdConvertorState.ts +++ b/apps/editor/src/convertors/toMarkdown/toMdConvertorState.ts @@ -175,7 +175,7 @@ export default class ToMdConvertorState { let trailing = ''; const progress = (node: Node | null, _: number | null, index: number) => { - let marks = node ? node.marks : []; + let marks = node ? (node.marks as Mark[]) : []; let leading = trailing; trailing = ''; diff --git a/apps/editor/src/convertors/toWysiwyg/toWwConvertorState.ts b/apps/editor/src/convertors/toWysiwyg/toWwConvertorState.ts index 40df958045..e529c77651 100644 --- a/apps/editor/src/convertors/toWysiwyg/toWwConvertorState.ts +++ b/apps/editor/src/convertors/toWysiwyg/toWwConvertorState.ts @@ -28,7 +28,7 @@ export default class ToWwConvertorState { this.schema = schema; this.convertors = convertors; this.stack = [{ type: this.schema.topNodeType, attrs: null, content: [] }]; - this.marks = Mark.none; + this.marks = Mark.none as Mark[]; } top() { @@ -57,11 +57,11 @@ export default class ToWwConvertorState { } openMark(mark: Mark) { - this.marks = mark.addToSet(this.marks); + this.marks = mark.addToSet(this.marks) as Mark[]; } closeMark(mark: MarkType) { - this.marks = mark.removeFromSet(this.marks); + this.marks = mark.removeFromSet(this.marks) as Mark[]; } addNode(type: NodeType, attrs: Attrs, content: Node[]) { @@ -82,7 +82,7 @@ export default class ToWwConvertorState { closeNode() { if (this.marks.length) { - this.marks = Mark.none; + this.marks = Mark.none as Mark[]; } const { type, attrs, content } = this.stack.pop() as StackItem; diff --git a/apps/editor/src/editorCore.ts b/apps/editor/src/editorCore.ts index cb2c7b9d50..1973c87994 100644 --- a/apps/editor/src/editorCore.ts +++ b/apps/editor/src/editorCore.ts @@ -38,7 +38,7 @@ import { WwToDOMAdaptor } from './wysiwyg/adaptor/wwToDOMAdaptor'; import { ScrollSync } from './markdown/scroll/scrollSync'; import { addDefaultImageBlobHook } from './helper/image'; import { setWidgetRules } from './widget/rules'; -import { cls, replaceBRWithEmptyBlock } from './utils/dom'; +import { cls, removeProseMirrorHackNodes, replaceBRWithEmptyBlock } from './utils/dom'; import { sanitizeHTML } from './sanitizer/htmlSanitizer'; import { createHTMLSchemaMap } from './wysiwyg/nodes/html'; import { getHTMLRenderConvertors } from './markdown/htmlRenderConvertors'; @@ -506,7 +506,7 @@ class ToastUIEditorCore { this.wwEditor.setModel(wwNode!); } }); - const html = this.wwEditor.view.dom.innerHTML; + const html = removeProseMirrorHackNodes(this.wwEditor.view.dom.innerHTML); if (this.placeholder) { const rePlaceholder = new RegExp( diff --git a/apps/editor/src/markdown/marks/blockQuote.ts b/apps/editor/src/markdown/marks/blockQuote.ts index e453508b2c..5cf689802c 100644 --- a/apps/editor/src/markdown/marks/blockQuote.ts +++ b/apps/editor/src/markdown/marks/blockQuote.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray } from 'prosemirror-model'; +import { DOMOutputSpec } from 'prosemirror-model'; import { Command } from 'prosemirror-commands'; import { EditorCommand } from '@t/spec'; import { clsWithMdPrefix } from '@/utils/dom'; @@ -21,7 +21,7 @@ export class BlockQuote extends Mark { get schema() { return { - toDOM(): DOMOutputSpecArray { + toDOM(): DOMOutputSpec { return ['span', { class: clsWithMdPrefix('block-quote') }, 0]; }, }; diff --git a/apps/editor/src/markdown/marks/code.ts b/apps/editor/src/markdown/marks/code.ts index 88840d534c..455112cb5e 100644 --- a/apps/editor/src/markdown/marks/code.ts +++ b/apps/editor/src/markdown/marks/code.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray, Mark as ProsemirrorMark } from 'prosemirror-model'; +import { DOMOutputSpec, Mark as ProsemirrorMark } from 'prosemirror-model'; import { EditorCommand } from '@t/spec'; import { clsWithMdPrefix } from '@/utils/dom'; import Mark from '@/spec/mark'; @@ -19,7 +19,7 @@ export class Code extends Mark { end: { default: false }, marked: { default: false }, }, - toDOM(mark: ProsemirrorMark): DOMOutputSpecArray { + toDOM(mark: ProsemirrorMark): DOMOutputSpec { const { start, end, marked } = mark.attrs; let classNames = 'code'; diff --git a/apps/editor/src/markdown/marks/codeBlock.ts b/apps/editor/src/markdown/marks/codeBlock.ts index 48978e6a84..8876364f34 100644 --- a/apps/editor/src/markdown/marks/codeBlock.ts +++ b/apps/editor/src/markdown/marks/codeBlock.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray } from 'prosemirror-model'; +import { DOMOutputSpec } from 'prosemirror-model'; import { Command } from 'prosemirror-commands'; import { EditorCommand, MdSpecContext } from '@t/spec'; import { clsWithMdPrefix } from '@/utils/dom'; @@ -19,7 +19,7 @@ export class CodeBlock extends Mark { get schema() { return { - toDOM(): DOMOutputSpecArray { + toDOM(): DOMOutputSpec { return ['span', { class: clsWithMdPrefix('code-block') }, 0]; }, }; diff --git a/apps/editor/src/markdown/marks/customBlock.ts b/apps/editor/src/markdown/marks/customBlock.ts index bae1dedb71..8f73972538 100644 --- a/apps/editor/src/markdown/marks/customBlock.ts +++ b/apps/editor/src/markdown/marks/customBlock.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray } from 'prosemirror-model'; +import { DOMOutputSpec } from 'prosemirror-model'; import { clsWithMdPrefix } from '@/utils/dom'; import Mark from '@/spec/mark'; import { EditorCommand } from '@t/spec'; @@ -14,7 +14,7 @@ export class CustomBlock extends Mark { get schema() { return { - toDOM(): DOMOutputSpecArray { + toDOM(): DOMOutputSpec { return ['span', { class: clsWithMdPrefix('custom-block') }, 0]; }, }; diff --git a/apps/editor/src/markdown/marks/emph.ts b/apps/editor/src/markdown/marks/emph.ts index 87a6969ec9..378144ac91 100644 --- a/apps/editor/src/markdown/marks/emph.ts +++ b/apps/editor/src/markdown/marks/emph.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray } from 'prosemirror-model'; +import { DOMOutputSpec } from 'prosemirror-model'; import { EditorCommand } from '@t/spec'; import { clsWithMdPrefix } from '@/utils/dom'; import Mark from '@/spec/mark'; @@ -14,7 +14,7 @@ export class Emph extends Mark { get schema() { return { - toDOM(): DOMOutputSpecArray { + toDOM(): DOMOutputSpec { return ['span', { class: clsWithMdPrefix('emph') }, 0]; }, }; diff --git a/apps/editor/src/markdown/marks/heading.ts b/apps/editor/src/markdown/marks/heading.ts index 508831ba8b..5c95784d20 100644 --- a/apps/editor/src/markdown/marks/heading.ts +++ b/apps/editor/src/markdown/marks/heading.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray, Mark as ProsemirrorMark } from 'prosemirror-model'; +import { DOMOutputSpec, Mark as ProsemirrorMark } from 'prosemirror-model'; import { EditorCommand } from '@t/spec'; import { clsWithMdPrefix } from '@/utils/dom'; import Mark from '@/spec/mark'; @@ -22,7 +22,7 @@ export class Heading extends Mark { level: { default: 1 }, seText: { default: false }, }, - toDOM({ attrs }: ProsemirrorMark): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorMark): DOMOutputSpec { const { level, seText } = attrs; let classNames = `heading|heading${level}`; diff --git a/apps/editor/src/markdown/marks/html.ts b/apps/editor/src/markdown/marks/html.ts index 7251d5727b..df00201417 100644 --- a/apps/editor/src/markdown/marks/html.ts +++ b/apps/editor/src/markdown/marks/html.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray } from 'prosemirror-model'; +import { DOMOutputSpec } from 'prosemirror-model'; import { clsWithMdPrefix } from '@/utils/dom'; import Mark from '@/spec/mark'; @@ -9,7 +9,7 @@ export class Html extends Mark { get schema() { return { - toDOM(): DOMOutputSpecArray { + toDOM(): DOMOutputSpec { return ['span', { class: clsWithMdPrefix('html') }, 0]; }, }; diff --git a/apps/editor/src/markdown/marks/link.ts b/apps/editor/src/markdown/marks/link.ts index 2c5f9a73ec..4199704c1a 100644 --- a/apps/editor/src/markdown/marks/link.ts +++ b/apps/editor/src/markdown/marks/link.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray, Mark as ProsemirrorMark } from 'prosemirror-model'; +import { DOMOutputSpec, Mark as ProsemirrorMark } from 'prosemirror-model'; import { EditorCommand } from '@t/spec'; import { clsWithMdPrefix } from '@/utils/dom'; import { escapeTextForLink } from '@/utils/common'; @@ -26,7 +26,7 @@ export class Link extends Mark { url: { default: false }, desc: { default: false }, }, - toDOM({ attrs }: ProsemirrorMark): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorMark): DOMOutputSpec { const { url, desc } = attrs; let classNames = 'link'; diff --git a/apps/editor/src/markdown/marks/listItem.ts b/apps/editor/src/markdown/marks/listItem.ts index dd98f49264..9c3b08fc1f 100644 --- a/apps/editor/src/markdown/marks/listItem.ts +++ b/apps/editor/src/markdown/marks/listItem.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray, Mark as ProsemirrorMark } from 'prosemirror-model'; +import { DOMOutputSpec, Mark as ProsemirrorMark } from 'prosemirror-model'; import { Transaction } from 'prosemirror-state'; import { Command } from 'prosemirror-commands'; import { ListItemMdNode, MdNode } from '@toast-ui/toastmark'; @@ -52,7 +52,7 @@ export class ListItem extends Mark { even: { default: false }, listStyle: { default: false }, }, - toDOM({ attrs }: ProsemirrorMark): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorMark): DOMOutputSpec { const { odd, even, listStyle } = attrs; let classNames = 'list-item'; diff --git a/apps/editor/src/markdown/marks/simpleMark.ts b/apps/editor/src/markdown/marks/simpleMark.ts index ef8e67007e..86f1b7acd5 100644 --- a/apps/editor/src/markdown/marks/simpleMark.ts +++ b/apps/editor/src/markdown/marks/simpleMark.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray } from 'prosemirror-model'; +import { DOMOutputSpec } from 'prosemirror-model'; import { clsWithMdPrefix } from '@/utils/dom'; import Mark from '@/spec/mark'; @@ -9,7 +9,7 @@ export class TaskDelimiter extends Mark { get schema() { return { - toDOM(): DOMOutputSpecArray { + toDOM(): DOMOutputSpec { return ['span', { class: clsWithMdPrefix('delimiter', 'list-item') }, 0]; }, }; @@ -23,7 +23,7 @@ export class Delimiter extends Mark { get schema() { return { - toDOM(): DOMOutputSpecArray { + toDOM(): DOMOutputSpec { return ['span', { class: clsWithMdPrefix('delimiter') }, 0]; }, }; @@ -37,7 +37,7 @@ export class Meta extends Mark { get schema() { return { - toDOM(): DOMOutputSpecArray { + toDOM(): DOMOutputSpec { return ['span', { class: clsWithMdPrefix('meta') }, 0]; }, }; @@ -51,7 +51,7 @@ export class MarkedText extends Mark { get schema() { return { - toDOM(): DOMOutputSpecArray { + toDOM(): DOMOutputSpec { return ['span', { class: clsWithMdPrefix('marked-text') }, 0]; }, }; @@ -65,7 +65,7 @@ export class TableCell extends Mark { get schema() { return { - toDOM(): DOMOutputSpecArray { + toDOM(): DOMOutputSpec { return ['span', { class: clsWithMdPrefix('table-cell') }, 0]; }, }; diff --git a/apps/editor/src/markdown/marks/strike.ts b/apps/editor/src/markdown/marks/strike.ts index c14b5dcfb0..3a2981ae2a 100644 --- a/apps/editor/src/markdown/marks/strike.ts +++ b/apps/editor/src/markdown/marks/strike.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray } from 'prosemirror-model'; +import { DOMOutputSpec } from 'prosemirror-model'; import { EditorCommand } from '@t/spec'; import { clsWithMdPrefix } from '@/utils/dom'; import Mark from '@/spec/mark'; @@ -14,7 +14,7 @@ export class Strike extends Mark { get schema() { return { - toDOM(): DOMOutputSpecArray { + toDOM(): DOMOutputSpec { return ['span', { class: clsWithMdPrefix('strike') }, 0]; }, }; diff --git a/apps/editor/src/markdown/marks/strong.ts b/apps/editor/src/markdown/marks/strong.ts index 38da870119..13579b8138 100644 --- a/apps/editor/src/markdown/marks/strong.ts +++ b/apps/editor/src/markdown/marks/strong.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray } from 'prosemirror-model'; +import { DOMOutputSpec } from 'prosemirror-model'; import { EditorCommand } from '@t/spec'; import { clsWithMdPrefix } from '@/utils/dom'; import Mark from '@/spec/mark'; @@ -14,7 +14,7 @@ export class Strong extends Mark { get schema() { return { - toDOM(): DOMOutputSpecArray { + toDOM(): DOMOutputSpec { return ['span', { class: clsWithMdPrefix('strong') }, 0]; }, }; diff --git a/apps/editor/src/markdown/marks/table.ts b/apps/editor/src/markdown/marks/table.ts index 67aa53958c..2b0cbd83d2 100644 --- a/apps/editor/src/markdown/marks/table.ts +++ b/apps/editor/src/markdown/marks/table.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray } from 'prosemirror-model'; +import { DOMOutputSpec } from 'prosemirror-model'; import { Command } from 'prosemirror-commands'; import type { Transaction } from 'prosemirror-state'; import { TableCellMdNode, MdNode, MdPos } from '@toast-ui/toastmark'; @@ -62,7 +62,7 @@ export class Table extends Mark { get schema() { return { - toDOM(): DOMOutputSpecArray { + toDOM(): DOMOutputSpec { return ['span', { class: clsWithMdPrefix('table') }, 0]; }, }; diff --git a/apps/editor/src/markdown/marks/thematicBreak.ts b/apps/editor/src/markdown/marks/thematicBreak.ts index be2fb9d8bc..e8d549396c 100644 --- a/apps/editor/src/markdown/marks/thematicBreak.ts +++ b/apps/editor/src/markdown/marks/thematicBreak.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray } from 'prosemirror-model'; +import { DOMOutputSpec } from 'prosemirror-model'; import type { Transaction } from 'prosemirror-state'; import { EditorCommand } from '@t/spec'; import { clsWithMdPrefix } from '@/utils/dom'; @@ -15,7 +15,7 @@ export class ThematicBreak extends Mark { get schema() { return { - toDOM(): DOMOutputSpecArray { + toDOM(): DOMOutputSpec { return ['span', { class: clsWithMdPrefix('thematic-break') }, 0]; }, }; diff --git a/apps/editor/src/markdown/mdPreview.ts b/apps/editor/src/markdown/mdPreview.ts index fb97117f2b..b6df0059f6 100644 --- a/apps/editor/src/markdown/mdPreview.ts +++ b/apps/editor/src/markdown/mdPreview.ts @@ -7,7 +7,13 @@ import { EditResult, MdNode, MdPos, Renderer } from '@toast-ui/toastmark'; import { Emitter } from '@t/event'; import { CustomHTMLRenderer, LinkAttributes } from '@t/editor'; -import { cls, createElementWith, removeNode, toggleClass } from '@/utils/dom'; +import { + cls, + createElementWith, + removeNode, + removeProseMirrorHackNodes, + toggleClass, +} from '@/utils/dom'; import { getHTMLRenderConvertors } from '@/markdown/htmlRenderConvertors'; import { isInlineNode, findClosestNode, getMdStartCh } from '@/utils/markdown'; import { findAdjacentElementToScrollTop } from './scroll/dom'; @@ -236,7 +242,7 @@ class MarkdownPreview { } getHTML() { - return this.previewContent.innerHTML; + return removeProseMirrorHackNodes(this.previewContent.innerHTML); } setHTML(html: string) { diff --git a/apps/editor/src/markdown/nodes/paragraph.ts b/apps/editor/src/markdown/nodes/paragraph.ts index 7d088caff5..2fcf4ef7d0 100644 --- a/apps/editor/src/markdown/nodes/paragraph.ts +++ b/apps/editor/src/markdown/nodes/paragraph.ts @@ -1,6 +1,6 @@ -import { DOMOutputSpecArray, ProsemirrorNode, Schema } from 'prosemirror-model'; +import { DOMOutputSpec, ProsemirrorNode, Schema } from 'prosemirror-model'; import { Transaction, Selection } from 'prosemirror-state'; -import { chainCommands, Command, joinForward } from 'prosemirror-commands'; +import { chainCommands, joinForward, Command } from 'prosemirror-commands'; import { EditorCommand, MdSpecContext } from '@t/spec'; import { clsWithMdPrefix } from '@/utils/dom'; import Node from '@/spec/node'; @@ -87,7 +87,7 @@ export class Paragraph extends Node { selectable: false, group: 'block', parseDOM: [{ tag: 'div' }], - toDOM({ attrs }: ProsemirrorNode): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorNode): DOMOutputSpec { return attrs.className ? ['div', { class: clsWithMdPrefix(attrs.className) }, 0] : ['div', 0]; diff --git a/apps/editor/src/utils/dom.ts b/apps/editor/src/utils/dom.ts index 7a12f744ca..408bf34dc8 100644 --- a/apps/editor/src/utils/dom.ts +++ b/apps/editor/src/utils/dom.ts @@ -264,3 +264,15 @@ export function replaceBRWithEmptyBlock(html: string) { return replacedHTML; } + +export function removeProseMirrorHackNodes(html: string) { + const reProseMirrorImage = //g; + const reProseMirrorTrailingBreak = / class="ProseMirror-trailingBreak"/g; + + let resultHTML = html; + + resultHTML = resultHTML.replace(reProseMirrorImage, ''); + resultHTML = resultHTML.replace(reProseMirrorTrailingBreak, ''); + + return resultHTML; +} diff --git a/apps/editor/src/widget/widgetNode.ts b/apps/editor/src/widget/widgetNode.ts index 955207757a..a93eb2b5ef 100644 --- a/apps/editor/src/widget/widgetNode.ts +++ b/apps/editor/src/widget/widgetNode.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray, ProsemirrorNode } from 'prosemirror-model'; +import { DOMOutputSpec, ProsemirrorNode } from 'prosemirror-model'; import SpecNode from '@/spec/node'; import { widgetToDOM } from './rules'; @@ -31,7 +31,7 @@ export class Widget extends SpecNode { content: 'text*', selectable: false, atom: true, - toDOM(): DOMOutputSpecArray { + toDOM(): DOMOutputSpec { return ['span', { class: 'tui-widget' }, 0]; }, parseDOM: [ diff --git a/apps/editor/src/wysiwyg/adaptor/wwToDOMAdaptor.ts b/apps/editor/src/wysiwyg/adaptor/wwToDOMAdaptor.ts index 0b51aa6871..913b53b20a 100644 --- a/apps/editor/src/wysiwyg/adaptor/wwToDOMAdaptor.ts +++ b/apps/editor/src/wysiwyg/adaptor/wwToDOMAdaptor.ts @@ -9,7 +9,7 @@ import { Renderer, TextToken, } from '@toast-ui/toastmark'; -import { Node as ProsemirrorNode, Mark } from 'prosemirror-model'; +import { ProsemirrorNode, Mark } from 'prosemirror-model'; import isArray from 'tui-code-snippet/type/isArray'; import { getHTMLRenderConvertors } from '@/markdown/htmlRenderConvertors'; import { ToDOMAdaptor } from '@t/convertor'; diff --git a/apps/editor/src/wysiwyg/command/list.ts b/apps/editor/src/wysiwyg/command/list.ts index 0291a1b508..e61e8115da 100644 --- a/apps/editor/src/wysiwyg/command/list.ts +++ b/apps/editor/src/wysiwyg/command/list.ts @@ -1,6 +1,6 @@ -import { Node as ProsemirrorNode, NodeType, NodeRange, Fragment, Slice } from 'prosemirror-model'; +import { ProsemirrorNode, NodeType, NodeRange, Fragment, Slice } from 'prosemirror-model'; import { ReplaceAroundStep, canSplit, liftTarget } from 'prosemirror-transform'; -import { Transaction, Selection } from 'prosemirror-state'; +import { Transaction, Selection, EditorState } from 'prosemirror-state'; import { Command } from 'prosemirror-commands'; import { findListItem, isInListNode } from '@/wysiwyg/helper/node'; @@ -255,7 +255,7 @@ export function toggleTask(): Command { } export function sinkListItem(listItem: NodeType): Command { - return ({ tr, selection }, dispatch) => { + return ({ tr, selection }: EditorState, dispatch) => { const { $from, $to } = selection; const range = $from.blockRange( $to, @@ -375,7 +375,7 @@ function liftOutOfList(tr: Transaction, range: NodeRange) { } export function liftListItem(listItem: NodeType): Command { - return ({ tr, selection }, dispatch) => { + return ({ tr, selection }: EditorState, dispatch) => { const { $from, $to } = selection; const range = $from.blockRange( $to, diff --git a/apps/editor/src/wysiwyg/helper/node.ts b/apps/editor/src/wysiwyg/helper/node.ts index 2d6a3904ed..428b57d6ce 100644 --- a/apps/editor/src/wysiwyg/helper/node.ts +++ b/apps/editor/src/wysiwyg/helper/node.ts @@ -1,4 +1,4 @@ -import { Node as ProsemirrorNode, ResolvedPos } from 'prosemirror-model'; +import { ProsemirrorNode, ResolvedPos } from 'prosemirror-model'; import { includes } from '@/utils/common'; type NodeAttrs = Record; diff --git a/apps/editor/src/wysiwyg/marks/code.ts b/apps/editor/src/wysiwyg/marks/code.ts index 5fe94cd594..ec203344c3 100644 --- a/apps/editor/src/wysiwyg/marks/code.ts +++ b/apps/editor/src/wysiwyg/marks/code.ts @@ -1,4 +1,4 @@ -import { Mark as ProsemirrorMark, DOMOutputSpecArray } from 'prosemirror-model'; +import { Mark as ProsemirrorMark, DOMOutputSpec } from 'prosemirror-model'; import { toggleMark } from 'prosemirror-commands'; import Mark from '@/spec/mark'; @@ -29,7 +29,7 @@ export class Code extends Mark { }, }, ], - toDOM({ attrs }: ProsemirrorMark): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorMark): DOMOutputSpec { return [attrs.rawHTML || 'code', getCustomAttrs(attrs)]; }, }; diff --git a/apps/editor/src/wysiwyg/marks/emph.ts b/apps/editor/src/wysiwyg/marks/emph.ts index 482f1eeb86..34474a8c9b 100644 --- a/apps/editor/src/wysiwyg/marks/emph.ts +++ b/apps/editor/src/wysiwyg/marks/emph.ts @@ -1,4 +1,4 @@ -import { Mark as ProsemirrorMark, DOMOutputSpecArray } from 'prosemirror-model'; +import { Mark as ProsemirrorMark, DOMOutputSpec } from 'prosemirror-model'; import { toggleMark } from 'prosemirror-commands'; import Mark from '@/spec/mark'; @@ -31,7 +31,7 @@ export class Emph extends Mark { ...getDefaultCustomAttrs(), }, parseDOM, - toDOM({ attrs }: ProsemirrorMark): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorMark): DOMOutputSpec { return [attrs.rawHTML || 'em', getCustomAttrs(attrs)]; }, }; diff --git a/apps/editor/src/wysiwyg/marks/link.ts b/apps/editor/src/wysiwyg/marks/link.ts index f6a4d5879f..32b05f818b 100644 --- a/apps/editor/src/wysiwyg/marks/link.ts +++ b/apps/editor/src/wysiwyg/marks/link.ts @@ -1,4 +1,4 @@ -import { Mark as ProsemirrorMark, DOMOutputSpecArray } from 'prosemirror-model'; +import { Mark as ProsemirrorMark, DOMOutputSpec } from 'prosemirror-model'; import { toggleMark } from 'prosemirror-commands'; import Mark from '@/spec/mark'; @@ -49,11 +49,12 @@ export class Link extends Mark { }, }, ], - toDOM: ({ attrs }: ProsemirrorMark): DOMOutputSpecArray => [ + toDOM: ({ attrs }: ProsemirrorMark): DOMOutputSpec => [ attrs.rawHTML || 'a', { href: escapeXml(attrs.linkUrl), - ...(this.linkAttributes as DOMOutputSpecArray), + // @ts-ignore + ...(this.linkAttributes as DOMOutputSpec), ...getCustomAttrs(attrs), }, ], diff --git a/apps/editor/src/wysiwyg/marks/strike.ts b/apps/editor/src/wysiwyg/marks/strike.ts index 1b6d5c1165..069e8664cb 100644 --- a/apps/editor/src/wysiwyg/marks/strike.ts +++ b/apps/editor/src/wysiwyg/marks/strike.ts @@ -1,4 +1,4 @@ -import { Mark as ProsemirrorMark, DOMOutputSpecArray } from 'prosemirror-model'; +import { Mark as ProsemirrorMark, DOMOutputSpec } from 'prosemirror-model'; import { toggleMark } from 'prosemirror-commands'; import Mark from '@/spec/mark'; @@ -31,7 +31,7 @@ export class Strike extends Mark { ...getDefaultCustomAttrs(), }, parseDOM, - toDOM({ attrs }: ProsemirrorMark): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorMark): DOMOutputSpec { return [attrs.rawHTML || 'del', getCustomAttrs(attrs)]; }, }; diff --git a/apps/editor/src/wysiwyg/marks/strong.ts b/apps/editor/src/wysiwyg/marks/strong.ts index eb83ae440f..4640a142ea 100644 --- a/apps/editor/src/wysiwyg/marks/strong.ts +++ b/apps/editor/src/wysiwyg/marks/strong.ts @@ -1,4 +1,4 @@ -import { Mark as ProsemirrorMark, DOMOutputSpecArray } from 'prosemirror-model'; +import { Mark as ProsemirrorMark, DOMOutputSpec } from 'prosemirror-model'; import { toggleMark } from 'prosemirror-commands'; import Mark from '@/spec/mark'; @@ -31,7 +31,7 @@ export class Strong extends Mark { ...getDefaultCustomAttrs(), }, parseDOM, - toDOM({ attrs }: ProsemirrorMark): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorMark): DOMOutputSpec { return [attrs.rawHTML || 'strong', getCustomAttrs(attrs)]; }, }; diff --git a/apps/editor/src/wysiwyg/nodes/blockQuote.ts b/apps/editor/src/wysiwyg/nodes/blockQuote.ts index 7034694a6b..3a7fda49a2 100644 --- a/apps/editor/src/wysiwyg/nodes/blockQuote.ts +++ b/apps/editor/src/wysiwyg/nodes/blockQuote.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray, ProsemirrorNode } from 'prosemirror-model'; +import { DOMOutputSpec, ProsemirrorNode } from 'prosemirror-model'; import { wrapIn } from 'prosemirror-commands'; import NodeSchema from '@/spec/node'; @@ -24,7 +24,7 @@ export class BlockQuote extends NodeSchema { content: 'block+', group: 'block', parseDOM: [createDOMInfoParsedRawHTML('blockquote')], - toDOM({ attrs }: ProsemirrorNode): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorNode): DOMOutputSpec { return ['blockquote', getCustomAttrs(attrs), 0]; }, }; diff --git a/apps/editor/src/wysiwyg/nodes/bulletList.ts b/apps/editor/src/wysiwyg/nodes/bulletList.ts index 8e294d7fe4..6bf2bf8c51 100644 --- a/apps/editor/src/wysiwyg/nodes/bulletList.ts +++ b/apps/editor/src/wysiwyg/nodes/bulletList.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray, ProsemirrorNode } from 'prosemirror-model'; +import { DOMOutputSpec, ProsemirrorNode } from 'prosemirror-model'; import NodeSchema from '@/spec/node'; import { getWwCommands } from '@/commands/wwCommands'; @@ -25,7 +25,7 @@ export class BulletList extends NodeSchema { ...getDefaultCustomAttrs(), }, parseDOM: [createDOMInfoParsedRawHTML('ul')], - toDOM({ attrs }: ProsemirrorNode): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorNode): DOMOutputSpec { return ['ul', getCustomAttrs(attrs), 0]; }, }; diff --git a/apps/editor/src/wysiwyg/nodes/codeBlock.ts b/apps/editor/src/wysiwyg/nodes/codeBlock.ts index bded582be3..1c38f99adc 100644 --- a/apps/editor/src/wysiwyg/nodes/codeBlock.ts +++ b/apps/editor/src/wysiwyg/nodes/codeBlock.ts @@ -1,4 +1,4 @@ -import { Node as ProsemirrorNode, DOMOutputSpecArray } from 'prosemirror-model'; +import { ProsemirrorNode, DOMOutputSpec } from 'prosemirror-model'; import { setBlockType, Command } from 'prosemirror-commands'; import { addParagraph } from '@/helper/manipulation'; @@ -40,7 +40,7 @@ export class CodeBlock extends NodeSchema { }, }, ], - toDOM({ attrs }: ProsemirrorNode): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorNode): DOMOutputSpec { return [ attrs.rawHTML || 'pre', ['code', { 'data-language': attrs.language, ...getCustomAttrs(attrs) }, 0], @@ -60,7 +60,7 @@ export class CodeBlock extends NodeSchema { const { view } = this.context; if (view!.endOfTextblock(direction) && $from.node().type.name === 'codeBlock') { - const lines = $from.parent.textContent.split('\n'); + const lines: string[] = $from.parent.textContent.split('\n'); const offset = direction === 'up' ? $from.start() : $from.end(); const range = diff --git a/apps/editor/src/wysiwyg/nodes/customBlock.ts b/apps/editor/src/wysiwyg/nodes/customBlock.ts index b0b0d9189b..4d6cfd172f 100644 --- a/apps/editor/src/wysiwyg/nodes/customBlock.ts +++ b/apps/editor/src/wysiwyg/nodes/customBlock.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray, ProsemirrorNode } from 'prosemirror-model'; +import { DOMOutputSpec, ProsemirrorNode } from 'prosemirror-model'; import { setBlockType } from 'prosemirror-commands'; import NodeSchema from '@/spec/node'; import { EditorCommand } from '@t/spec'; @@ -28,7 +28,7 @@ export class CustomBlock extends NodeSchema { }, }, ], - toDOM({ attrs }: ProsemirrorNode): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorNode): DOMOutputSpec { return ['div', { 'data-custom-info': attrs.info || null }, 0]; }, }; diff --git a/apps/editor/src/wysiwyg/nodes/frontMatter.ts b/apps/editor/src/wysiwyg/nodes/frontMatter.ts index 60b66f23d9..985cb47bcb 100644 --- a/apps/editor/src/wysiwyg/nodes/frontMatter.ts +++ b/apps/editor/src/wysiwyg/nodes/frontMatter.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray } from 'prosemirror-model'; +import { DOMOutputSpec } from 'prosemirror-model'; import { exitCode } from 'prosemirror-commands'; import NodeSchema from '@/spec/node'; @@ -22,7 +22,7 @@ export class FrontMatter extends NodeSchema { tag: 'div[data-front-matter]', }, ], - toDOM(): DOMOutputSpecArray { + toDOM(): DOMOutputSpec { return ['div', { 'data-front-matter': 'true' }, 0]; }, }; diff --git a/apps/editor/src/wysiwyg/nodes/heading.ts b/apps/editor/src/wysiwyg/nodes/heading.ts index 61ffb1db72..6e6b12d7ec 100644 --- a/apps/editor/src/wysiwyg/nodes/heading.ts +++ b/apps/editor/src/wysiwyg/nodes/heading.ts @@ -1,4 +1,4 @@ -import { Node as ProsemirrorNode, DOMOutputSpecArray } from 'prosemirror-model'; +import { ProsemirrorNode, DOMOutputSpec } from 'prosemirror-model'; import { setBlockType } from 'prosemirror-commands'; import NodeSchema from '@/spec/node'; @@ -41,7 +41,7 @@ export class Heading extends NodeSchema { group: 'block', defining: true, parseDOM, - toDOM({ attrs }: ProsemirrorNode): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorNode): DOMOutputSpec { return [`h${attrs.level}`, getCustomAttrs(attrs), 0]; }, }; diff --git a/apps/editor/src/wysiwyg/nodes/html.ts b/apps/editor/src/wysiwyg/nodes/html.ts index 6cf16c9f55..7840238fa6 100644 --- a/apps/editor/src/wysiwyg/nodes/html.ts +++ b/apps/editor/src/wysiwyg/nodes/html.ts @@ -1,7 +1,7 @@ import { - Node as ProsemirrorNode, + ProsemirrorNode, Mark as ProsemirrorMark, - DOMOutputSpecArray, + DOMOutputSpec, NodeSpec, MarkSpec, } from 'prosemirror-model'; @@ -82,7 +82,7 @@ const schemaFactory = { }, }, ], - toDOM(node: ProsemirrorNode): DOMOutputSpecArray { + toDOM(node: ProsemirrorNode): DOMOutputSpec { const { dom, htmlAttrs } = sanitizeDOM(node, typeName, sanitizeHTML, wwToDOMAdaptor); htmlAttrs.class = htmlAttrs.class ? `${htmlAttrs.class} html-block` : 'html-block'; @@ -107,7 +107,7 @@ const schemaFactory = { }, }, ], - toDOM(node: ProsemirrorMark): DOMOutputSpecArray { + toDOM(node: ProsemirrorMark): DOMOutputSpec { const { htmlAttrs } = sanitizeDOM(node, typeName, sanitizeHTML, wwToDOMAdaptor); return [typeName, htmlAttrs, 0]; diff --git a/apps/editor/src/wysiwyg/nodes/htmlComment.ts b/apps/editor/src/wysiwyg/nodes/htmlComment.ts index a79c831eaf..9c05e899de 100644 --- a/apps/editor/src/wysiwyg/nodes/htmlComment.ts +++ b/apps/editor/src/wysiwyg/nodes/htmlComment.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray } from 'prosemirror-model'; +import { DOMOutputSpec } from 'prosemirror-model'; import { exitCode } from 'prosemirror-commands'; import NodeSchema from '@/spec/node'; @@ -17,7 +17,7 @@ export class HTMLComment extends NodeSchema { code: true, defining: true, parseDOM: [{ preserveWhitespace: 'full' as const, tag: 'div[data-html-comment]' }], - toDOM(): DOMOutputSpecArray { + toDOM(): DOMOutputSpec { return ['div', { 'data-html-comment': 'true' }, 0]; }, }; diff --git a/apps/editor/src/wysiwyg/nodes/image.ts b/apps/editor/src/wysiwyg/nodes/image.ts index 6be15e8743..7b47c1b066 100644 --- a/apps/editor/src/wysiwyg/nodes/image.ts +++ b/apps/editor/src/wysiwyg/nodes/image.ts @@ -1,4 +1,4 @@ -import { Node as ProsemirrorNode, DOMOutputSpecArray } from 'prosemirror-model'; +import { ProsemirrorNode, DOMOutputSpec } from 'prosemirror-model'; import NodeSchema from '@/spec/node'; import { escapeXml } from '@/utils/common'; @@ -41,7 +41,7 @@ export class Image extends NodeSchema { }, }, ], - toDOM({ attrs }: ProsemirrorNode): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorNode): DOMOutputSpec { return [ attrs.rawHTML || 'img', { diff --git a/apps/editor/src/wysiwyg/nodes/listItem.ts b/apps/editor/src/wysiwyg/nodes/listItem.ts index 60d0d14f00..6387922020 100644 --- a/apps/editor/src/wysiwyg/nodes/listItem.ts +++ b/apps/editor/src/wysiwyg/nodes/listItem.ts @@ -1,5 +1,5 @@ import type { Command } from 'prosemirror-commands'; -import type { Node as ProsemirrorNode, DOMOutputSpecArray } from 'prosemirror-model'; +import type { ProsemirrorNode, DOMOutputSpec } from 'prosemirror-model'; import NodeSchema from '@/spec/node'; import { splitListItem } from '@/wysiwyg/command/list'; @@ -33,7 +33,7 @@ export class ListItem extends NodeSchema { }, }, ], - toDOM({ attrs }: ProsemirrorNode): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorNode): DOMOutputSpec { const { task, checked } = attrs; if (!task) { diff --git a/apps/editor/src/wysiwyg/nodes/orderedList.ts b/apps/editor/src/wysiwyg/nodes/orderedList.ts index b8d9e54edb..5b9d9e92c7 100644 --- a/apps/editor/src/wysiwyg/nodes/orderedList.ts +++ b/apps/editor/src/wysiwyg/nodes/orderedList.ts @@ -1,4 +1,4 @@ -import { Node as ProsemirrorNode, DOMOutputSpecArray } from 'prosemirror-model'; +import { ProsemirrorNode, DOMOutputSpec } from 'prosemirror-model'; import NodeSchema from '@/spec/node'; import { getWwCommands } from '@/commands/wwCommands'; @@ -35,7 +35,7 @@ export class OrderedList extends NodeSchema { }, }, ], - toDOM({ attrs }: ProsemirrorNode): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorNode): DOMOutputSpec { return [ attrs.rawHTML || 'ol', { start: attrs.order === 1 ? null : attrs.order, ...getCustomAttrs(attrs) }, diff --git a/apps/editor/src/wysiwyg/nodes/paragraph.ts b/apps/editor/src/wysiwyg/nodes/paragraph.ts index 58236954b1..bf69ca4b76 100644 --- a/apps/editor/src/wysiwyg/nodes/paragraph.ts +++ b/apps/editor/src/wysiwyg/nodes/paragraph.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray, ProsemirrorNode } from 'prosemirror-model'; +import { DOMOutputSpec, ProsemirrorNode } from 'prosemirror-model'; import NodeSchema from '@/spec/node'; import { getDefaultCustomAttrs, getCustomAttrs } from '@/wysiwyg/helper/node'; @@ -16,7 +16,7 @@ export class Paragraph extends NodeSchema { ...getDefaultCustomAttrs(), }, parseDOM: [{ tag: 'p' }], - toDOM({ attrs }: ProsemirrorNode): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorNode): DOMOutputSpec { return ['p', getCustomAttrs(attrs), 0]; }, }; diff --git a/apps/editor/src/wysiwyg/nodes/table.ts b/apps/editor/src/wysiwyg/nodes/table.ts index 263a6d5951..9a5e0b0a2b 100644 --- a/apps/editor/src/wysiwyg/nodes/table.ts +++ b/apps/editor/src/wysiwyg/nodes/table.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray, Node as ProsemirrorNode } from 'prosemirror-model'; +import { DOMOutputSpec, ProsemirrorNode } from 'prosemirror-model'; import { TextSelection, Transaction } from 'prosemirror-state'; import { Command } from 'prosemirror-commands'; @@ -98,7 +98,7 @@ export class Table extends NodeSchema { ...getDefaultCustomAttrs(), }, parseDOM: [createDOMInfoParsedRawHTML('table')], - toDOM({ attrs }: ProsemirrorNode): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorNode): DOMOutputSpec { return ['table', getCustomAttrs(attrs), 0]; }, }; diff --git a/apps/editor/src/wysiwyg/nodes/tableBody.ts b/apps/editor/src/wysiwyg/nodes/tableBody.ts index ef160ce29f..04d84d2fc6 100644 --- a/apps/editor/src/wysiwyg/nodes/tableBody.ts +++ b/apps/editor/src/wysiwyg/nodes/tableBody.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray, ProsemirrorNode } from 'prosemirror-model'; +import { DOMOutputSpec, ProsemirrorNode } from 'prosemirror-model'; import NodeSchema from '@/spec/node'; import { getCustomAttrs, getDefaultCustomAttrs } from '@/wysiwyg/helper/node'; @@ -31,7 +31,7 @@ export class TableBody extends NodeSchema { }, }, ], - toDOM({ attrs }: ProsemirrorNode): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorNode): DOMOutputSpec { return ['tbody', getCustomAttrs(attrs), 0]; }, }; diff --git a/apps/editor/src/wysiwyg/nodes/tableBodyCell.ts b/apps/editor/src/wysiwyg/nodes/tableBodyCell.ts index da27e39c48..70166a4e88 100644 --- a/apps/editor/src/wysiwyg/nodes/tableBodyCell.ts +++ b/apps/editor/src/wysiwyg/nodes/tableBodyCell.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray, Node as ProsemirrorNode } from 'prosemirror-model'; +import { DOMOutputSpec, ProsemirrorNode } from 'prosemirror-model'; import NodeSchema from '@/spec/node'; import { createCellAttrs, createParsedCellDOM } from '@/wysiwyg/helper/node'; @@ -21,7 +21,7 @@ export class TableBodyCell extends NodeSchema { }, isolating: true, parseDOM: [createParsedCellDOM('td')], - toDOM({ attrs }: ProsemirrorNode): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorNode): DOMOutputSpec { const cellAttrs = createCellAttrs(attrs); return ['td', cellAttrs, 0]; diff --git a/apps/editor/src/wysiwyg/nodes/tableHead.ts b/apps/editor/src/wysiwyg/nodes/tableHead.ts index 131f654521..7ca9d83014 100644 --- a/apps/editor/src/wysiwyg/nodes/tableHead.ts +++ b/apps/editor/src/wysiwyg/nodes/tableHead.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray, ProsemirrorNode } from 'prosemirror-model'; +import { DOMOutputSpec, ProsemirrorNode } from 'prosemirror-model'; import NodeSchema from '@/spec/node'; import { @@ -20,7 +20,7 @@ export class TableHead extends NodeSchema { ...getDefaultCustomAttrs(), }, parseDOM: [createDOMInfoParsedRawHTML('thead')], - toDOM({ attrs }: ProsemirrorNode): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorNode): DOMOutputSpec { return ['thead', getCustomAttrs(attrs), 0]; }, }; diff --git a/apps/editor/src/wysiwyg/nodes/tableHeadCell.ts b/apps/editor/src/wysiwyg/nodes/tableHeadCell.ts index 23218fa8c0..e58909435a 100644 --- a/apps/editor/src/wysiwyg/nodes/tableHeadCell.ts +++ b/apps/editor/src/wysiwyg/nodes/tableHeadCell.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray, Node as ProsemirrorNode } from 'prosemirror-model'; +import { DOMOutputSpec, ProsemirrorNode } from 'prosemirror-model'; import NodeSchema from '@/spec/node'; import { @@ -26,7 +26,7 @@ export class TableHeadCell extends NodeSchema { }, isolating: true, parseDOM: [createParsedCellDOM('th')], - toDOM({ attrs }: ProsemirrorNode): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorNode): DOMOutputSpec { const cellAttrs = createCellAttrs(attrs); return ['th', { ...cellAttrs, ...getCustomAttrs(attrs) }, 0]; diff --git a/apps/editor/src/wysiwyg/nodes/tableRow.ts b/apps/editor/src/wysiwyg/nodes/tableRow.ts index c5c4b3cc18..e497068eee 100644 --- a/apps/editor/src/wysiwyg/nodes/tableRow.ts +++ b/apps/editor/src/wysiwyg/nodes/tableRow.ts @@ -1,4 +1,4 @@ -import { DOMOutputSpecArray, ProsemirrorNode } from 'prosemirror-model'; +import { DOMOutputSpec, ProsemirrorNode } from 'prosemirror-model'; import NodeSchema from '@/spec/node'; import { getDefaultCustomAttrs, getCustomAttrs } from '@/wysiwyg/helper/node'; @@ -30,7 +30,7 @@ export class TableRow extends NodeSchema { }, }, ], - toDOM({ attrs }: ProsemirrorNode): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorNode): DOMOutputSpec { return ['tr', getCustomAttrs(attrs), 0]; }, }; diff --git a/apps/editor/src/wysiwyg/nodes/thematicBreak.ts b/apps/editor/src/wysiwyg/nodes/thematicBreak.ts index 283dcd31dd..67e7778524 100644 --- a/apps/editor/src/wysiwyg/nodes/thematicBreak.ts +++ b/apps/editor/src/wysiwyg/nodes/thematicBreak.ts @@ -1,4 +1,4 @@ -import { Node as ProsemirrorNode, DOMOutputSpecArray } from 'prosemirror-model'; +import { ProsemirrorNode, DOMOutputSpec } from 'prosemirror-model'; import Node from '@/spec/node'; @@ -21,7 +21,7 @@ export class ThematicBreak extends Node { group: 'block', parseDOM: [{ tag: 'hr' }], selectable: false, - toDOM({ attrs }: ProsemirrorNode): DOMOutputSpecArray { + toDOM({ attrs }: ProsemirrorNode): DOMOutputSpec { return ['div', getCustomAttrs(attrs), [attrs.rawHTML || 'hr']]; }, }; diff --git a/apps/editor/src/wysiwyg/nodeview/codeBlockView.ts b/apps/editor/src/wysiwyg/nodeview/codeBlockView.ts index ab64696562..c3c3aefff1 100644 --- a/apps/editor/src/wysiwyg/nodeview/codeBlockView.ts +++ b/apps/editor/src/wysiwyg/nodeview/codeBlockView.ts @@ -1,5 +1,5 @@ import { EditorView, NodeView } from 'prosemirror-view'; -import { Node as ProsemirrorNode } from 'prosemirror-model'; +import { ProsemirrorNode } from 'prosemirror-model'; import isFunction from 'tui-code-snippet/type/isFunction'; import css from 'tui-code-snippet/domUtil/css'; @@ -20,7 +20,7 @@ const WRAPPER_CLASS_NAME = 'toastui-editor-ww-code-block'; const CODE_BLOCK_LANG_CLASS_NAME = 'toastui-editor-ww-code-block-language'; export class CodeBlockView implements NodeView { - dom: HTMLElement | null = null; + dom!: HTMLElement; contentDOM: HTMLElement | null = null; diff --git a/apps/editor/src/wysiwyg/nodeview/customBlockView.ts b/apps/editor/src/wysiwyg/nodeview/customBlockView.ts index 56571adb75..6fb3538224 100644 --- a/apps/editor/src/wysiwyg/nodeview/customBlockView.ts +++ b/apps/editor/src/wysiwyg/nodeview/customBlockView.ts @@ -1,5 +1,5 @@ import { EditorView, NodeView } from 'prosemirror-view'; -import { Node as ProsemirrorNode } from 'prosemirror-model'; +import { ProsemirrorNode } from 'prosemirror-model'; import { StepMap } from 'prosemirror-transform'; import { EditorState, TextSelection, Transaction } from 'prosemirror-state'; import { newlineInCode } from 'prosemirror-commands'; diff --git a/apps/editor/src/wysiwyg/plugins/selection/cellSelection.ts b/apps/editor/src/wysiwyg/plugins/selection/cellSelection.ts index a78f90710c..7d6a28976a 100644 --- a/apps/editor/src/wysiwyg/plugins/selection/cellSelection.ts +++ b/apps/editor/src/wysiwyg/plugins/selection/cellSelection.ts @@ -126,8 +126,13 @@ export default class CellSelection extends Selection { const copiedRow = row.copy(Fragment.from(cells)); const targetNode = isTableHeadCell ? tableHead : tableBody; + // @ts-ignore targetNode.content = targetNode.content.append(Fragment.from(copiedRow)); } return new Slice(createTableFragment(tableHead, tableBody), 1, 1); } + + toJSON() { + return JSON.stringify(this); + } } diff --git a/apps/editor/src/wysiwyg/plugins/toolbarState.ts b/apps/editor/src/wysiwyg/plugins/toolbarState.ts index 6cb52a08d5..f54a0852cd 100644 --- a/apps/editor/src/wysiwyg/plugins/toolbarState.ts +++ b/apps/editor/src/wysiwyg/plugins/toolbarState.ts @@ -61,7 +61,7 @@ function getToolbarState(selection: Selection, doc: Node, schema: Schema) { } as ToolbarStateMap; doc.nodesBetween(from, to, (node, _, parentNode) => { - const type = getToolbarStateType(node, parentNode); + const type = getToolbarStateType(node, parentNode!); if (includes(EXCEPT_TYPES, type)) { return; diff --git a/apps/editor/src/wysiwyg/wwEditor.ts b/apps/editor/src/wysiwyg/wwEditor.ts index 482ef411a8..4326ae9c23 100644 --- a/apps/editor/src/wysiwyg/wwEditor.ts +++ b/apps/editor/src/wysiwyg/wwEditor.ts @@ -1,5 +1,5 @@ import { EditorView, NodeView } from 'prosemirror-view'; -import { Node as ProsemirrorNode, Slice, Fragment, Mark, Schema } from 'prosemirror-model'; +import { ProsemirrorNode, Slice, Fragment, Mark, Schema } from 'prosemirror-model'; import isNumber from 'tui-code-snippet/type/isNumber'; import toArray from 'tui-code-snippet/collection/toArray'; @@ -28,7 +28,7 @@ import { HTMLSchemaMap, LinkAttributes, WidgetStyle } from '@t/editor'; import { NodeViewPropMap, PluginProp } from '@t/plugin'; import { createNodesWithWidget } from '@/widget/rules'; import { widgetNodeView } from '@/widget/widgetNode'; -import { cls } from '@/utils/dom'; +import { cls, removeProseMirrorHackNodes } from '@/utils/dom'; import { includes } from '@/utils/common'; import { isInTableNode } from '@/wysiwyg/helper/node'; @@ -207,7 +207,7 @@ export default class WysiwygEditor extends EditorBase { } getHTML() { - return this.view.dom.innerHTML; + return removeProseMirrorHackNodes(this.view.dom.innerHTML); } getModel() { @@ -313,7 +313,7 @@ export default class WysiwygEditor extends EditorBase { isText && offset <= startOffset && offset + nodeSize >= startOffset && - maybeHasMark(nodeMarks) + maybeHasMark(nodeMarks as Mark[]) ) { start = start + offset; end = start + nodeSize; diff --git a/apps/editor/types/convertor.d.ts b/apps/editor/types/convertor.d.ts index a3cb6bac3e..718c1c7ade 100644 --- a/apps/editor/types/convertor.d.ts +++ b/apps/editor/types/convertor.d.ts @@ -1,4 +1,4 @@ -import { NodeType, MarkType, Schema, Node as ProsemirrorNode, Mark } from 'prosemirror-model'; +import { NodeType, MarkType, Schema, ProsemirrorNode, Mark } from 'prosemirror-model'; import { MdNode, MdNodeType, RendererOptions, HTMLToken, MdPos } from './toastmark'; import { WwNodeType, WwMarkType } from './wysiwyg'; diff --git a/apps/editor/types/prosemirror-commands.d.ts b/apps/editor/types/prosemirror-commands.d.ts new file mode 100644 index 0000000000..eb39a69824 --- /dev/null +++ b/apps/editor/types/prosemirror-commands.d.ts @@ -0,0 +1,15 @@ +import { EditorState, Transaction } from 'prosemirror-state'; +import { EditorView } from 'prosemirror-view'; +import { Schema } from 'prosemirror-model'; + +import 'prosemirror-commands'; + +declare module 'prosemirror-commands' { + export interface Command { + (state: EditorState, dispatch?: (tr: Transaction) => void, view?: EditorView): boolean; + } + + export interface Keymap { + [key: string]: Command; + } +} diff --git a/apps/editor/types/prosemirror-model.d.ts b/apps/editor/types/prosemirror-model.d.ts index be264e46cc..8f501be513 100644 --- a/apps/editor/types/prosemirror-model.d.ts +++ b/apps/editor/types/prosemirror-model.d.ts @@ -7,16 +7,7 @@ declare module 'prosemirror-model' { findDiffEnd(other: ProsemirrorNode | Fragment): { a: number; b: number } | null | undefined; } - export interface ProsemirrorNode extends Model.Node { - descendants( - fn: ( - node: Model.Node, - pos: number, - parent: Model.Node, - index?: number - ) => boolean | void | null | undefined - ): void; - } + export type ProsemirrorNode = Model.Node; export interface NodeType { compatibleContent(node: NodeType): boolean; diff --git a/package-lock.json b/package-lock.json index 72b1df7699..2dcdfc5739 100644 --- a/package-lock.json +++ b/package-lock.json @@ -83,14 +83,13 @@ "license": "MIT", "dependencies": { "dompurify": "^2.3.3", - "prosemirror-commands": "~1.1.9", - "prosemirror-history": "~1.1.3", - "prosemirror-inputrules": "~1.1.3", - "prosemirror-keymap": "~1.1.4", - "prosemirror-model": "~1.14.1", - "prosemirror-state": "~1.3.4", - "prosemirror-transform": "~1.3.0", - "prosemirror-view": "~1.18.7" + "prosemirror-commands": "^1.1.9", + "prosemirror-history": "^1.1.3", + "prosemirror-inputrules": "^1.1.3", + "prosemirror-keymap": "^1.1.4", + "prosemirror-model": "^1.14.1", + "prosemirror-state": "^1.3.4", + "prosemirror-view": "^1.18.7" }, "devDependencies": { "@toast-ui/release-notes": "^2.0.1", @@ -20526,9 +20525,9 @@ } }, "node_modules/orderedmap": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-1.1.1.tgz", - "integrity": "sha512-3Ux8um0zXbVacKUkcytc0u3HgC0b0bBLT+I60r2J/En72cI0nZffqrA7Xtf2Hqs27j1g82llR5Mhbd0Z1XW4AQ==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.0.0.tgz", + "integrity": "sha512-buf4PoAMlh45b8a8gsGy/X6w279TSqkyAS0C0wdTSJwFSU+ljQFJON5I8NfjLHoCXwpSROIo2wr0g33T+kQshQ==" }, "node_modules/original": { "version": "1.0.2", @@ -22100,9 +22099,9 @@ "dev": true }, "node_modules/prosemirror-commands": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.1.9.tgz", - "integrity": "sha512-zedlbQ+8QK0tIeibb6vbnAX5FO/S5x67xHgF57Fned+3G6RZY3JAGma9kC1jSCmLF/XC7MCZ90oekb0qo2b+Pw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.3.0.tgz", + "integrity": "sha512-BwBbZ5OAScPcm0x7H8SPbqjuEJnCU2RJT9LDyOiiIl/3NbL1nJZI4SFNHwU2e/tRr2Xe7JsptpzseqvZvToLBQ==", "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-state": "^1.0.0", @@ -22110,9 +22109,9 @@ } }, "node_modules/prosemirror-history": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.1.3.tgz", - "integrity": "sha512-zGDotijea+vnfnyyUGyiy1wfOQhf0B/b6zYcCouBV8yo6JmrE9X23M5q7Nf/nATywEZbgRLG70R4DmfSTC+gfg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.3.0.tgz", + "integrity": "sha512-qo/9Wn4B/Bq89/YD+eNWFbAytu6dmIM85EhID+fz9Jcl9+DfGEo8TTSrRhP15+fFEoaPqpHSxlvSzSEbmlxlUA==", "dependencies": { "prosemirror-state": "^1.2.2", "prosemirror-transform": "^1.0.0", @@ -22120,54 +22119,54 @@ } }, "node_modules/prosemirror-inputrules": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.1.3.tgz", - "integrity": "sha512-ZaHCLyBtvbyIHv0f5p6boQTIJjlD6o2NPZiEaZWT2DA+j591zS29QQEMT4lBqwcLW3qRSf7ZvoKNbf05YrsStw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.2.0.tgz", + "integrity": "sha512-eAW/M/NTSSzpCOxfR8Abw6OagdG0MiDAiWHQMQveIsZtoKVYzm0AflSPq/ymqJd56/Su1YPbwy9lM13wgHOFmQ==", "dependencies": { "prosemirror-state": "^1.0.0", "prosemirror-transform": "^1.0.0" } }, "node_modules/prosemirror-keymap": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.1.4.tgz", - "integrity": "sha512-Al8cVUOnDFL4gcI5IDlG6xbZ0aOD/i3B17VT+1JbHWDguCgt/lBHVTHUBcKvvbSg6+q/W4Nj1Fu6bwZSca3xjg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.0.tgz", + "integrity": "sha512-TdSfu+YyLDd54ufN/ZeD1VtBRYpgZnTPnnbY+4R08DDgs84KrIPEPbJL8t1Lm2dkljFx6xeBE26YWH3aIzkPKg==", "dependencies": { "prosemirror-state": "^1.0.0", "w3c-keyname": "^2.2.0" } }, "node_modules/prosemirror-model": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.14.1.tgz", - "integrity": "sha512-vZcbI+24VloFefKZkDnMaEpipL/vSKKPdFiik4KOnTzq3e6AO7+CAOixZ2G/SsfRaYC965XvnOIEbhIQdgki7w==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.18.1.tgz", + "integrity": "sha512-IxSVBKAEMjD7s3n8cgtwMlxAXZrC7Mlag7zYsAKDndAqnDScvSmp/UdnRTV/B33lTCVU3CCm7dyAn/rVVD0mcw==", "dependencies": { - "orderedmap": "^1.1.0" + "orderedmap": "^2.0.0" } }, "node_modules/prosemirror-state": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.3.4.tgz", - "integrity": "sha512-Xkkrpd1y/TQ6HKzN3agsQIGRcLckUMA9u3j207L04mt8ToRgpGeyhbVv0HI7omDORIBHjR29b7AwlATFFf2GLA==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.1.tgz", + "integrity": "sha512-U/LBDW2gNmVa07sz/D229XigSdDQ5CLFwVB1Vb32MJbAHHhWe/6pOc721faI17tqw4pZ49i1xfY/jEZ9tbIhPg==", "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-transform": "^1.0.0" } }, "node_modules/prosemirror-transform": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.3.0.tgz", - "integrity": "sha512-c6hWwm6k/yGitBM75yElXiSH0FVMn8adTss8kPDHKyfbqq5Px/dKjguhWINMe6AB/CqArpL5KLWDNbBI6K2Pmg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.6.0.tgz", + "integrity": "sha512-MAp7AjsjEGEqQY0sSMufNIUuEyB1ZR9Fqlm8dTwwWwpEJRv/plsKjWXBbx52q3Ml8MtaMcd7ic14zAHVB3WaMw==", "dependencies": { "prosemirror-model": "^1.0.0" } }, "node_modules/prosemirror-view": { - "version": "1.18.7", - "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.18.7.tgz", - "integrity": "sha512-pUCxoyuWnbVfJ/ukhQ+7+bfDMArG3wu6hHnnTFi61C7Teb5OILUhkkhEhF2/RsppBFWrkwsNcf8rQm8SSoSKRg==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.27.0.tgz", + "integrity": "sha512-yNCQW5eiPkrMgjOT5Xa/ItIvcM7JBG7ikZKaHo26hdBW5OLNnIWGZ0BV6/OiBk742teLybLVNPCpYUcW405Ckg==", "dependencies": { - "prosemirror-model": "^1.1.0", + "prosemirror-model": "^1.16.0", "prosemirror-state": "^1.0.0", "prosemirror-transform": "^1.1.0" } @@ -33361,14 +33360,13 @@ "@types/dompurify": "2.3.3", "cross-env": "^6.0.3", "dompurify": "^2.3.3", - "prosemirror-commands": "~1.1.9", - "prosemirror-history": "~1.1.3", - "prosemirror-inputrules": "~1.1.3", - "prosemirror-keymap": "~1.1.4", - "prosemirror-model": "~1.14.1", - "prosemirror-state": "~1.3.4", - "prosemirror-transform": "~1.3.0", - "prosemirror-view": "~1.18.7" + "prosemirror-commands": "^1.1.9", + "prosemirror-history": "^1.1.3", + "prosemirror-inputrules": "^1.1.3", + "prosemirror-keymap": "^1.1.4", + "prosemirror-model": "^1.14.1", + "prosemirror-state": "^1.3.4", + "prosemirror-view": "^1.18.7" } }, "@toast-ui/editor-plugin-chart": { @@ -44920,9 +44918,9 @@ } }, "orderedmap": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-1.1.1.tgz", - "integrity": "sha512-3Ux8um0zXbVacKUkcytc0u3HgC0b0bBLT+I60r2J/En72cI0nZffqrA7Xtf2Hqs27j1g82llR5Mhbd0Z1XW4AQ==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.0.0.tgz", + "integrity": "sha512-buf4PoAMlh45b8a8gsGy/X6w279TSqkyAS0C0wdTSJwFSU+ljQFJON5I8NfjLHoCXwpSROIo2wr0g33T+kQshQ==" }, "original": { "version": "1.0.2", @@ -46094,9 +46092,9 @@ } }, "prosemirror-commands": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.1.9.tgz", - "integrity": "sha512-zedlbQ+8QK0tIeibb6vbnAX5FO/S5x67xHgF57Fned+3G6RZY3JAGma9kC1jSCmLF/XC7MCZ90oekb0qo2b+Pw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.3.0.tgz", + "integrity": "sha512-BwBbZ5OAScPcm0x7H8SPbqjuEJnCU2RJT9LDyOiiIl/3NbL1nJZI4SFNHwU2e/tRr2Xe7JsptpzseqvZvToLBQ==", "requires": { "prosemirror-model": "^1.0.0", "prosemirror-state": "^1.0.0", @@ -46104,9 +46102,9 @@ } }, "prosemirror-history": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.1.3.tgz", - "integrity": "sha512-zGDotijea+vnfnyyUGyiy1wfOQhf0B/b6zYcCouBV8yo6JmrE9X23M5q7Nf/nATywEZbgRLG70R4DmfSTC+gfg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.3.0.tgz", + "integrity": "sha512-qo/9Wn4B/Bq89/YD+eNWFbAytu6dmIM85EhID+fz9Jcl9+DfGEo8TTSrRhP15+fFEoaPqpHSxlvSzSEbmlxlUA==", "requires": { "prosemirror-state": "^1.2.2", "prosemirror-transform": "^1.0.0", @@ -46114,54 +46112,54 @@ } }, "prosemirror-inputrules": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.1.3.tgz", - "integrity": "sha512-ZaHCLyBtvbyIHv0f5p6boQTIJjlD6o2NPZiEaZWT2DA+j591zS29QQEMT4lBqwcLW3qRSf7ZvoKNbf05YrsStw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.2.0.tgz", + "integrity": "sha512-eAW/M/NTSSzpCOxfR8Abw6OagdG0MiDAiWHQMQveIsZtoKVYzm0AflSPq/ymqJd56/Su1YPbwy9lM13wgHOFmQ==", "requires": { "prosemirror-state": "^1.0.0", "prosemirror-transform": "^1.0.0" } }, "prosemirror-keymap": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.1.4.tgz", - "integrity": "sha512-Al8cVUOnDFL4gcI5IDlG6xbZ0aOD/i3B17VT+1JbHWDguCgt/lBHVTHUBcKvvbSg6+q/W4Nj1Fu6bwZSca3xjg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.0.tgz", + "integrity": "sha512-TdSfu+YyLDd54ufN/ZeD1VtBRYpgZnTPnnbY+4R08DDgs84KrIPEPbJL8t1Lm2dkljFx6xeBE26YWH3aIzkPKg==", "requires": { "prosemirror-state": "^1.0.0", "w3c-keyname": "^2.2.0" } }, "prosemirror-model": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.14.1.tgz", - "integrity": "sha512-vZcbI+24VloFefKZkDnMaEpipL/vSKKPdFiik4KOnTzq3e6AO7+CAOixZ2G/SsfRaYC965XvnOIEbhIQdgki7w==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.18.1.tgz", + "integrity": "sha512-IxSVBKAEMjD7s3n8cgtwMlxAXZrC7Mlag7zYsAKDndAqnDScvSmp/UdnRTV/B33lTCVU3CCm7dyAn/rVVD0mcw==", "requires": { - "orderedmap": "^1.1.0" + "orderedmap": "^2.0.0" } }, "prosemirror-state": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.3.4.tgz", - "integrity": "sha512-Xkkrpd1y/TQ6HKzN3agsQIGRcLckUMA9u3j207L04mt8ToRgpGeyhbVv0HI7omDORIBHjR29b7AwlATFFf2GLA==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.1.tgz", + "integrity": "sha512-U/LBDW2gNmVa07sz/D229XigSdDQ5CLFwVB1Vb32MJbAHHhWe/6pOc721faI17tqw4pZ49i1xfY/jEZ9tbIhPg==", "requires": { "prosemirror-model": "^1.0.0", "prosemirror-transform": "^1.0.0" } }, "prosemirror-transform": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.3.0.tgz", - "integrity": "sha512-c6hWwm6k/yGitBM75yElXiSH0FVMn8adTss8kPDHKyfbqq5Px/dKjguhWINMe6AB/CqArpL5KLWDNbBI6K2Pmg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.6.0.tgz", + "integrity": "sha512-MAp7AjsjEGEqQY0sSMufNIUuEyB1ZR9Fqlm8dTwwWwpEJRv/plsKjWXBbx52q3Ml8MtaMcd7ic14zAHVB3WaMw==", "requires": { "prosemirror-model": "^1.0.0" } }, "prosemirror-view": { - "version": "1.18.7", - "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.18.7.tgz", - "integrity": "sha512-pUCxoyuWnbVfJ/ukhQ+7+bfDMArG3wu6hHnnTFi61C7Teb5OILUhkkhEhF2/RsppBFWrkwsNcf8rQm8SSoSKRg==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.27.0.tgz", + "integrity": "sha512-yNCQW5eiPkrMgjOT5Xa/ItIvcM7JBG7ikZKaHo26hdBW5OLNnIWGZ0BV6/OiBk742teLybLVNPCpYUcW405Ckg==", "requires": { - "prosemirror-model": "^1.1.0", + "prosemirror-model": "^1.16.0", "prosemirror-state": "^1.0.0", "prosemirror-transform": "^1.1.0" } diff --git a/plugins/code-syntax-highlight/src/nodeViews/codeSyntaxHighlightView.ts b/plugins/code-syntax-highlight/src/nodeViews/codeSyntaxHighlightView.ts index 9a43775f9d..7a9a7774c9 100644 --- a/plugins/code-syntax-highlight/src/nodeViews/codeSyntaxHighlightView.ts +++ b/plugins/code-syntax-highlight/src/nodeViews/codeSyntaxHighlightView.ts @@ -21,7 +21,7 @@ function getCustomAttrs(attrs: Record) { } class CodeSyntaxHighlightView implements NodeView { - dom: HTMLElement | null = null; + dom!: HTMLElement; contentDOM: HTMLElement | null = null; diff --git a/plugins/color-syntax/src/__test__/integration/colorSyntaxPlugin.spec.ts b/plugins/color-syntax/src/__test__/integration/colorSyntaxPlugin.spec.ts index 6449b11aa3..70d533d774 100644 --- a/plugins/color-syntax/src/__test__/integration/colorSyntaxPlugin.spec.ts +++ b/plugins/color-syntax/src/__test__/integration/colorSyntaxPlugin.spec.ts @@ -2,6 +2,7 @@ import Editor from '@toast-ui/editor'; import colorPicker from 'tui-color-picker'; import { oneLineTrim } from 'common-tags'; import colorSyntaxPlugin from '@/index'; +import { removeProseMirrorHackNodes } from '@/utils/dom'; function removeDataAttr(html: string) { return html @@ -16,7 +17,9 @@ describe('colorSyntax', () => { function assertWwEditorHTML(html: string) { const wwEditorEl = editor.getEditorElements().wwEditor; - expect(wwEditorEl).toContainHTML(html); + const wwEditorHTML = removeProseMirrorHackNodes(wwEditorEl.outerHTML); + + expect(wwEditorHTML).toContain(html); } function assertMdPreviewHTML(html: string) { diff --git a/plugins/color-syntax/src/utils/dom.ts b/plugins/color-syntax/src/utils/dom.ts index d0009ee2db..aee2e09c0f 100644 --- a/plugins/color-syntax/src/utils/dom.ts +++ b/plugins/color-syntax/src/utils/dom.ts @@ -11,3 +11,15 @@ export function findParentByClassName(el: HTMLElement, className: string) { return currentEl; } + +export function removeProseMirrorHackNodes(html: string) { + const reProseMirrorImage = //g; + const reProseMirrorTrailingBreak = / class="ProseMirror-trailingBreak"/g; + + let resultHTML = html; + + resultHTML = resultHTML.replace(reProseMirrorImage, ''); + resultHTML = resultHTML.replace(reProseMirrorTrailingBreak, ''); + + return resultHTML; +} diff --git a/plugins/table-merged-cell/src/__test__/integration/wysiwyg/addRow.spec.ts b/plugins/table-merged-cell/src/__test__/integration/wysiwyg/addRow.spec.ts index ff72b3915b..2829e57384 100644 --- a/plugins/table-merged-cell/src/__test__/integration/wysiwyg/addRow.spec.ts +++ b/plugins/table-merged-cell/src/__test__/integration/wysiwyg/addRow.spec.ts @@ -1,15 +1,9 @@ import { oneLineTrim } from 'common-tags'; import Editor from '@toast-ui/editor'; -import { createEditor } from './helper/utils'; +import { assertWYSIWYGHTML, createEditor } from './helper/utils'; let container: HTMLElement, editor: Editor; -function assertWYSIWYGHTML(html: string) { - const wwEditorEl = editor.getEditorElements().wwEditor; - - expect(wwEditorEl.innerHTML).toContain(html); -} - beforeEach(() => { const editorInfo = createEditor(); @@ -68,7 +62,7 @@ describe('addRowToUp command', () => { `; - assertWYSIWYGHTML(expected); + assertWYSIWYGHTML(editor, expected); }); it('should add row to up and extend row-spanning cell', () => { @@ -114,7 +108,7 @@ describe('addRowToUp command', () => { `; - assertWYSIWYGHTML(expected); + assertWYSIWYGHTML(editor, expected); }); it('should add row to up as many as the row-spanning count', () => { @@ -167,7 +161,7 @@ describe('addRowToUp command', () => { `; - assertWYSIWYGHTML(expected); + assertWYSIWYGHTML(editor, expected); }); }); @@ -217,7 +211,7 @@ describe('addRowToDown command', () => { `; - assertWYSIWYGHTML(expected); + assertWYSIWYGHTML(editor, expected); }); it('should add row to down and not extend row-spanning cell', () => { @@ -263,7 +257,7 @@ describe('addRowToDown command', () => { `; - assertWYSIWYGHTML(expected); + assertWYSIWYGHTML(editor, expected); }); it('should add row to down as many as the row-spanning count', () => { @@ -316,6 +310,6 @@ describe('addRowToDown command', () => { `; - assertWYSIWYGHTML(expected); + assertWYSIWYGHTML(editor, expected); }); }); diff --git a/plugins/table-merged-cell/src/__test__/integration/wysiwyg/helper/cellSelection.ts b/plugins/table-merged-cell/src/__test__/integration/wysiwyg/helper/cellSelection.ts index 17818e84f6..424b0178bc 100644 --- a/plugins/table-merged-cell/src/__test__/integration/wysiwyg/helper/cellSelection.ts +++ b/plugins/table-merged-cell/src/__test__/integration/wysiwyg/helper/cellSelection.ts @@ -126,8 +126,13 @@ export default class CellSelection extends Selection { const copiedRow = row.copy(Fragment.from(cells)); const targetNode = isTableHeadCell ? tableHead : tableBody; + // @ts-ignore targetNode.content = targetNode.content.append(Fragment.from(copiedRow)); } return new Slice(createTableFragment(tableHead, tableBody), 1, 1); } + + toJSON() { + return JSON.stringify(this); + } } diff --git a/plugins/table-merged-cell/src/__test__/integration/wysiwyg/helper/utils.ts b/plugins/table-merged-cell/src/__test__/integration/wysiwyg/helper/utils.ts index c4fe5abf2c..d67acf9f51 100644 --- a/plugins/table-merged-cell/src/__test__/integration/wysiwyg/helper/utils.ts +++ b/plugins/table-merged-cell/src/__test__/integration/wysiwyg/helper/utils.ts @@ -3,8 +3,9 @@ import mergedTableCellPlugin from '@/index'; export function assertWYSIWYGHTML(editor: Editor, html: string) { const wwEditorEl = editor.getEditorElements().wwEditor; + const wwEditorHTML = removeProseMirrorHackNodes(wwEditorEl.outerHTML); - expect(wwEditorEl.innerHTML).toContain(html); + expect(wwEditorHTML).toContain(html); } export function createEditor() { @@ -33,3 +34,15 @@ export function createEditor() { return { container, editor }; } + +export function removeProseMirrorHackNodes(html: string) { + const reProseMirrorImage = //g; + const reProseMirrorTrailingBreak = / class="ProseMirror-trailingBreak"/g; + + let resultHTML = html; + + resultHTML = resultHTML.replace(reProseMirrorImage, ''); + resultHTML = resultHTML.replace(reProseMirrorTrailingBreak, ''); + + return resultHTML; +}