@zipify/wysiwyg 2.0.0-0 → 2.0.0-10

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 (118) hide show
  1. package/.eslintrc.js +1 -1
  2. package/config/build/cli.config.js +8 -2
  3. package/config/build/lib.config.js +4 -2
  4. package/dist/cli.js +10 -2
  5. package/dist/wysiwyg.css +53 -37
  6. package/dist/wysiwyg.mjs +2131 -405
  7. package/example/ExampleApp.vue +13 -2
  8. package/lib/Wysiwyg.vue +3 -2
  9. package/lib/__tests__/utils/buildTestExtensions.js +2 -1
  10. package/lib/assets/icons/indicator.svg +4 -0
  11. package/lib/cli/commands/Command.js +39 -0
  12. package/lib/cli/commands/ToJsonCommand.js +46 -0
  13. package/lib/cli/commands/VersionCommand.js +11 -0
  14. package/lib/cli/commands/index.js +2 -0
  15. package/lib/cli/index.js +1 -0
  16. package/lib/components/base/Button.vue +6 -0
  17. package/lib/components/base/dropdown/Dropdown.vue +7 -1
  18. package/lib/components/base/dropdown/DropdownActivator.vue +25 -4
  19. package/lib/components/base/dropdown/__tests__/DropdownActivator.test.js +23 -1
  20. package/lib/components/toolbar/controls/AlignmentControl.vue +12 -1
  21. package/lib/components/toolbar/controls/FontColorControl.vue +14 -0
  22. package/lib/components/toolbar/controls/FontFamilyControl.vue +4 -0
  23. package/lib/components/toolbar/controls/FontSizeControl.vue +6 -1
  24. package/lib/components/toolbar/controls/FontWeightControl.vue +12 -0
  25. package/lib/components/toolbar/controls/ItalicControl.vue +14 -0
  26. package/lib/components/toolbar/controls/LineHeightControl.vue +15 -0
  27. package/lib/components/toolbar/controls/StylePresetControl.vue +1 -1
  28. package/lib/components/toolbar/controls/UnderlineControl.vue +13 -0
  29. package/lib/components/toolbar/controls/__tests__/AlignmentControl.test.js +72 -5
  30. package/lib/components/toolbar/controls/__tests__/FontColorControl.test.js +22 -1
  31. package/lib/components/toolbar/controls/__tests__/FontFamilyControl.test.js +1 -0
  32. package/lib/components/toolbar/controls/__tests__/FontSizeControl.test.js +1 -0
  33. package/lib/components/toolbar/controls/__tests__/FontWeightControl.test.js +1 -0
  34. package/lib/components/toolbar/controls/__tests__/ItalicControl.test.js +23 -1
  35. package/lib/components/toolbar/controls/__tests__/LineHeightControl.test.js +23 -1
  36. package/lib/components/toolbar/controls/__tests__/StylePresetControl.test.js +6 -6
  37. package/lib/components/toolbar/controls/__tests__/UnderlineControl.test.js +25 -1
  38. package/lib/composables/__tests__/useEditor.test.js +1 -1
  39. package/lib/composables/useEditor.js +9 -8
  40. package/lib/directives/__tests__/tooltip.test.js +22 -4
  41. package/lib/directives/tooltip.js +4 -1
  42. package/lib/entry-cli.js +7 -20
  43. package/lib/entry-lib.js +1 -1
  44. package/lib/enums/MarkGroups.js +4 -0
  45. package/lib/enums/TextSettings.js +5 -5
  46. package/lib/enums/index.js +1 -0
  47. package/lib/extensions/BackgroundColor.js +0 -1
  48. package/lib/extensions/FontColor.js +2 -2
  49. package/lib/extensions/FontFamily.js +3 -3
  50. package/lib/extensions/FontSize.js +2 -2
  51. package/lib/extensions/FontStyle.js +2 -2
  52. package/lib/extensions/FontWeight.js +2 -2
  53. package/lib/extensions/Link.js +1 -1
  54. package/lib/extensions/StylePreset.js +9 -3
  55. package/lib/extensions/Superscript.js +5 -2
  56. package/lib/extensions/TextDecoration.js +19 -29
  57. package/lib/extensions/__tests__/Alignment.test.js +2 -2
  58. package/lib/extensions/__tests__/BackgroundColor.test.js +4 -3
  59. package/lib/extensions/__tests__/FontColor.test.js +4 -3
  60. package/lib/extensions/__tests__/FontFamily.test.js +6 -6
  61. package/lib/extensions/__tests__/FontSize.test.js +9 -8
  62. package/lib/extensions/__tests__/FontStyle.test.js +6 -5
  63. package/lib/extensions/__tests__/FontWeight.test.js +2 -2
  64. package/lib/extensions/__tests__/LineHeight.test.js +2 -1
  65. package/lib/extensions/__tests__/StylePreset.test.js +51 -0
  66. package/lib/extensions/__tests__/Superscript.test.js +102 -0
  67. package/lib/extensions/__tests__/TextDecoration.test.js +40 -24
  68. package/lib/extensions/__tests__/__snapshots__/BackgroundColor.test.js.snap +24 -24
  69. package/lib/extensions/__tests__/__snapshots__/FontColor.test.js.snap +1 -1
  70. package/lib/extensions/__tests__/__snapshots__/FontFamily.test.js.snap +19 -23
  71. package/lib/extensions/__tests__/__snapshots__/FontSize.test.js.snap +2 -2
  72. package/lib/extensions/__tests__/__snapshots__/FontStyle.test.js.snap +1 -1
  73. package/lib/extensions/__tests__/__snapshots__/FontWeight.test.js.snap +13 -17
  74. package/lib/extensions/__tests__/__snapshots__/Superscript.test.js.snap +107 -0
  75. package/lib/extensions/__tests__/__snapshots__/TextDecoration.test.js.snap +102 -102
  76. package/lib/extensions/core/Document.js +2 -1
  77. package/lib/extensions/core/Heading.js +2 -1
  78. package/lib/extensions/core/NodeProcessor.js +63 -20
  79. package/lib/extensions/core/Paragraph.js +2 -1
  80. package/lib/extensions/core/TextProcessor.js +0 -5
  81. package/lib/extensions/core/__tests__/NodeProcessor.test.js +364 -11
  82. package/lib/extensions/core/__tests__/TextProcessor.test.js +1 -22
  83. package/lib/extensions/core/__tests__/__snapshots__/NodeProcessor.test.js.snap +309 -0
  84. package/lib/extensions/core/__tests__/__snapshots__/TextProcessor.test.js.snap +7 -27
  85. package/lib/extensions/core/steps/AddNodeMarkStep.js +6 -0
  86. package/lib/extensions/core/steps/AttrStep.js +60 -0
  87. package/lib/extensions/core/steps/RemoveNodeMarkStep.js +6 -0
  88. package/lib/extensions/core/steps/index.js +1 -0
  89. package/lib/extensions/list/List.js +70 -9
  90. package/lib/extensions/list/ListItem.js +2 -2
  91. package/lib/extensions/list/__tests__/List.test.js +26 -17
  92. package/lib/extensions/list/__tests__/__snapshots__/List.test.js.snap +36 -36
  93. package/lib/services/NodeFactory.js +73 -13
  94. package/lib/services/__tests__/NodeFactory.test.js +124 -0
  95. package/lib/services/__tests__/__snapshots__/NodeFactory.test.js.snap +326 -0
  96. package/lib/services/index.js +1 -1
  97. package/lib/services/normalizer/BaseNormalizer.js +11 -0
  98. package/lib/services/{BrowserDomParser.js → normalizer/BrowserDomParser.js} +0 -0
  99. package/lib/services/normalizer/ContentNormalizer.js +24 -0
  100. package/lib/services/normalizer/HtmlNormalizer.js +297 -0
  101. package/lib/services/normalizer/JsonNormalizer.js +82 -0
  102. package/lib/services/{__tests__/ContentNormalizer.test.js → normalizer/__tests__/HtmlNormalizer.test.js} +42 -4
  103. package/lib/services/normalizer/__tests__/JsonNormalizer.test.js +87 -0
  104. package/lib/services/normalizer/__tests__/__snapshots__/JsonNormalizer.test.js.snap +196 -0
  105. package/lib/services/normalizer/index.js +1 -0
  106. package/lib/styles/content.css +8 -0
  107. package/lib/utils/__tests__/findMarkByType.test.js +17 -0
  108. package/lib/utils/__tests__/isMarkAppliedToParent.test.js +53 -0
  109. package/lib/utils/__tests__/isNodeFullySelected.test.js +44 -0
  110. package/lib/utils/__tests__/resolveTextPosition.test.js +39 -0
  111. package/lib/utils/copyMark.js +5 -0
  112. package/lib/utils/index.js +1 -1
  113. package/lib/utils/isMarkAppliedToParent.js +2 -7
  114. package/lib/utils/isNodeFullySelected.js +4 -7
  115. package/lib/utils/resolveTextPosition.js +4 -6
  116. package/package.json +31 -27
  117. package/lib/services/ContentNormalizer.js +0 -194
  118. package/lib/utils/resolveNodePosition.js +0 -6
