@zipify/wysiwyg 1.0.0-dev.9 → 1.0.0-dev.90

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 (232) hide show
  1. package/.editorconfig +1 -1
  2. package/.eslintrc.js +2 -2
  3. package/.github/dependabot.yaml +1 -0
  4. package/.lintstagedrc +2 -2
  5. package/.release-it.json +3 -1
  6. package/.stylelintrc +0 -4
  7. package/README.md +2 -2
  8. package/config/jest/setupTests.js +0 -3
  9. package/config/vite/example.config.js +25 -0
  10. package/config/vite/lib.config.js +30 -0
  11. package/config/{webpack → vite}/settings.js +0 -0
  12. package/dist/wysiwyg.css +404 -373
  13. package/dist/wysiwyg.mjs +26014 -0
  14. package/example/ExampleApp.vue +35 -4
  15. package/example/example.js +0 -3
  16. package/example/{example.html → index.html} +1 -0
  17. package/example/pageBlocks.js +31 -0
  18. package/example/presets.js +2 -2
  19. package/example/tooltip/Tooltip.js +1 -1
  20. package/jest.config.js +3 -1
  21. package/lib/Wysiwyg.vue +73 -14
  22. package/lib/__tests__/utils/index.js +0 -1
  23. package/lib/__tests__/utils/withComponentContext.js +1 -1
  24. package/lib/assets/icons/background-color.svg +3 -1
  25. package/lib/assets/icons/font-color.svg +1 -3
  26. package/lib/assets/icons/link.svg +3 -0
  27. package/lib/assets/icons/unlink.svg +3 -0
  28. package/lib/components/base/Button.vue +23 -2
  29. package/lib/components/base/Checkbox.vue +89 -0
  30. package/lib/components/base/FieldLabel.vue +2 -1
  31. package/lib/components/base/Icon.vue +3 -3
  32. package/lib/components/base/Modal.vue +1 -2
  33. package/lib/components/base/NumberField.vue +2 -2
  34. package/lib/components/base/Range.vue +1 -1
  35. package/lib/components/base/ScrollView.vue +1 -3
  36. package/lib/components/base/TextField.vue +108 -0
  37. package/lib/components/base/__tests__/Modal.test.js +7 -2
  38. package/lib/components/base/__tests__/TextField.test.js +57 -0
  39. package/lib/components/base/__tests__/__snapshots__/TextField.test.js.snap +9 -0
  40. package/lib/components/base/colorPicker/ColorPicker.vue +14 -12
  41. package/lib/components/base/colorPicker/composables/__tests__/usePickerApi.test.js +6 -6
  42. package/lib/components/base/colorPicker/composables/usePickerApi.js +15 -8
  43. package/lib/components/base/colorPicker/composables/usePickerHotkeys.js +3 -2
  44. package/lib/components/base/composables/__tests__/useActivatedListener.test.js +1 -1
  45. package/lib/components/base/composables/__tests__/useDeselectionLock.test.js +1 -1
  46. package/lib/components/base/composables/__tests__/useElementRef.test.js +1 -1
  47. package/lib/components/base/composables/__tests__/useModalToggler.test.js +1 -1
  48. package/lib/components/base/composables/__tests__/useNumberValue.test.js +1 -1
  49. package/lib/components/base/composables/__tests__/useScrollView.test.js +1 -1
  50. package/lib/components/base/composables/__tests__/useTempValue.test.js +1 -1
  51. package/lib/components/base/composables/__tests__/useValidator.test.js +44 -0
  52. package/lib/components/base/composables/index.js +1 -0
  53. package/lib/components/base/composables/useActivatedListener.js +1 -1
  54. package/lib/components/base/composables/useDeselectionLock.js +1 -1
  55. package/lib/components/base/composables/useElementRef.js +1 -1
  56. package/lib/components/base/composables/useModalToggler.js +6 -2
  57. package/lib/components/base/composables/useScrollView.js +1 -1
  58. package/lib/components/base/composables/useTempValue.js +1 -1
  59. package/lib/components/base/composables/useValidator.js +23 -0
  60. package/lib/components/base/dropdown/Dropdown.vue +16 -4
  61. package/lib/components/base/dropdown/DropdownActivator.vue +19 -3
  62. package/lib/components/base/dropdown/DropdownGroup.vue +1 -1
  63. package/lib/components/base/dropdown/DropdownMenu.vue +1 -1
  64. package/lib/components/base/dropdown/DropdownOption.vue +1 -1
  65. package/lib/components/base/dropdown/__tests__/DropdownActivator.test.js +1 -1
  66. package/lib/components/base/dropdown/__tests__/DropdownMenu.test.js +1 -1
  67. package/lib/components/base/dropdown/__tests__/DropdownOption.test.js +1 -1
  68. package/lib/components/base/dropdown/composables/__tests__/useActiveOptionManager.test.js +1 -1
  69. package/lib/components/base/dropdown/composables/__tests__/useDropdownEntityTitle.test.js +1 -1
  70. package/lib/components/base/dropdown/composables/useActiveOptionManager.js +1 -1
  71. package/lib/components/base/dropdown/composables/useDropdownEntityTitle.js +1 -1
  72. package/lib/components/base/index.js +3 -1
  73. package/lib/components/toolbar/Toolbar.vue +51 -9
  74. package/lib/components/toolbar/ToolbarDivider.vue +1 -1
  75. package/lib/components/toolbar/ToolbarFull.vue +41 -10
  76. package/lib/components/toolbar/ToolbarRow.vue +1 -0
  77. package/lib/components/toolbar/__tests__/Toolbar.test.js +6 -0
  78. package/lib/components/toolbar/controls/AlignmentControl.vue +1 -1
  79. package/lib/components/toolbar/controls/AlignmentDeviceControl.vue +1 -1
  80. package/lib/components/toolbar/controls/BackgroundColorControl.vue +1 -1
  81. package/lib/components/toolbar/controls/CaseStyleControl.vue +1 -1
  82. package/lib/components/toolbar/controls/FontColorControl.vue +1 -1
  83. package/lib/components/toolbar/controls/FontFamilyControl.vue +1 -1
  84. package/lib/components/toolbar/controls/FontSizeControl.vue +8 -1
  85. package/lib/components/toolbar/controls/FontWeightControl.vue +1 -1
  86. package/lib/components/toolbar/controls/ItalicControl.vue +1 -1
  87. package/lib/components/toolbar/controls/LineHeightControl.vue +1 -1
  88. package/lib/components/toolbar/controls/ListControl.vue +68 -34
  89. package/lib/components/toolbar/controls/RemoveFormatControl.vue +1 -1
  90. package/lib/components/toolbar/controls/StrikeThroughControl.vue +1 -1
  91. package/lib/components/toolbar/controls/StylePresetControl.vue +15 -2
  92. package/lib/components/toolbar/controls/SuperscriptControl.vue +1 -1
  93. package/lib/components/toolbar/controls/UnderlineControl.vue +2 -2
  94. package/lib/components/toolbar/controls/__tests__/AlignmentControl.test.js +1 -1
  95. package/lib/components/toolbar/controls/__tests__/AlignmentDeviceControl.test.js +1 -1
  96. package/lib/components/toolbar/controls/__tests__/BackgroundColorControl.test.js +1 -1
  97. package/lib/components/toolbar/controls/__tests__/CaseStyleControl.test.js +1 -1
  98. package/lib/components/toolbar/controls/__tests__/FontColorControl.test.js +1 -1
  99. package/lib/components/toolbar/controls/__tests__/FontFamilyControl.test.js +1 -1
  100. package/lib/components/toolbar/controls/__tests__/FontSizeControl.test.js +1 -1
  101. package/lib/components/toolbar/controls/__tests__/FontWeightControl.test.js +1 -1
  102. package/lib/components/toolbar/controls/__tests__/ItalicControl.test.js +1 -1
  103. package/lib/components/toolbar/controls/__tests__/LineHeightControl.test.js +1 -1
  104. package/lib/components/toolbar/controls/__tests__/ListControl.test.js +18 -3
  105. package/lib/components/toolbar/controls/__tests__/StrikeThroughControl.test.js +1 -1
  106. package/lib/components/toolbar/controls/__tests__/StylePresetControl.test.js +17 -1
  107. package/lib/components/toolbar/controls/__tests__/UnderlineControl.test.js +5 -1
  108. package/lib/components/toolbar/controls/composables/useRecentFonts.js +1 -1
  109. package/lib/components/toolbar/controls/index.js +1 -0
  110. package/lib/components/toolbar/controls/link/LinkControl.vue +160 -0
  111. package/lib/components/toolbar/controls/link/LinkControlApply.vue +35 -0
  112. package/lib/components/toolbar/controls/link/LinkControlHeader.vue +69 -0
  113. package/lib/components/toolbar/controls/link/__tests__/LinkControl.test.js +79 -0
  114. package/lib/components/toolbar/controls/link/__tests__/LinkControlHeader.test.js +42 -0
  115. package/lib/components/toolbar/controls/link/composables/__tests__/__snapshots__/useLink.test.js.snap +15 -0
  116. package/lib/components/toolbar/controls/link/composables/__tests__/useLink.test.js +172 -0
  117. package/lib/components/toolbar/controls/link/composables/index.js +1 -0
  118. package/lib/components/toolbar/controls/link/composables/useLink.js +82 -0
  119. package/lib/components/toolbar/controls/link/destination/LinkControlDestination.vue +103 -0
  120. package/lib/components/toolbar/controls/link/destination/LinkControlPageBlock.vue +54 -0
  121. package/lib/components/toolbar/controls/link/destination/LinkControlUrl.vue +52 -0
  122. package/lib/components/toolbar/controls/link/destination/__tests__/LinkControlPageBlock.test.js +36 -0
  123. package/lib/components/toolbar/controls/link/destination/__tests__/LinkControlUrl.test.js +46 -0
  124. package/lib/components/toolbar/controls/link/destination/__tests__/__snapshots__/LinkControlPageBlock.test.js.snap +9 -0
  125. package/lib/components/toolbar/controls/link/destination/__tests__/__snapshots__/LinkControlUrl.test.js.snap +17 -0
  126. package/lib/components/toolbar/controls/link/destination/index.js +1 -0
  127. package/lib/components/toolbar/controls/link/index.js +1 -0
  128. package/lib/composables/__tests__/__snapshots__/useEditor.test.js.snap +1 -0
  129. package/lib/composables/__tests__/useEditor.test.js +5 -4
  130. package/lib/composables/useEditor.js +12 -9
  131. package/lib/composables/useToolbar.js +26 -19
  132. package/lib/directives/__tests__/outClick.test.js +6 -0
  133. package/lib/directives/outClick.js +19 -6
  134. package/lib/enums/Alignments.js +10 -1
  135. package/lib/enums/LinkDestinations.js +4 -0
  136. package/lib/enums/LinkTargets.js +4 -0
  137. package/lib/enums/TextSettings.js +3 -1
  138. package/lib/enums/index.js +2 -0
  139. package/lib/extensions/Alignment.js +22 -8
  140. package/lib/extensions/BackgroundColor.js +15 -7
  141. package/lib/extensions/DeviceManager.js +2 -5
  142. package/lib/extensions/FontColor.js +15 -7
  143. package/lib/extensions/FontFamily.js +26 -9
  144. package/lib/extensions/FontSize.js +33 -13
  145. package/lib/extensions/FontStyle.js +24 -14
  146. package/lib/extensions/FontWeight.js +25 -15
  147. package/lib/extensions/LineHeight.js +33 -29
  148. package/lib/extensions/Link.js +90 -0
  149. package/lib/extensions/StylePreset.js +20 -19
  150. package/lib/extensions/Superscript.js +5 -1
  151. package/lib/extensions/TextDecoration.js +46 -13
  152. package/lib/extensions/__tests__/Alignment.test.js +14 -9
  153. package/lib/extensions/__tests__/BackgroundColor.test.js +13 -8
  154. package/lib/extensions/__tests__/CaseStyle.test.js +4 -7
  155. package/lib/extensions/__tests__/FontColor.test.js +13 -8
  156. package/lib/extensions/__tests__/FontFamily.test.js +34 -10
  157. package/lib/extensions/__tests__/FontSize.test.js +16 -10
  158. package/lib/extensions/__tests__/FontStyle.test.js +13 -8
  159. package/lib/extensions/__tests__/FontWeight.test.js +21 -8
  160. package/lib/extensions/__tests__/LineHeight.test.js +25 -14
  161. package/lib/extensions/__tests__/Link.test.js +101 -0
  162. package/lib/extensions/__tests__/StylePreset.test.js +72 -10
  163. package/lib/extensions/__tests__/TextDecoration.test.js +53 -8
  164. package/lib/extensions/__tests__/__snapshots__/Alignment.test.js.snap +26 -2
  165. package/lib/extensions/__tests__/__snapshots__/BackgroundColor.test.js.snap +30 -1
  166. package/lib/extensions/__tests__/__snapshots__/FontColor.test.js.snap +18 -1
  167. package/lib/extensions/__tests__/__snapshots__/FontFamily.test.js.snap +88 -1
  168. package/lib/extensions/__tests__/__snapshots__/FontSize.test.js.snap +33 -2
  169. package/lib/extensions/__tests__/__snapshots__/FontStyle.test.js.snap +25 -4
  170. package/lib/extensions/__tests__/__snapshots__/FontWeight.test.js.snap +47 -1
  171. package/lib/extensions/__tests__/__snapshots__/LineHeight.test.js.snap +26 -2
  172. package/lib/extensions/__tests__/__snapshots__/Link.test.js.snap +225 -0
  173. package/lib/extensions/__tests__/__snapshots__/StylePreset.test.js.snap +6 -2
  174. package/lib/extensions/__tests__/__snapshots__/TextDecoration.test.js.snap +183 -3
  175. package/lib/extensions/core/CopyPasteProcessor.js +10 -0
  176. package/lib/extensions/core/NodeProcessor.js +1 -1
  177. package/lib/extensions/core/TextProcessor.js +11 -24
  178. package/lib/extensions/core/__tests__/NodeProcessor.test.js +4 -7
  179. package/lib/extensions/core/__tests__/SelectionProcessor.test.js +4 -7
  180. package/lib/extensions/core/__tests__/TextProcessor.test.js +139 -14
  181. package/lib/extensions/core/__tests__/__snapshots__/TextProcessor.test.js.snap +26 -0
  182. package/lib/extensions/core/index.js +11 -2
  183. package/lib/extensions/core/plugins/PastePlugin.js +57 -0
  184. package/lib/extensions/core/plugins/ProseMirrorPlugin.js +20 -0
  185. package/lib/extensions/core/plugins/index.js +1 -0
  186. package/lib/extensions/index.js +46 -34
  187. package/lib/extensions/list/List.js +5 -4
  188. package/lib/extensions/list/__tests__/List.test.js +6 -10
  189. package/lib/extensions/list/__tests__/__snapshots__/List.test.js.snap +60 -20
  190. package/lib/index.js +3 -0
  191. package/lib/injectionTokens.js +3 -1
  192. package/lib/services/ContentNormalizer.js +144 -28
  193. package/lib/services/ContextWidnow.js +23 -0
  194. package/lib/{__tests__/utils → services}/NodeFactory.js +5 -1
  195. package/lib/services/__tests__/ContentNormalizer.test.js +124 -8
  196. package/lib/services/__tests__/FavoriteColors.test.js +1 -1
  197. package/lib/services/index.js +2 -0
  198. package/lib/styles/content.css +108 -13
  199. package/lib/styles/helpers/offsets.css +16 -0
  200. package/lib/styles/variables.css +6 -0
  201. package/lib/utils/__tests__/__snapshots__/renderInlineSetting.test.js.snap +4 -4
  202. package/lib/utils/__tests__/convertAlignment.test.js +16 -0
  203. package/lib/utils/__tests__/convertFontSize.test.js +21 -0
  204. package/lib/utils/__tests__/convertLineHeight.test.js +21 -0
  205. package/lib/utils/convertAlignment.js +12 -0
  206. package/lib/utils/convertColor.js +1 -1
  207. package/lib/utils/convertFontSize.js +8 -0
  208. package/lib/utils/convertLineHeight.js +17 -0
  209. package/lib/utils/importIcon.js +7 -6
  210. package/lib/utils/index.js +4 -0
  211. package/lib/utils/isWysiwygContent.js +12 -0
  212. package/lib/utils/renderInlineSetting.js +1 -1
  213. package/package.json +26 -30
  214. package/config/webpack/example.config.js +0 -88
  215. package/config/webpack/lib.config.js +0 -44
  216. package/config/webpack/loaders/index.js +0 -6
  217. package/config/webpack/loaders/js-loader.js +0 -5
  218. package/config/webpack/loaders/style-loader.js +0 -9
  219. package/config/webpack/loaders/svg-loader.js +0 -4
  220. package/config/webpack/loaders/vue-loader.js +0 -4
  221. package/dist/wysiwyg.js +0 -2
  222. package/dist/wysiwyg.js.LICENSE.txt +0 -1
  223. package/lib/extensions/core/inputRules/closeDoubleQuote.js +0 -6
  224. package/lib/extensions/core/inputRules/closeSingleQuote.js +0 -6
  225. package/lib/extensions/core/inputRules/copyright.js +0 -6
  226. package/lib/extensions/core/inputRules/ellipsis.js +0 -6
  227. package/lib/extensions/core/inputRules/emDash.js +0 -6
  228. package/lib/extensions/core/inputRules/index.js +0 -9
  229. package/lib/extensions/core/inputRules/openDoubleQuote.js +0 -6
  230. package/lib/extensions/core/inputRules/openSingleQuote.js +0 -6
  231. package/lib/extensions/core/inputRules/registeredTrademark.js +0 -6
  232. package/lib/extensions/core/inputRules/trademark.js +0 -6
