@zipify/wysiwyg 1.3.0-0 → 2.0.0-0
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/cli.js +2 -2
- package/dist/wysiwyg.css +31 -42
- package/dist/wysiwyg.mjs +454 -399
- package/lib/__tests__/utils/buildTestExtensions.js +14 -0
- package/lib/__tests__/utils/index.js +1 -0
- package/lib/components/base/Button.vue +0 -7
- package/lib/components/base/dropdown/Dropdown.vue +1 -7
- package/lib/components/base/dropdown/DropdownActivator.vue +4 -19
- package/lib/components/base/dropdown/__tests__/DropdownActivator.test.js +1 -23
- package/lib/components/toolbar/controls/AlignmentControl.vue +1 -11
- package/lib/components/toolbar/controls/FontColorControl.vue +0 -13
- package/lib/components/toolbar/controls/FontFamilyControl.vue +0 -4
- package/lib/components/toolbar/controls/FontSizeControl.vue +1 -6
- package/lib/components/toolbar/controls/FontWeightControl.vue +0 -12
- package/lib/components/toolbar/controls/ItalicControl.vue +0 -13
- package/lib/components/toolbar/controls/LineHeightControl.vue +0 -14
- package/lib/components/toolbar/controls/SuperscriptControl.vue +2 -2
- package/lib/components/toolbar/controls/UnderlineControl.vue +0 -12
- package/lib/components/toolbar/controls/__tests__/AlignmentControl.test.js +5 -72
- package/lib/components/toolbar/controls/__tests__/FontColorControl.test.js +1 -22
- package/lib/components/toolbar/controls/__tests__/FontFamilyControl.test.js +0 -1
- package/lib/components/toolbar/controls/__tests__/FontSizeControl.test.js +0 -1
- package/lib/components/toolbar/controls/__tests__/FontWeightControl.test.js +0 -1
- package/lib/components/toolbar/controls/__tests__/ItalicControl.test.js +1 -23
- package/lib/components/toolbar/controls/__tests__/LineHeightControl.test.js +1 -23
- package/lib/components/toolbar/controls/__tests__/SuperscriptControl.test.js +2 -2
- package/lib/components/toolbar/controls/__tests__/UnderlineControl.test.js +1 -25
- package/lib/composables/__tests__/useEditor.test.js +2 -2
- package/lib/extensions/BackgroundColor.js +4 -4
- package/lib/extensions/FontColor.js +4 -5
- package/lib/extensions/FontFamily.js +4 -5
- package/lib/extensions/FontSize.js +5 -7
- package/lib/extensions/FontStyle.js +13 -11
- package/lib/extensions/FontWeight.js +6 -9
- package/lib/extensions/StylePreset.js +0 -14
- package/lib/extensions/Superscript.js +23 -1
- package/lib/extensions/TextDecoration.js +33 -20
- package/lib/extensions/__tests__/Alignment.test.js +10 -7
- package/lib/extensions/__tests__/BackgroundColor.test.js +6 -3
- package/lib/extensions/__tests__/CaseStyle.test.js +11 -7
- package/lib/extensions/__tests__/FontColor.test.js +6 -3
- package/lib/extensions/__tests__/FontFamily.test.js +29 -22
- package/lib/extensions/__tests__/FontSize.test.js +24 -17
- package/lib/extensions/__tests__/FontStyle.test.js +22 -16
- package/lib/extensions/__tests__/FontWeight.test.js +26 -19
- package/lib/extensions/__tests__/LineHeight.test.js +14 -11
- package/lib/extensions/__tests__/Link.test.js +14 -10
- package/lib/extensions/__tests__/Margin.test.js +2 -2
- package/lib/extensions/__tests__/StylePreset.test.js +49 -100
- package/lib/extensions/__tests__/TextDecoration.test.js +72 -46
- package/lib/extensions/__tests__/__snapshots__/BackgroundColor.test.js.snap +24 -24
- package/lib/extensions/__tests__/__snapshots__/FontColor.test.js.snap +24 -24
- package/lib/extensions/__tests__/__snapshots__/FontFamily.test.js.snap +86 -82
- package/lib/extensions/__tests__/__snapshots__/FontSize.test.js.snap +70 -70
- package/lib/extensions/__tests__/__snapshots__/FontStyle.test.js.snap +53 -45
- package/lib/extensions/__tests__/__snapshots__/FontWeight.test.js.snap +64 -60
- package/lib/extensions/__tests__/__snapshots__/TextDecoration.test.js.snap +148 -83
- package/lib/extensions/core/Document.js +5 -0
- package/lib/extensions/core/Heading.js +10 -0
- package/lib/extensions/core/NodeProcessor.js +84 -4
- package/lib/extensions/core/Paragraph.js +9 -0
- package/lib/extensions/core/TextProcessor.js +10 -12
- package/lib/extensions/core/__tests__/NodeProcessor.test.js +82 -10
- package/lib/extensions/core/__tests__/SelectionProcessor.test.js +2 -2
- package/lib/extensions/core/__tests__/TextProcessor.test.js +18 -20
- package/lib/extensions/core/__tests__/__snapshots__/NodeProcessor.test.js.snap +132 -0
- package/lib/extensions/core/index.js +5 -5
- package/lib/extensions/core/steps/AddNodeMarkStep.js +60 -0
- package/lib/extensions/core/steps/RemoveNodeMarkStep.js +50 -0
- package/lib/extensions/core/steps/index.js +2 -0
- package/lib/extensions/list/List.js +1 -0
- package/lib/extensions/list/ListItem.js +5 -0
- package/lib/extensions/list/__tests__/List.test.js +30 -25
- package/lib/services/ContentNormalizer.js +1 -100
- package/lib/services/NodeFactory.js +16 -6
- package/lib/services/__tests__/ContentNormalizer.test.js +0 -64
- package/lib/utils/findMarkByType.js +5 -0
- package/lib/utils/index.js +5 -0
- package/lib/utils/isMarkAppliedToParent.js +15 -0
- package/lib/utils/isNodeFullySelected.js +10 -0
- package/lib/utils/resolveNodePosition.js +6 -0
- package/lib/utils/resolveTextPosition.js +6 -0
- package/package.json +1 -1
- package/lib/assets/icons/indicator.svg +0 -5
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Extension } from '@tiptap/vue-2';
|
|
2
|
-
import { createCommand } from '../../utils';
|
|
2
|
+
import { createCommand, resolveTextPosition } from '../../utils';
|
|
3
3
|
|
|
4
4
|
export const TextProcessor = Extension.create({
|
|
5
5
|
name: 'text_processor',
|
|
@@ -13,30 +13,28 @@ export const TextProcessor = Extension.create({
|
|
|
13
13
|
}),
|
|
14
14
|
|
|
15
15
|
unsetMarks: createCommand(({ commands }, marks) => {
|
|
16
|
+
// TODO check unset mark
|
|
16
17
|
marks.forEach((mark) => commands.unsetMark(mark));
|
|
17
18
|
}),
|
|
18
19
|
|
|
19
20
|
transformText: createCommand(({ state }, transform) => {
|
|
20
|
-
const {
|
|
21
|
+
const { $from, $to } = state.tr.selection;
|
|
21
22
|
|
|
22
|
-
if (
|
|
23
|
+
if ($from.pos === $to.pos) return;
|
|
23
24
|
|
|
24
|
-
state.doc.nodesBetween(
|
|
25
|
+
state.doc.nodesBetween($from.pos, $to.pos, (node, position) => {
|
|
25
26
|
if (!node.isText) return;
|
|
26
27
|
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
const substringFrom = Math.max(0, selection.from - position);
|
|
31
|
-
const substringTo = Math.max(0, selection.to - position);
|
|
28
|
+
const textPosition = resolveTextPosition($from, $to, node, position);
|
|
29
|
+
const substringFrom = Math.max(0, $from.pos - position);
|
|
30
|
+
const substringTo = Math.max(0, $to.pos - position);
|
|
32
31
|
|
|
33
32
|
const updatedText = transform({
|
|
34
|
-
text: node.textContent.substring(substringFrom, substringTo)
|
|
35
|
-
position: { start: startPosition, end: endPosition }
|
|
33
|
+
text: node.textContent.substring(substringFrom, substringTo)
|
|
36
34
|
});
|
|
37
35
|
const updatedNode = state.schema.text(updatedText, node.marks);
|
|
38
36
|
|
|
39
|
-
state.tr.replaceWith(
|
|
37
|
+
state.tr.replaceWith(textPosition.from, textPosition.to, updatedNode);
|
|
40
38
|
});
|
|
41
39
|
})
|
|
42
40
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Editor, Extension } from '@tiptap/vue-2';
|
|
2
|
-
import {
|
|
1
|
+
import { Editor, Extension, Mark } from '@tiptap/vue-2';
|
|
2
|
+
import { buildTestExtensions } from '../../../__tests__/utils';
|
|
3
|
+
import { NodeTypes, TextSettings } from '../../../enums';
|
|
3
4
|
import { ContentNormalizer, NodeFactory } from '../../../services';
|
|
4
|
-
import { buildCoreExtensions } from '../index';
|
|
5
5
|
|
|
6
|
-
const
|
|
7
|
-
name:
|
|
6
|
+
const MockLineHeight = Extension.create({
|
|
7
|
+
name: TextSettings.LINE_HEIGHT,
|
|
8
8
|
|
|
9
9
|
addGlobalAttributes: () => [
|
|
10
10
|
{
|
|
@@ -19,10 +19,19 @@ const LineHeight = Extension.create({
|
|
|
19
19
|
]
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
+
const MockFontWeight = Mark.create({
|
|
23
|
+
name: TextSettings.FONT_WEIGHT,
|
|
24
|
+
group: 'settings',
|
|
25
|
+
renderHTML: () => ['span', {}, 0],
|
|
26
|
+
addAttributes: () => ({ value: { required: true } })
|
|
27
|
+
});
|
|
28
|
+
|
|
22
29
|
function createEditor({ content }) {
|
|
23
30
|
return new Editor({
|
|
24
31
|
content: ContentNormalizer.normalize(content),
|
|
25
|
-
extensions:
|
|
32
|
+
extensions: buildTestExtensions({
|
|
33
|
+
include: [MockLineHeight, MockFontWeight]
|
|
34
|
+
})
|
|
26
35
|
});
|
|
27
36
|
}
|
|
28
37
|
|
|
@@ -79,7 +88,8 @@ describe('block attributes', () => {
|
|
|
79
88
|
content: createContent({ line_height: null })
|
|
80
89
|
});
|
|
81
90
|
|
|
82
|
-
editor.
|
|
91
|
+
editor.commands.selectAll();
|
|
92
|
+
editor.commands.setBlockAttributes('line_height', { mobile: '1.3' });
|
|
83
93
|
|
|
84
94
|
expect(editor.getJSON()).toMatchSnapshot();
|
|
85
95
|
});
|
|
@@ -89,7 +99,8 @@ describe('block attributes', () => {
|
|
|
89
99
|
content: createContent({ line_height: null })
|
|
90
100
|
});
|
|
91
101
|
|
|
92
|
-
editor.
|
|
102
|
+
editor.commands.selectAll();
|
|
103
|
+
editor.commands.setBlockAttributes('line_height', { mobile: '1.3' }, DEFAULTS);
|
|
93
104
|
|
|
94
105
|
expect(editor.getJSON()).toMatchSnapshot();
|
|
95
106
|
});
|
|
@@ -101,7 +112,8 @@ describe('block attributes', () => {
|
|
|
101
112
|
})
|
|
102
113
|
});
|
|
103
114
|
|
|
104
|
-
editor.
|
|
115
|
+
editor.commands.selectAll();
|
|
116
|
+
editor.commands.setBlockAttributes('line_height', { mobile: '1.3' });
|
|
105
117
|
|
|
106
118
|
expect(editor.getJSON()).toMatchSnapshot();
|
|
107
119
|
});
|
|
@@ -113,7 +125,67 @@ describe('block attributes', () => {
|
|
|
113
125
|
})
|
|
114
126
|
});
|
|
115
127
|
|
|
116
|
-
editor.
|
|
128
|
+
editor.commands.selectAll();
|
|
129
|
+
editor.commands.setBlockAttributes('line_height', { mobile: '1.3' }, DEFAULTS);
|
|
130
|
+
|
|
131
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
describe('apply mark', () => {
|
|
136
|
+
test('should apply mark to word', () => {
|
|
137
|
+
const editor = createEditor({
|
|
138
|
+
content: NodeFactory.doc([NodeFactory.paragraph('lorem ipsum')])
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
editor.commands.setTextSelection({ from: 1, to: 6 });
|
|
142
|
+
editor.commands.applyMark(TextSettings.FONT_WEIGHT, { value: '700' });
|
|
143
|
+
|
|
144
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
test('should merge marks', () => {
|
|
148
|
+
const editor = createEditor({
|
|
149
|
+
content: NodeFactory.doc([
|
|
150
|
+
NodeFactory.paragraph([
|
|
151
|
+
NodeFactory.text('lorem', [
|
|
152
|
+
NodeFactory.mark(TextSettings.FONT_WEIGHT, { value: '900' })
|
|
153
|
+
]),
|
|
154
|
+
NodeFactory.text(' ipsum')
|
|
155
|
+
])
|
|
156
|
+
])
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
editor.commands.setTextSelection({ from: 1, to: 10 });
|
|
160
|
+
editor.commands.applyMark(TextSettings.FONT_WEIGHT, { value: '700' });
|
|
161
|
+
|
|
162
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
test('should apply mark to block', () => {
|
|
166
|
+
const editor = createEditor({
|
|
167
|
+
content: NodeFactory.doc([NodeFactory.paragraph('lorem ipsum')])
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
editor
|
|
171
|
+
.chain()
|
|
172
|
+
.selectAll()
|
|
173
|
+
.applyMark(TextSettings.FONT_WEIGHT, { value: '700' })
|
|
174
|
+
.run();
|
|
175
|
+
|
|
176
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test('should apply text mark to paragraph with mark', () => {
|
|
180
|
+
const editor = createEditor({
|
|
181
|
+
content: NodeFactory.doc([
|
|
182
|
+
NodeFactory.paragraph(null, [NodeFactory.mark(TextSettings.FONT_WEIGHT, { value: '700' })], 'lorem impum')
|
|
183
|
+
])
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
editor.commands.setTextSelection({ from: 1, to: 6 });
|
|
188
|
+
editor.commands.applyMark(TextSettings.FONT_WEIGHT, { value: '400' });
|
|
117
189
|
|
|
118
190
|
expect(editor.getJSON()).toMatchSnapshot();
|
|
119
191
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Editor } from '@tiptap/vue-2';
|
|
2
|
+
import { buildTestExtensions } from '../../../__tests__/utils';
|
|
2
3
|
import { ContentNormalizer, NodeFactory } from '../../../services';
|
|
3
|
-
import { buildCoreExtensions } from '../index';
|
|
4
4
|
|
|
5
5
|
function createEditor() {
|
|
6
6
|
const content = NodeFactory.doc([
|
|
@@ -10,7 +10,7 @@ function createEditor() {
|
|
|
10
10
|
|
|
11
11
|
return new Editor({
|
|
12
12
|
content: ContentNormalizer.normalize(content),
|
|
13
|
-
extensions:
|
|
13
|
+
extensions: buildTestExtensions()
|
|
14
14
|
});
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Editor, Mark, Extension } from '@tiptap/vue-2';
|
|
2
|
+
import { buildTestExtensions } from '../../../__tests__/utils';
|
|
2
3
|
import { ContentNormalizer, NodeFactory } from '../../../services';
|
|
3
4
|
import { NodeTypes, TextSettings } from '../../../enums';
|
|
4
|
-
import { buildCoreExtensions } from '../index';
|
|
5
5
|
|
|
6
6
|
const MockFontSize = Mark.create({
|
|
7
7
|
name: TextSettings.FONT_SIZE,
|
|
@@ -103,17 +103,19 @@ function createEditor({ content }) {
|
|
|
103
103
|
return new Editor({
|
|
104
104
|
content: ContentNormalizer.normalize(content),
|
|
105
105
|
element: document.createElement('div'),
|
|
106
|
-
extensions:
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
106
|
+
extensions: buildTestExtensions({
|
|
107
|
+
include: [
|
|
108
|
+
MockFontSize,
|
|
109
|
+
MockFontWeight,
|
|
110
|
+
MockAlignment,
|
|
111
|
+
MockBackgroundColor,
|
|
112
|
+
MockFontColor,
|
|
113
|
+
MockFontFamily,
|
|
114
|
+
MockFontStyle,
|
|
115
|
+
MockTextDecoration,
|
|
116
|
+
MockSuperscript
|
|
117
|
+
]
|
|
118
|
+
})
|
|
117
119
|
});
|
|
118
120
|
}
|
|
119
121
|
|
|
@@ -125,10 +127,8 @@ describe('transform text', () => {
|
|
|
125
127
|
])
|
|
126
128
|
});
|
|
127
129
|
|
|
128
|
-
editor.
|
|
129
|
-
|
|
130
|
-
.transformText(({ text }) => text.toUpperCase())
|
|
131
|
-
.run();
|
|
130
|
+
editor.commands.setTextSelection({ from: 2, to: 6 });
|
|
131
|
+
editor.commands.transformText(({ text }) => text.toUpperCase());
|
|
132
132
|
|
|
133
133
|
expect(editor.getJSON()).toMatchSnapshot();
|
|
134
134
|
});
|
|
@@ -144,10 +144,8 @@ describe('transform text', () => {
|
|
|
144
144
|
])
|
|
145
145
|
});
|
|
146
146
|
|
|
147
|
-
editor.
|
|
148
|
-
|
|
149
|
-
.transformText(({ text }) => text.toUpperCase())
|
|
150
|
-
.run();
|
|
147
|
+
editor.commands.setTextSelection({ from: 2, to: 6 });
|
|
148
|
+
editor.commands.transformText(({ text }) => text.toUpperCase());
|
|
151
149
|
|
|
152
150
|
expect(editor.getJSON()).toMatchSnapshot();
|
|
153
151
|
});
|
|
@@ -1,5 +1,137 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
|
+
exports[`apply mark should apply mark to block 1`] = `
|
|
4
|
+
Object {
|
|
5
|
+
"content": Array [
|
|
6
|
+
Object {
|
|
7
|
+
"attrs": Object {
|
|
8
|
+
"line_height": null,
|
|
9
|
+
},
|
|
10
|
+
"content": Array [
|
|
11
|
+
Object {
|
|
12
|
+
"text": "lorem ipsum",
|
|
13
|
+
"type": "text",
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
"marks": Array [
|
|
17
|
+
Object {
|
|
18
|
+
"attrs": Object {
|
|
19
|
+
"value": "700",
|
|
20
|
+
},
|
|
21
|
+
"type": "font_weight",
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
"type": "paragraph",
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
"type": "doc",
|
|
28
|
+
}
|
|
29
|
+
`;
|
|
30
|
+
|
|
31
|
+
exports[`apply mark should apply mark to word 1`] = `
|
|
32
|
+
Object {
|
|
33
|
+
"content": Array [
|
|
34
|
+
Object {
|
|
35
|
+
"attrs": Object {
|
|
36
|
+
"line_height": null,
|
|
37
|
+
},
|
|
38
|
+
"content": Array [
|
|
39
|
+
Object {
|
|
40
|
+
"marks": Array [
|
|
41
|
+
Object {
|
|
42
|
+
"attrs": Object {
|
|
43
|
+
"value": "700",
|
|
44
|
+
},
|
|
45
|
+
"type": "font_weight",
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
"text": "lorem",
|
|
49
|
+
"type": "text",
|
|
50
|
+
},
|
|
51
|
+
Object {
|
|
52
|
+
"text": " ipsum",
|
|
53
|
+
"type": "text",
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
"type": "paragraph",
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
"type": "doc",
|
|
60
|
+
}
|
|
61
|
+
`;
|
|
62
|
+
|
|
63
|
+
exports[`apply mark should apply text mark to paragraph with mark 1`] = `
|
|
64
|
+
Object {
|
|
65
|
+
"content": Array [
|
|
66
|
+
Object {
|
|
67
|
+
"attrs": Object {
|
|
68
|
+
"line_height": null,
|
|
69
|
+
},
|
|
70
|
+
"content": Array [
|
|
71
|
+
Object {
|
|
72
|
+
"marks": Array [
|
|
73
|
+
Object {
|
|
74
|
+
"attrs": Object {
|
|
75
|
+
"value": "400",
|
|
76
|
+
},
|
|
77
|
+
"type": "font_weight",
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
"text": "lorem",
|
|
81
|
+
"type": "text",
|
|
82
|
+
},
|
|
83
|
+
Object {
|
|
84
|
+
"text": " impum",
|
|
85
|
+
"type": "text",
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
"marks": Array [
|
|
89
|
+
Object {
|
|
90
|
+
"attrs": Object {
|
|
91
|
+
"value": "700",
|
|
92
|
+
},
|
|
93
|
+
"type": "font_weight",
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
"type": "paragraph",
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
"type": "doc",
|
|
100
|
+
}
|
|
101
|
+
`;
|
|
102
|
+
|
|
103
|
+
exports[`apply mark should merge marks 1`] = `
|
|
104
|
+
Object {
|
|
105
|
+
"content": Array [
|
|
106
|
+
Object {
|
|
107
|
+
"attrs": Object {
|
|
108
|
+
"line_height": null,
|
|
109
|
+
},
|
|
110
|
+
"content": Array [
|
|
111
|
+
Object {
|
|
112
|
+
"marks": Array [
|
|
113
|
+
Object {
|
|
114
|
+
"attrs": Object {
|
|
115
|
+
"value": "700",
|
|
116
|
+
},
|
|
117
|
+
"type": "font_weight",
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
"text": "lorem ips",
|
|
121
|
+
"type": "text",
|
|
122
|
+
},
|
|
123
|
+
Object {
|
|
124
|
+
"text": "um",
|
|
125
|
+
"type": "text",
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
"type": "paragraph",
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
"type": "doc",
|
|
132
|
+
}
|
|
133
|
+
`;
|
|
134
|
+
|
|
3
135
|
exports[`block attributes should set attributes 1`] = `
|
|
4
136
|
Object {
|
|
5
137
|
"content": Array [
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import Document from '@tiptap/extension-document';
|
|
2
|
-
import Paragraph from '@tiptap/extension-paragraph';
|
|
3
1
|
import Text from '@tiptap/extension-text';
|
|
4
2
|
import Placeholder from '@tiptap/extension-placeholder';
|
|
5
3
|
import History from '@tiptap/extension-history';
|
|
@@ -7,16 +5,18 @@ import { NodeProcessor } from './NodeProcessor';
|
|
|
7
5
|
import { TextProcessor } from './TextProcessor';
|
|
8
6
|
import { SelectionProcessor } from './SelectionProcessor';
|
|
9
7
|
import { CopyPasteProcessor } from './CopyPasteProcessor';
|
|
8
|
+
import { Document } from './Document';
|
|
9
|
+
import { Paragraph } from './Paragraph';
|
|
10
|
+
import { Heading } from './Heading';
|
|
10
11
|
|
|
11
12
|
export const buildCoreExtensions = () => [
|
|
12
13
|
Document,
|
|
13
|
-
Paragraph.configure({
|
|
14
|
-
HTMLAttributes: { class: 'zw-style' }
|
|
15
|
-
}),
|
|
16
14
|
Placeholder.configure({
|
|
17
15
|
placeholder: 'Type your text here...',
|
|
18
16
|
emptyNodeClass: 'zw-wysiwyg__placeholder'
|
|
19
17
|
}),
|
|
18
|
+
Paragraph,
|
|
19
|
+
Heading,
|
|
20
20
|
Text,
|
|
21
21
|
History,
|
|
22
22
|
NodeProcessor,
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Step, StepResult } from 'prosemirror-transform';
|
|
2
|
+
import { Slice, Fragment } from 'prosemirror-model';
|
|
3
|
+
import { RemoveNodeMarkStep } from './RemoveNodeMarkStep';
|
|
4
|
+
|
|
5
|
+
export class AddNodeMarkStep extends Step {
|
|
6
|
+
static fromJSON(schema, json) {
|
|
7
|
+
if (typeof json.pos != 'number') {
|
|
8
|
+
throw new RangeError('Invalid input for AddNodeMarkStep.fromJSON');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return new AddNodeMarkStep(json.pos, schema.markFromJSON(json.mark));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
constructor(pos, mark) {
|
|
15
|
+
super();
|
|
16
|
+
this.pos = pos;
|
|
17
|
+
this.mark = mark;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
apply(doc) {
|
|
21
|
+
const node = doc.nodeAt(this.pos);
|
|
22
|
+
|
|
23
|
+
if (!node) return StepResult.fail('No node at mark step\'s position');
|
|
24
|
+
|
|
25
|
+
const updated = node.type.create(node.attrs, null, this.mark.addToSet(node.marks));
|
|
26
|
+
const slice = new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1);
|
|
27
|
+
|
|
28
|
+
return StepResult.fromReplace(doc, this.pos, this.pos + 1, slice);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
invert(doc) {
|
|
32
|
+
const node = doc.nodeAt(this.pos);
|
|
33
|
+
|
|
34
|
+
if (node) {
|
|
35
|
+
const newSet = this.mark.addToSet(node.marks);
|
|
36
|
+
|
|
37
|
+
if (newSet.length === node.marks.length) {
|
|
38
|
+
for (const mark of node.marks) {
|
|
39
|
+
if (!mark.isInSet(newSet)) {
|
|
40
|
+
return new AddNodeMarkStep(this.pos, mark);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return new AddNodeMarkStep(this.pos, this.mark);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return new RemoveNodeMarkStep(this.pos, this.mark);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
map(mapping) {
|
|
50
|
+
const pos = mapping.mapResult(this.pos, 1);
|
|
51
|
+
|
|
52
|
+
return pos.deletedAfter ? null : new AddNodeMarkStep(pos.pos, this.mark);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
toJSON() {
|
|
56
|
+
return { stepType: 'addNodeMark', pos: this.pos, mark: this.mark.toJSON() };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
Step.jsonID('addNodeMark', AddNodeMarkStep);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Step, StepResult } from 'prosemirror-transform';
|
|
2
|
+
import { Slice, Fragment } from 'prosemirror-model';
|
|
3
|
+
import { AddNodeMarkStep } from './AddNodeMarkStep';
|
|
4
|
+
|
|
5
|
+
export class RemoveNodeMarkStep extends Step {
|
|
6
|
+
static fromJSON(schema, json) {
|
|
7
|
+
if (typeof json.pos != 'number') {
|
|
8
|
+
throw new RangeError('Invalid input for RemoveNodeMarkStep.fromJSON');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return new RemoveNodeMarkStep(json.pos, schema.markFromJSON(json.mark));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
constructor(pos, mark) {
|
|
15
|
+
super();
|
|
16
|
+
this.pos = pos;
|
|
17
|
+
this.mark = mark;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
apply(doc) {
|
|
21
|
+
const node = doc.nodeAt(this.pos);
|
|
22
|
+
|
|
23
|
+
if (!node) return StepResult.fail('No node at mark step\'s position');
|
|
24
|
+
|
|
25
|
+
const updated = node.type.create(node.attrs, null, this.mark.removeFromSet(node.marks));
|
|
26
|
+
const slice = new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1);
|
|
27
|
+
|
|
28
|
+
return StepResult.fromReplace(doc, this.pos, this.pos + 1, slice);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
invert(doc) {
|
|
32
|
+
const node = doc.nodeAt(this.pos);
|
|
33
|
+
|
|
34
|
+
if (!node || !this.mark.isInSet(node.marks)) return this;
|
|
35
|
+
|
|
36
|
+
return new AddNodeMarkStep(this.pos, this.mark);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
map(mapping) {
|
|
40
|
+
const pos = mapping.mapResult(this.pos, 1);
|
|
41
|
+
|
|
42
|
+
return pos.deletedAfter ? null : new RemoveNodeMarkStep(pos.pos, this.mark);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
toJSON() {
|
|
46
|
+
return { stepType: 'removeNodeMark', pos: this.pos, mark: this.mark.toJSON() };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
Step.jsonID('removeNodeMark', RemoveNodeMarkStep);
|
|
@@ -3,6 +3,11 @@ import { NodeTypes } from '../../enums';
|
|
|
3
3
|
|
|
4
4
|
export const ListItem = Base.extend({
|
|
5
5
|
name: NodeTypes.LIST_ITEM,
|
|
6
|
+
marks: 'settings',
|
|
7
|
+
|
|
8
|
+
addOptions: () => ({
|
|
9
|
+
HTMLAttributes: { class: 'zw-style' }
|
|
10
|
+
}),
|
|
6
11
|
|
|
7
12
|
addKeyboardShortcuts() {
|
|
8
13
|
const { Enter } = this.parent();
|
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
import { Editor } from '@tiptap/vue-2';
|
|
2
|
+
import { buildTestExtensions } from '../../../__tests__/utils';
|
|
2
3
|
import { ListTypes } from '../../../enums';
|
|
3
4
|
import { StylePreset } from '../../StylePreset';
|
|
4
|
-
import { List } from '../List';
|
|
5
5
|
import { ContentNormalizer, NodeFactory } from '../../../services';
|
|
6
|
-
import {
|
|
6
|
+
import { List } from '../List';
|
|
7
7
|
|
|
8
8
|
function createEditor({ content }) {
|
|
9
9
|
return new Editor({
|
|
10
10
|
content: ContentNormalizer.normalize(content),
|
|
11
11
|
element: document.createElement('div'),
|
|
12
|
-
extensions:
|
|
13
|
-
|
|
14
|
-
baseClass: 'zw-list--'
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
)
|
|
12
|
+
extensions: buildTestExtensions({
|
|
13
|
+
include: [
|
|
14
|
+
List.configure({ baseClass: 'zw-list--' }),
|
|
15
|
+
StylePreset.configure({
|
|
16
|
+
presets: [
|
|
17
|
+
{
|
|
18
|
+
id: 'regular-1',
|
|
19
|
+
common: {},
|
|
20
|
+
mobile: {},
|
|
21
|
+
tablet: {},
|
|
22
|
+
desktop: {}
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
defaultId: 'regular-1',
|
|
26
|
+
baseClass: 'zw ts-'
|
|
27
|
+
})
|
|
28
|
+
]
|
|
29
|
+
})
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -67,7 +67,8 @@ describe('apply list', () => {
|
|
|
67
67
|
])
|
|
68
68
|
});
|
|
69
69
|
|
|
70
|
-
editor.
|
|
70
|
+
editor.commands.selectAll();
|
|
71
|
+
editor.commands.applyList(ListTypes.LATIN);
|
|
71
72
|
|
|
72
73
|
expect(editor.getJSON()).toMatchSnapshot();
|
|
73
74
|
});
|
|
@@ -82,7 +83,8 @@ describe('apply list', () => {
|
|
|
82
83
|
])
|
|
83
84
|
});
|
|
84
85
|
|
|
85
|
-
editor.
|
|
86
|
+
editor.commands.selectAll();
|
|
87
|
+
editor.commands.removeList();
|
|
86
88
|
|
|
87
89
|
expect(editor.getJSON()).toMatchSnapshot();
|
|
88
90
|
});
|
|
@@ -97,7 +99,8 @@ describe('apply list', () => {
|
|
|
97
99
|
])
|
|
98
100
|
});
|
|
99
101
|
|
|
100
|
-
editor.
|
|
102
|
+
editor.commands.selectAll();
|
|
103
|
+
editor.commands.applyList(ListTypes.LATIN);
|
|
101
104
|
|
|
102
105
|
expect(editor.getJSON()).toMatchSnapshot();
|
|
103
106
|
});
|
|
@@ -112,7 +115,8 @@ describe('apply list', () => {
|
|
|
112
115
|
])
|
|
113
116
|
});
|
|
114
117
|
|
|
115
|
-
editor.
|
|
118
|
+
editor.commands.selectAll();
|
|
119
|
+
editor.commands.applyList(ListTypes.ROMAN);
|
|
116
120
|
|
|
117
121
|
expect(editor.getJSON()).toMatchSnapshot();
|
|
118
122
|
});
|
|
@@ -125,7 +129,8 @@ describe('apply list', () => {
|
|
|
125
129
|
])
|
|
126
130
|
});
|
|
127
131
|
|
|
128
|
-
editor.
|
|
132
|
+
editor.commands.selectAll();
|
|
133
|
+
editor.commands.applyList(ListTypes.LATIN);
|
|
129
134
|
|
|
130
135
|
expect(editor.getJSON()).toMatchSnapshot();
|
|
131
136
|
});
|