@@ -6,19 +6,19 @@ Object {
6
6
  Object {
7
7
  "content": Array [
8
8
  Object {
9
+ "marks": Array [
10
+ Object {
11
+ "attrs": Object {
12
+ "strike_through": false,
13
+ "underline": true,
14
+ },
15
+ "type": "text_decoration",
16
+ },
17
+ ],
9
18
  "text": "hello world",
10
19
  "type": "text",
11
20
  },
12
21
  ],
13
- "marks": Array [
14
- Object {
15
- "attrs": Object {
16
- "strike_through": false,
17
- "underline": true,
18
- },
19
- "type": "text_decoration",
20
- },
21
- ],
22
22
  "type": "paragraph",
23
23
  },
24
24
  ],
@@ -71,19 +71,19 @@ Object {
71
71
  Object {
72
72
  "content": Array [
73
73
  Object {
74
+ "marks": Array [
75
+ Object {
76
+ "attrs": Object {
77
+ "strike_through": false,
78
+ "underline": true,
79
+ },
80
+ "type": "text_decoration",
81
+ },
82
+ ],
74
83
  "text": "hello world",
75
84
  "type": "text",
76
85
  },
77
86
  ],
78
- "marks": Array [
79
- Object {
80
- "attrs": Object {
81
- "strike_through": false,
82
- "underline": true,
83
- },
84
- "type": "text_decoration",
85
- },
86
- ],
87
87
  "type": "paragraph",
88
88
  },
89
89
  ],
