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

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 +1 -1
  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 +25 -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/style.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,8 +1,15 @@
1
1
  import { Extension } from '@tiptap/vue-2';
2
- import { computed, toRef } from '@vue/composition-api';
2
+ import { computed, toRef } from 'vue';
3
3
  import { Heading } from '@tiptap/extension-heading';
4
4
  import { createCommand } from '../utils';
5
5
  import { Devices, NodeTypes, TextSettings } from '../enums';
6
+ import { ContextWindow } from '../services';
7
+
8
+ function makePresetClass(base, preset) {
9
+ const baseClass = base.split(' ').map((part) => `.${part}`).join('');
10
+
11
+ return baseClass + preset.id;
12
+ }
6
13
 
7
14
  export const StylePreset = Extension.create({
8
15
  name: 'style_preset',
@@ -14,12 +21,6 @@ export const StylePreset = Extension.create({
14
21
  })
15
22
  ],
16
23
 
17
- addOptions: () => ({
18
- presetsRef: null,
19
- defaultId: null,
20
- makeVariable: null
21
- }),
22
-
23
24
  addStorage: () => ({
24
25
  presetStyleEl: null
25
26
  }),
@@ -32,10 +33,31 @@ export const StylePreset = Extension.create({
32
33
  preset: {
33
34
  isRequired: false,
34
35
  default: { id: this.options.defaultId },
36
+
37
+ parseHTML: (element) => {
38
+ const presets = this.options.presets;
39
+
40
+ if (element.parentElement.tagName === 'LI') return null;
41
+
42
+ for (const { id, node, fallbackClass } of presets) {
43
+ const isFallback = fallbackClass && element.classList.contains(fallbackClass);
44
+
45
+ if (isFallback) return { id };
46
+
47
+ const className = makePresetClass(this.options.baseClass, { id });
48
+
49
+ if (element.matches(className)) return { id };
50
+ if (element.tagName === `H${node?.level}`) return { id };
51
+ }
52
+
53
+ // Matches all paragraphs without classes to default preset
54
+ return element.tagName === 'P' ? { id: this.options.defaultId } : null;
55
+ },
56
+
35
57
  renderHTML: (attrs) => {
36
58
  if (!attrs.preset) return null;
37
59
 
38
- return { class: `zw-preset--${attrs.preset.id}` };
60
+ return { class: this.options.baseClass + attrs.preset.id };
39
61
  }
40
62
  }
41
63
  }
@@ -50,7 +72,7 @@ export const StylePreset = Extension.create({
50
72
 
51
73
  return {
52
74
  getPresetList: createCommand(() => computed(() => {
53
- return this.options.presetsRef.value.filter((preset) => !preset.hidden);
75
+ return this.options.presets.filter((preset) => !preset.hidden);
54
76
  })),
55
77
 
56
78
  getPreset: createCommand(({ commands }) => {
@@ -121,7 +143,7 @@ export const StylePreset = Extension.create({
121
143
  chain()
122
144
  .storeSelection()
123
145
  .expandSelectionToBlock()
124
- .unsetAllMarks()
146
+ .unsetMarks(TextSettings.marks)
125
147
  .resetAttributes(NodeTypes.PARAGRAPH, TextSettings.attributes)
126
148
  .resetAttributes(NodeTypes.HEADING, TextSettings.attributes)
127
149
  .restoreSelection()
@@ -136,18 +158,19 @@ export const StylePreset = Extension.create({
136
158
  },
137
159
 
138
160
  onCreate() {
139
- const existingStyleEl = document.querySelector('[data-zw-styles]');
161
+ const existingStyleEl = ContextWindow.document.querySelector('[data-zw-styles]');
140
162
 
141
163
  if (existingStyleEl) {
142
164
  this.storage.presetStyleEl = existingStyleEl;
143
165
  return;
144
166
  }
145
167
 
146
- this.storage.presetStyleEl = document.createElement('style');
168
+ this.storage.presetStyleEl = ContextWindow.document.createElement('style');
147
169
  this.storage.presetStyleEl.dataset.zwStyles = '';
148
170
 
149
- for (const preset of this.options.presetsRef.value) {
150
- const css = [` .zw-preset--${preset.id} {`];
171
+ for (const preset of this.options.presets) {
172
+ const className = makePresetClass(this.options.baseClass, preset);
173
+ const css = [` ${className} {`];
151
174
 
152
175
  for (const device of Devices.values) {
153
176
  for (const setting of Object.keys(preset[device])) {
@@ -163,6 +186,6 @@ export const StylePreset = Extension.create({
163
186
  this.storage.presetStyleEl.innerHTML += css.join(' ');
164
187
  }
165
188
 
166
- document.head.append(this.storage.presetStyleEl);
189
+ ContextWindow.head.append(this.storage.presetStyleEl);
167
190
  }
168
191
  });
@@ -1,5 +1,5 @@
1
1
  import { Mark } from '@tiptap/vue-2';
2
- import { computed } from '@vue/composition-api';
2
+ import { computed } from 'vue';
3
3
  import { createCommand, createKeyboardShortcut, renderMark } from '../utils';
4
4
  import { TextSettings } from '../enums';
5
5
 
@@ -13,10 +13,10 @@ export const TextDecoration = Mark.create({
13
13
 
14
14
  addCommands() {
15
15
  return {
16
- isUnderline: createCommand(({ commands }) => {
16
+ isUnderline: createCommand(({ commands, editor }) => {
17
17
  const decoration = commands.getTextDecoration();
18
18
 
19
- return computed(() => decoration.value.underline);
19
+ return computed(() => editor.isActive('link') || decoration.value.underline);
20
20
  }),
21
21
 
22
22
  isStrikeThrough: createCommand(({ commands }) => {
@@ -51,7 +51,9 @@ export const TextDecoration = Mark.create({
51
51
  });
52
52
  }),
53
53
 
54
- toggleUnderline: createCommand(({ commands }) => {
54
+ toggleUnderline: createCommand(({ commands, editor }) => {
55
+ if (editor.isActive('link')) return;
56
+
55
57
  commands.toggleTextDecoration('underline');
56
58
  }),
57
59
 
@@ -86,6 +88,30 @@ export const TextDecoration = Mark.create({
86
88
  'Mod-U': createKeyboardShortcut('toggleUnderline')
87
89
  }),
88
90
 
91
+ parseHTML() {
92
+ const getAttrs = (value) => {
93
+ const underline = value.includes('underline');
94
+ const strike_through = value.includes('line-through');
95
+
96
+ if (!underline && !strike_through) {
97
+ return false;
98
+ }
99
+
100
+ return { underline, strike_through };
101
+ };
102
+
103
+ return [
104
+ {
105
+ style: '--zw-text-decoration',
106
+ getAttrs
107
+ },
108
+ {
109
+ style: 'text-decoration-line',
110
+ getAttrs
111
+ }
112
+ ];
113
+ },
114
+
89
115
  renderHTML({ HTMLAttributes: attrs }) {
90
116
  const decorations = [];
91
117
 
@@ -1,11 +1,12 @@
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 { Alignment } from '../Alignment';
7
6
  import { DeviceManager } from '../DeviceManager';
8
7
  import { Alignments } from '../../enums';
8
+ import { ContentNormalizer } from '../../services';
9
+ import { buildCoreExtensions } from '../core';
9
10
 
10
11
  const MockStylePreset = Extension.create({
11
12
  name: 'style_preset',
@@ -23,10 +24,10 @@ const MockStylePreset = Extension.create({
23
24
 
24
25
  function createEditor({ content }) {
25
26
  return new Editor({
26
- content,
27
- extensions: CORE_EXTENSIONS.concat(
27
+ content: ContentNormalizer.normalize(content),
28
+ extensions: buildCoreExtensions().concat(
28
29
  MockStylePreset,
29
- DeviceManager.configure({ deviceRef: ref('desktop') }),
30
+ DeviceManager.configure({ device: ref('desktop') }),
30
31
  Alignment
31
32
  )
32
33
  });
@@ -105,3 +106,29 @@ describe('rendering', () => {
105
106
  expect(editor.getHTML()).toMatchSnapshot();
106
107
  });
107
108
  });
109
+
110
+ describe('parsing html', () => {
111
+ test('should get alignment from text', () => {
112
+ const editor = createEditor({
113
+ content: '<p style="text-align:center">test</p>'
114
+ });
115
+
116
+ expect(editor.getJSON()).toMatchSnapshot();
117
+ });
118
+
119
+ test('should get alignment from rendered view', () => {
120
+ const editor = createEditor({
121
+ content: '<p style="--zw-text-align-mobile:center;--zw-text-align-desktop:right">test</p>'
122
+ });
123
+
124
+ expect(editor.getJSON()).toMatchSnapshot();
125
+ });
126
+
127
+ test('should set null if no alignment', () => {
128
+ const editor = createEditor({
129
+ content: '<p>test</p>'
130
+ });
131
+
132
+ expect(editor.getJSON()).toMatchSnapshot();
133
+ });
134
+ });
@@ -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 { BackgroundColor } from '../BackgroundColor';
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, BackgroundColor)
23
+ content: ContentNormalizer.normalize(content),
24
+ extensions: buildCoreExtensions().concat(MockStylePreset, BackgroundColor)
24
25
  });
25
26
  }
26
27
 
@@ -73,3 +74,37 @@ describe('rendering', () => {
73
74
  expect(editor.getHTML()).toMatchSnapshot();
74
75
  });
75
76
  });
77
+
78
+ describe('parsing html', () => {
79
+ test('should get value from paragraph', () => {
80
+ const editor = createEditor({
81
+ content: '<p style="background-color: red">test</p>'
82
+ });
83
+
84
+ expect(editor.getJSON()).toMatchSnapshot();
85
+ });
86
+
87
+ test('should get value from text', () => {
88
+ const editor = createEditor({
89
+ content: '<p><span style="background-color: red">lorem</span> ipsum</p>'
90
+ });
91
+
92
+ expect(editor.getJSON()).toMatchSnapshot();
93
+ });
94
+
95
+ test('should get value from rendered view', () => {
96
+ const editor = createEditor({
97
+ content: '<p><span style="--zw-background-color: red">lorem</span> ipsum</p>'
98
+ });
99
+
100
+ expect(editor.getJSON()).toMatchSnapshot();
101
+ });
102
+
103
+ test('should merge paragraph and text settings', () => {
104
+ const editor = createEditor({
105
+ content: '<p style="background-color: red"><span style="background-color: #000">lorem</span> ipsum</p>'
106
+ });
107
+
108
+ expect(editor.getJSON()).toMatchSnapshot();
109
+ });
110
+ });
@@ -1,13 +1,14 @@
1
1
  import { Editor } from '@tiptap/vue-2';
2
2
  import { NodeFactory } from '../../__tests__/utils';
3
3
  import { CaseStyles } from '../../enums';
4
- import { CORE_EXTENSIONS } from '../core';
5
4
  import { CaseStyle } from '../CaseStyle';
5
+ import { ContentNormalizer } from '../../services';
6
+ import { buildCoreExtensions } from '../core';
6
7
 
7
8
  function createEditor({ content }) {
8
9
  return new Editor({
9
- content,
10
- extensions: CORE_EXTENSIONS.concat(CaseStyle)
10
+ content: ContentNormalizer.normalize(content),
11
+ extensions: buildCoreExtensions().concat(CaseStyle)
11
12
  });
12
13
  }
13
14
 
@@ -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 { FontColor } from '../FontColor';
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, FontColor)
23
+ content: ContentNormalizer.normalize(content),
24
+ extensions: buildCoreExtensions().concat(MockStylePreset, FontColor)
24
25
  });
25
26
  }
26
27
 
@@ -83,3 +84,37 @@ describe('rendering', () => {
83
84
  expect(editor.getHTML()).toMatchSnapshot();
84
85
  });
85
86
  });
87
+
88
+ describe('parsing html', () => {
89
+ test('should get value from paragraph', () => {
90
+ const editor = createEditor({
91
+ content: '<p style="color: red">test</p>'
92
+ });
93
+
94
+ expect(editor.getJSON()).toMatchSnapshot();
95
+ });
96
+
97
+ test('should get value from text', () => {
98
+ const editor = createEditor({
99
+ content: '<p><span style="color: red">lorem</span> ipsum</p>'
100
+ });
101
+
102
+ expect(editor.getJSON()).toMatchSnapshot();
103
+ });
104
+
105
+ test('should get value from parsed view', () => {
106
+ const editor = createEditor({
107
+ content: '<p><span style="--zw-color: red">lorem</span> ipsum</p>'
108
+ });
109
+
110
+ expect(editor.getJSON()).toMatchSnapshot();
111
+ });
112
+
113
+ test('should merge paragraph and text settings', () => {
114
+ const editor = createEditor({
115
+ content: '<p style="color: red"><span style="color: #000">lorem</span> ipsum</p>'
116
+ });
117
+
118
+ expect(editor.getJSON()).toMatchSnapshot();
119
+ });
120
+ });
@@ -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 { FontFamily } from '../FontFamily';
8
7
  import { FontWeight } from '../FontWeight';
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,14 +26,17 @@ 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: [
33
34
  new Font({ name: 'Lato', styles: ['400', '700', '700i'] }),
34
- new Font({ name: 'Bungee', styles: ['400'] })
35
- ]
35
+ new Font({ name: 'Bungee', styles: ['400'] }),
36
+ new Font({ name: 'Roboto', styles: ['400'] }),
37
+ new Font({ name: 'Josefin Slab', styles: ['400'] })
38
+ ],
39
+ defaultFont: 'Lato'
36
40
  }),
37
41
  FontWeight,
38
42
  FontStyle
@@ -169,3 +173,53 @@ describe('rendering', () => {
169
173
  expect(editor.getHTML()).toMatchSnapshot();
170
174
  });
171
175
  });
176
+
177
+ describe('parsing html', () => {
178
+ test('should get value from paragraph', () => {
179
+ const editor = createEditor({
180
+ content: '<p style="font-family: Lato">test</p>'
181
+ });
182
+
183
+ expect(editor.getJSON()).toMatchSnapshot();
184
+ });
185
+
186
+ test('should get value from text', () => {
187
+ const editor = createEditor({
188
+ content: '<p><span style="font-family: Lato">lorem</span> ipsum</p>'
189
+ });
190
+
191
+ expect(editor.getJSON()).toMatchSnapshot();
192
+ });
193
+
194
+ test('should get value from rendered view', () => {
195
+ const editor = createEditor({
196
+ content: '<p><span style="--zw-font-family: Lato">lorem</span> ipsum</p>'
197
+ });
198
+
199
+ expect(editor.getJSON()).toMatchSnapshot();
200
+ });
201
+
202
+ test('should get set default if undefined font', () => {
203
+ const editor = createEditor({
204
+ content: '<p><span style="--zw-font-family: Arial">lorem</span> ipsum</p>'
205
+ });
206
+
207
+ expect(editor.getJSON()).toMatchSnapshot();
208
+ });
209
+
210
+ test('should merge paragraph and text settings', () => {
211
+ const editor = createEditor({
212
+ content: '<p style="font-family: Lato"><span style="font-family: Roboto">lorem</span> ipsum</p>'
213
+ });
214
+
215
+ expect(editor.getJSON()).toMatchSnapshot();
216
+ });
217
+
218
+ test('should get parse font name with quotes', () => {
219
+ const editor = createEditor({
220
+ content: '<p>hello <span style="font-family: &quot;Josefin Slab&quot;;">world</span></p>'
221
+ });
222
+
223
+ expect(editor.getJSON()).toMatchSnapshot();
224
+ });
225
+ });
@@ -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 { FontSize } from '../FontSize';
7
6
  import { DeviceManager } from '../DeviceManager';
7
+ import { ContentNormalizer } from '../../services';
8
+ import { buildCoreExtensions } from '../core';
8
9
 
9
10
  const MockStylePreset = Extension.create({
10
11
  name: 'style_preset',
@@ -22,11 +23,11 @@ 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
29
  DeviceManager.configure({
29
- deviceRef: ref('desktop')
30
+ device: ref('desktop')
30
31
  }),
31
32
  FontSize.configure({
32
33
  minSize: 5,
@@ -181,3 +182,37 @@ describe('rendering', () => {
181
182
  expect(editor.getHTML()).toMatchSnapshot();
182
183
  });
183
184
  });
185
+
186
+ describe('parsing html', () => {
187
+ test('should get value from paragraph', () => {
188
+ const editor = createEditor({
189
+ content: '<p style="font-size: 24px">test</p>'
190
+ });
191
+
192
+ expect(editor.getJSON()).toMatchSnapshot();
193
+ });
194
+
195
+ test('should get value from text', () => {
196
+ const editor = createEditor({
197
+ content: '<p><span style="font-size: 24px">lorem</span> ipsum</p>'
198
+ });
199
+
200
+ expect(editor.getJSON()).toMatchSnapshot();
201
+ });
202
+
203
+ test('should get value from rendered view', () => {
204
+ const editor = createEditor({
205
+ content: '<p><span style="--zw-font-size-mobile: 24px; --zw-font-size-desktop:30px">lorem</span> ipsum</p>'
206
+ });
207
+
208
+ expect(editor.getJSON()).toMatchSnapshot();
209
+ });
210
+
211
+ test('should merge paragraph and text settings', () => {
212
+ const editor = createEditor({
213
+ content: '<p style="font-size: 24px"><span style="font-size: 20px">lorem</span> ipsum</p>'
214
+ });
215
+
216
+ expect(editor.getJSON()).toMatchSnapshot();
217
+ });
218
+ });
@@ -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 { FontStyle } from '../FontStyle';
7
6
  import { FontFamily } from '../FontFamily';
8
7
  import { Font } from '../../models';
9
8
  import { FontWeight } from '../FontWeight';
9
+ import { ContentNormalizer } from '../../services';
10
+ import { buildCoreExtensions } from '../core';
10
11
 
11
12
  const MockStylePreset = Extension.create({
12
13
  name: 'style_preset',
@@ -26,8 +27,8 @@ const MockStylePreset = Extension.create({
26
27
 
27
28
  function createEditor({ content }) {
28
29
  return new Editor({
29
- content,
30
- extensions: CORE_EXTENSIONS.concat(
30
+ content: ContentNormalizer.normalize(content),
31
+ extensions: buildCoreExtensions().concat(
31
32
  MockStylePreset,
32
33
  FontStyle,
33
34
  FontWeight,
@@ -134,3 +135,45 @@ describe('rendering', () => {
134
135
  expect(editor.getHTML()).toMatchSnapshot();
135
136
  });
136
137
  });
138
+
139
+ describe('parsing html', () => {
140
+ test('should get value from paragraph', () => {
141
+ const editor = createEditor({
142
+ content: '<p style="font-style: italic">test</p>'
143
+ });
144
+
145
+ expect(editor.getJSON()).toMatchSnapshot();
146
+ });
147
+
148
+ test('should get value from text', () => {
149
+ const editor = createEditor({
150
+ content: '<p><span style="font-style: italic">lorem</span> ipsum</p>'
151
+ });
152
+
153
+ expect(editor.getJSON()).toMatchSnapshot();
154
+ });
155
+
156
+ test('should get value from rendered view', () => {
157
+ const editor = createEditor({
158
+ content: '<p><span style="--zw-font-style: italic">lorem</span> ipsum</p>'
159
+ });
160
+
161
+ expect(editor.getJSON()).toMatchSnapshot();
162
+ });
163
+
164
+ test('should get value from i tag', () => {
165
+ const editor = createEditor({
166
+ content: '<p><i>lorem</i> ipsum</p>'
167
+ });
168
+
169
+ expect(editor.getJSON()).toMatchSnapshot();
170
+ });
171
+
172
+ test('should merge paragraph and text settings', () => {
173
+ const editor = createEditor({
174
+ content: '<p style="font-style: italic"><span style="font-style: normal">lorem</span> ipsum</p>'
175
+ });
176
+
177
+ expect(editor.getJSON()).toMatchSnapshot();
178
+ });
179
+ });