@@ -0,0 +1,90 @@
1
+ import Base from '@tiptap/extension-link';
2
+ import { createCommand } from '../utils';
3
+ import { LinkDestinations, LinkTargets } from '../enums';
4
+
5
+ export const Link = Base.extend({
6
+ name: 'link',
7
+
8
+ addOptions() {
9
+ return {
10
+ ...this.parent?.(),
11
+ openOnClick: false
12
+ };
13
+ },
14
+
15
+ addAttributes() {
16
+ return {
17
+ href: {
18
+ default: null,
19
+ parseHTML: (element) => {
20
+ const href = element.getAttribute('href');
21
+
22
+ if (!href.startsWith('#')) return href;
23
+
24
+ return parseFloat(element.getAttribute('href').replace('#', ''));
25
+ }
26
+ },
27
+
28
+ target: {
29
+ default: LinkTargets.SELF,
30
+ parseHTML: (element) => element.getAttribute('target') || LinkTargets.SELF
31
+ },
32
+
33
+ destination: {
34
+ default: LinkDestinations.URL,
35
+ parseHTML: (element) => {
36
+ const href = element.getAttribute('href');
37
+
38
+ if (!href.startsWith('#')) return LinkDestinations.URL;
39
+
40
+ const id = href.replace('#', '');
41
+ const blocks = this.options.pageBlocks.value || this.options.pageBlocks;
42
+ const block = blocks.find((block) => block.id === parseInt(id));
43
+
44
+ return block ? LinkDestinations.BLOCK : LinkDestinations.URL;
45
+ }
46
+ }
47
+ };
48
+ },
49
+
50
+ addCommands() {
51
+ return {
52
+ ...this.parent?.(),
53
+ applyLink: createCommand(({ commands, chain }, attributes) => {
54
+ if (!commands.getSelectedText()) {
55
+ return commands.insertContent({
56
+ type: 'text',
57
+ marks: [
58
+ {
59
+ type: 'link',
60
+ attrs: { ...attributes }
61
+ }
62
+ ],
63
+ text: attributes.text
64
+ });
65
+ }
66
+
67
+ return chain()
68
+ .setMark(this.name, attributes)
69
+ .transformText(() => attributes.text)
70
+ .extendMarkRange('link')
71
+ .run();
72
+ })
73
+ };
74
+ },
75
+
76
+ renderHTML({ HTMLAttributes: attrs }) {
77
+ const href = attrs.destination === LinkDestinations.BLOCK ? `#${attrs.href}` : attrs.href;
78
+
79
+ const presetClass = this.options.basePresetClass + this.options.preset.id;
80
+ const classes = `${presetClass} zw-style`;
81
+
82
+ const linkAttrs = {
83
+ href,
84
+ target: attrs.target,
85
+ class: classes
86
+ };
87
+
88
+ return ['a', linkAttrs, 0];
89
+ }
90
+ });
@@ -1,8 +1,9 @@
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';
6
7
 