@@ -97,19 +97,19 @@ Object {
97
97
  Object {
98
98
  "content": Array [
99
99
  Object {
100
+ "marks": Array [
101
+ Object {
102
+ "attrs": Object {
103
+ "strike_through": true,
104
+ "underline": true,
105
+ },
106
+ "type": "text_decoration",
107
+ },
108
+ ],
100
109
  "text": "hello world",
101
110
  "type": "text",
102
111
  },
103
112
  ],
104
- "marks": Array [
105
- Object {
106
- "attrs": Object {
107
- "strike_through": true,
108
- "underline": true,
109
- },
110
- "type": "text_decoration",
111
- },
112
- ],
113
113
  "type": "paragraph",
114
114
  },
115
115
  ],
@@ -123,19 +123,19 @@ Object {
123
123
  Object {
124
124
  "content": Array [
125
125
  Object {
126
- "text": "lorem ipsum",
126
+ "marks": Array [
127
+ Object {
128
+ "attrs": Object {
129
+ "strike_through": false,
130
+ "underline": false,
131
+ },
132
+ "type": "text_decoration",
133
+ },
134
+ ],
135
+ "text": "hello world",
127
136
  "type": "text",
128
137
  },
129
138
  ],
130
- "marks": Array [
131
- Object {
132
- "attrs": Object {
133
- "strike_through": false,
134
- "underline": false,
135
- },
136
- "type": "text_decoration",
137
- },
138
- ],
139
139
  "type": "paragraph",
140
140
  },
141
141
  ],
@@ -149,19 +149,19 @@ Object {
149
149
  Object {
150
150
  "content": Array [
151
151
  Object {
152
+ "marks": Array [
153
+ Object {
154
+ "attrs": Object {
155
+ "strike_through": true,
156
+ "underline": false,
157
+ },
158
+ "type": "text_decoration",
159
+ },
160
+ ],
152
161
  "text": "hello world",
153
162
  "type": "text",
154
163
  },
155
164
  ],
156
- "marks": Array [
157
- Object {
158
- "attrs": Object {
159
- "strike_through": true,
160
- "underline": false,
161
- },
162
- "type": "text_decoration",
163
- },
164
- ],
165
165
  "type": "paragraph",
166
166
  },
167
167
  ],
