@zipify/wysiwyg 1.0.0-dev.4 → 1.0.0-dev.42

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 (217) hide show
  1. package/.editorconfig +1 -1
  2. package/.eslintignore +1 -0
  3. package/.eslintrc.js +2 -2
  4. package/.github/dependabot.yaml +1 -0
  5. package/.lintstagedrc +2 -2
  6. package/.release-it.json +3 -2
  7. package/.stylelintignore +1 -0
  8. package/.stylelintrc +0 -4
  9. package/README.md +5 -3
  10. package/config/jest/setupTests.js +7 -4
  11. package/config/vite/lib.config.js +31 -0
  12. package/config/vite/settings.js +9 -0
  13. package/config/webpack/example.config.js +2 -0
  14. package/config/webpack/lib.config.js +43 -0
  15. package/config/webpack/loaders/style-loader.js +3 -1
  16. package/config/webpack/loaders/svg-loader.js +1 -1
  17. package/dist/wysiwyg.css +1 -0
  18. package/dist/wysiwyg.mjs +18198 -0
  19. package/example/ExampleApp.vue +52 -33
  20. package/example/example.js +25 -2
  21. package/example/pageBlocks.js +31 -0
  22. package/example/presets.js +4 -2
  23. package/lib/Wysiwyg.vue +42 -22
  24. package/lib/__tests__/utils/withComponentContext.js +1 -1
  25. package/lib/assets/icons/alignment-center.svg +3 -0
  26. package/lib/assets/icons/alignment-justify.svg +3 -0
  27. package/lib/assets/icons/alignment-left.svg +3 -0
  28. package/lib/assets/icons/alignment-right.svg +3 -0
  29. package/lib/assets/icons/arrow.svg +3 -0
  30. package/lib/assets/icons/background-color.svg +3 -0
  31. package/lib/assets/icons/case-style.svg +3 -0
  32. package/lib/assets/icons/font-color.svg +5 -0
  33. package/lib/assets/icons/italic.svg +3 -0
  34. package/lib/assets/icons/line-height.svg +3 -0
  35. package/lib/assets/icons/link.svg +3 -0
  36. package/lib/assets/icons/list-circle.svg +3 -0
  37. package/lib/assets/icons/list-decimal.svg +3 -0
  38. package/lib/assets/icons/list-disc.svg +3 -0
  39. package/lib/assets/icons/list-latin.svg +3 -0
  40. package/lib/assets/icons/list-roman.svg +3 -0
  41. package/lib/assets/icons/list-square.svg +3 -0
  42. package/lib/assets/icons/remove-format.svg +3 -0
  43. package/lib/assets/icons/reset-styles.svg +3 -0
  44. package/lib/assets/icons/strike-through.svg +3 -0
  45. package/lib/assets/icons/superscript.svg +3 -0
  46. package/lib/assets/icons/underline.svg +3 -0
  47. package/lib/assets/icons/unlink.svg +3 -0
  48. package/lib/components/base/Button.vue +22 -2
  49. package/lib/components/base/Checkbox.vue +89 -0
  50. package/lib/components/base/FieldLabel.vue +2 -1
  51. package/lib/components/base/Icon.vue +19 -11
  52. package/lib/components/base/Modal.vue +1 -2
  53. package/lib/components/base/NumberField.vue +2 -2
  54. package/lib/components/base/Range.vue +1 -1
  55. package/lib/components/base/ScrollView.vue +2 -2
  56. package/lib/components/base/TextField.vue +106 -0
  57. package/lib/components/base/__tests__/Icon.test.js +6 -13
  58. package/lib/components/base/__tests__/Modal.test.js +8 -2
  59. package/lib/components/base/__tests__/TextField.test.js +57 -0
  60. package/lib/components/base/__tests__/__snapshots__/TextField.test.js.snap +9 -0
  61. package/lib/components/base/colorPicker/ColorPicker.vue +1 -1
  62. package/lib/components/base/colorPicker/composables/__tests__/usePickerApi.test.js +1 -1
  63. package/lib/components/base/colorPicker/composables/usePickerApi.js +1 -1
  64. package/lib/components/base/colorPicker/composables/usePickerHotkeys.js +3 -2
  65. package/lib/components/base/composables/__tests__/useActivatedListener.test.js +1 -1
  66. package/lib/components/base/composables/__tests__/useDeselectionLock.test.js +1 -1
  67. package/lib/components/base/composables/__tests__/useElementRef.test.js +1 -1
  68. package/lib/components/base/composables/__tests__/useModalToggler.test.js +1 -1
  69. package/lib/components/base/composables/__tests__/useNumberValue.test.js +1 -1
  70. package/lib/components/base/composables/__tests__/useScrollView.test.js +1 -1
  71. package/lib/components/base/composables/__tests__/useTempValue.test.js +1 -1
  72. package/lib/components/base/composables/index.js +1 -0
  73. package/lib/components/base/composables/useActivatedListener.js +1 -1
  74. package/lib/components/base/composables/useDeselectionLock.js +1 -1
  75. package/lib/components/base/composables/useElementRef.js +1 -1
  76. package/lib/components/base/composables/useModalToggler.js +1 -1
  77. package/lib/components/base/composables/useScrollView.js +1 -1
  78. package/lib/components/base/composables/useTempValue.js +1 -1
  79. package/lib/components/base/composables/useValidator.js +19 -0
  80. package/lib/components/base/dropdown/Dropdown.vue +16 -4
  81. package/lib/components/base/dropdown/DropdownActivator.vue +19 -3
  82. package/lib/components/base/dropdown/DropdownGroup.vue +1 -1
  83. package/lib/components/base/dropdown/DropdownMenu.vue +1 -1
  84. package/lib/components/base/dropdown/DropdownOption.vue +1 -1
  85. package/lib/components/base/dropdown/__tests__/DropdownActivator.test.js +1 -1
  86. package/lib/components/base/dropdown/__tests__/DropdownMenu.test.js +1 -1
  87. package/lib/components/base/dropdown/__tests__/DropdownOption.test.js +1 -1
  88. package/lib/components/base/dropdown/composables/__tests__/useActiveOptionManager.test.js +1 -1
  89. package/lib/components/base/dropdown/composables/__tests__/useDropdownEntityTitle.test.js +1 -1
  90. package/lib/components/base/dropdown/composables/useActiveOptionManager.js +1 -1
  91. package/lib/components/base/dropdown/composables/useDropdownEntityTitle.js +1 -1
  92. package/lib/components/base/index.js +3 -1
  93. package/lib/components/toolbar/Toolbar.vue +49 -9
  94. package/lib/components/toolbar/ToolbarDivider.vue +1 -1
  95. package/lib/components/toolbar/ToolbarFull.vue +10 -2
  96. package/lib/components/toolbar/__tests__/Toolbar.test.js +8 -1
  97. package/lib/components/toolbar/controls/AlignmentControl.vue +1 -1
  98. package/lib/components/toolbar/controls/AlignmentDeviceControl.vue +1 -1
  99. package/lib/components/toolbar/controls/BackgroundColorControl.vue +1 -1
  100. package/lib/components/toolbar/controls/CaseStyleControl.vue +1 -1
  101. package/lib/components/toolbar/controls/FontColorControl.vue +1 -1
  102. package/lib/components/toolbar/controls/FontFamilyControl.vue +1 -1
  103. package/lib/components/toolbar/controls/FontSizeControl.vue +8 -1
  104. package/lib/components/toolbar/controls/FontWeightControl.vue +1 -1
  105. package/lib/components/toolbar/controls/ItalicControl.vue +1 -1
  106. package/lib/components/toolbar/controls/LineHeightControl.vue +1 -1
  107. package/lib/components/toolbar/controls/ListControl.vue +2 -6
  108. package/lib/components/toolbar/controls/RemoveFormatControl.vue +1 -1
  109. package/lib/components/toolbar/controls/StrikeThroughControl.vue +1 -1
  110. package/lib/components/toolbar/controls/StylePresetControl.vue +1 -1
  111. package/lib/components/toolbar/controls/SuperscriptControl.vue +1 -1
  112. package/lib/components/toolbar/controls/UnderlineControl.vue +2 -2
  113. package/lib/components/toolbar/controls/__tests__/AlignmentControl.test.js +1 -1
  114. package/lib/components/toolbar/controls/__tests__/AlignmentDeviceControl.test.js +1 -1
  115. package/lib/components/toolbar/controls/__tests__/BackgroundColorControl.test.js +1 -1
  116. package/lib/components/toolbar/controls/__tests__/CaseStyleControl.test.js +1 -1
  117. package/lib/components/toolbar/controls/__tests__/FontColorControl.test.js +1 -1
  118. package/lib/components/toolbar/controls/__tests__/FontFamilyControl.test.js +1 -1
  119. package/lib/components/toolbar/controls/__tests__/FontSizeControl.test.js +1 -1
  120. package/lib/components/toolbar/controls/__tests__/FontWeightControl.test.js +1 -1
  121. package/lib/components/toolbar/controls/__tests__/ItalicControl.test.js +1 -1
  122. package/lib/components/toolbar/controls/__tests__/LineHeightControl.test.js +1 -1
  123. package/lib/components/toolbar/controls/__tests__/ListControl.test.js +1 -1
  124. package/lib/components/toolbar/controls/__tests__/StrikeThroughControl.test.js +1 -1
  125. package/lib/components/toolbar/controls/__tests__/StylePresetControl.test.js +1 -1
  126. package/lib/components/toolbar/controls/__tests__/UnderlineControl.test.js +5 -1
  127. package/lib/components/toolbar/controls/composables/useRecentFonts.js +1 -1
  128. package/lib/components/toolbar/controls/index.js +1 -0
  129. package/lib/components/toolbar/controls/link/LinkControl.vue +152 -0
  130. package/lib/components/toolbar/controls/link/LinkControlApply.vue +35 -0
  131. package/lib/components/toolbar/controls/link/LinkControlHeader.vue +67 -0
  132. package/lib/components/toolbar/controls/link/composables/index.js +1 -0
  133. package/lib/components/toolbar/controls/link/composables/useLink.js +61 -0
  134. package/lib/components/toolbar/controls/link/destination/LinkControlDestination.vue +103 -0
  135. package/lib/components/toolbar/controls/link/destination/LinkControlPageBlock.vue +54 -0
  136. package/lib/components/toolbar/controls/link/destination/LinkControlUrl.vue +52 -0
  137. package/lib/components/toolbar/controls/link/destination/index.js +1 -0
  138. package/lib/components/toolbar/controls/link/index.js +1 -0
  139. package/lib/composables/__tests__/useEditor.test.js +15 -6
  140. package/lib/composables/useEditor.js +13 -8
  141. package/lib/composables/useToolbar.js +14 -29
  142. package/lib/directives/outClick.js +20 -4
  143. package/lib/enums/LinkDestinations.js +4 -0
  144. package/lib/enums/LinkTargets.js +4 -0
  145. package/lib/enums/TextSettings.js +3 -1
  146. package/lib/enums/index.js +2 -0
  147. package/lib/extensions/Alignment.js +22 -4
  148. package/lib/extensions/BackgroundColor.js +17 -2
  149. package/lib/extensions/DeviceManager.js +2 -5
  150. package/lib/extensions/FontColor.js +17 -2
  151. package/lib/extensions/FontFamily.js +27 -3
  152. package/lib/extensions/FontSize.js +29 -4
  153. package/lib/extensions/FontStyle.js +24 -3
  154. package/lib/extensions/FontWeight.js +34 -2
  155. package/lib/extensions/LineHeight.js +30 -4
  156. package/lib/extensions/Link.js +101 -0
  157. package/lib/extensions/StylePreset.js +38 -15
  158. package/lib/extensions/TextDecoration.js +30 -4
  159. package/lib/extensions/__tests__/Alignment.test.js +32 -5
  160. package/lib/extensions/__tests__/BackgroundColor.test.js +39 -4
  161. package/lib/extensions/__tests__/CaseStyle.test.js +4 -3
  162. package/lib/extensions/__tests__/FontColor.test.js +39 -4
  163. package/lib/extensions/__tests__/FontFamily.test.js +60 -6
  164. package/lib/extensions/__tests__/FontSize.test.js +40 -5
  165. package/lib/extensions/__tests__/FontStyle.test.js +47 -4
  166. package/lib/extensions/__tests__/FontWeight.test.js +67 -4
  167. package/lib/extensions/__tests__/LineHeight.test.js +51 -5
  168. package/lib/extensions/__tests__/StylePreset.test.js +144 -6
  169. package/lib/extensions/__tests__/TextDecoration.test.js +88 -4
  170. package/lib/extensions/__tests__/__snapshots__/Alignment.test.js.snap +70 -2
  171. package/lib/extensions/__tests__/__snapshots__/BackgroundColor.test.js.snap +121 -1
  172. package/lib/extensions/__tests__/__snapshots__/FontColor.test.js.snap +109 -1
  173. package/lib/extensions/__tests__/__snapshots__/FontFamily.test.js.snap +179 -1
  174. package/lib/extensions/__tests__/__snapshots__/FontSize.test.js.snap +132 -2
  175. package/lib/extensions/__tests__/__snapshots__/FontStyle.test.js.snap +142 -1
  176. package/lib/extensions/__tests__/__snapshots__/FontWeight.test.js.snap +179 -1
  177. package/lib/extensions/__tests__/__snapshots__/LineHeight.test.js.snap +118 -2
  178. package/lib/extensions/__tests__/__snapshots__/StylePreset.test.js.snap +171 -2
  179. package/lib/extensions/__tests__/__snapshots__/TextDecoration.test.js.snap +300 -3
  180. package/lib/extensions/core/CopyPasteProcessor.js +10 -0
  181. package/lib/extensions/core/NodeProcessor.js +1 -1
  182. package/lib/extensions/core/TextProcessor.js +10 -0
  183. package/lib/extensions/core/__tests__/NodeProcessor.test.js +4 -3
  184. package/lib/extensions/core/__tests__/SelectionProcessor.test.js +9 -6
  185. package/lib/extensions/core/__tests__/TextProcessor.test.js +139 -10
  186. package/lib/extensions/core/__tests__/__snapshots__/TextProcessor.test.js.snap +26 -0
  187. package/lib/extensions/core/index.js +11 -2
  188. package/lib/extensions/core/plugins/PastePlugin.js +48 -0
  189. package/lib/extensions/core/plugins/ProseMirrorPlugin.js +20 -0
  190. package/lib/extensions/core/plugins/index.js +1 -0
  191. package/lib/extensions/index.js +41 -33
  192. package/lib/extensions/list/List.js +35 -1
  193. package/lib/extensions/list/__tests__/List.test.js +117 -8
  194. package/lib/extensions/list/__tests__/__snapshots__/List.test.js.snap +481 -0
  195. package/lib/injectionTokens.js +2 -1
  196. package/lib/services/ContentNormalizer.js +157 -0
  197. package/lib/services/ContextWidnow.js +23 -0
  198. package/lib/services/Storage.js +1 -13
  199. package/lib/services/__tests__/ContentNormalizer.test.js +74 -0
  200. package/lib/services/__tests__/FavoriteColors.test.js +20 -0
  201. package/lib/services/__tests__/JsonSerializer.test.js +23 -0
  202. package/lib/services/__tests__/Storage.test.js +79 -0
  203. package/lib/services/index.js +2 -0
  204. package/lib/styles/content.css +96 -9
  205. package/lib/styles/helpers/offsets.css +16 -0
  206. package/lib/styles/variables.css +6 -0
  207. package/lib/utils/__tests__/__snapshots__/renderInlineSetting.test.js.snap +4 -4
  208. package/lib/utils/__tests__/convertColor.test.js +19 -0
  209. package/lib/utils/__tests__/createKeyboardShortcut.test.js +25 -0
  210. package/lib/utils/__tests__/renderInlineSetting.test.js +26 -0
  211. package/lib/utils/convertColor.js +7 -0
  212. package/lib/utils/importIcon.js +13 -0
  213. package/lib/utils/index.js +2 -0
  214. package/lib/utils/renderInlineSetting.js +2 -2
  215. package/package.json +21 -16
  216. package/lib/assets/icons.svg +0 -69
  217. package/lib/composables/__tests__/useToolbar.test.js +0 -56
