@zipify/wysiwyg 1.3.0-0 → 2.0.0-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.
Files changed (103) hide show
  1. package/.eslintrc.js +1 -1
  2. package/config/build/lib.config.js +4 -2
  3. package/dist/cli.js +10 -2
  4. package/dist/wysiwyg.css +43 -48
  5. package/dist/wysiwyg.mjs +1928 -787
  6. package/example/ExampleApp.vue +3 -1
  7. package/lib/__tests__/utils/buildTestExtensions.js +14 -0
  8. package/lib/__tests__/utils/index.js +1 -0
  9. package/lib/components/base/Button.vue +0 -7
  10. package/lib/components/base/dropdown/Dropdown.vue +1 -7
  11. package/lib/components/base/dropdown/DropdownActivator.vue +4 -19
  12. package/lib/components/base/dropdown/__tests__/DropdownActivator.test.js +1 -23
  13. package/lib/components/toolbar/controls/AlignmentControl.vue +1 -11
  14. package/lib/components/toolbar/controls/FontColorControl.vue +0 -13
  15. package/lib/components/toolbar/controls/FontFamilyControl.vue +0 -4
  16. package/lib/components/toolbar/controls/FontSizeControl.vue +1 -6
  17. package/lib/components/toolbar/controls/FontWeightControl.vue +0 -12
  18. package/lib/components/toolbar/controls/ItalicControl.vue +0 -13
  19. package/lib/components/toolbar/controls/LineHeightControl.vue +0 -14
  20. package/lib/components/toolbar/controls/StylePresetControl.vue +1 -1
  21. package/lib/components/toolbar/controls/SuperscriptControl.vue +2 -2
  22. package/lib/components/toolbar/controls/UnderlineControl.vue +0 -12
  23. package/lib/components/toolbar/controls/__tests__/AlignmentControl.test.js +5 -72
  24. package/lib/components/toolbar/controls/__tests__/FontColorControl.test.js +1 -22
  25. package/lib/components/toolbar/controls/__tests__/FontFamilyControl.test.js +0 -1
  26. package/lib/components/toolbar/controls/__tests__/FontSizeControl.test.js +0 -1
  27. package/lib/components/toolbar/controls/__tests__/FontWeightControl.test.js +0 -1
  28. package/lib/components/toolbar/controls/__tests__/ItalicControl.test.js +1 -23
  29. package/lib/components/toolbar/controls/__tests__/LineHeightControl.test.js +1 -23
  30. package/lib/components/toolbar/controls/__tests__/StylePresetControl.test.js +2 -2
  31. package/lib/components/toolbar/controls/__tests__/SuperscriptControl.test.js +2 -2
  32. package/lib/components/toolbar/controls/__tests__/UnderlineControl.test.js +1 -25
  33. package/lib/composables/__tests__/useEditor.test.js +2 -2
  34. package/lib/enums/TextSettings.js +5 -5
  35. package/lib/extensions/BackgroundColor.js +4 -4
  36. package/lib/extensions/FontColor.js +4 -5
  37. package/lib/extensions/FontFamily.js +4 -5
  38. package/lib/extensions/FontSize.js +5 -7
  39. package/lib/extensions/FontStyle.js +13 -11
  40. package/lib/extensions/FontWeight.js +6 -9
  41. package/lib/extensions/Link.js +1 -1
  42. package/lib/extensions/StylePreset.js +1 -15
  43. package/lib/extensions/Superscript.js +23 -1
  44. package/lib/extensions/TextDecoration.js +16 -20
  45. package/lib/extensions/__tests__/Alignment.test.js +10 -7
  46. package/lib/extensions/__tests__/BackgroundColor.test.js +6 -3
  47. package/lib/extensions/__tests__/CaseStyle.test.js +11 -7
  48. package/lib/extensions/__tests__/FontColor.test.js +6 -3
  49. package/lib/extensions/__tests__/FontFamily.test.js +29 -22
  50. package/lib/extensions/__tests__/FontSize.test.js +24 -17
  51. package/lib/extensions/__tests__/FontStyle.test.js +22 -16
  52. package/lib/extensions/__tests__/FontWeight.test.js +28 -21
  53. package/lib/extensions/__tests__/LineHeight.test.js +14 -11
  54. package/lib/extensions/__tests__/Link.test.js +14 -10
  55. package/lib/extensions/__tests__/Margin.test.js +2 -2
  56. package/lib/extensions/__tests__/StylePreset.test.js +49 -100
  57. package/lib/extensions/__tests__/TextDecoration.test.js +59 -37
  58. package/lib/extensions/__tests__/__snapshots__/BackgroundColor.test.js.snap +25 -25
  59. package/lib/extensions/__tests__/__snapshots__/FontColor.test.js.snap +25 -25
  60. package/lib/extensions/__tests__/__snapshots__/FontFamily.test.js.snap +105 -105
  61. package/lib/extensions/__tests__/__snapshots__/FontSize.test.js.snap +72 -72
  62. package/lib/extensions/__tests__/__snapshots__/FontStyle.test.js.snap +54 -46
  63. package/lib/extensions/__tests__/__snapshots__/FontWeight.test.js.snap +77 -77
  64. package/lib/extensions/__tests__/__snapshots__/TextDecoration.test.js.snap +68 -3
  65. package/lib/extensions/core/Document.js +5 -0
  66. package/lib/extensions/core/Heading.js +10 -0
  67. package/lib/extensions/core/NodeProcessor.js +112 -10
  68. package/lib/extensions/core/Paragraph.js +9 -0
  69. package/lib/extensions/core/TextProcessor.js +9 -16
  70. package/lib/extensions/core/__tests__/NodeProcessor.test.js +137 -10
  71. package/lib/extensions/core/__tests__/SelectionProcessor.test.js +2 -2
  72. package/lib/extensions/core/__tests__/TextProcessor.test.js +18 -41
  73. package/lib/extensions/core/__tests__/__snapshots__/NodeProcessor.test.js.snap +192 -0
  74. package/lib/extensions/core/__tests__/__snapshots__/TextProcessor.test.js.snap +7 -27
  75. package/lib/extensions/core/index.js +5 -5
  76. package/lib/extensions/core/steps/AddNodeMarkStep.js +60 -0
  77. package/lib/extensions/core/steps/AttrStep.js +54 -0
  78. package/lib/extensions/core/steps/RemoveNodeMarkStep.js +50 -0
  79. package/lib/extensions/core/steps/index.js +3 -0
  80. package/lib/extensions/list/List.js +1 -0
  81. package/lib/extensions/list/ListItem.js +5 -0
  82. package/lib/extensions/list/__tests__/List.test.js +30 -25
  83. package/lib/services/NodeFactory.js +25 -21
  84. package/lib/services/index.js +1 -1
  85. package/lib/services/normalizer/BaseNormalizer.js +11 -0
  86. package/lib/services/{BrowserDomParser.js → normalizer/BrowserDomParser.js} +0 -0
  87. package/lib/services/normalizer/ContentNormalizer.js +24 -0
  88. package/lib/services/normalizer/HtmlNormalizer.js +245 -0
  89. package/lib/services/normalizer/JsonNormalizer.js +81 -0
  90. package/lib/services/{__tests__/ContentNormalizer.test.js → normalizer/__tests__/HtmlNormalizer.test.js} +27 -67
  91. package/lib/services/normalizer/__tests__/JsonNormalizer.test.js +70 -0
  92. package/lib/services/normalizer/__tests__/__snapshots__/JsonNormalizer.test.js.snap +159 -0
  93. package/lib/services/normalizer/index.js +1 -0
  94. package/lib/styles/content.css +8 -0
  95. package/lib/utils/findMarkByType.js +5 -0
  96. package/lib/utils/index.js +5 -0
  97. package/lib/utils/isMarkAppliedToParent.js +10 -0
  98. package/lib/utils/isNodeFullySelected.js +10 -0
  99. package/lib/utils/resolveNodePosition.js +6 -0
  100. package/lib/utils/resolveTextPosition.js +6 -0
  101. package/package.json +3 -1
  102. package/lib/assets/icons/indicator.svg +0 -5
  103. package/lib/services/ContentNormalizer.js +0 -293