@@ -175,19 +175,19 @@ Object {
175
175
  Object {
176
176
  "content": Array [
177
177
  Object {
178
- "text": "lorem ipsum",
178
+ "marks": Array [
179
+ Object {
180
+ "attrs": Object {
181
+ "strike_through": false,
182
+ "underline": false,
183
+ },
184
+ "type": "text_decoration",
185
+ },
186
+ ],
187
+ "text": "hello world",
179
188
  "type": "text",
180
189
  },
181
190
  ],
182
- "marks": Array [
183
- Object {
184
- "attrs": Object {
185
- "strike_through": false,
186
- "underline": false,
187
- },
188
- "type": "text_decoration",
189
- },
190
- ],
191
191
  "type": "paragraph",
192
192
  },
193
193
  ],
@@ -201,19 +201,19 @@ Object {
201
201
  Object {
202
202
  "content": Array [
203
203
  Object {
204
+ "marks": Array [
205
+ Object {
206
+ "attrs": Object {
207
+ "strike_through": false,
208
+ "underline": true,
209
+ },
210
+ "type": "text_decoration",
211
+ },
212
+ ],
204
213
  "text": "hello world",
205
214
  "type": "text",
206
215
  },
207
216
  ],
208
- "marks": Array [
209
- Object {
210
- "attrs": Object {
211
- "strike_through": false,
212
- "underline": true,
213
- },
214
- "type": "text_decoration",
215
- },
216
- ],
217
217
  "type": "paragraph",
218
218
  },
219
219
  ],
@@ -227,19 +227,19 @@ Object {
227
227
  Object {
228
228
  "content": Array [
229
229
  Object {
230
+ "marks": Array [
231
+ Object {
232
+ "attrs": Object {
233
+ "strike_through": true,
234
+ "underline": true,
235
+ },
236
+ "type": "text_decoration",
237
+ },
238
+ ],
230
239
  "text": "test",
231
240
  "type": "text",
232
241
  },
233
242
  ],
234
- "marks": Array [
235
- Object {
236
- "attrs": Object {
237
- "strike_through": true,
238
- "underline": true,
239
- },
240
- "type": "text_decoration",
241
- },
242
- ],
243
243
  "type": "paragraph",
244
244
  },
245
245
  ],
@@ -343,19 +343,19 @@ Object {
343
343
  Object {
344
344
  "content": Array [
345
345
  Object {
346
+ "marks": Array [
347
+ Object {
348
+ "attrs": Object {
349
+ "strike_through": true,
350
+ "underline": false,
351
+ },
352
+ "type": "text_decoration",
353
+ },
354
+ ],
346
355
  "text": "test",
347
356
  "type": "text",
348
357
  },
349
358
  ],
350
- "marks": Array [
351
- Object {
352
- "attrs": Object {
353
- "strike_through": true,
354
- "underline": false,
355
- },
356
- "type": "text_decoration",
357
- },
358
- ],
359
359
  "type": "paragraph",
360
360
  },
361
361
  ],
@@ -429,19 +429,19 @@ Object {
429
429
  Object {
430
430
  "content": Array [
431
431
  Object {
432
+ "marks": Array [
433
+ Object {
434
+ "attrs": Object {
435
+ "strike_through": false,
436
+ "underline": true,
437
+ },
438
+ "type": "text_decoration",
439
+ },
440
+ ],
432
441
  "text": "test",
433
442
  "type": "text",
434
443
  },
435
444
  ],
436
- "marks": Array [
437
- Object {
438
- "attrs": Object {
439
- "strike_through": false,
440
- "underline": true,
441
- },
442
- "type": "text_decoration",
443
- },
444
- ],
445
445
  "type": "paragraph",
446
446
  },
447
447
  ],
