@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.
- package/.eslintrc.js +17 -235
- package/.github/actions/setup/action.yaml +1 -1
- package/README.md +2 -0
- package/config/build/cli.config.js +7 -7
- package/config/build/lib.config.js +6 -4
- package/config/svgo.js +6 -3
- package/dist/cli.js +5 -4
- package/dist/wysiwyg.css +36 -33
- package/dist/wysiwyg.mjs +12403 -11604
- package/example/ExampleApp.vue +1 -1
- package/example/presets.js +7 -7
- package/example/tooltip/Tooltip.js +94 -69
- package/example/tooltip/tooltip.css +8 -31
- package/lib/Wysiwyg.vue +3 -0
- package/lib/__tests__/utils/buildTestExtensions.js +24 -2
- package/lib/cli/commands/ToJsonCommand.js +6 -6
- package/lib/components/base/__tests__/Button.test.js +1 -1
- package/lib/components/base/composables/__tests__/useDeselectionLock.test.js +2 -2
- package/lib/components/base/composables/__tests__/useElementRef.test.js +1 -1
- package/lib/components/base/composables/__tests__/useModalToggler.test.js +0 -2
- package/lib/components/base/composables/__tests__/useValidator.test.js +2 -2
- package/lib/components/base/composables/useModalToggler.js +30 -21
- package/lib/components/base/dropdown/DropdownActivator.vue +4 -0
- package/lib/components/toolbar/Toolbar.vue +1 -1
- package/lib/components/toolbar/base/__tests__/ToolbarDivider.test.js +1 -1
- package/lib/components/toolbar/controls/StylePresetControl.vue +2 -2
- package/lib/components/toolbar/controls/__tests__/LineHeightControl.test.js +0 -2
- package/lib/components/toolbar/controls/composables/__tests__/useRecentFonts.test.js +1 -1
- package/lib/components/toolbar/controls/link/composables/__tests__/useLink.test.js +2 -2
- package/lib/composables/useToolbar.js +24 -19
- package/lib/{entry-cli.js → entryCli.js} +0 -0
- package/lib/{entry-lib.js → entryLib.js} +0 -0
- package/lib/extensions/Alignment.js +6 -6
- package/lib/extensions/FontSize.js +1 -2
- package/lib/extensions/Link.js +2 -0
- package/lib/extensions/StylePreset.js +8 -46
- package/lib/extensions/__tests__/Alignment.test.js +1 -1
- package/lib/extensions/__tests__/BackgroundColor.test.js +2 -2
- package/lib/extensions/__tests__/FontColor.test.js +3 -3
- package/lib/extensions/__tests__/FontFamily.test.js +3 -3
- package/lib/extensions/__tests__/FontSize.test.js +3 -3
- package/lib/extensions/__tests__/FontWeight.test.js +4 -4
- package/lib/extensions/__tests__/LineHeight.test.js +2 -2
- package/lib/extensions/__tests__/Link.test.js +33 -5
- package/lib/extensions/__tests__/StylePreset.test.js +90 -119
- package/lib/extensions/__tests__/__snapshots__/Alignment.test.js.snap +2 -2
- package/lib/extensions/__tests__/__snapshots__/Link.test.js.snap +27 -0
- package/lib/extensions/__tests__/__snapshots__/StylePreset.test.js.snap +0 -2
- package/lib/extensions/core/NodeProcessor.js +9 -6
- package/lib/extensions/core/__tests__/NodeProcessor.test.js +6 -8
- package/lib/extensions/core/__tests__/TextProcessor.test.js +1 -1
- package/lib/extensions/core/index.js +0 -2
- package/lib/extensions/core/plugins/PlaceholderPlugin.js +2 -2
- package/lib/extensions/index.js +7 -3
- package/lib/extensions/list/List.js +4 -5
- package/lib/extensions/list/ListItem.js +1 -2
- package/lib/extensions/list/__tests__/List.test.js +7 -2
- package/lib/models/Font.js +2 -2
- package/lib/models/__tests__/Font.test.js +3 -9
- package/lib/services/ContentSerializer.js +9 -9
- package/lib/services/{ContextWidnow.js → ContextWindow.js} +0 -0
- package/lib/services/HtmlToJsonParser.js +3 -3
- package/lib/services/NodeFactory.js +6 -6
- package/lib/services/StylePresetRenderer.js +73 -0
- package/lib/services/__tests__/JsonSerializer.test.js +1 -1
- package/lib/services/__tests__/Storage.test.js +1 -1
- package/lib/services/__tests__/StylePresetRenderer.test.js +98 -0
- package/lib/services/__tests__/__snapshots__/StylePresetRenderer.test.js.snap +5 -0
- package/lib/services/index.js +2 -1
- package/lib/services/normalizer/BrowserDomParser.js +2 -2
- package/lib/services/normalizer/ContentNormalizer.js +3 -3
- package/lib/services/normalizer/HtmlNormalizer.js +52 -52
- package/lib/services/normalizer/JsonNormalizer.js +21 -21
- package/lib/styles/content.css +10 -10
- package/lib/utils/__tests__/convertAlignment.test.js +1 -1
- package/lib/utils/__tests__/renderInlineSetting.test.js +2 -2
- package/package.json +48 -46
- package/lib/extensions/core/steps/AddNodeMarkStep.js +0 -66
- package/lib/extensions/core/steps/AttrStep.js +0 -60
- package/lib/extensions/core/steps/RemoveNodeMarkStep.js +0 -56
- package/lib/extensions/core/steps/index.js +0 -3
package/example/ExampleApp.vue
CHANGED
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
|
|
51
51
|
<script>
|
|
52
52
|
import { computed, onMounted, ref, unref } from 'vue';
|
|
53
|
-
import { Wysiwyg } from '../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';
|
package/example/presets.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const PRESETS = [
|
|
2
2
|
{
|
|
3
3
|
'id': 'h1',
|
|
4
|
-
'name': '
|
|
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': '
|
|
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': '
|
|
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': '
|
|
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': '
|
|
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': '
|
|
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': '
|
|
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 {
|
|
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:
|
|
21
|
+
leaveDuration: 200
|
|
17
22
|
};
|
|
18
23
|
}
|
|
19
24
|
|
|
20
|
-
static get
|
|
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
|
|
34
|
-
|
|
38
|
+
/** @type {object} options for Popper.js instance */
|
|
39
|
+
popperOptions = {};
|
|
35
40
|
|
|
36
41
|
/** @type {object} styles for tooltip's wrapper element */
|
|
37
|
-
|
|
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 {
|
|
43
|
-
|
|
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.
|
|
54
|
-
* @param [params.
|
|
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,
|
|
62
|
+
constructor({ triggerEl, message, popperOptions, popperStyles, animationOptions }) {
|
|
58
63
|
this.triggerEl = triggerEl;
|
|
59
64
|
this.message = message;
|
|
60
65
|
|
|
61
|
-
this.
|
|
62
|
-
this.
|
|
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
|
|
72
|
+
this._initialize();
|
|
68
73
|
}
|
|
69
74
|
|
|
70
|
-
|
|
71
|
-
let tooltip = this
|
|
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
|
-
|
|
86
|
+
_createTooltip() {
|
|
82
87
|
let element = document.createElement('div');
|
|
83
88
|
|
|
84
|
-
Object.keys(this.
|
|
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.
|
|
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
|
-
|
|
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
|
|
105
|
+
this._renderHotkeyTip();
|
|
103
106
|
}
|
|
104
107
|
|
|
105
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
134
|
+
_getModifiers() {
|
|
132
135
|
return [
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
-
|
|
173
|
+
_setTooltipDuration(duration = 0) {
|
|
141
174
|
this.elements.container.style.transitionDuration = `${duration}ms`;
|
|
142
175
|
}
|
|
143
176
|
|
|
144
|
-
|
|
145
|
-
const modifiers = this
|
|
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
|
-
|
|
158
|
-
|
|
159
|
-
top: `${y}px`
|
|
160
|
-
});
|
|
180
|
+
const createPopper = popperGenerator({
|
|
181
|
+
defaultModifiers: [...defaultModifiers, arrow, flip, offset, preventOverflow]
|
|
161
182
|
});
|
|
162
183
|
|
|
163
|
-
|
|
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
|
-
|
|
192
|
+
_toggle(makeVisible) {
|
|
176
193
|
const { enterDuration, leaveDuration } = this.animationOptions;
|
|
177
194
|
|
|
178
|
-
this
|
|
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.
|
|
200
|
+
if (this.popperInstance) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
184
203
|
|
|
185
204
|
document.body.appendChild(this.elements.tooltip);
|
|
186
|
-
this.popperInstance = this
|
|
205
|
+
this.popperInstance = this._renderPopper();
|
|
187
206
|
|
|
188
|
-
this
|
|
189
|
-
this
|
|
207
|
+
this._renderContent(this.message);
|
|
208
|
+
this._toggle(true);
|
|
190
209
|
}
|
|
191
210
|
|
|
192
211
|
close() {
|
|
193
|
-
if (!this.
|
|
212
|
+
if (!this.popperInstance) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
194
215
|
|
|
195
|
-
this
|
|
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
|
|
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
|
-
|
|
212
|
-
this.
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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
|
|
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
|
|
37
|
+
const json = this._stringifyContent(content);
|
|
38
38
|
|
|
39
|
-
this.output(format === 'rb' ? this
|
|
39
|
+
this.output(format === 'rb' ? this._formatOutputRb(json) : json);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
37
|
-
event
|
|
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).
|
|
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).
|
|
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).
|
|
42
|
+
expect(validator.error.value).toBeNull();
|
|
43
43
|
});
|
|
44
44
|
});
|