@@ -1,10 +1,10 @@
1
- import { Editor, Extension } from '@tiptap/vue-2';
2
- import { NodeTypes } from '../../../enums';
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 LineHeight = Extension.create({
7
- name: 'line_height',
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: buildCoreExtensions().concat(LineHeight) // Included to core 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.chain().selectAll().setBlockAttributes('line_height', { mobile: '1.3' }).run();
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.chain().selectAll().setBlockAttributes('line_height', { mobile: '1.3' }, DEFAULTS).run();
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.chain().selectAll().setBlockAttributes('line_height', { mobile: '1.3' }).run();
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,122 @@ describe('block attributes', () => {
113
125
  })
114
126
  });
115
127
 
116
- editor.chain().selectAll().setBlockAttributes('line_height', { mobile: '1.3' }, DEFAULTS).run();
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' });
189
+
190
+ expect(editor.getJSON()).toMatchSnapshot();
191
+ });
192
+ });
193
+
194
+ describe('remove marks', () => {
195
+ test('should remove text marks', () => {
196
+ const editor = createEditor({
197
+ content: NodeFactory.doc([
198
+ NodeFactory.paragraph([
199
+ NodeFactory.text('lorem', [
200
+ NodeFactory.mark(TextSettings.FONT_WEIGHT, { value: '700' })
201
+ ]),
202
+ NodeFactory.text(' ipsum')
203
+ ])
204
+ ])
205
+ });
206
+
207
+ editor.commands.selectAll();
208
+ editor.commands.removeMarks([TextSettings.FONT_WEIGHT]);
209
+
210
+ expect(editor.getJSON()).toMatchSnapshot();
211
+ });
212
+
213
+ test('should remove block marks', () => {
214
+ const editor = createEditor({
215
+ content: NodeFactory.doc([
216
+ NodeFactory.paragraph(null, [
217
+ NodeFactory.mark(TextSettings.FONT_WEIGHT, { value: '700' })
218
+ ], 'lorem ipsum')
219
+ ])
220
+ });
221
+
222
+ editor.commands.selectAll();
223
+ editor.commands.removeMarks([TextSettings.FONT_WEIGHT]);
224
+
225
+ expect(editor.getJSON()).toMatchSnapshot();
226
+ });
227
+
228
+ test('should remove block and text marks', () => {
229
+ const editor = createEditor({
230
+ content: NodeFactory.doc([
231
+ NodeFactory.paragraph(null, [
232
+ NodeFactory.mark(TextSettings.FONT_WEIGHT, { value: '700' })
233
+ ], [
234
+ NodeFactory.text('lorem'),
235
+ NodeFactory.text(' ipsum', [
236
+ NodeFactory.mark(TextSettings.FONT_WEIGHT, { value: '400' })
237
+ ])
238
+ ])
239
+ ])
240
+ });
241
+
242
+ editor.commands.selectAll();
243
+ editor.commands.removeMarks([TextSettings.FONT_WEIGHT]);
117
244
 
118
245
  expect(editor.getJSON()).toMatchSnapshot();
119
246
  });
@@ -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: buildCoreExtensions() // included to core
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: buildCoreExtensions().concat(
107
- MockFontSize,
108
- MockFontWeight,
109
- MockAlignment,
110
- MockBackgroundColor,
111
- MockFontColor,
112
- MockFontFamily,
113
- MockFontStyle,
114
- MockTextDecoration,
115
- MockSuperscript
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.chain()
129
- .setTextSelection({ from: 2, to: 6 })
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.chain()
148
- .setTextSelection({ from: 2, to: 6 })
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
  });
@@ -166,24 +164,3 @@ describe('selected text', () => {
166
164
  expect(editor.commands.getSelectedText()).toEqual('o worl');
167
165
  });
168
166
  });