@@ -519,7 +519,7 @@ Object {
519
519
  Object {
520
520
  "attrs": Object {
521
521
  "strike_through": true,
522
- "underline": false,
522
+ "underline": true,
523
523
  },
524
524
  "type": "text_decoration",
525
525
  },
@@ -528,19 +528,19 @@ Object {
528
528
  "type": "text",
529
529
  },
530
530
  Object {
531
+ "marks": Array [
532
+ Object {
533
+ "attrs": Object {
534
+ "strike_through": false,
535
+ "underline": true,
536
+ },
537
+ "type": "text_decoration",
538
+ },
539
+ ],
531
540
  "text": " ipsum",
532
541
  "type": "text",
533
542
  },
534
543
  ],
535
- "marks": Array [
536
- Object {
537
- "attrs": Object {
538
- "strike_through": false,
539
- "underline": true,
540
- },
541
- "type": "text_decoration",
542
- },
543
- ],
544
544
  "type": "paragraph",
545
545
  },
546
546
  ],
@@ -1,5 +1,6 @@
1
1
  import { Document as Base } from '@tiptap/extension-document';
2
+ import { MarkGroups } from '../../enums';
2
3
 
3
4
  export const Document = Base.extend({
4
- marks: 'settings'
5
+ marks: MarkGroups.SETTINGS
5
6
  });
@@ -1,7 +1,8 @@
1
1
  import { Heading as Base } from '@tiptap/extension-heading';
2
+ import { MarkGroups } from '../../enums';
2
3
 
