@akinon/ui-editor 1.0.9 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/tiptap/extensions/__tests__/comment-extension.test.js +8 -4
- package/dist/cjs/tiptap/extensions/__tests__/comment-extension.test.ts +10 -4
- package/dist/cjs/tiptap/extensions/__tests__/custom-table-cell-extension.test.tsx +13 -1
- package/dist/cjs/tiptap/utils/tiptap-extensions.js +1 -1
- package/dist/esm/tiptap/extensions/__tests__/comment-extension.test.js +8 -4
- package/dist/esm/tiptap/extensions/__tests__/comment-extension.test.ts +10 -4
- package/dist/esm/tiptap/extensions/__tests__/custom-table-cell-extension.test.tsx +13 -1
- package/dist/esm/tiptap/utils/tiptap-extensions.js +1 -1
- package/package.json +9 -9
- package/dist/cjs/tiptap/utils/__tests__/format-html.test.d.ts +0 -2
- package/dist/cjs/tiptap/utils/__tests__/format-html.test.d.ts.map +0 -1
- package/dist/cjs/tiptap/utils/__tests__/format-html.test.js +0 -68
- package/dist/cjs/tiptap/utils/__tests__/format-html.test.ts +0 -91
- package/dist/cjs/tiptap/utils/__tests__/normalize-html.test.d.ts +0 -2
- package/dist/cjs/tiptap/utils/__tests__/normalize-html.test.d.ts.map +0 -1
- package/dist/cjs/tiptap/utils/__tests__/normalize-html.test.js +0 -53
- package/dist/cjs/tiptap/utils/__tests__/normalize-html.test.ts +0 -77
- package/dist/cjs/tiptap/utils/format-html.d.ts +0 -6
- package/dist/cjs/tiptap/utils/format-html.d.ts.map +0 -1
- package/dist/cjs/tiptap/utils/format-html.js +0 -108
- package/dist/cjs/tiptap/utils/normalize-html.d.ts +0 -7
- package/dist/cjs/tiptap/utils/normalize-html.d.ts.map +0 -1
- package/dist/cjs/tiptap/utils/normalize-html.js +0 -109
- package/dist/esm/tiptap/utils/__tests__/format-html.test.d.ts +0 -2
- package/dist/esm/tiptap/utils/__tests__/format-html.test.d.ts.map +0 -1
- package/dist/esm/tiptap/utils/__tests__/format-html.test.js +0 -68
- package/dist/esm/tiptap/utils/__tests__/format-html.test.ts +0 -91
- package/dist/esm/tiptap/utils/__tests__/normalize-html.test.d.ts +0 -2
- package/dist/esm/tiptap/utils/__tests__/normalize-html.test.d.ts.map +0 -1
- package/dist/esm/tiptap/utils/__tests__/normalize-html.test.js +0 -53
- package/dist/esm/tiptap/utils/__tests__/normalize-html.test.ts +0 -77
- package/dist/esm/tiptap/utils/format-html.d.ts +0 -6
- package/dist/esm/tiptap/utils/format-html.d.ts.map +0 -1
- package/dist/esm/tiptap/utils/format-html.js +0 -108
- package/dist/esm/tiptap/utils/normalize-html.d.ts +0 -7
- package/dist/esm/tiptap/utils/normalize-html.d.ts.map +0 -1
- package/dist/esm/tiptap/utils/normalize-html.js +0 -109
|
@@ -2,12 +2,16 @@ import { Editor } from '@tiptap/core';
|
|
|
2
2
|
import Document from '@tiptap/extension-document';
|
|
3
3
|
import Paragraph from '@tiptap/extension-paragraph';
|
|
4
4
|
import Text from '@tiptap/extension-text';
|
|
5
|
-
import { describe, expect, it } from 'vitest';
|
|
5
|
+
import { afterEach, describe, expect, it } from 'vitest';
|
|
6
6
|
import { CommentExtension } from '../comment-extension';
|
|
7
7
|
describe('CommentExtension', () => {
|
|
8
|
+
let editor;
|
|
9
|
+
afterEach(() => {
|
|
10
|
+
editor === null || editor === void 0 ? void 0 : editor.destroy();
|
|
11
|
+
});
|
|
8
12
|
it('should parse span with data-type="comment"', () => {
|
|
9
13
|
var _a, _b;
|
|
10
|
-
|
|
14
|
+
editor = new Editor({
|
|
11
15
|
extensions: [Document, Paragraph, Text, CommentExtension],
|
|
12
16
|
content: '<span data-type="comment" data-content="test comment">text</span>'
|
|
13
17
|
});
|
|
@@ -24,7 +28,7 @@ describe('CommentExtension', () => {
|
|
|
24
28
|
]);
|
|
25
29
|
});
|
|
26
30
|
it('should render span with correct attributes', () => {
|
|
27
|
-
|
|
31
|
+
editor = new Editor({
|
|
28
32
|
extensions: [Document, Paragraph, Text, CommentExtension],
|
|
29
33
|
content: {
|
|
30
34
|
type: 'doc',
|
|
@@ -55,7 +59,7 @@ describe('CommentExtension', () => {
|
|
|
55
59
|
});
|
|
56
60
|
it('should execute setComment command', () => {
|
|
57
61
|
var _a, _b;
|
|
58
|
-
|
|
62
|
+
editor = new Editor({
|
|
59
63
|
extensions: [Document, Paragraph, Text, CommentExtension]
|
|
60
64
|
});
|
|
61
65
|
editor.commands.setContent('<p>test</p>');
|
|
@@ -2,13 +2,19 @@ import { Editor } from '@tiptap/core';
|
|
|
2
2
|
import Document from '@tiptap/extension-document';
|
|
3
3
|
import Paragraph from '@tiptap/extension-paragraph';
|
|
4
4
|
import Text from '@tiptap/extension-text';
|
|
5
|
-
import { describe, expect, it } from 'vitest';
|
|
5
|
+
import { afterEach, describe, expect, it } from 'vitest';
|
|
6
6
|
|
|
7
7
|
import { CommentExtension } from '../comment-extension';
|
|
8
8
|
|
|
9
9
|
describe('CommentExtension', () => {
|
|
10
|
+
let editor: Editor;
|
|
11
|
+
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
editor?.destroy();
|
|
14
|
+
});
|
|
15
|
+
|
|
10
16
|
it('should parse span with data-type="comment"', () => {
|
|
11
|
-
|
|
17
|
+
editor = new Editor({
|
|
12
18
|
extensions: [Document, Paragraph, Text, CommentExtension],
|
|
13
19
|
content:
|
|
14
20
|
'<span data-type="comment" data-content="test comment">text</span>'
|
|
@@ -29,7 +35,7 @@ describe('CommentExtension', () => {
|
|
|
29
35
|
});
|
|
30
36
|
|
|
31
37
|
it('should render span with correct attributes', () => {
|
|
32
|
-
|
|
38
|
+
editor = new Editor({
|
|
33
39
|
extensions: [Document, Paragraph, Text, CommentExtension],
|
|
34
40
|
content: {
|
|
35
41
|
type: 'doc',
|
|
@@ -61,7 +67,7 @@ describe('CommentExtension', () => {
|
|
|
61
67
|
});
|
|
62
68
|
|
|
63
69
|
it('should execute setComment command', () => {
|
|
64
|
-
|
|
70
|
+
editor = new Editor({
|
|
65
71
|
extensions: [Document, Paragraph, Text, CommentExtension]
|
|
66
72
|
});
|
|
67
73
|
|
|
@@ -4,11 +4,21 @@ import Paragraph from '@tiptap/extension-paragraph';
|
|
|
4
4
|
import { Table, TableRow } from '@tiptap/extension-table';
|
|
5
5
|
import Text from '@tiptap/extension-text';
|
|
6
6
|
import { NodeType } from '@tiptap/pm/model';
|
|
7
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
7
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
8
8
|
|
|
9
9
|
import { CustomTableCell } from '../custom-table-cell-extension';
|
|
10
10
|
import { CustomTableHeader } from '../custom-table-header-extension';
|
|
11
11
|
|
|
12
|
+
// ProseMirror's DOMObserver schedules a flush via setTimeout after the editor
|
|
13
|
+
// mounts. If the editor is not destroyed before the happy-dom environment is
|
|
14
|
+
// torn down, that timer fires post-teardown and throws "document is not
|
|
15
|
+
// defined", failing the pipeline step even though every test passed. Tracking
|
|
16
|
+
// every Editor instance and destroying it in afterEach cancels the timer.
|
|
17
|
+
const editors: Editor[] = [];
|
|
18
|
+
afterEach(() => {
|
|
19
|
+
while (editors.length) editors.pop()?.destroy();
|
|
20
|
+
});
|
|
21
|
+
|
|
12
22
|
describe('CustomTableCell', () => {
|
|
13
23
|
it('should render with custom attributes', () => {
|
|
14
24
|
const editor = new Editor({
|
|
@@ -31,6 +41,7 @@ describe('CustomTableCell', () => {
|
|
|
31
41
|
</table>
|
|
32
42
|
`
|
|
33
43
|
});
|
|
44
|
+
editors.push(editor);
|
|
34
45
|
|
|
35
46
|
const cell = editor.view.dom.querySelector('td');
|
|
36
47
|
expect(cell).not.toBeNull();
|
|
@@ -55,6 +66,7 @@ describe('CustomTableCell', () => {
|
|
|
55
66
|
CustomTableHeader
|
|
56
67
|
]
|
|
57
68
|
});
|
|
69
|
+
editors.push(editor2);
|
|
58
70
|
|
|
59
71
|
expect(() => {
|
|
60
72
|
editor2.commands.insertTable({ rows: 3, cols: 3 });
|
|
@@ -40,7 +40,7 @@ import { HTML_ELEMENTS } from '../constants/html-elements';
|
|
|
40
40
|
import { CommentExtension, CustomTableCell, CustomTableHeader, HtmlBlockExtension, HtmlInlineExtension, IframeExtension, ImageUploadExtension, ResetMarksOnEnter } from '../extensions';
|
|
41
41
|
import { SecureScriptExtension } from '../extensions/secure-script-extension';
|
|
42
42
|
import { addDataAttributesToParent, extractDataAttributes } from './data-attributes-helper';
|
|
43
|
-
const DROP_CURSOR_COLOR = '
|
|
43
|
+
const DROP_CURSOR_COLOR = 'var(--color-neutral-50)';
|
|
44
44
|
export const getExtensions = (placeholder) => [
|
|
45
45
|
Document.extend({
|
|
46
46
|
content: '(block|horizontalRule)+'
|
|
@@ -2,12 +2,16 @@ import { Editor } from '@tiptap/core';
|
|
|
2
2
|
import Document from '@tiptap/extension-document';
|
|
3
3
|
import Paragraph from '@tiptap/extension-paragraph';
|
|
4
4
|
import Text from '@tiptap/extension-text';
|
|
5
|
-
import { describe, expect, it } from 'vitest';
|
|
5
|
+
import { afterEach, describe, expect, it } from 'vitest';
|
|
6
6
|
import { CommentExtension } from '../comment-extension';
|
|
7
7
|
describe('CommentExtension', () => {
|
|
8
|
+
let editor;
|
|
9
|
+
afterEach(() => {
|
|
10
|
+
editor === null || editor === void 0 ? void 0 : editor.destroy();
|
|
11
|
+
});
|
|
8
12
|
it('should parse span with data-type="comment"', () => {
|
|
9
13
|
var _a, _b;
|
|
10
|
-
|
|
14
|
+
editor = new Editor({
|
|
11
15
|
extensions: [Document, Paragraph, Text, CommentExtension],
|
|
12
16
|
content: '<span data-type="comment" data-content="test comment">text</span>'
|
|
13
17
|
});
|
|
@@ -24,7 +28,7 @@ describe('CommentExtension', () => {
|
|
|
24
28
|
]);
|
|
25
29
|
});
|
|
26
30
|
it('should render span with correct attributes', () => {
|
|
27
|
-
|
|
31
|
+
editor = new Editor({
|
|
28
32
|
extensions: [Document, Paragraph, Text, CommentExtension],
|
|
29
33
|
content: {
|
|
30
34
|
type: 'doc',
|
|
@@ -55,7 +59,7 @@ describe('CommentExtension', () => {
|
|
|
55
59
|
});
|
|
56
60
|
it('should execute setComment command', () => {
|
|
57
61
|
var _a, _b;
|
|
58
|
-
|
|
62
|
+
editor = new Editor({
|
|
59
63
|
extensions: [Document, Paragraph, Text, CommentExtension]
|
|
60
64
|
});
|
|
61
65
|
editor.commands.setContent('<p>test</p>');
|
|
@@ -2,13 +2,19 @@ import { Editor } from '@tiptap/core';
|
|
|
2
2
|
import Document from '@tiptap/extension-document';
|
|
3
3
|
import Paragraph from '@tiptap/extension-paragraph';
|
|
4
4
|
import Text from '@tiptap/extension-text';
|
|
5
|
-
import { describe, expect, it } from 'vitest';
|
|
5
|
+
import { afterEach, describe, expect, it } from 'vitest';
|
|
6
6
|
|
|
7
7
|
import { CommentExtension } from '../comment-extension';
|
|
8
8
|
|
|
9
9
|
describe('CommentExtension', () => {
|
|
10
|
+
let editor: Editor;
|
|
11
|
+
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
editor?.destroy();
|
|
14
|
+
});
|
|
15
|
+
|
|
10
16
|
it('should parse span with data-type="comment"', () => {
|
|
11
|
-
|
|
17
|
+
editor = new Editor({
|
|
12
18
|
extensions: [Document, Paragraph, Text, CommentExtension],
|
|
13
19
|
content:
|
|
14
20
|
'<span data-type="comment" data-content="test comment">text</span>'
|
|
@@ -29,7 +35,7 @@ describe('CommentExtension', () => {
|
|
|
29
35
|
});
|
|
30
36
|
|
|
31
37
|
it('should render span with correct attributes', () => {
|
|
32
|
-
|
|
38
|
+
editor = new Editor({
|
|
33
39
|
extensions: [Document, Paragraph, Text, CommentExtension],
|
|
34
40
|
content: {
|
|
35
41
|
type: 'doc',
|
|
@@ -61,7 +67,7 @@ describe('CommentExtension', () => {
|
|
|
61
67
|
});
|
|
62
68
|
|
|
63
69
|
it('should execute setComment command', () => {
|
|
64
|
-
|
|
70
|
+
editor = new Editor({
|
|
65
71
|
extensions: [Document, Paragraph, Text, CommentExtension]
|
|
66
72
|
});
|
|
67
73
|
|
|
@@ -4,11 +4,21 @@ import Paragraph from '@tiptap/extension-paragraph';
|
|
|
4
4
|
import { Table, TableRow } from '@tiptap/extension-table';
|
|
5
5
|
import Text from '@tiptap/extension-text';
|
|
6
6
|
import { NodeType } from '@tiptap/pm/model';
|
|
7
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
7
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
8
8
|
|
|
9
9
|
import { CustomTableCell } from '../custom-table-cell-extension';
|
|
10
10
|
import { CustomTableHeader } from '../custom-table-header-extension';
|
|
11
11
|
|
|
12
|
+
// ProseMirror's DOMObserver schedules a flush via setTimeout after the editor
|
|
13
|
+
// mounts. If the editor is not destroyed before the happy-dom environment is
|
|
14
|
+
// torn down, that timer fires post-teardown and throws "document is not
|
|
15
|
+
// defined", failing the pipeline step even though every test passed. Tracking
|
|
16
|
+
// every Editor instance and destroying it in afterEach cancels the timer.
|
|
17
|
+
const editors: Editor[] = [];
|
|
18
|
+
afterEach(() => {
|
|
19
|
+
while (editors.length) editors.pop()?.destroy();
|
|
20
|
+
});
|
|
21
|
+
|
|
12
22
|
describe('CustomTableCell', () => {
|
|
13
23
|
it('should render with custom attributes', () => {
|
|
14
24
|
const editor = new Editor({
|
|
@@ -31,6 +41,7 @@ describe('CustomTableCell', () => {
|
|
|
31
41
|
</table>
|
|
32
42
|
`
|
|
33
43
|
});
|
|
44
|
+
editors.push(editor);
|
|
34
45
|
|
|
35
46
|
const cell = editor.view.dom.querySelector('td');
|
|
36
47
|
expect(cell).not.toBeNull();
|
|
@@ -55,6 +66,7 @@ describe('CustomTableCell', () => {
|
|
|
55
66
|
CustomTableHeader
|
|
56
67
|
]
|
|
57
68
|
});
|
|
69
|
+
editors.push(editor2);
|
|
58
70
|
|
|
59
71
|
expect(() => {
|
|
60
72
|
editor2.commands.insertTable({ rows: 3, cols: 3 });
|
|
@@ -40,7 +40,7 @@ import { HTML_ELEMENTS } from '../constants/html-elements';
|
|
|
40
40
|
import { CommentExtension, CustomTableCell, CustomTableHeader, HtmlBlockExtension, HtmlInlineExtension, IframeExtension, ImageUploadExtension, ResetMarksOnEnter } from '../extensions';
|
|
41
41
|
import { SecureScriptExtension } from '../extensions/secure-script-extension';
|
|
42
42
|
import { addDataAttributesToParent, extractDataAttributes } from './data-attributes-helper';
|
|
43
|
-
const DROP_CURSOR_COLOR = '
|
|
43
|
+
const DROP_CURSOR_COLOR = 'var(--color-neutral-50)';
|
|
44
44
|
export const getExtensions = (placeholder) => [
|
|
45
45
|
Document.extend({
|
|
46
46
|
content: '(block|horizontalRule)+'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akinon/ui-editor",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A headless lightweight text editor for Akinon.",
|
|
6
6
|
"type": "module",
|
|
@@ -53,23 +53,23 @@
|
|
|
53
53
|
"prettier": "^3.6.2",
|
|
54
54
|
"y-protocols": "^1.0.7",
|
|
55
55
|
"yjs": "^13.6.29",
|
|
56
|
-
"@akinon/
|
|
56
|
+
"@akinon/akilocale": "1.2.8",
|
|
57
|
+
"@akinon/ui-button": "1.5.1",
|
|
57
58
|
"@akinon/ui-color-picker": "1.1.8",
|
|
58
59
|
"@akinon/ui-dropdown": "1.1.8",
|
|
60
|
+
"@akinon/ui-input": "1.2.9",
|
|
59
61
|
"@akinon/ui-popover": "1.1.8",
|
|
60
|
-
"@akinon/ui-select": "1.4.
|
|
61
|
-
"@akinon/ui-
|
|
62
|
-
"@akinon/ui-
|
|
63
|
-
"@akinon/ui-theme": "1.2.8",
|
|
64
|
-
"@akinon/akilocale": "1.2.8"
|
|
62
|
+
"@akinon/ui-select": "1.4.11",
|
|
63
|
+
"@akinon/ui-theme": "1.3.0",
|
|
64
|
+
"@akinon/ui-upload": "1.5.1"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
67
|
"clean-package": "^2.2.0",
|
|
68
68
|
"copyfiles": "^2.4.1",
|
|
69
69
|
"rimraf": "^5.0.10",
|
|
70
70
|
"typescript": "*",
|
|
71
|
-
"@akinon/
|
|
72
|
-
"@akinon/
|
|
71
|
+
"@akinon/typescript-config": "1.1.8",
|
|
72
|
+
"@akinon/vitest-config": "1.1.8"
|
|
73
73
|
},
|
|
74
74
|
"peerDependencies": {
|
|
75
75
|
"react": "^18 || ^19",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"format-html.test.d.ts","sourceRoot":"","sources":["../../../../../src/tiptap/utils/__tests__/format-html.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { formatHtml } from '../format-html';
|
|
3
|
-
describe('formatHtml', () => {
|
|
4
|
-
it('should format simple nested divs with indentation', () => {
|
|
5
|
-
const input = '<div><div>content</div></div>';
|
|
6
|
-
const expected = `
|
|
7
|
-
<div>
|
|
8
|
-
<div>content</div>
|
|
9
|
-
</div>
|
|
10
|
-
`.trim();
|
|
11
|
-
expect(formatHtml(input)).toBe(expected);
|
|
12
|
-
});
|
|
13
|
-
it('should handle attributes correctly', () => {
|
|
14
|
-
const input = '<div class="foo" id="bar">content</div>';
|
|
15
|
-
expect(formatHtml(input)).toBe(input.trim());
|
|
16
|
-
});
|
|
17
|
-
it('should handle void elements like br and hr', () => {
|
|
18
|
-
const input = '<div>text<br />more text<hr /></div>';
|
|
19
|
-
const output = formatHtml(input);
|
|
20
|
-
expect(output).toContain('<br />');
|
|
21
|
-
expect(output).toContain('<hr />');
|
|
22
|
-
});
|
|
23
|
-
it('should preserve whitespace in pre tags', () => {
|
|
24
|
-
const input = '<pre> keep this space </pre>';
|
|
25
|
-
expect(formatHtml(input)).toBe(input.trim());
|
|
26
|
-
});
|
|
27
|
-
it('should ensure newline before block elements', () => {
|
|
28
|
-
const input = '<span>text</span><div>block</div>';
|
|
29
|
-
const expected = `
|
|
30
|
-
<span>text</span>
|
|
31
|
-
<div>block</div>
|
|
32
|
-
`.trim();
|
|
33
|
-
expect(formatHtml(input)).toBe(expected);
|
|
34
|
-
});
|
|
35
|
-
it('should dedent script content', () => {
|
|
36
|
-
const input = `<script>
|
|
37
|
-
function foo() {
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
</script>`;
|
|
41
|
-
const output = formatHtml(input);
|
|
42
|
-
expect(output).toContain('function foo() {');
|
|
43
|
-
expect(output).toContain(' return true;');
|
|
44
|
-
});
|
|
45
|
-
it('should handle empty script tags', () => {
|
|
46
|
-
const input = '<script></script>';
|
|
47
|
-
expect(formatHtml(input)).toBe(input);
|
|
48
|
-
});
|
|
49
|
-
it('should convert comment spans back to HTML comments', () => {
|
|
50
|
-
const input = '<span data-type="comment" data-content=" my comment "></span>';
|
|
51
|
-
const expected = '<!-- my comment -->';
|
|
52
|
-
expect(formatHtml(input)).toBe(expected);
|
|
53
|
-
const inputMissingContent = '<span data-type="comment"></span>';
|
|
54
|
-
const expectedMissingContent = '<!---->';
|
|
55
|
-
expect(formatHtml(inputMissingContent)).toBe(expectedMissingContent);
|
|
56
|
-
});
|
|
57
|
-
it('should handle scripts with empty lines', () => {
|
|
58
|
-
const input = `<script>
|
|
59
|
-
var a = 1;
|
|
60
|
-
|
|
61
|
-
var b = 2;
|
|
62
|
-
</script>`;
|
|
63
|
-
const output = formatHtml(input);
|
|
64
|
-
expect(output).toContain('var a = 1;');
|
|
65
|
-
expect(output).toContain('var b = 2;');
|
|
66
|
-
expect(output).toMatch(/;\n\s*var b/);
|
|
67
|
-
});
|
|
68
|
-
});
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
|
|
3
|
-
import { formatHtml } from '../format-html';
|
|
4
|
-
|
|
5
|
-
describe('formatHtml', () => {
|
|
6
|
-
it('should format simple nested divs with indentation', () => {
|
|
7
|
-
const input = '<div><div>content</div></div>';
|
|
8
|
-
const expected = `
|
|
9
|
-
<div>
|
|
10
|
-
<div>content</div>
|
|
11
|
-
</div>
|
|
12
|
-
`.trim();
|
|
13
|
-
|
|
14
|
-
expect(formatHtml(input)).toBe(expected);
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it('should handle attributes correctly', () => {
|
|
18
|
-
const input = '<div class="foo" id="bar">content</div>';
|
|
19
|
-
|
|
20
|
-
expect(formatHtml(input)).toBe(input.trim());
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('should handle void elements like br and hr', () => {
|
|
24
|
-
const input = '<div>text<br />more text<hr /></div>';
|
|
25
|
-
const output = formatHtml(input);
|
|
26
|
-
|
|
27
|
-
expect(output).toContain('<br />');
|
|
28
|
-
expect(output).toContain('<hr />');
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('should preserve whitespace in pre tags', () => {
|
|
32
|
-
const input = '<pre> keep this space </pre>';
|
|
33
|
-
|
|
34
|
-
expect(formatHtml(input)).toBe(input.trim());
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('should ensure newline before block elements', () => {
|
|
38
|
-
const input = '<span>text</span><div>block</div>';
|
|
39
|
-
const expected = `
|
|
40
|
-
<span>text</span>
|
|
41
|
-
<div>block</div>
|
|
42
|
-
`.trim();
|
|
43
|
-
expect(formatHtml(input)).toBe(expected);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('should dedent script content', () => {
|
|
47
|
-
const input = `<script>
|
|
48
|
-
function foo() {
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
</script>`;
|
|
52
|
-
|
|
53
|
-
const output = formatHtml(input);
|
|
54
|
-
|
|
55
|
-
expect(output).toContain('function foo() {');
|
|
56
|
-
expect(output).toContain(' return true;');
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('should handle empty script tags', () => {
|
|
60
|
-
const input = '<script></script>';
|
|
61
|
-
|
|
62
|
-
expect(formatHtml(input)).toBe(input);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('should convert comment spans back to HTML comments', () => {
|
|
66
|
-
const input =
|
|
67
|
-
'<span data-type="comment" data-content=" my comment "></span>';
|
|
68
|
-
const expected = '<!-- my comment -->';
|
|
69
|
-
|
|
70
|
-
expect(formatHtml(input)).toBe(expected);
|
|
71
|
-
|
|
72
|
-
const inputMissingContent = '<span data-type="comment"></span>';
|
|
73
|
-
const expectedMissingContent = '<!---->';
|
|
74
|
-
|
|
75
|
-
expect(formatHtml(inputMissingContent)).toBe(expectedMissingContent);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('should handle scripts with empty lines', () => {
|
|
79
|
-
const input = `<script>
|
|
80
|
-
var a = 1;
|
|
81
|
-
|
|
82
|
-
var b = 2;
|
|
83
|
-
</script>`;
|
|
84
|
-
|
|
85
|
-
const output = formatHtml(input);
|
|
86
|
-
|
|
87
|
-
expect(output).toContain('var a = 1;');
|
|
88
|
-
expect(output).toContain('var b = 2;');
|
|
89
|
-
expect(output).toMatch(/;\n\s*var b/);
|
|
90
|
-
});
|
|
91
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"normalize-html.test.d.ts","sourceRoot":"","sources":["../../../../../src/tiptap/utils/__tests__/normalize-html.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { normalizeHtml } from '../normalize-html';
|
|
3
|
-
describe('normalizeHtml', () => {
|
|
4
|
-
it('should convert HTML comments to span placeholders', () => {
|
|
5
|
-
const input = '<div><!-- my comment --></div>';
|
|
6
|
-
const output = normalizeHtml(input);
|
|
7
|
-
expect(output).toContain('<span data-type="comment" data-content=" my comment "></span>');
|
|
8
|
-
const inputEmpty = '<!---->';
|
|
9
|
-
expect(normalizeHtml(inputEmpty)).toContain('<span data-type="comment" data-content=""></span>');
|
|
10
|
-
});
|
|
11
|
-
it('should dedent script tags to avoid extra indentation', () => {
|
|
12
|
-
const input = `
|
|
13
|
-
<script>
|
|
14
|
-
console.log('test');
|
|
15
|
-
</script>
|
|
16
|
-
`;
|
|
17
|
-
const output = normalizeHtml(input);
|
|
18
|
-
expect(output).toContain("console.log('test');");
|
|
19
|
-
});
|
|
20
|
-
it('should flatten empty paragraphs containing only breaks', () => {
|
|
21
|
-
const input = '<p><br></p>';
|
|
22
|
-
const output = normalizeHtml(input);
|
|
23
|
-
expect(output).toBe('<br>');
|
|
24
|
-
});
|
|
25
|
-
it('should merge consecutive break tags if they are excessive', () => {
|
|
26
|
-
const input = 'Line<br><br>Line';
|
|
27
|
-
const output = normalizeHtml(input);
|
|
28
|
-
expect(output).toBe('Line<br>Line');
|
|
29
|
-
});
|
|
30
|
-
it('should merge consecutive break tags separated by whitespace', () => {
|
|
31
|
-
const input = 'Line<br> <br>Line';
|
|
32
|
-
const output = normalizeHtml(input);
|
|
33
|
-
expect(output).toBe('Line <br>Line');
|
|
34
|
-
});
|
|
35
|
-
it('should unwrap HR elements from paragraphs', () => {
|
|
36
|
-
const input = '<p><hr></p>';
|
|
37
|
-
const output = normalizeHtml(input);
|
|
38
|
-
expect(output).toBe('<hr>');
|
|
39
|
-
const inputWithSpace = '<p> <hr> </p>';
|
|
40
|
-
const outputWithSpace = normalizeHtml(inputWithSpace);
|
|
41
|
-
expect(outputWithSpace).toBe('<hr>');
|
|
42
|
-
});
|
|
43
|
-
it('should NOT unwrap HR from paragraphs if there is other content', () => {
|
|
44
|
-
const input = '<p>Content<hr></p>';
|
|
45
|
-
const output = normalizeHtml(input);
|
|
46
|
-
expect(output).toBe('<p>Content<hr></p>');
|
|
47
|
-
});
|
|
48
|
-
it('should flatten empty paragraphs containing whitespace and breaks', () => {
|
|
49
|
-
const input = '<p> <br> </p>';
|
|
50
|
-
const output = normalizeHtml(input);
|
|
51
|
-
expect(output).toBe('<br>');
|
|
52
|
-
});
|
|
53
|
-
});
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
|
|
3
|
-
import { normalizeHtml } from '../normalize-html';
|
|
4
|
-
|
|
5
|
-
describe('normalizeHtml', () => {
|
|
6
|
-
it('should convert HTML comments to span placeholders', () => {
|
|
7
|
-
const input = '<div><!-- my comment --></div>';
|
|
8
|
-
const output = normalizeHtml(input);
|
|
9
|
-
|
|
10
|
-
expect(output).toContain(
|
|
11
|
-
'<span data-type="comment" data-content=" my comment "></span>'
|
|
12
|
-
);
|
|
13
|
-
|
|
14
|
-
const inputEmpty = '<!---->';
|
|
15
|
-
expect(normalizeHtml(inputEmpty)).toContain(
|
|
16
|
-
'<span data-type="comment" data-content=""></span>'
|
|
17
|
-
);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('should dedent script tags to avoid extra indentation', () => {
|
|
21
|
-
const input = `
|
|
22
|
-
<script>
|
|
23
|
-
console.log('test');
|
|
24
|
-
</script>
|
|
25
|
-
`;
|
|
26
|
-
const output = normalizeHtml(input);
|
|
27
|
-
|
|
28
|
-
expect(output).toContain("console.log('test');");
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('should flatten empty paragraphs containing only breaks', () => {
|
|
32
|
-
const input = '<p><br></p>';
|
|
33
|
-
const output = normalizeHtml(input);
|
|
34
|
-
|
|
35
|
-
expect(output).toBe('<br>');
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it('should merge consecutive break tags if they are excessive', () => {
|
|
39
|
-
const input = 'Line<br><br>Line';
|
|
40
|
-
const output = normalizeHtml(input);
|
|
41
|
-
|
|
42
|
-
expect(output).toBe('Line<br>Line');
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('should merge consecutive break tags separated by whitespace', () => {
|
|
46
|
-
const input = 'Line<br> <br>Line';
|
|
47
|
-
const output = normalizeHtml(input);
|
|
48
|
-
|
|
49
|
-
expect(output).toBe('Line <br>Line');
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('should unwrap HR elements from paragraphs', () => {
|
|
53
|
-
const input = '<p><hr></p>';
|
|
54
|
-
const output = normalizeHtml(input);
|
|
55
|
-
|
|
56
|
-
expect(output).toBe('<hr>');
|
|
57
|
-
|
|
58
|
-
const inputWithSpace = '<p> <hr> </p>';
|
|
59
|
-
const outputWithSpace = normalizeHtml(inputWithSpace);
|
|
60
|
-
|
|
61
|
-
expect(outputWithSpace).toBe('<hr>');
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('should NOT unwrap HR from paragraphs if there is other content', () => {
|
|
65
|
-
const input = '<p>Content<hr></p>';
|
|
66
|
-
const output = normalizeHtml(input);
|
|
67
|
-
|
|
68
|
-
expect(output).toBe('<p>Content<hr></p>');
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it('should flatten empty paragraphs containing whitespace and breaks', () => {
|
|
72
|
-
const input = '<p> <br> </p>';
|
|
73
|
-
const output = normalizeHtml(input);
|
|
74
|
-
|
|
75
|
-
expect(output).toBe('<br>');
|
|
76
|
-
});
|
|
77
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"format-html.d.ts","sourceRoot":"","sources":["../../../../src/tiptap/utils/format-html.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,KAAG,MAQzC,CAAC"}
|