7
8
  function makePresetClass(base, preset) {
8
9
  const baseClass = base.split(' ').map((part) => `.${part}`).join('');
@@ -20,13 +21,6 @@ export const StylePreset = Extension.create({
20
21
  })
21
22
  ],
22
23
 
23
- addOptions: () => ({
24
- presetsRef: null,
25
- defaultId: null,
26
- baseClass: null,
27
- makeVariable: null
28
- }),
29
-
30
24
  addStorage: () => ({
31
25
  presetStyleEl: null
32
26
  }),
@@ -38,10 +32,12 @@ export const StylePreset = Extension.create({
38
32
  attributes: {
39
33
  preset: {
40
34
  isRequired: false,
41
- default: null,
35
+ default: { id: this.options.defaultId },
42
36
 
43
37
  parseHTML: (element) => {
44
- const presets = this.options.presetsRef.value;
38
+ const presets = this.options.presets.value || this.options.presets;
39
+
40
+ if (element.parentElement.tagName === 'LI') return null;
45
41
 
46
42
  for (const { id, node, fallbackClass } of presets) {
47
43
  const isFallback = fallbackClass && element.classList.contains(fallbackClass);
@@ -76,7 +72,7 @@ export const StylePreset = Extension.create({
76
72
 
77
73
  return {
78
74
  getPresetList: createCommand(() => computed(() => {
79
- return this.options.presetsRef.value.filter((preset) => !preset.hidden);
75
+ return this.options.presets.filter((preset) => !preset.hidden);
80
76
  })),
81
77
 
82
78
  getPreset: createCommand(({ commands }) => {
@@ -147,32 +143,37 @@ export const StylePreset = Extension.create({
147
143
  chain()
148
144
  .storeSelection()
149
145
  .expandSelectionToBlock()
150
- .unsetAllMarks()
146
+ .unsetMarks(TextSettings.marks)
151
147
  .resetAttributes(NodeTypes.PARAGRAPH, TextSettings.attributes)
152
148
  .resetAttributes(NodeTypes.HEADING, TextSettings.attributes)
153
149
  .restoreSelection()
154
150
  .run();
155
151
  }),
156
152
 
157
- removeFormat: createCommand(({ commands }) => {
158
- commands.removePresetCustomization();
159
- commands.applyDefaultPreset();
153
+ removeFormat: createCommand(({ chain }) => {
154
+ chain()
155
+ .storeSelection()
156
+ .expandSelectionToBlock()
157
+ .unsetAllMarks()
158
+ .applyDefaultPreset()
159
+ .restoreSelection()
160
+ .run();
160
161
  })
161
162
  };
162
163
  },
163
164
 
164
165
  onCreate() {
165
- const existingStyleEl = document.querySelector('[data-zw-styles]');
166
+ const existingStyleEl = ContextWindow.document.querySelector('[data-zw-styles]');
166
167
 
167
168
  if (existingStyleEl) {
168
169
  this.storage.presetStyleEl = existingStyleEl;
169
170
  return;
170
171
  }
171
172
 
172
- this.storage.presetStyleEl = document.createElement('style');
173
+ this.storage.presetStyleEl = ContextWindow.document.createElement('style');
173
174
  this.storage.presetStyleEl.dataset.zwStyles = '';
174
175
 
175
- for (const preset of this.options.presetsRef.value) {
176
+ for (const preset of this.options.presets) {
176
177
  const className = makePresetClass(this.options.baseClass, preset);
177
178
  const css = [` ${className} {`];
178
179
 
@@ -190,6 +191,6 @@ export const StylePreset = Extension.create({
190
191
  this.storage.presetStyleEl.innerHTML += css.join(' ');
191
192
  }
192
193
 
193
- document.head.append(this.storage.presetStyleEl);
194
+ ContextWindow.head.append(this.storage.presetStyleEl);
194
195
  }
195
196
  });
@@ -1,5 +1,9 @@
1
1
  import Base from '@tiptap/extension-superscript';
2
2
 
3
3
  export const Superscript = Base.extend({
4
- addKeyboardShortcuts: null
4
+ addKeyboardShortcuts: null,
5
+
6
+ addOptions: () => ({
7
+ HTMLAttributes: { class: 'zw-superscript' }
8
+ })
5
9
  });
@@ -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,16 +88,47 @@ export const TextDecoration = Mark.create({
86
88
  'Mod-U': createKeyboardShortcut('toggleUnderline')
87
89
  }),
88
90
 
89
- parseHTML: () => [
90
- {
91
- style: 'text-decoration-line',
91
+ parseHTML() {
92
+ const getAttrs = (value) => {
93
+ const underline = value.includes('underline');
94
+ const strike_through = value.includes('line-through');
92
95
 
93
- getAttrs: (value) => ({
94
- underline: value.includes('underline'),
95
- strike_through: value.includes('line-through')
96
- })
97
- }
98
- ],
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
+ style: 'text-decoration',
114
+ getAttrs
115
+ },
116
+ {
117
+ tag: 's',
118
+ attrs: {
119
+ underline: false,
120
+ strike_through: true
121
+ }
122
+ },
123
+ {
124
+ tag: 'u',
125
+ attrs: {
126
+ underline: true,
127
+ strike_through: false
128
+ }
129
+ }
130
+ ];
131
+ },
99
132
 
100
133
  renderHTML({ HTMLAttributes: attrs }) {
101
134
  const decorations = [];
@@ -1,12 +1,11 @@
1
1
  import { Editor, Extension } from '@tiptap/vue-2';
2
- import { ref } from '@vue/composition-api';
3
- import { NodeFactory } from '../../__tests__/utils';
2
+ import { ref } from 'vue';
4
3
  import { createCommand } from '../../utils';
5
- import { CORE_EXTENSIONS } from '../core';
6
4
  import { Alignment } from '../Alignment';
7
5
  import { DeviceManager } from '../DeviceManager';
8
6
  import { Alignments } from '../../enums';
9
- import { ContentNormalizer } from '../../services';
7
+ import { ContentNormalizer, NodeFactory } from '../../services';
8
+ import { buildCoreExtensions } from '../core';
10
9
 
11
10
  const MockStylePreset = Extension.create({
12
11
  name: 'style_preset',
@@ -23,13 +22,11 @@ const MockStylePreset = Extension.create({
23
22
  });
24
23
 
25
24
  function createEditor({ content }) {
26
- const normalizer = new ContentNormalizer();
27
-
28
25
  return new Editor({
29
- content: normalizer.normalize(content),
30
- extensions: CORE_EXTENSIONS.concat(
26
+ content: ContentNormalizer.normalize(content),
27
+ extensions: buildCoreExtensions().concat(
31
28
  MockStylePreset,
32
- DeviceManager.configure({ deviceRef: ref('desktop') }),
29
+ DeviceManager.configure({ device: ref('desktop') }),
33
30
  Alignment
34
31
  )
35
32
  });
@@ -118,6 +115,14 @@ describe('parsing html', () => {
118
115
  expect(editor.getJSON()).toMatchSnapshot();
119
116
  });
120
117
 
118
+ test('should get alignment from rendered view', () => {
119
+ const editor = createEditor({
120
+ content: '<p style="--zw-text-align-mobile:center;--zw-text-align-desktop:right">test</p>'
121
+ });
122
+
123
+ expect(editor.getJSON()).toMatchSnapshot();
124
+ });
125
+
121
126
  test('should set null if no alignment', () => {
122
127
  const editor = createEditor({
123
128
  content: '<p>test</p>'
@@ -1,10 +1,9 @@
1
1
  import { Editor, Extension } from '@tiptap/vue-2';
2
- import { ref } from '@vue/composition-api';
3
- import { NodeFactory } from '../../__tests__/utils';
2
+ import { ref } from 'vue';
4
3
  import { createCommand } from '../../utils';
5
- import { CORE_EXTENSIONS } from '../core';
6
4
  import { BackgroundColor } from '../BackgroundColor';
7
- import { ContentNormalizer } from '../../services';
5
+ import { ContentNormalizer, NodeFactory } from '../../services';
6
+ import { buildCoreExtensions } from '../core';
8
7
 
9
8
  const MockStylePreset = Extension.create({
10
9
  name: 'style_preset',
@@ -19,11 +18,9 @@ const MockStylePreset = Extension.create({
19
18
  });
20
19
 
21
20
  function createEditor({ content }) {
22
- const normalizer = new ContentNormalizer();
23
-
24
21
  return new Editor({
25
- content: normalizer.normalize(content),
26
- extensions: CORE_EXTENSIONS.concat(MockStylePreset, BackgroundColor)
22
+ content: ContentNormalizer.normalize(content),
23
+ extensions: buildCoreExtensions().concat(MockStylePreset, BackgroundColor)
27
24
  });
28
25
  }
29
26
 
@@ -94,6 +91,14 @@ describe('parsing html', () => {
94
91
  expect(editor.getJSON()).toMatchSnapshot();
95
92
  });
96
93
 
94
+ test('should get value from rendered view', () => {
95
+ const editor = createEditor({
96
+ content: '<p><span style="--zw-background-color: red">lorem</span> ipsum</p>'
97
+ });
98
+
99
+ expect(editor.getJSON()).toMatchSnapshot();
100
+ });
101
+
97
102
  test('should merge paragraph and text settings', () => {
98
103
  const editor = createEditor({
99
104
  content: '<p style="background-color: red"><span style="background-color: #000">lorem</span> ipsum</p>'
@@ -1,16 +1,13 @@
1
1
  import { Editor } from '@tiptap/vue-2';
2
- import { NodeFactory } from '../../__tests__/utils';
3
2
  import { CaseStyles } from '../../enums';
4
- import { CORE_EXTENSIONS } from '../core';
5
3
  import { CaseStyle } from '../CaseStyle';
6
- import { ContentNormalizer } from '../../services';
4
+ import { ContentNormalizer, NodeFactory } from '../../services';
5
+ import { buildCoreExtensions } from '../core';
7
6
 
8
7
  function createEditor({ content }) {
9
- const normalizer = new ContentNormalizer();
10
-
11
8
  return new Editor({
12
- content: normalizer.normalize(content),
13
- extensions: CORE_EXTENSIONS.concat(CaseStyle)
9
+ content: ContentNormalizer.normalize(content),
10
+ extensions: buildCoreExtensions().concat(CaseStyle)
14
11
  });
15
12
  }
16
13
 
@@ -1,10 +1,9 @@
1
1
  import { Editor, Extension } from '@tiptap/vue-2';
2
- import { ref } from '@vue/composition-api';
3
- import { NodeFactory } from '../../__tests__/utils';
2
+ import { ref } from 'vue';
4
3
  import { createCommand } from '../../utils';
5
- import { CORE_EXTENSIONS } from '../core';
6
4
  import { FontColor } from '../FontColor';
7
- import { ContentNormalizer } from '../../services';
5
+ import { ContentNormalizer, NodeFactory } from '../../services';
6
+ import { buildCoreExtensions } from '../core';
8
7
 
9
8
  const MockStylePreset = Extension.create({
10
9
  name: 'style_preset',
@@ -19,11 +18,9 @@ const MockStylePreset = Extension.create({
19
18
  });
20
19
 
21
20
  function createEditor({ content }) {
22
- const normalizer = new ContentNormalizer();
23
-
24
21
  return new Editor({
25
- content: normalizer.normalize(content),
26
- extensions: CORE_EXTENSIONS.concat(MockStylePreset, FontColor)
22
+ content: ContentNormalizer.normalize(content),
23
+ extensions: buildCoreExtensions().concat(MockStylePreset, FontColor)
27
24
  });
28
25
  }
29
26
 
@@ -104,6 +101,14 @@ describe('parsing html', () => {
104
101
  expect(editor.getJSON()).toMatchSnapshot();
105
102
  });
106
103
 
104
+ test('should get value from parsed view', () => {
105
+ const editor = createEditor({
106
+ content: '<p><span style="--zw-color: red">lorem</span> ipsum</p>'
107
+ });
108
+
109
+ expect(editor.getJSON()).toMatchSnapshot();
110
+ });
111
+
107
112
  test('should merge paragraph and text settings', () => {
108
113
  const editor = createEditor({
109
114
  content: '<p style="color: red"><span style="color: #000">lorem</span> ipsum</p>'
@@ -1,13 +1,12 @@
1
1
  import { Editor, Extension } from '@tiptap/vue-2';
2
- import { ref } from '@vue/composition-api';
3
- import { NodeFactory } from '../../__tests__/utils';
2
+ import { ref } from 'vue';
4
3
  import { createCommand } from '../../utils';
5
- import { CORE_EXTENSIONS } from '../core';
6
4
  import { Font } from '../../models';
7
5
  import { FontFamily } from '../FontFamily';
8
6
  import { FontWeight } from '../FontWeight';
9
7
  import { FontStyle } from '../FontStyle';
10
- import { ContentNormalizer } from '../../services';
8
+ import { ContentNormalizer, NodeFactory } from '../../services';
9
+ import { buildCoreExtensions } from '../core';
11
10
 
12
11
  const MockStylePreset = Extension.create({
13
12
  name: 'style_preset',
@@ -25,17 +24,18 @@ const MockStylePreset = Extension.create({
25
24
  });
26
25
 
27
26
  function createEditor({ content }) {
28
- const normalizer = new ContentNormalizer();
29
-
30
27
  return new Editor({
31
- content: normalizer.normalize(content),
32
- extensions: CORE_EXTENSIONS.concat(
28
+ content: ContentNormalizer.normalize(content),
29
+ extensions: buildCoreExtensions().concat(
33
30
  MockStylePreset,
34
31
  FontFamily.configure({
35
32
  fonts: [
36
33
  new Font({ name: 'Lato', styles: ['400', '700', '700i'] }),
37
- new Font({ name: 'Bungee', styles: ['400'] })
38
- ]
34
+ new Font({ name: 'Bungee', styles: ['400'] }),
35
+ new Font({ name: 'Roboto', styles: ['400'] }),
36
+ new Font({ name: 'Josefin Slab', styles: ['400'] })
37
+ ],
38
+ defaultFont: 'Lato'
39
39
  }),
40
40
  FontWeight,
41
41
  FontStyle
@@ -190,6 +190,22 @@ describe('parsing html', () => {
190
190
  expect(editor.getJSON()).toMatchSnapshot();
191
191
  });
192
192
 
193
+ test('should get value from rendered view', () => {
194
+ const editor = createEditor({
195
+ content: '<p><span style="--zw-font-family: Lato">lorem</span> ipsum</p>'
196
+ });
197
+
198
+ expect(editor.getJSON()).toMatchSnapshot();
199
+ });
200
+
201
+ test('should get set default if undefined font', () => {
202
+ const editor = createEditor({
203
+ content: '<p><span style="--zw-font-family: Arial">lorem</span> ipsum</p>'
204
+ });
205
+
206
+ expect(editor.getJSON()).toMatchSnapshot();
207
+ });
208
+
193
209
  test('should merge paragraph and text settings', () => {
194
210
  const editor = createEditor({
195
211
  content: '<p style="font-family: Lato"><span style="font-family: Roboto">lorem</span> ipsum</p>'
@@ -197,4 +213,12 @@ describe('parsing html', () => {
197
213
 
198
214
  expect(editor.getJSON()).toMatchSnapshot();
199
215
  });
216
+
217
+ test('should get parse font name with quotes', () => {
218
+ const editor = createEditor({
219
+ content: '<p>hello <span style="font-family: &quot;Josefin Slab&quot;;">world</span></p>'
220
+ });
221
+
222
+ expect(editor.getJSON()).toMatchSnapshot();
223
+ });
200
224
  });
@@ -1,11 +1,10 @@
1
1
  import { Editor, Extension } from '@tiptap/vue-2';
2
- import { ref } from '@vue/composition-api';
3
- import { NodeFactory } from '../../__tests__/utils';
2
+ import { ref } from 'vue';
4
3
  import { createCommand } from '../../utils';
5
- import { CORE_EXTENSIONS } from '../core';
6
4
  import { FontSize } from '../FontSize';
7
5
  import { DeviceManager } from '../DeviceManager';
8
- import { ContentNormalizer } from '../../services';
6
+ import { ContentNormalizer, NodeFactory } from '../../services';
7
+ import { buildCoreExtensions } from '../core';
9
8
 
10
9
  const MockStylePreset = Extension.create({
11
10
  name: 'style_preset',
@@ -22,18 +21,17 @@ const MockStylePreset = Extension.create({
22
21
  });
23
22
 
24
23
  function createEditor({ content }) {
25
- const normalizer = new ContentNormalizer();
26
-
27
24
  return new Editor({
28
- content: normalizer.normalize(content),
29
- extensions: CORE_EXTENSIONS.concat(
25
+ content: ContentNormalizer.normalize(content),
26
+ extensions: buildCoreExtensions().concat(
30
27
  MockStylePreset,
31
28
  DeviceManager.configure({
32
- deviceRef: ref('desktop')
29
+ device: ref('desktop')
33
30
  }),
34
31
  FontSize.configure({
35
32
  minSize: 5,
36
- maxSize: 20
33
+ maxSize: 20,
34
+ wrapperRef: ref(document.createElement('div'))
37
35
  })
38
36
  )
39
37
  });
@@ -202,6 +200,14 @@ describe('parsing html', () => {
202
200
  expect(editor.getJSON()).toMatchSnapshot();
203
201
  });
204
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
+
205
211
  test('should merge paragraph and text settings', () => {
206
212
  const editor = createEditor({
207
213
  content: '<p style="font-size: 24px"><span style="font-size: 20px">lorem</span> ipsum</p>'
@@ -1,13 +1,12 @@
1
1
  import { Editor, Extension } from '@tiptap/vue-2';
2
- import { ref } from '@vue/composition-api';
3
- import { NodeFactory } from '../../__tests__/utils';
2
+ import { ref } from 'vue';
4
3
  import { createCommand } from '../../utils';
5
- import { CORE_EXTENSIONS } from '../core';
6
4
  import { FontStyle } from '../FontStyle';
7
5
  import { FontFamily } from '../FontFamily';
8
6
  import { Font } from '../../models';
9
7
  import { FontWeight } from '../FontWeight';
10
- import { ContentNormalizer } from '../../services';
8
+ import { ContentNormalizer, NodeFactory } from '../../services';
9
+ import { buildCoreExtensions } from '../core';
11
10
 
12
11
  const MockStylePreset = Extension.create({
13
12
  name: 'style_preset',
@@ -26,11 +25,9 @@ const MockStylePreset = Extension.create({
26
25
  });
27
26
 
28
27
  function createEditor({ content }) {
29
- const normalizer = new ContentNormalizer();
30
-
31
28
  return new Editor({
32
- content: normalizer.normalize(content),
33
- extensions: CORE_EXTENSIONS.concat(
29
+ content: ContentNormalizer.normalize(content),
30
+ extensions: buildCoreExtensions().concat(
34
31
  MockStylePreset,
35
32
  FontStyle,
36
33
  FontWeight,
@@ -155,6 +152,14 @@ describe('parsing html', () => {
155
152
  expect(editor.getJSON()).toMatchSnapshot();
156
153
  });
157
154
 
155
+ test('should get value from rendered view', () => {
156
+ const editor = createEditor({
157
+ content: '<p><span style="--zw-font-style: italic">lorem</span> ipsum</p>'
158
+ });
159
+
160
+ expect(editor.getJSON()).toMatchSnapshot();
161
+ });
162
+
158
163
  test('should get value from i tag', () => {
159
164
  const editor = createEditor({
160
165
  content: '<p><i>lorem</i> ipsum</p>'