3
4
  export const Heading = Base.extend({
4
- marks: '_',
5
+ marks: MarkGroups.ALL,
5
6
 
6
7
  addOptions: () => ({
7
8
  levels: [1, 2, 3, 4],
@@ -7,22 +7,24 @@ import {
7
7
  isNodeFullySelected,
8
8
  resolveTextPosition
9
9
  } from '../../utils';
10
- import { NodeTypes } from '../../enums';
11
- import { AddNodeMarkStep } from './steps';
10
+ import { MarkGroups, NodeTypes } from '../../enums';
11
+ import { AddNodeMarkStep, AttrStep, RemoveNodeMarkStep } from './steps';
12
12
 
13
13
  export const NodeProcessor = Extension.create({
14
14
  name: 'node_processor',
15
15
 
16
16
  addCommands() {
17
17
  return {
18
- setBlockAttributes: createCommand(({ commands }, name, attrs, defaults = {}) => {
18
+ setBlockAttributes: createCommand(({ commands, state }, name, attrs, defaults = {}) => {
19
19
  const current = unref(commands.getBlockAttributes(name)) ?? {};
20
+ const { doc, tr } = state;
21
+ const { from, to } = tr.selection;
20
22
 
21
- for (const type of NodeTypes.blocks) {
22
- commands.updateAttributes(type, {
23
- [name]: { ...defaults, ...current, ...attrs }
24
- });
25
- }
23
+ doc.nodesBetween(from, to, (node, position) => {
24
+ if (!NodeTypes.blocks.includes(node.type.name)) return;
25
+
26
+ tr.step(new AttrStep(position, name, { ...defaults, ...current, ...attrs }));
27
+ });
26
28
  }),
27
29
 
28
30
  getBlockAttributes: createCommand(({ editor }, name, defaults) => computed(() => {
@@ -35,16 +37,16 @@ export const NodeProcessor = Extension.create({
35
37
  return Object.keys(attrs).length ? attrs : null;
36
38
  })),
37
39
 
38
- applyMark: createCommand(({ state }, name, value, customizer = {}) => {
40
+ applyMark: createCommand(({ state, commands }, name, value) => {
39
41
  const { tr, doc, schema } = state;
40
42
  const { $from, $to } = tr.selection;
41
43
  const markType = getMarkType(name, schema);
44
+ const markGroup = markType.spec.group || '';
42
45
 
43
- const onAppliedToParent = customizer.onAppliedToParent || ((context) => {
44
- const { tr, textPosition, applyingMark } = context;
45
-
46
- tr.removeMark(textPosition.from, textPosition.to, applyingMark.type);
47
- });
46
+ if (!markGroup.includes(MarkGroups.SETTINGS)) {
47
+ // Apply inline mark if block level not supported
48
+ return commands.setMark(name, value);
49
+ }
48
50
 
49
51
  if ($from.pos === $to.pos) return;
50
52
 
@@ -55,9 +57,8 @@ export const NodeProcessor = Extension.create({
55
57
  const applyingMark = markType.create({ ...(initialMark?.attrs || {}), ...value });
56
58
  const textPosition = resolveTextPosition($from, $to, node, position);
57
59
 
58
- if (isMarkAppliedToParent(tr, position, applyingMark, customizer.compareParentMark)) {
59
- onAppliedToParent({ tr, textPosition, applyingMark, initialMark, node });
60
- return;
60
+ if (isMarkAppliedToParent(tr.doc, position, applyingMark)) {
61
+ return commands._removeNodeMark({ tr, node, position, mark: markType });
61
62
  }
62
63
 
63
64
  if (node.isText) {
@@ -65,7 +66,7 @@ export const NodeProcessor = Extension.create({
65
66
  return;
66
67
  }
67
68
 
68
- if (isNodeFullySelected($from, $to, node, position)) {
69
+ if (isNodeFullySelected(tr.doc, tr.selection, node, position)) {
69
70
  tr.step(new AddNodeMarkStep(position, applyingMark));
70
71
  }
71
72
  });
@@ -102,10 +103,52 @@ export const NodeProcessor = Extension.create({
102
103
  }),
103
104
 
104
105
  getDeviceSettingMark: createCommand(({ commands }, name, defaultRef) => {
105
- const selectionRef = commands.getMark(name);
106
+ const selectionRef = commands.getMarks(name);
106
107
  const deviceRef = commands.getDevice();
107
108
 
108
- return computed(() => unref(selectionRef)?.[unref(deviceRef)] ?? unref(defaultRef));
109
+ return computed(() => {
110
+ for (const attrs of unref(selectionRef)) {
111
+ const value = attrs[unref(deviceRef)];
112
+
113
+ if (value) return value;
114
+ }
115
+
116
+ return unref(defaultRef);
117
+ });
118
+ }),
119
+
120
+ removeAllMarks: createCommand(({ state, commands }) => {
121
+ const { tr, doc } = state;
122
+ const { from, to } = tr.selection;
123
+
124
+ doc.nodesBetween(from, to, (node, position) => {
125
+ for (const mark of node.marks) {
126
+ commands._removeNodeMark({ tr, node, position, mark });
127
+ }
128
+ });
129
+ }),
130
+
131
+ removeMarks: createCommand(({ state, commands }, marks) => {
132
+ const { tr, doc } = state;
133
+ const { from, to } = tr.selection;
134
+
135
+ doc.nodesBetween(from, to, (node, position) => {
136
+ const removingMarks = node.marks.filter((mark) => marks.includes(mark.type.name));
137
+
138
+ for (const mark of removingMarks) {
139
+ commands._removeNodeMark({ tr, node, position, mark });
140
+ }
141
+ });
142
+ }),
143
+
144
+ removeMark: createCommand(({ commands, state }, node, position, mark) => {
145
+ commands._removeNodeMark({ tr: state.tr, node, position, mark });
146
+ }),
147
+
148
+ _removeNodeMark: createCommand((context, { tr, node, position, mark }) => {
149
+ return node.isText
150
+ ? tr.removeMark(position, position + node.nodeSize, mark)
151
+ : tr.step(new RemoveNodeMarkStep(position, mark));
109
152
  })
110
153
  };
111
154
  }
@@ -1,7 +1,8 @@
1
1
  import { Paragraph as Base } from '@tiptap/extension-paragraph';
2
+ import { MarkGroups } from '../../enums';
2
3
 
3
4
  export const Paragraph = Base.extend({
4
- marks: '_',
5
+ marks: MarkGroups.ALL,
5
6
 
6
7
  addOptions: () => ({
7
8
  HTMLAttributes: { class: 'zw-style' }
@@ -12,11 +12,6 @@ export const TextProcessor = Extension.create({
12
12
  return state.doc.textBetween(from, to, ' ');
13
13
  }),
14
14
 
15
- unsetMarks: createCommand(({ commands }, marks) => {
16
- // TODO check unset mark
17
- marks.forEach((mark) => commands.unsetMark(mark));
18
- }),
19
-
20
15
  transformText: createCommand(({ state }, transform) => {
21
16
  const { $from, $to } = state.tr.selection;
22
17