@@ -1,12 +1,13 @@
1
1
  import { Editor, Extension } from '@tiptap/vue-2';
2
- import { ref } from '@vue/composition-api';
2
+ import { ref } from 'vue';
3
3
  import { NodeFactory } from '../../__tests__/utils';
4
4
  import { createCommand } from '../../utils';
5
- import { CORE_EXTENSIONS } from '../core';
6
5
  import { Font } from '../../models';
7
6
  import { FontWeight } from '../FontWeight';
8
7
  import { FontFamily } from '../FontFamily';
9
8
  import { FontStyle } from '../FontStyle';
9
+ import { ContentNormalizer } from '../../services';
10
+ import { buildCoreExtensions } from '../core';
10
11
 
11
12
  const MockStylePreset = Extension.create({
12
13
  name: 'style_preset',
@@ -25,8 +26,8 @@ const MockStylePreset = Extension.create({
25
26
 
26
27
  function createEditor({ content }) {
27
28
  return new Editor({
28
- content,
29
- extensions: CORE_EXTENSIONS.concat(
29
+ content: ContentNormalizer.normalize(content),
30
+ extensions: buildCoreExtensions().concat(
30
31
  MockStylePreset,
31
32
  FontFamily.configure({
32
33
  fonts: [
@@ -74,6 +75,18 @@ describe('get font weight', () => {
74
75
 
75
76
  expect(editor.commands.getFontWeight().value).toEqual('400');
76
77
  });
78
+
79
+ test('should get closest available font weight', () => {
80
+ const editor = createEditor({
81
+ content: createContent(NodeFactory.text('hello world', [
82
+ NodeFactory.mark('font_weight', { value: '800' })
83
+ ]))
84
+ });
85
+
86
+ editor.commands.selectAll();
87
+
88
+ expect(editor.commands.getFontWeight().value).toEqual('700');
89
+ });
77
90
  });
78
91
 
79
92
  describe('apply font weight', () => {
@@ -149,3 +162,53 @@ describe('rendering', () => {
149
162
  expect(editor.getHTML()).toMatchSnapshot();
150
163
  });
151
164
  });
165
+
166
+ describe('parsing html', () => {
167
+ test('should get value from paragraph', () => {
168
+ const editor = createEditor({
169
+ content: '<p style="font-weight: 700">test</p>'
170
+ });
171
+
172
+ expect(editor.getJSON()).toMatchSnapshot();
173
+ });
174
+
175
+ test('should get value from text', () => {
176
+ const editor = createEditor({
177
+ content: '<p><span style="font-weight: 700">lorem</span> ipsum</p>'
178
+ });
179
+
180
+ expect(editor.getJSON()).toMatchSnapshot();
181
+ });
182
+
183
+ test('should get value from rendered view', () => {
184
+ const editor = createEditor({
185
+ content: '<p><span style="--zw-font-weight: 700">lorem</span> ipsum</p>'
186
+ });
187
+
188
+ expect(editor.getJSON()).toMatchSnapshot();
189
+ });
190
+
191
+ test('should get value from b tag', () => {
192
+ const editor = createEditor({
193
+ content: '<p><b>lorem</b> ipsum</p>'
194
+ });
195
+
196
+ expect(editor.getJSON()).toMatchSnapshot();
197
+ });
198
+
199
+ test('should get value from strong tag', () => {
200
+ const editor = createEditor({
201
+ content: '<p><strong>lorem</strong> ipsum</p>'
202
+ });
203
+
204
+ expect(editor.getJSON()).toMatchSnapshot();
205
+ });
206
+
207
+ test('should merge paragraph and text settings', () => {
208
+ const editor = createEditor({
209
+ content: '<p style="font-weight: 500"><span style="font-weight: 700">lorem</span> ipsum</p>'
210
+ });
211
+
212
+ expect(editor.getJSON()).toMatchSnapshot();
213
+ });
214
+ });
@@ -1,10 +1,11 @@
1
1
  import { Editor, Extension } from '@tiptap/vue-2';
2
- import { ref } from '@vue/composition-api';
2
+ import { ref } from 'vue';
3
3
  import { NodeFactory } from '../../__tests__/utils';
4
4
  import { createCommand } from '../../utils';
5
- import { CORE_EXTENSIONS } from '../core';
6
5
  import { DeviceManager } from '../DeviceManager';
7
6
  import { LineHeight } from '../LineHeight';
7
+ import { ContentNormalizer } from '../../services';
8
+ import { buildCoreExtensions } from '../core';
8
9
 
9
10
  const MockStylePreset = Extension.create({
10
11
  name: 'style_preset',
@@ -22,10 +23,10 @@ const MockStylePreset = Extension.create({
22
23
 
23
24
  function createEditor({ content }) {
24
25
  return new Editor({
25
- content,
26
- extensions: CORE_EXTENSIONS.concat(
26
+ content: ContentNormalizer.normalize(content),
27
+ extensions: buildCoreExtensions().concat(
27
28
  MockStylePreset,
28
- DeviceManager.configure({ deviceRef: ref('desktop') }),
29
+ DeviceManager.configure({ device: ref('desktop') }),
29
30
  LineHeight
30
31
  )
31
32
  });
@@ -104,3 +105,48 @@ describe('rendering', () => {
104
105
  expect(editor.getHTML()).toMatchSnapshot();
105
106
  });
106
107
  });
108
+
109
+ describe('parsing html', () => {
110
+ test('should get value from text in relative units', () => {
111
+ const editor = createEditor({
112
+ content: '<p style="line-height: 1.2">test</p>'
113
+ });
114
+
115
+ expect(editor.getJSON()).toMatchSnapshot();
116
+ });
117
+
118
+ test('should get value from text in px units with font size', () => {
119
+ const editor = createEditor({
120
+ content: '<p style="line-height: 24px; font-size: 20px;">test</p>'
121
+ });
122
+
123
+ expect(editor.getJSON()).toMatchSnapshot();
124
+ });
125
+
126
+ test('should get value from text in px units with no font size', () => {
127
+ global.document.body.style.fontSize = '20px';
128
+
129
+ const editor = createEditor({
130
+ content: '<p style="line-height: 24px">test</p>'
131
+ });
132
+
133
+ expect(editor.getJSON()).toMatchSnapshot();
134
+ global.document.body.style.removeProperty('font-size');
135
+ });
136
+
137
+ test('should get value from rendered view', () => {
138
+ const editor = createEditor({
139
+ content: '<p style="--zw-line-height-mobile:1.2;--zw-line-height-desktop:1.4">test</p>'
140
+ });
141
+
142
+ expect(editor.getJSON()).toMatchSnapshot();
143
+ });
144
+
145
+ test('should set null if no alignment', () => {
146
+ const editor = createEditor({
147
+ content: '<p>test</p>'
148
+ });
149
+
150
+ expect(editor.getJSON()).toMatchSnapshot();
151
+ });
152
+ });
@@ -1,10 +1,10 @@
1
1
  import { Editor, Extension, Mark } from '@tiptap/vue-2';
2
- import { ref } from '@vue/composition-api';
3
2
  import { NodeFactory } from '../../__tests__/utils';
4
- import { CORE_EXTENSIONS } from '../core';
5
3
  import { StylePreset } from '../StylePreset';
6
4
  import { List } from '../list';
7
5
  import { ListTypes, NodeTypes, TextSettings } from '../../enums';
6
+ import { ContentNormalizer } from '../../services';
7
+ import { buildCoreExtensions } from '../core';
8
8
 
9
9
  const MockFontSize = Mark.create({
10
10
  name: TextSettings.FONT_SIZE,
@@ -42,15 +42,76 @@ const MockAlignment = Extension.create({
42
42
  ]
43
43
  });
44
44
 
45
+ const MockBackgroundColor = Mark.create({
46
+ name: TextSettings.BACKGROUND_COLOR,
47
+
48
+ addAttributes: () => ({
49
+ value: { default: null }
50
+ }),
51
+
52
+ renderHTML: () => ['span', {}, 0]
53
+ });
54
+
55
+ const MockFontColor = Mark.create({
56
+ name: TextSettings.FONT_COLOR,
57
+
58
+ addAttributes: () => ({
59
+ value: { default: null }
60
+ }),
61
+
62
+ renderHTML: () => ['span', {}, 0]
63
+ });
64
+
65
+ const MockFontFamily = Mark.create({
66
+ name: TextSettings.FONT_FAMILY,
67
+
68
+ addAttributes: () => ({
69
+ value: { default: null }
70
+ }),
71
+
72
+ renderHTML: () => ['span', {}, 0]
73
+ });
74
+
75
+ const MockFontStyle = Mark.create({
76
+ name: TextSettings.FONT_STYLE,
77
+
78
+ addAttributes: () => ({
79
+ value: { default: null }
80
+ }),
81
+
82
+ renderHTML: () => ['span', {}, 0]
83
+ });
84
+
85
+ const MockTextDecoration = Mark.create({
86
+ name: TextSettings.TEXT_DECORATION,
87
+
88
+ addAttributes: () => ({
89
+ value: { default: null }
90
+ }),
91
+
92
+ renderHTML: () => ['span', {}, 0]
93
+ });
94
+
95
+ const MockSuperscript = Mark.create({
96
+ name: TextSettings.SUPERSCRIPT,
97
+
98
+ addAttributes: () => ({
99
+ value: { default: null }
100
+ }),
101
+
102
+ renderHTML: () => ['span', {}, 0]
103
+ });
104
+
45
105
  function createEditor({ content, presets, defaultId }) {
46
106
  return new Promise((resolve) => {
47
107
  const editor = new Editor({
48
- content,
108
+ content: ContentNormalizer.normalize(content),
49
109
  onCreate: () => resolve(editor),
50
110
 
51
- extensions: CORE_EXTENSIONS.concat(
111
+ extensions: buildCoreExtensions().concat(
52
112
  StylePreset.configure({
53
- presetsRef: ref(presets),
113
+ presets: presets,
114
+ baseClass: 'zw ts-',
54
115
  defaultId,
55
116
 
56
117
  makeVariable({ device, preset, property }) {
@@ -64,7 +125,13 @@ function createEditor({ content, presets, defaultId }) {
64
125
  }),
65
126
  MockFontSize,
66
127
  MockFontWeight,
67
- MockAlignment
128
+ MockAlignment,
129
+ MockBackgroundColor,
130
+ MockFontColor,
131
+ MockFontFamily,
132
+ MockFontStyle,
133
+ MockTextDecoration,
134
+ MockSuperscript
68
135
  )
69
136
  });
70
137
  });
@@ -398,3 +465,74 @@ describe('remove preset customization', () => {
398
465
  );
399
466
  });
400
467
  });
468
+
469
+ describe('parsing html', () => {
470
+ test('should get by fallback class', async () => {
471
+ const editor = await createEditor({
472
+ content: '<p class="zpa-regular2">lorem ipsum</p>',
473
+ defaultId: 'regular-1',
474
+ presets: [
475
+ createPreset({ id: 'regular-1' }),
476
+ createPreset({ id: 'regular-2', fallbackClass: 'zpa-regular2' })
477
+ ]
478
+ });
479
+
480
+ expect(editor.getJSON()).toMatchSnapshot();
481
+ });
482
+
483
+ test('should get by preset class', async () => {
484
+ const editor = await createEditor({
485
+ content: '<p class="zw ts-regular-2">lorem ipsum</p>',
486
+ defaultId: 'regular-1',
487
+ presets: [
488
+ createPreset({ id: 'regular-1' }),
489
+ createPreset({ id: 'regular-2' })
490
+ ]
491
+ });
492
+
493
+ expect(editor.getJSON()).toMatchSnapshot();
494
+ });
495
+
496
+ test('should get by heading tag', async () => {
497
+ const editor = await createEditor({
498
+ content: '<h3>lorem ipsum</h3>',
499
+ defaultId: 'regular-1',
500
+ presets: [
501
+ createPreset({ id: 'regular-1' }),
502
+ createPreset({ id: 'h3', node: { type: 'heading', level: 3 } })
503
+ ]
504
+ });
505
+
506
+ expect(editor.getJSON()).toMatchSnapshot();
507
+ });
508
+
509
+ test('should set default preset to unstyled paragraph', async () => {
510
+ const editor = await createEditor({
511
+ content: '<p>lorem ipsum</p>',
512
+ defaultId: 'regular-1',
513
+ presets: [createPreset({ id: 'regular-1' })]
514
+ });
515
+
516
+ expect(editor.getJSON()).toMatchSnapshot();
517
+ });
518
+
519
+ test('should set null to list item', async () => {
520
+ const editor = await createEditor({
521
+ content: '<ul><li>lorem ipsum</li></ul>',
522
+ defaultId: 'regular-1',
523
+ presets: [createPreset({ id: 'regular-1' })]
524
+ });
525
+
526
+ expect(editor.getJSON()).toMatchSnapshot();
527
+ });
528
+
529
+ test('should set null to list item with preset', async () => {
530
+ const editor = await createEditor({
531
+ content: '<ul class="zw regular-1"><li>lorem ipsum</li></ul>',
532
+ defaultId: 'regular-1',
533
+ presets: [createPreset({ id: 'regular-1' })]
534
+ });
535
+
536
+ expect(editor.getJSON()).toMatchSnapshot();
537
+ });
538
+ });
@@ -1,9 +1,10 @@
1
1
  import { Editor, Extension } from '@tiptap/vue-2';
2
- import { ref } from '@vue/composition-api';
2
+ import { ref } from 'vue';
3
3
  import { NodeFactory } from '../../__tests__/utils';
4
4
  import { createCommand } from '../../utils';
5
- import { CORE_EXTENSIONS } from '../core';
6
5
  import { TextDecoration } from '../TextDecoration';
6
+ import { ContentNormalizer } from '../../services';
7
+ import { buildCoreExtensions } from '../core';
7
8
 
8
9
  const MockStylePreset = Extension.create({
9
10
  name: 'style_preset',
@@ -19,8 +20,8 @@ const MockStylePreset = Extension.create({
19
20
 
20
21
  function createEditor({ content }) {
21
22
  return new Editor({
22
- content,
23
- extensions: CORE_EXTENSIONS.concat(MockStylePreset, TextDecoration)
23
+ content: ContentNormalizer.normalize(content),
24
+ extensions: buildCoreExtensions().concat(MockStylePreset, TextDecoration)
24
25
  });
25
26
  }
26
27
 
@@ -256,3 +257,86 @@ describe('rendering', () => {
256
257
  expect(editor.getHTML()).toMatchSnapshot();
257
258
  });
258
259
  });
260
+
261
+
262
+ describe('parsing html', () => {
263
+ test('should get underline from paragraph', () => {
264
+ const editor = createEditor({
265
+ content: '<p style="text-decoration-line: underline">test</p>'
266
+ });
267
+
268
+ expect(editor.getJSON()).toMatchSnapshot();
269
+ });
270
+
271
+ test('should get strike through from paragraph', () => {
272
+ const editor = createEditor({
273
+ content: '<p style="text-decoration-line: line-through">test</p>'
274
+ });
275
+
276
+ expect(editor.getJSON()).toMatchSnapshot();
277
+ });
278
+
279
+ test('should get both from paragraph', () => {
280
+ const editor = createEditor({
281
+ content: '<p style="text-decoration-line: line-through underline">test</p>'
282
+ });
283
+
284
+ expect(editor.getJSON()).toMatchSnapshot();
285
+ });
286
+
287
+ test('should get underline from text', () => {
288
+ const editor = createEditor({
289
+ content: '<p><span style="text-decoration-line: underline">lorem</span> ipsum</p>'
290
+ });
291
+
292
+ expect(editor.getJSON()).toMatchSnapshot();
293
+ });
294
+
295
+ test('should get underline from rendered view', () => {
296
+ const editor = createEditor({
297
+ content: '<p><span style="--zw-text-decoration: underline">lorem</span> ipsum</p>'
298
+ });
299
+
300
+ expect(editor.getJSON()).toMatchSnapshot();
301
+ });
302
+
303
+ test('should get strike through from text', () => {
304
+ const editor = createEditor({
305
+ content: '<p><span style="text-decoration-line: line-through">lorem</span> ipsum</p>'
306
+ });
307
+
308
+ expect(editor.getJSON()).toMatchSnapshot();
309
+ });
310
+
311
+ test('should get strike through from rendered view', () => {
312
+ const editor = createEditor({
313
+ content: '<p><span style="--zw-text-decoration: line-through">lorem</span> ipsum</p>'
314
+ });
315
+
316
+ expect(editor.getJSON()).toMatchSnapshot();
317
+ });
318
+
319
+ test('should get both from text', () => {
320
+ const editor = createEditor({
321
+ content: '<p><span style="text-decoration-line: underline line-through">lorem</span> ipsum</p>'
322
+ });
323
+
324
+ expect(editor.getJSON()).toMatchSnapshot();
325
+ });
326
+
327
+ test('should get both from rendered view', () => {
328
+ const editor = createEditor({
329
+ content: '<p><span style="--zw-text-decoration: underline line-through">lorem</span> ipsum</p>'
330
+ });
331
+
332
+ expect(editor.getJSON()).toMatchSnapshot();
333
+ });
334
+
335
+ test('should merge paragraph and text settings', () => {
336
+ const editor = createEditor({
337
+ content: '<p style="text-decoration-line: underline"><span style="text-decoration-line: line-through">lorem</span> ipsum</p>'
338
+ });
339
+
340
+ expect(editor.getJSON()).toMatchSnapshot();
341
+ });
342
+ });
@@ -24,6 +24,74 @@ Object {
24
24
  }
25
25
  `;
26
26
 
27
- exports[`rendering should render all devices 1`] = `"<p class=\\"zw-style\\" style=\\"--zw-mobile-text-align: left; --zw-tablet-text-align: right; --zw-desktop-text-align: center;\\">hello world</p>"`;
27
+ exports[`parsing html should get alignment from rendered view 1`] = `
28
+ Object {
29
+ "content": Array [
30
+ Object {
31
+ "attrs": Object {
32
+ "alignment": Object {
33
+ "desktop": "right",
34
+ "mobile": "center",
35
+ "tablet": null,
36
+ },
37
+ },
38
+ "content": Array [
39
+ Object {
40
+ "text": "test",
41
+ "type": "text",
42
+ },
43
+ ],
44
+ "type": "paragraph",
45
+ },
46
+ ],
47
+ "type": "doc",
48
+ }
49
+ `;
50
+
51
+ exports[`parsing html should get alignment from text 1`] = `
52
+ Object {
53
+ "content": Array [
54
+ Object {
55
+ "attrs": Object {
56
+ "alignment": Object {
57
+ "desktop": "center",
58
+ "mobile": "center",
59
+ "tablet": "center",
60
+ },
61
+ },
62
+ "content": Array [
63
+ Object {
64
+ "text": "test",
65
+ "type": "text",
66
+ },
67
+ ],
68
+ "type": "paragraph",
69
+ },
70
+ ],
71
+ "type": "doc",
72
+ }
73
+ `;
74
+
75
+ exports[`parsing html should set null if no alignment 1`] = `
76
+ Object {
77
+ "content": Array [
78
+ Object {
79
+ "attrs": Object {
80
+ "alignment": null,
81
+ },
82
+ "content": Array [
83
+ Object {
84
+ "text": "test",
85
+ "type": "text",
86
+ },
87
+ ],
88
+ "type": "paragraph",
89
+ },
90
+ ],
91
+ "type": "doc",
92
+ }
93
+ `;
94
+
95
+ exports[`rendering should render all devices 1`] = `"<p class=\\"zw-style\\" style=\\"--zw-text-align-mobile:left;--zw-text-align-tablet:right;--zw-text-align-desktop:center;\\">hello world</p>"`;
28
96
 
29
- exports[`rendering should render only desktop 1`] = `"<p class=\\"zw-style\\" style=\\"--zw-desktop-text-align: center;\\">hello world</p>"`;
97
+ exports[`rendering should render only desktop 1`] = `"<p class=\\"zw-style\\" style=\\"--zw-text-align-desktop:center;\\">hello world</p>"`;
@@ -25,4 +25,124 @@ Object {
25
25
  }
26
26
  `;
27
27
 
28
- exports[`rendering should render html 1`] = `"<p class=\\"zw-style\\"><span style=\\"--zw-background-color: green;\\" class=\\"zw-style\\">hello world</span></p>"`;
28
+ exports[`parsing html should get value from paragraph 1`] = `
29
+ Object {
30
+ "content": Array [
31
+ Object {
32
+ "content": Array [
33
+ Object {
34
+ "marks": Array [
35
+ Object {
36
+ "attrs": Object {
37
+ "value": "#FF0000",
38
+ },
39
+ "type": "background_color",
40
+ },
41
+ ],
42
+ "text": "test",
43
+ "type": "text",
44
+ },
45
+ ],
46
+ "type": "paragraph",
47
+ },
48
+ ],
49
+ "type": "doc",
50
+ }
51
+ `;
52
+
53
+ exports[`parsing html should get value from rendered view 1`] = `
54
+ Object {
55
+ "content": Array [
56
+ Object {
57
+ "content": Array [
58
+ Object {
59
+ "marks": Array [
60
+ Object {
61
+ "attrs": Object {
62
+ "value": "#FF0000",
63
+ },
64
+ "type": "background_color",
65
+ },
66
+ ],
67
+ "text": "lorem",
68
+ "type": "text",
69
+ },
70
+ Object {
71
+ "text": " ipsum",
72
+ "type": "text",
73
+ },
74
+ ],
75
+ "type": "paragraph",
76
+ },
77
+ ],
78
+ "type": "doc",
79
+ }
80
+ `;
81
+
82
+ exports[`parsing html should get value from text 1`] = `
83
+ Object {
84
+ "content": Array [
85
+ Object {
86
+ "content": Array [
87
+ Object {
88
+ "marks": Array [
89
+ Object {
90
+ "attrs": Object {
91
+ "value": "#FF0000",
92
+ },
93
+ "type": "background_color",
94
+ },
95
+ ],
96
+ "text": "lorem",
97
+ "type": "text",
98
+ },
99
+ Object {
100
+ "text": " ipsum",
101
+ "type": "text",
102
+ },
103
+ ],
104
+ "type": "paragraph",
105
+ },
106
+ ],
107
+ "type": "doc",
108
+ }
109
+ `;
110
+
111
+ exports[`parsing html should merge paragraph and text settings 1`] = `
112
+ Object {
113
+ "content": Array [
114
+ Object {
115
+ "content": Array [
116
+ Object {
117
+ "marks": Array [
118
+ Object {
119
+ "attrs": Object {
120
+ "value": "#000000",
121
+ },
122
+ "type": "background_color",
123
+ },
124
+ ],
125
+ "text": "lorem",
126
+ "type": "text",
127
+ },
128
+ Object {
129
+ "marks": Array [
130
+ Object {
131
+ "attrs": Object {
132
+ "value": "#FF0000",
133
+ },
134
+ "type": "background_color",
135
+ },
136
+ ],
137
+ "text": " ipsum",
138
+ "type": "text",
139
+ },
140
+ ],
141
+ "type": "paragraph",
142
+ },
143
+ ],
144
+ "type": "doc",
145
+ }
146
+ `;
147
+
148
+ exports[`rendering should render html 1`] = `"<p class=\\"zw-style\\"><span style=\\"--zw-background-color:green;\\" class=\\"zw-style\\">hello world</span></p>"`;