@zipify/wysiwyg 3.1.0-0 → 3.1.0

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 (81) hide show
  1. package/.eslintrc.js +17 -235
  2. package/.github/actions/setup/action.yaml +1 -1
  3. package/README.md +2 -0
  4. package/config/build/cli.config.js +7 -7
  5. package/config/build/lib.config.js +6 -4
  6. package/config/svgo.js +6 -3
  7. package/dist/cli.js +5 -4
  8. package/dist/wysiwyg.css +36 -33
  9. package/dist/wysiwyg.mjs +12403 -11604
  10. package/example/ExampleApp.vue +1 -1
  11. package/example/presets.js +7 -7
  12. package/example/tooltip/Tooltip.js +94 -69
  13. package/example/tooltip/tooltip.css +8 -31
  14. package/lib/Wysiwyg.vue +3 -0
  15. package/lib/__tests__/utils/buildTestExtensions.js +24 -2
  16. package/lib/cli/commands/ToJsonCommand.js +6 -6
  17. package/lib/components/base/__tests__/Button.test.js +1 -1
  18. package/lib/components/base/composables/__tests__/useDeselectionLock.test.js +2 -2
  19. package/lib/components/base/composables/__tests__/useElementRef.test.js +1 -1
  20. package/lib/components/base/composables/__tests__/useModalToggler.test.js +0 -2
  21. package/lib/components/base/composables/__tests__/useValidator.test.js +2 -2
  22. package/lib/components/base/composables/useModalToggler.js +30 -21
  23. package/lib/components/base/dropdown/DropdownActivator.vue +4 -0
  24. package/lib/components/toolbar/Toolbar.vue +1 -1
  25. package/lib/components/toolbar/base/__tests__/ToolbarDivider.test.js +1 -1
  26. package/lib/components/toolbar/controls/StylePresetControl.vue +2 -2
  27. package/lib/components/toolbar/controls/__tests__/LineHeightControl.test.js +0 -2
  28. package/lib/components/toolbar/controls/composables/__tests__/useRecentFonts.test.js +1 -1
  29. package/lib/components/toolbar/controls/link/composables/__tests__/useLink.test.js +2 -2
  30. package/lib/composables/useToolbar.js +24 -19
  31. package/lib/{entry-cli.js → entryCli.js} +0 -0
  32. package/lib/{entry-lib.js → entryLib.js} +0 -0
  33. package/lib/extensions/Alignment.js +6 -6
  34. package/lib/extensions/FontSize.js +1 -2
  35. package/lib/extensions/Link.js +2 -0
  36. package/lib/extensions/StylePreset.js +8 -46
  37. package/lib/extensions/__tests__/Alignment.test.js +1 -1
  38. package/lib/extensions/__tests__/BackgroundColor.test.js +2 -2
  39. package/lib/extensions/__tests__/FontColor.test.js +3 -3
  40. package/lib/extensions/__tests__/FontFamily.test.js +3 -3
  41. package/lib/extensions/__tests__/FontSize.test.js +3 -3
  42. package/lib/extensions/__tests__/FontWeight.test.js +4 -4
  43. package/lib/extensions/__tests__/LineHeight.test.js +2 -2
  44. package/lib/extensions/__tests__/Link.test.js +33 -5
  45. package/lib/extensions/__tests__/StylePreset.test.js +90 -119
  46. package/lib/extensions/__tests__/__snapshots__/Alignment.test.js.snap +2 -2
  47. package/lib/extensions/__tests__/__snapshots__/Link.test.js.snap +27 -0
  48. package/lib/extensions/__tests__/__snapshots__/StylePreset.test.js.snap +0 -2
  49. package/lib/extensions/core/NodeProcessor.js +9 -6
  50. package/lib/extensions/core/__tests__/NodeProcessor.test.js +6 -8
  51. package/lib/extensions/core/__tests__/TextProcessor.test.js +1 -1
  52. package/lib/extensions/core/index.js +0 -2
  53. package/lib/extensions/core/plugins/PlaceholderPlugin.js +2 -2
  54. package/lib/extensions/index.js +7 -3
  55. package/lib/extensions/list/List.js +4 -5
  56. package/lib/extensions/list/ListItem.js +1 -2
  57. package/lib/extensions/list/__tests__/List.test.js +7 -2
  58. package/lib/models/Font.js +2 -2
  59. package/lib/models/__tests__/Font.test.js +3 -9
  60. package/lib/services/ContentSerializer.js +9 -9
  61. package/lib/services/{ContextWidnow.js → ContextWindow.js} +0 -0
  62. package/lib/services/HtmlToJsonParser.js +3 -3
  63. package/lib/services/NodeFactory.js +6 -6
  64. package/lib/services/StylePresetRenderer.js +73 -0
  65. package/lib/services/__tests__/JsonSerializer.test.js +1 -1
  66. package/lib/services/__tests__/Storage.test.js +1 -1
  67. package/lib/services/__tests__/StylePresetRenderer.test.js +98 -0
  68. package/lib/services/__tests__/__snapshots__/StylePresetRenderer.test.js.snap +5 -0
  69. package/lib/services/index.js +2 -1
  70. package/lib/services/normalizer/BrowserDomParser.js +2 -2
  71. package/lib/services/normalizer/ContentNormalizer.js +3 -3
  72. package/lib/services/normalizer/HtmlNormalizer.js +52 -52
  73. package/lib/services/normalizer/JsonNormalizer.js +21 -21
  74. package/lib/styles/content.css +10 -10
  75. package/lib/utils/__tests__/convertAlignment.test.js +1 -1
  76. package/lib/utils/__tests__/renderInlineSetting.test.js +2 -2
  77. package/package.json +48 -46
  78. package/lib/extensions/core/steps/AddNodeMarkStep.js +0 -66
  79. package/lib/extensions/core/steps/AttrStep.js +0 -60
  80. package/lib/extensions/core/steps/RemoveNodeMarkStep.js +0 -56
  81. package/lib/extensions/core/steps/index.js +0 -3