169
-
170
- describe('unset marks', () => {
171
- test('should reset all marks', () => {
172
- const editor = createEditor({
173
- content: NodeFactory.doc([
174
- NodeFactory.paragraph([
175
- NodeFactory.text('hello world', [
176
- NodeFactory.mark('font_weight', { value: '700' })
177
- ])
178
- ])
179
- ])
180
- });
181
-
182
- editor.chain()
183
- .selectAll()
184
- .unsetMarks(TextSettings.marks)
185
- .run();
186
-
187
- expect(editor.getJSON()).toMatchSnapshot();
188
- });
189
- });
@@ -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 [
@@ -91,3 +223,63 @@ Object {
91
223
  "type": "doc",
92
224
  }
93
225
  `;
226
+
227
+ exports[`remove marks should remove block and text marks 1`] = `
228
+ Object {
229
+ "content": Array [
230
+ Object {
231
+ "attrs": Object {
232
+ "line_height": null,
233
+ },
234
+ "content": Array [
235
+ Object {
236
+ "text": "lorem ipsum",
237
+ "type": "text",
238
+ },
239
+ ],
240
+ "type": "paragraph",
241
+ },
242
+ ],
243
+ "type": "doc",
244
+ }
245
+ `;
246
+
247
+ exports[`remove marks should remove block marks 1`] = `
248
+ Object {
249
+ "content": Array [
250
+ Object {
251
+ "attrs": Object {
252
+ "line_height": null,
253
+ },
254
+ "content": Array [
255
+ Object {
256
+ "text": "lorem ipsum",
257
+ "type": "text",
258
+ },
259
+ ],
260
+ "type": "paragraph",
261
+ },
262
+ ],
263
+ "type": "doc",
264
+ }
265
+ `;
266
+
267
+ exports[`remove marks should remove text marks 1`] = `
268
+ Object {
269
+ "content": Array [
270
+ Object {
271
+ "attrs": Object {
272
+ "line_height": null,
273
+ },
274
+ "content": Array [
275
+ Object {
276
+ "text": "lorem ipsum",
277
+ "type": "text",
278
+ },
279
+ ],
280
+ "type": "paragraph",
281
+ },
282
+ ],
283
+ "type": "doc",
284
+ }
285
+ `;
@@ -9,36 +9,16 @@ Object {
9
9
  },
10
10
  "content": Array [
11
11
  Object {
12
- "marks": Array [
13
- Object {
14
- "attrs": Object {
15
- "value": "700",
16
- },
17
- "type": "font_weight",
18
- },
19
- ],
20
12
  "text": "hELLO world",
21
13
  "type": "text",
22
14
  },
23
15
  ],
24
- "type": "paragraph",
25
- },
26
- ],
27
- "type": "doc",
28
- }
29
- `;
30
-
31
- exports[`transform text should transform selected text 1`] = `
32
- Object {
33
- "content": Array [
34
- Object {
35
- "attrs": Object {
36
- "alignment": null,
37
- },
38
- "content": Array [
16
+ "marks": Array [
39
17
  Object {
40
- "text": "hELLO world",
41
- "type": "text",
18
+ "attrs": Object {
19
+ "value": "700",
20
+ },
21
+ "type": "font_weight",
42
22
  },
43
23
  ],
44
24
  "type": "paragraph",
@@ -48,7 +28,7 @@ Object {
48
28
  }
49
29
  `;
50
30
 
51
- exports[`unset marks should reset all marks 1`] = `
31
+ exports[`transform text should transform selected text 1`] = `
52
32
  Object {
53
33
  "content": Array [
54
34
  Object {
@@ -57,7 +37,7 @@ Object {
57
37
  },
58
38
  "content": Array [
59
39
  Object {
60
- "text": "hello world",
40
+ "text": "hELLO world",
61
41
  "type": "text",
62
42
  },
63
43
  ],
@@ -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,54 @@
1
+ import { Step, StepResult, StepMap } from 'prosemirror-transform';
2
+ import { Fragment, Slice } from 'prosemirror-model';
3
+
4
+ export class AttrStep extends Step {
5
+ static fromJSON(schema, json) {
6
+ if (typeof json.pos != 'number' || typeof json.attr != 'string') {
7
+ throw new RangeError('Invalid input for AttrStep.fromJSON');
8
+ }
9
+ return new AttrStep(json.pos, json.attr, json.value);
10
+ }
11
+
12
+ constructor(pos, attr, value) {
13
+ super();
14
+ this.pos = pos;
15
+ this.attr = attr;
16
+ this.value = value;
17
+ }
18
+
19
+ apply(doc) {
20
+ const node = doc.nodeAt(this.pos);
21
+
22
+ if (!node) return StepResult.fail('No node at attribute step\'s position');
23
+
24
+ const attrs = Object.create(null);
25
+
26
+ for (let name in node.attrs) attrs[name] = node.attrs[name];
27
+ attrs[this.attr] = this.value;
28
+
29
+ const updated = node.type.create(attrs, null, node.marks);
30
+ const slice = new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1);
31
+
32
+ return StepResult.fromReplace(doc, this.pos, this.pos + 1, slice);
33
+ }
34
+
35
+ getMap() {
36
+ return StepMap.empty;
37
+ }
38
+
39
+ invert(doc) {
40
+ return new AttrStep(this.pos, this.attr, doc.nodeAt(this.pos).attrs[this.attr]);
41
+ }
42
+
43
+ map(mapping) {
44
+ let pos = mapping.mapResult(this.pos, 1);
45
+
46
+ return pos.deletedAfter ? null : new AttrStep(pos.pos, this.attr, this.value);
47
+ }
48
+
49
+ toJSON() {
50
+ return { stepType: 'attr', pos: this.pos, attr: this.attr, value: this.value };
51
+ }
52
+ }
53
+
54
+ Step.jsonID('attr', AttrStep);