@@ -50,7 +50,7 @@
50
50
 
51
51
  <script>
52
52
  import { computed, onMounted, ref, unref } from 'vue';
53
- import { Wysiwyg } from '../lib/entry-lib';
53
+ import { Wysiwyg } from '../lib/entryLib';
54
54
  import { FONTS } from './fonts';
55
55
  import { PRESETS, renderPresetVariable } from './presets';
56
56
  import { PAGE_BLOCKS } from './pageBlocks';
@@ -1,7 +1,7 @@
1
1
  export const PRESETS = [
2
2
  {
3
3
  'id': 'h1',
4
- 'name': 'H1',
4
+ 'name': 'Heading 1',
5
5
  'node': {
6
6
  'type': 'heading',
7
7
  'level': 1
@@ -31,7 +31,7 @@ export const PRESETS = [
31
31
  },
32
32
  {
33
33
  'id': 'h2',
34
- 'name': 'H2',
34
+ 'name': 'Heading 2',
35
35
  'node': {
36
36
  'type': 'heading',
37
37
  'level': 2
@@ -61,7 +61,7 @@ export const PRESETS = [
61
61
  },
62
62
  {
63
63
  'id': 'h3',
64
- 'name': 'H3',
64
+ 'name': 'Sub-heading 1',
65
65
  'node': {
66
66
  'type': 'heading',
67
67
  'level': 3
@@ -91,7 +91,7 @@ export const PRESETS = [
91
91
  },
92
92
  {
93
93
  'id': 'h4',
94
- 'name': 'H4',
94
+ 'name': 'Sub-heading 2',
95
95
  'node': {
96
96
  'type': 'heading',
97
97
  'level': 4
@@ -148,7 +148,7 @@ export const PRESETS = [
148
148
  },
149
149
  {
150
150
  'id': 'regular-1',
151
- 'name': 'Regular',
151
+ 'name': 'Body Copy 1',
152
152
  'desktop': {
153
153
  'alignment': null,
154
154
  'line_height': '1.43',
@@ -174,7 +174,7 @@ export const PRESETS = [
174
174
  },
175
175
  {
176
176
  'id': 'regular-2',
177
- 'name': 'Regular 2',
177
+ 'name': 'Body Copy 2',
178
178
  'fallbackClass': 'zpa-regular2',
179
179
  'desktop': {
180
180
  'alignment': null,
@@ -201,7 +201,7 @@ export const PRESETS = [
201
201
  },
202
202
  {
203
203
  'id': 'regular-3',
204
- 'name': 'Regular 3',
204
+ 'name': 'Body Copy 3',
205
205
  'fallbackClass': 'zpa-regular3',
206
206
  'desktop': {
207
207
  'alignment': null,
@@ -1,6 +1,11 @@
1
1
  import './tooltip.css';
2
2
 
3
- import { arrow, autoUpdate, computePosition, flip, offset, shift } from '@floating-ui/dom';
3
+ import { popperGenerator, defaultModifiers } from '@popperjs/core/lib/popper-lite';
4
+ import arrow from '@popperjs/core/lib/modifiers/arrow';
5
+ import flip from '@popperjs/core/lib/modifiers/flip';
6
+ import offset from '@popperjs/core/lib/modifiers/offset';
7
+ import preventOverflow from '@popperjs/core/lib/modifiers/preventOverflow';
8
+ import { TooltipCloseOnScrollModifier } from './modifiers';
4
9
 
5
10
  export class Tooltip {
6
11
  static get defaultOptions() {
@@ -13,11 +18,11 @@ export class Tooltip {
13
18
  static get animationOptions() {
14
19
  return {
15
20
  enterDuration: 150,
16
- leaveDuration: 100
21
+ leaveDuration: 200
17
22
  };
18
23
  }
19
24
 
20
- static get tooltipStyles() {
25
+ static get popperStyles() {
21
26
  return {
22
27
  willChange: 'transform',
23
28
  zIndex: 999999
@@ -30,17 +35,17 @@ export class Tooltip {
30
35
  /** @type {string} tooltip's content */
31
36
  message = '';
32
37
 
33
- /** @type {object} options for FloatingUI instance */
34
- tooltipOptions = {};
38
+ /** @type {object} options for Popper.js instance */
39
+ popperOptions = {};
35
40
 
36
41
  /** @type {object} styles for tooltip's wrapper element */
37
- tooltipStyles = {};
42
+ popperStyles = {};
38
43
 
39
44
  /** @type {{ enterDuration: number, leaveDuration: number }} tooltip's fade in / fade out durations */
40
45
  animationOptions = {};
41
46
 
42
- /** @type {function | null} created FloatingUI instance */
43
- floatingInstance = null;
47
+ /** @type {object | null} created Popper.js instance */
48
+ popperInstance = null;
44
49
 
45
50
  /** @type {{ tooltip: HTMLElement, container: HTMLElement, contentEl: HTMLElement, arrow: HTMLElement }} elements of tooltip */
46
51
  elements = {};
@@ -50,25 +55,25 @@ export class Tooltip {
50
55
  * @param params {object}
51
56
  * @param params.triggerEl {HTMLElement}
52
57
  * @param params.message {string}
53
- * @param [params.tooltipOptions] {{ placement: string, size: string }}
54
- * @param [params.tooltipStyles] {object}
58
+ * @param [params.popperOptions] {{ placement: string, size: string }}
59
+ * @param [params.popperStyles] {object}
55
60
  * @param [params.animationOptions] {{ enterDuration: number, leaveDuration: number }}
56
61
  */
57
- constructor({ triggerEl, message, tooltipOptions, tooltipStyles, animationOptions }) {
62
+ constructor({ triggerEl, message, popperOptions, popperStyles, animationOptions }) {
58
63
  this.triggerEl = triggerEl;
59
64
  this.message = message;
60
65
 
61
- this.tooltipOptions = Object.assign({}, Tooltip.defaultOptions, tooltipOptions);
62
- this.tooltipStyles = Object.assign({}, Tooltip.tooltipStyles, tooltipStyles);
66
+ this.popperOptions = Object.assign({}, Tooltip.defaultOptions, popperOptions);
67
+ this.popperStyles = Object.assign({}, Tooltip.popperStyles, popperStyles);
63
68
  this.animationOptions = Object.assign({}, Tooltip.animationOptions, animationOptions);
64
69
 
65
70
  this._isMacOS = window.navigator.userAgent.toLowerCase().includes('mac os');
66
71
 
67
- this.#initialize();
72
+ this._initialize();
68
73
  }
69
74
 
70
- #initialize() {
71
- let tooltip = this.#createTooltip();
75
+ _initialize() {
76
+ let tooltip = this._createTooltip();
72
77
 
73
78
  this.elements = {
74
79
  tooltip,
@@ -78,15 +83,13 @@ export class Tooltip {
78
83
  };
79
84
  }
80
85
 
81
- #createTooltip() {
86
+ _createTooltip() {
82
87
  let element = document.createElement('div');
83
88
 
84
- Object.keys(this.tooltipStyles).forEach((style) => (element.style[style] = this.tooltipStyles[style]));
85
-
86
- element.classList.add('zpa-tooltip__wrapper');
89
+ Object.keys(this.popperStyles).forEach((style) => (element.style[style] = this.popperStyles[style]));
87
90
 
88
91
  element.innerHTML = `
89
- <div class="zpa-tooltip zpa-tooltip--${this.tooltipOptions.size}" data-container>
92
+ <div class="zpa-tooltip zpa-tooltip--${this.popperOptions.size}" data-container>
90
93
  <div class="zpa-tooltip__content" data-content></div>
91
94
  <div class="zpa-tooltip__arrow" data-arrow></div>
92
95
  </div>`;
@@ -94,20 +97,20 @@ export class Tooltip {
94
97
  return element;
95
98
  }
96
99
 
97
- #renderContent(message) {
100
+ _renderContent(message) {
98
101
  // Do not use .innerHTML, it will break tooltips in Scripts section!
99
102
  this.elements.contentEl.textContent = message;
100
103
 
101
104
  this.elements.hotkey?.remove();
102
- this.#renderHotkeyTip();
105
+ this._renderHotkeyTip();
103
106
  }
104
107
 
105
- #renderHotkeyTip() {
108
+ _renderHotkeyTip() {
106
109
  const raw = this.triggerEl.dataset.tooltipHotkey;
107
110
 
108
111
  if (!raw) return;
109
112
 
110
- const parts = raw.split(' ').map(this.#formatHotkeyPart.bind(this));
113
+ const parts = raw.split(' ').map(this._formatHotkeyPart.bind(this));
111
114
  const tipEl = document.createElement('span');
112
115
 
113
116
  tipEl.classList.add('zpa-tooltip__hotkey');
@@ -116,7 +119,7 @@ export class Tooltip {
116
119
  this.elements.contentEl.append(tipEl);
117
120
  }
118
121
 
119
- #formatHotkeyPart(part) {
122
+ _formatHotkeyPart(part) {
120
123
  switch (part.toLowerCase()) {
121
124
  case 'mod':
122
125
  return this._isMacOS ? '⌘' : 'Ctrl';
@@ -128,89 +131,111 @@ export class Tooltip {
128
131
  }
129
132
  }
130
133
 
131
- #getModifiers() {
134
+ _getModifiers() {
132
135
  return [
133
- flip(),
134
- offset({ mainAxis: 8 }),
135
- shift({ padding: 4 }),
136
- arrow({ element: this.elements.arrow })
136
+ {
137
+ name: 'arrow',
138
+ options: {
139
+ element: '[data-arrow]'
140
+ }
141
+ },
142
+ {
143
+ name: 'offset',
144
+ options: {
145
+ offset: [0, 8]
146
+ }
147
+ },
148
+ {
149
+ name: 'preventOverflow',
150
+ options: {
151
+ padding: {
152
+ top: 4,
153
+ bottom: 4,
154
+ left: 8,
155
+ right: 8
156
+ }
157
+ }
158
+ },
159
+ {
160
+ name: 'customAttributes',
161
+ enabled: true,
162
+ phase: 'beforeWrite',
163
+ requires: ['computeStyles'],
164
+ fn: ({ state }) => {
165
+ this.elements.arrow.classList.add(`zpa-tooltip__arrow--${state.placement}`);
166
+ state.attributes.popper = {};
167
+ }
168
+ },
169
+ TooltipCloseOnScrollModifier.init({ tooltip: this })
137
170
  ];
138
171
  }
139
172
 
140
- #setTooltipDuration(duration = 0) {
173
+ _setTooltipDuration(duration = 0) {
141
174
  this.elements.container.style.transitionDuration = `${duration}ms`;
142
175
  }
143
176
 
144
- #renderPopper() {
145
- const modifiers = this.#getModifiers();
146
-
147
- this.floatingInstance = autoUpdate(this.triggerEl, this.elements.tooltip, async () => {
148
- const positioning = await computePosition(this.triggerEl, this.elements.tooltip, {
149
- placement: this.tooltipOptions.placement,
150
- middleware: [...modifiers]
151
- });
152
-
153
- const { x, y, middlewareData, placement } = positioning;
154
-
155
- if (middlewareData.arrow) this.#renderArrow(placement, middlewareData.arrow);
177
+ _renderPopper() {
178
+ const modifiers = this._getModifiers();
156
179
 
157
- Object.assign(this.elements.tooltip.style, {
158
- left: `${x}px`,
159
- top: `${y}px`
160
- });
180
+ const createPopper = popperGenerator({
181
+ defaultModifiers: [...defaultModifiers, arrow, flip, offset, preventOverflow]
161
182
  });
162
183
 
163
- return this.floatingInstance;
164
- }
165
-
166
- #renderArrow(placement, { x, y }) {
167
- this.elements.tooltip.classList.add(`zpa-tooltip--${placement}`);
168
-
169
- Object.assign(this.elements.arrow.style, {
170
- left: x != null ? `${x}px` : '',
171
- top: y != null ? `${y}px` : ''
184
+ this.popperInstance = createPopper(this.triggerEl, this.elements.tooltip, {
185
+ placement: this.popperOptions.placement,
186
+ modifiers
172
187
  });
188
+
189
+ return this.popperInstance;
173
190
  }
174
191
 
175
- #toggle(makeVisible) {
192
+ _toggle(makeVisible) {
176
193
  const { enterDuration, leaveDuration } = this.animationOptions;
177
194
 
178
- this.#setTooltipDuration(makeVisible ? enterDuration : leaveDuration);
195
+ this._setTooltipDuration(makeVisible ? enterDuration : leaveDuration);
179
196
  this.elements.container.classList.toggle('zpa-tooltip--open', makeVisible);
180
197
  }
181
198
 
182
199
  open() {
183
- if (this.floatingInstance) return;
200
+ if (this.popperInstance) {
201
+ return;
202
+ }
184
203
 
185
204
  document.body.appendChild(this.elements.tooltip);
186
- this.popperInstance = this.#renderPopper();
205
+ this.popperInstance = this._renderPopper();
187
206
 
188
- this.#renderContent(this.message);
189
- this.#toggle(true);
207
+ this._renderContent(this.message);
208
+ this._toggle(true);
190
209
  }
191
210
 
192
211
  close() {
193
- if (!this.floatingInstance) return;
212
+ if (!this.popperInstance) {
213
+ return;
214
+ }
194
215
 
195
- this.#toggle(false);
216
+ this._toggle(false);
196
217
 
197
218
  return setTimeout(() => {
198
219
  this.destroy();
199
220
  }, this.animationOptions.leaveDuration);
200
221
  }
201
222
 
223
+ update() {
224
+ this.popperInstance?.update();
225
+ }
226
+
202
227
  updateContent(content) {
203
228
  this.message = content;
204
- this.#renderContent(this.message);
229
+ this._renderContent(this.message);
230
+ this.update();
205
231
  }
206
232
 
207
233
  destroy() {
208
234
  this.elements.tooltip.remove();
209
235
 
210
236
  if (this.popperInstance) {
211
- // destroy instance
212
- this.floatingInstance();
213
- this.floatingInstance = null;
237
+ this.popperInstance.destroy();
238
+ this.popperInstance = null;
214
239
  }
215
240
  }
216
241
  }
@@ -1,9 +1,3 @@
1
- .zpa-tooltip__wrapper {
2
- position: absolute;
3
- top: 0;
4
- left: 0;
5
- }
6
-
7
1
  .zpa-tooltip {
8
2
  position: relative;
9
3
  background-color: #36404C;
@@ -37,7 +31,6 @@
37
31
  }
38
32
 
39
33
  .zpa-tooltip__arrow {
40
- position: absolute;
41
34
  width: 16px;
42
35
  height: 16px;
43
36
  color: #36404C;
@@ -50,15 +43,11 @@
50
43
  border-style: solid;
51
44
  }
52
45
 
53
- .zpa-tooltip--top {
54
- transform-origin: center bottom;
55
- }
56
-
57
- .zpa-tooltip--top .zpa-tooltip__arrow {
46
+ .zpa-tooltip__arrow--top {
58
47
  bottom: 0;
59
48
  }
60
49
 
61
- .zpa-tooltip--top .zpa-tooltip__arrow::before {
50
+ .zpa-tooltip__arrow--top::before {
62
51
  bottom: -7px;
63
52
  left: 0;
64
53
  border-width: 8px 8px 0;
@@ -66,15 +55,11 @@
66
55
  transform-origin: center top;
67
56
  }
68
57
 
69
- .zpa-tooltip--bottom {
70
- transform-origin: center top;
71
- }
72
-
73
- .zpa-tooltip--bottom .zpa-tooltip__arrow {
58
+ .zpa-tooltip__arrow--bottom {
74
59
  top: 0;
75
60
  }
76
61
 
77
- .zpa-tooltip--bottom .zpa-tooltip__arrow::before {
62
+ .zpa-tooltip__arrow--bottom::before {
78
63
  top: -7px;
79
64
  left: 0;
80
65
  border-width: 0 8px 8px;
@@ -82,30 +67,22 @@
82
67
  transform-origin: center bottom;
83
68
  }
84
69
 
85
- .zpa-tooltip--left {
86
- transform-origin: center right;
87
- }
88
-
89
- .zpa-tooltip--left .zpa-tooltip__arrow {
70
+ .zpa-tooltip__arrow--left {
90
71
  right: 0;
91
72
  }
92
73
 
93
- .zpa-tooltip--left .zpa-tooltip__arrow::before {
74
+ .zpa-tooltip__arrow--left::before {
94
75
  border-width: 8px 0 8px 8px;
95
76
  border-left-color: initial;
96
77
  right: -7px;
97
78
  transform-origin: center left;
98
79
  }
99
80
 
100
- .zpa-tooltip--right {
101
- transform-origin: center left;
102
- }
103
-
104
- .zpa-tooltip--right .zpa-tooltip__arrow {
81
+ .zpa-tooltip__arrow--right {
105
82
  left: 0;
106
83
  }
107
84
 
108
- .zpa-tooltip--right .zpa-tooltip__arrow::before {
85
+ .zpa-tooltip__arrow--right::before {
109
86
  left: -7px;
110
87
  border-width: 8px 8px 8px 0;
111
88
  border-right-color: initial;
package/lib/Wysiwyg.vue CHANGED
@@ -155,9 +155,11 @@ export default {
155
155
  isActiveRef: isToolbarActiveRef,
156
156
  offsets: props.toolbarOffsets
157
157
  });
158
+ const updateToolbar = () => toolbar.update();
158
159
 
159
160
  function onChange(content) {
160
161
  emit('input', content);
162
+ updateToolbar();
161
163
  }
162
164
 
163
165
  const pageBlocks = toRef(props, 'pageBlocks');
@@ -206,6 +208,7 @@ export default {
206
208
  toolbarRef,
207
209
  wysiwygRef,
208
210
  toolbar,
211
+ updateToolbar,
209
212
  getContent,
210
213
  getContentCustomization
211
214
  };
@@ -1,6 +1,6 @@
1
1
  import { Mark } from '@tiptap/vue-2';
2
2
  import { buildCoreExtensions } from '../../extensions/core';
3
- import { MarkGroups } from '../../enums';
3
+ import { MarkGroups, TextSettings } from '../../enums';
4
4
 
5
5
  // each node allows using 'settings' group of marks,
6
6
  // and it fails when there are no nodes with this group
@@ -10,6 +10,28 @@ const SettingMark = Mark.create({
10
10
  renderHTML: () => []
11
11
  });
12
12
 
13
+ // NodeProcessor requires link mark
14
+ const LinkMark = Mark.create({
15
+ name: TextSettings.LINK,
16
+ renderHTML: () => []
17
+ });
18
+
19
+ const isMark = (extension) => extension && extension.type === 'mark';
20
+
13
21
  export function buildTestExtensions({ include } = {}) {
14
- return buildCoreExtensions().concat(SettingMark, include || []);
22
+ const extensions = buildCoreExtensions().concat(include || []);
23
+
24
+ const isSettingPreset = extensions.some((extension) => {
25
+ return isMark(extension) && extension.config.group === MarkGroups.SETTINGS;
26
+ });
27
+
28
+ if (!isSettingPreset) extensions.push(SettingMark);
29
+
30
+ const isLinkPreset = extensions.some((extension) => {
31
+ return isMark(extension) && extension.name === TextSettings.LINK;
32
+ });
33
+
34
+ if (!isLinkPreset) extensions.push(LinkMark);
35
+
36
+ return extensions;
15
37
  }
@@ -32,14 +32,14 @@ export class ToJsonCommand extends Command {
32
32
  nodeDomParser: new NodeDomParser()
33
33
  });
34
34
 
35
- const jsonList = htmlList.map((html) => serializer.toJSON(this.#formatInputHtml(html)));
35
+ const jsonList = htmlList.map((html) => serializer.toJSON(this._formatInputHtml(html)));
36
36
  const content = jsonList.length === 1 ? jsonList[0] : jsonList;
37
- const json = this.#stringifyContent(content);
37
+ const json = this._stringifyContent(content);
38
38
 
39
- this.output(format === 'rb' ? this.#formatOutputRb(json) : json);
39
+ this.output(format === 'rb' ? this._formatOutputRb(json) : json);
40
40
  }
41
41
 
42
- #formatInputHtml(html) {
42
+ _formatInputHtml(html) {
43
43
  return html
44
44
  .replace(/\\(["'])/g, '$1')
45
45
  .replace(/rgba\(\d{1,3}, ?\d{1,3}, ?\d{1,3}, (\d{1,2}%)\)/g, (substring, alpha) => {
@@ -47,13 +47,13 @@ export class ToJsonCommand extends Command {
47
47
  });
48
48
  }
49
49
 
50
- #stringifyContent(content) {
50
+ _stringifyContent(content) {
51
51
  const skipNullValue = (_, value) => value === null ? undefined : value;
52
52
 
53
53
  return JSON.stringify(content, skipNullValue, 2);
54
54
  }
55
55
 
56
- #formatOutputRb(json) {
56
+ _formatOutputRb(json) {
57
57
  return json
58
58
  .replace(/\\"/g, '"')
59
59
  .replace(/font-family: ?'(.+)'/g, 'font-family: "$1"')
@@ -42,7 +42,7 @@ describe('rendering', () => {
42
42
  expect(wrapper.classes('zw-button--icon')).toBeTruthy();
43
43
  });
44
44
 
45
- test('should render icon style', () => {
45
+ test('should render iconless style', () => {
46
46
  const wrapper = createComponent({ icon: false });
47
47
 
48
48
  expect(wrapper.classes('zw-button--icon')).toBeFalsy();
@@ -33,8 +33,8 @@ describe('prevent deselection', () => {
33
33
  function click(el, { target } = {}) {
34
34
  const event = new MouseEvent('mousedown');
35
35
 
36
- event.preventDefault = jest.fn();
37
- event.stopPropagation = jest.fn();
36
+ jest.spyOn(event, 'preventDefault').mockImplementation();
37
+ jest.spyOn(event, 'stopPropagation').mockImplementation();
38
38
  setReadonlyProperty(event, 'target', target || { tagName: 'DIV' });
39
39
 
40
40
  el.dispatchEvent(event);
@@ -10,7 +10,7 @@ describe('resolve element from ref', () => {
10
10
  test('should return null if no element', () => {
11
11
  const elementRef = useElementRef(ref(null));
12
12
 
13
- expect(elementRef.value).toBe(null);
13
+ expect(elementRef.value).toBeNull();
14
14
  });
15
15
 
16
16
  test('should return element if dom ref', () => {
@@ -4,8 +4,6 @@ import { InjectionTokens } from '../../../../injectionTokens';
4
4
  import { useModalToggler } from '../useModalToggler';
5
5
  import { useElementRef } from '../useElementRef';
6
6
 
7
- jest.mock('@floating-ui/dom');
8
-
9
7
  const createEditor = () => ({
10
8
  commands: {
11
9
  storeSelection: jest.fn(),
@@ -24,7 +24,7 @@ describe('validation', () => {
24
24
 
25
25
  validator.validate();
26
26
 
27
- expect(validator.error.value).toBe(null);
27
+ expect(validator.error.value).toBeNull();
28
28
  });
29
29
 
30
30
  test('should reset error', () => {
@@ -39,6 +39,6 @@ describe('validation', () => {
39
39
  expect(validator.error.value).toBe('Can\'t be empty');
40
40
 
41
41
  validator.reset();
42
- expect(validator.error.value).toBe(null);
42
+ expect(validator.error.value).toBeNull();
43
43
  });
44
44
  });