@zipify/wysiwyg 2.0.0-7 → 2.0.0-8
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/config/build/cli.config.js +6 -2
- package/dist/cli.js +3 -3
- package/dist/wysiwyg.css +41 -31
- package/dist/wysiwyg.mjs +187 -34
- package/lib/assets/icons/indicator.svg +4 -0
- package/lib/cli/commands/Command.js +34 -0
- package/lib/cli/commands/ToJsonCommand.js +45 -0
- package/lib/cli/commands/index.js +1 -0
- package/lib/cli/index.js +1 -0
- package/lib/components/base/Button.vue +6 -0
- package/lib/components/base/dropdown/Dropdown.vue +7 -1
- package/lib/components/base/dropdown/DropdownActivator.vue +25 -4
- package/lib/components/base/dropdown/__tests__/DropdownActivator.test.js +23 -1
- package/lib/components/toolbar/controls/AlignmentControl.vue +12 -1
- package/lib/components/toolbar/controls/FontColorControl.vue +14 -0
- package/lib/components/toolbar/controls/FontFamilyControl.vue +4 -0
- package/lib/components/toolbar/controls/FontSizeControl.vue +6 -1
- package/lib/components/toolbar/controls/FontWeightControl.vue +12 -0
- package/lib/components/toolbar/controls/ItalicControl.vue +14 -0
- package/lib/components/toolbar/controls/LineHeightControl.vue +15 -0
- package/lib/components/toolbar/controls/UnderlineControl.vue +13 -0
- package/lib/components/toolbar/controls/__tests__/AlignmentControl.test.js +72 -5
- package/lib/components/toolbar/controls/__tests__/FontColorControl.test.js +22 -1
- package/lib/components/toolbar/controls/__tests__/FontFamilyControl.test.js +1 -0
- package/lib/components/toolbar/controls/__tests__/FontSizeControl.test.js +1 -0
- package/lib/components/toolbar/controls/__tests__/FontWeightControl.test.js +1 -0
- package/lib/components/toolbar/controls/__tests__/ItalicControl.test.js +23 -1
- package/lib/components/toolbar/controls/__tests__/LineHeightControl.test.js +23 -1
- package/lib/components/toolbar/controls/__tests__/UnderlineControl.test.js +25 -1
- package/lib/directives/__tests__/tooltip.test.js +22 -4
- package/lib/directives/tooltip.js +4 -1
- package/lib/entry-cli.js +6 -21
- package/lib/extensions/StylePreset.js +6 -0
- package/lib/extensions/TextDecoration.js +7 -0
- package/lib/extensions/__tests__/StylePreset.test.js +51 -0
- package/lib/extensions/__tests__/TextDecoration.test.js +20 -0
- package/package.json +3 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ToJsonCommand } from './ToJsonCommand';
|
package/lib/cli/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="zw-dropdown" ref="dropdownRef">
|
|
3
|
-
<DropdownActivator :color="color">
|
|
3
|
+
<DropdownActivator :color="color" :is-customized="isCustomized">
|
|
4
4
|
<template #default="attrs">
|
|
5
5
|
<slot name="activator" v-bind="attrs" />
|
|
6
6
|
</template>
|
|
@@ -60,6 +60,12 @@ export default {
|
|
|
60
60
|
type: String,
|
|
61
61
|
required: false,
|
|
62
62
|
default: 'none'
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
isCustomized: {
|
|
66
|
+
type: Boolean,
|
|
67
|
+
required: false,
|
|
68
|
+
default: false
|
|
63
69
|
}
|
|
64
70
|
},
|
|
65
71
|
|
|
@@ -12,6 +12,15 @@
|
|
|
12
12
|
{{ activeOptionTitle }}
|
|
13
13
|
</span>
|
|
14
14
|
|
|
15
|
+
<Icon
|
|
16
|
+
v-if="isCustomized"
|
|
17
|
+
class="zw-dropdown__customized-indicator"
|
|
18
|
+
name="indicator"
|
|
19
|
+
size="9px"
|
|
20
|
+
data-test-selector="customizedIndicator"
|
|
21
|
+
v-tooltip.xs="'Default parameter setting is changed'"
|
|
22
|
+
/>
|
|
23
|
+
|
|
15
24
|
<Icon
|
|
16
25
|
class="zw-dropdown__activator-arrow"
|
|
17
26
|
name="arrow"
|
|
@@ -27,6 +36,7 @@
|
|
|
27
36
|
import { computed, inject, toRef } from 'vue';
|
|
28
37
|
import Button from '../Button';
|
|
29
38
|
import Icon from '../Icon';
|
|
39
|
+
import { tooltip } from '../../../directives';
|
|
30
40
|
import { InjectionTokens } from './injectionTokens';
|
|
31
41
|
import { useDropdownEntityTitle } from './composables';
|
|
32
42
|
|
|
@@ -38,6 +48,10 @@ export default {
|
|
|
38
48
|
Button
|
|
39
49
|
},
|
|
40
50
|
|
|
51
|
+
directives: {
|
|
52
|
+
tooltip
|
|
53
|
+
},
|
|
54
|
+
|
|
41
55
|
model: {
|
|
42
56
|
event: 'change'
|
|
43
57
|
},
|
|
@@ -47,6 +61,12 @@ export default {
|
|
|
47
61
|
type: String,
|
|
48
62
|
required: false,
|
|
49
63
|
default: 'none'
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
isCustomized: {
|
|
67
|
+
type: Boolean,
|
|
68
|
+
required: false,
|
|
69
|
+
default: false
|
|
50
70
|
}
|
|
51
71
|
},
|
|
52
72
|
|
|
@@ -77,10 +97,6 @@ export default {
|
|
|
77
97
|
width: 100%;
|
|
78
98
|
}
|
|
79
99
|
|
|
80
|
-
.zw-dropdown__activator-title {
|
|
81
|
-
margin-right: var(--zw-offset-xs);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
100
|
.zw-dropdown__activator-arrow {
|
|
85
101
|
margin-left: auto;
|
|
86
102
|
}
|
|
@@ -94,4 +110,9 @@ export default {
|
|
|
94
110
|
font-size: var(--zw-font-size-xxs);
|
|
95
111
|
color: rgb(var(--zw-color-white));
|
|
96
112
|
}
|
|
113
|
+
|
|
114
|
+
.zw-dropdown__customized-indicator {
|
|
115
|
+
position: relative;
|
|
116
|
+
top: calc(0px - var(--zw-offset-xs));
|
|
117
|
+
}
|
|
97
118
|
</style>
|
|
@@ -4,6 +4,10 @@ import DropdownActivator from '../DropdownActivator';
|
|
|
4
4
|
import { InjectionTokens } from '../injectionTokens';
|
|
5
5
|
import Button from '../../Button';
|
|
6
6
|
|
|
7
|
+
const SELECTORS = {
|
|
8
|
+
INDICATOR: '[data-test-selector="customizedIndicator"]'
|
|
9
|
+
};
|
|
10
|
+
|
|
7
11
|
const createToggler = ({ isOpened } = {}) => ({
|
|
8
12
|
isOpened: ref(isOpened ?? false),
|
|
9
13
|
open: jest.fn()
|
|
@@ -13,8 +17,12 @@ const createActiveOptionManager = ({ activeOption } = {}) => ({
|
|
|
13
17
|
activeOption: ref(activeOption ?? { id: 'test' })
|
|
14
18
|
});
|
|
15
19
|
|
|
16
|
-
function createComponent({ toggler, activeOptionManager } = {}) {
|
|
20
|
+
function createComponent({ toggler, isCustomized, activeOptionManager } = {}) {
|
|
17
21
|
return shallowMount(DropdownActivator, {
|
|
22
|
+
propsData: {
|
|
23
|
+
isCustomized: ref(isCustomized ?? false)
|
|
24
|
+
},
|
|
25
|
+
|
|
18
26
|
provide: {
|
|
19
27
|
[InjectionTokens.TOGGLER]: toggler ?? createToggler(),
|
|
20
28
|
[InjectionTokens.ACTIVE_MANAGER]: activeOptionManager ?? createActiveOptionManager()
|
|
@@ -40,6 +48,20 @@ describe('rendering', () => {
|
|
|
40
48
|
expect(buttonWrapper.props('active')).toBe(false);
|
|
41
49
|
expect(buttonWrapper.classes('zw-dropdown__activator--active')).toBeFalsy();
|
|
42
50
|
});
|
|
51
|
+
|
|
52
|
+
test('should render indicator of customized styles', () => {
|
|
53
|
+
const toggler = createToggler({ isOpened: false });
|
|
54
|
+
const wrapper = createComponent({ toggler, isCustomized: true });
|
|
55
|
+
|
|
56
|
+
expect(wrapper).toVueContainComponent(SELECTORS.INDICATOR);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('should not render indicator of customized styles', () => {
|
|
60
|
+
const toggler = createToggler({ isOpened: false });
|
|
61
|
+
const wrapper = createComponent({ toggler });
|
|
62
|
+
|
|
63
|
+
expect(wrapper).not.toVueContainComponent(SELECTORS.INDICATOR);
|
|
64
|
+
});
|
|
43
65
|
});
|
|
44
66
|
|
|
45
67
|
describe('open dropdown', () => {
|
|
@@ -2,12 +2,21 @@
|
|
|
2
2
|
<ButtonToggle :value="currentValue" :options="$options.alignments" @change="apply">
|
|
3
3
|
<template #option="{ isActive, option, activate }">
|
|
4
4
|
<Button
|
|
5
|
+
class="zw-position--relative"
|
|
5
6
|
icon
|
|
6
7
|
skin="toolbar"
|
|
7
8
|
:active="isActive"
|
|
8
9
|
@click="activate"
|
|
9
10
|
v-tooltip="option.tooltip"
|
|
10
11
|
>
|
|
12
|
+
<Icon
|
|
13
|
+
v-if="isCustomized && isActive"
|
|
14
|
+
class="zw-button__customized-indicator"
|
|
15
|
+
name="indicator"
|
|
16
|
+
size="9px"
|
|
17
|
+
data-test-selector="customizedIndicator"
|
|
18
|
+
v-tooltip.xs="'Default parameter setting is changed'"
|
|
19
|
+
/>
|
|
11
20
|
<Icon :name="`alignment-${option.id}`" size="28px" auto-color />
|
|
12
21
|
</Button>
|
|
13
22
|
</template>
|
|
@@ -17,7 +26,7 @@
|
|
|
17
26
|
<script>
|
|
18
27
|
import { inject } from 'vue';
|
|
19
28
|
import { InjectionTokens } from '../../../injectionTokens';
|
|
20
|
-
import { Alignments } from '../../../enums';
|
|
29
|
+
import { Alignments, TextSettings } from '../../../enums';
|
|
21
30
|
import { ButtonToggle, Button, Icon } from '../../base';
|
|
22
31
|
import { tooltip } from '../../../directives';
|
|
23
32
|
|
|
@@ -57,6 +66,7 @@ export default {
|
|
|
57
66
|
const editor = inject(InjectionTokens.EDITOR);
|
|
58
67
|
|
|
59
68
|
const currentValue = editor.commands.getAlignment();
|
|
69
|
+
const isCustomized = editor.commands.isSettingCustomized('attributes', TextSettings.ALIGNMENT);
|
|
60
70
|
|
|
61
71
|
function apply(value) {
|
|
62
72
|
editor.chain().focus().applyAlignment(value).run();
|
|
@@ -65,6 +75,7 @@ export default {
|
|
|
65
75
|
|
|
66
76
|
return {
|
|
67
77
|
currentValue,
|
|
78
|
+
isCustomized,
|
|
68
79
|
apply
|
|
69
80
|
};
|
|
70
81
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
<ColorPicker :value="currentValue" @change="apply">
|
|
3
3
|
<template #activator="{ toggle, isOpened }">
|
|
4
4
|
<Button
|
|
5
|
+
class="zw-position--relative"
|
|
5
6
|
icon
|
|
6
7
|
skin="toolbar"
|
|
7
8
|
:active="isOpened"
|
|
@@ -9,6 +10,15 @@
|
|
|
9
10
|
v-tooltip="'Font Color'"
|
|
10
11
|
>
|
|
11
12
|
<Icon name="font-color" size="28px" auto-color />
|
|
13
|
+
|
|
14
|
+
<Icon
|
|
15
|
+
v-if="isCustomized"
|
|
16
|
+
class="zw-button__customized-indicator"
|
|
17
|
+
name="indicator"
|
|
18
|
+
size="9px"
|
|
19
|
+
data-test-selector="customizedIndicator"
|
|
20
|
+
v-tooltip.xs="'Default parameter setting is changed'"
|
|
21
|
+
/>
|
|
12
22
|
</Button>
|
|
13
23
|
</template>
|
|
14
24
|
</ColorPicker>
|
|
@@ -19,6 +29,7 @@ import { inject } from 'vue';
|
|
|
19
29
|
import { ColorPicker, Button, Icon } from '../../base';
|
|
20
30
|
import { InjectionTokens } from '../../../injectionTokens';
|
|
21
31
|
import { tooltip } from '../../../directives';
|
|
32
|
+
import { TextSettings } from '../../../enums';
|
|
22
33
|
|
|
23
34
|
export default {
|
|
24
35
|
name: 'FontColorControl',
|
|
@@ -37,10 +48,13 @@ export default {
|
|
|
37
48
|
const editor = inject(InjectionTokens.EDITOR);
|
|
38
49
|
|
|
39
50
|
const currentValue = editor.commands.getFontColor();
|
|
51
|
+
const isCustomized = editor.commands.isSettingCustomized('marks', TextSettings.FONT_COLOR);
|
|
52
|
+
|
|
40
53
|
const apply = (color) => editor.chain().applyFontColor(color).run();
|
|
41
54
|
|
|
42
55
|
return {
|
|
43
56
|
currentValue,
|
|
57
|
+
isCustomized,
|
|
44
58
|
apply
|
|
45
59
|
};
|
|
46
60
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
class="zw-font-family-control"
|
|
4
4
|
:options="options"
|
|
5
5
|
:value="currentValue"
|
|
6
|
+
:is-customized="isCustomized"
|
|
6
7
|
@change="apply"
|
|
7
8
|
v-tooltip="'Font Name'"
|
|
8
9
|
>
|
|
@@ -22,6 +23,7 @@ import { computed, inject } from 'vue';
|
|
|
22
23
|
import { InjectionTokens } from '../../../injectionTokens';
|
|
23
24
|
import { tooltip } from '../../../directives';
|
|
24
25
|
import { Dropdown, DropdownOption } from '../../base';
|
|
26
|
+
import { TextSettings } from '../../../enums';
|
|
25
27
|
import { useRecentFonts } from './composables';
|
|
26
28
|
|
|
27
29
|
export default {
|
|
@@ -67,6 +69,7 @@ export default {
|
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
const currentValue = editor.commands.getFontFamily();
|
|
72
|
+
const isCustomized = editor.commands.isSettingCustomized('marks', TextSettings.FONT_FAMILY);
|
|
70
73
|
|
|
71
74
|
const apply = (fontFamily) => {
|
|
72
75
|
recentFontNames.add(fontFamily);
|
|
@@ -76,6 +79,7 @@ export default {
|
|
|
76
79
|
return {
|
|
77
80
|
options,
|
|
78
81
|
currentValue,
|
|
82
|
+
isCustomized,
|
|
79
83
|
renderOptionStyles,
|
|
80
84
|
apply
|
|
81
85
|
};
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
class="zw-font-size-control"
|
|
4
4
|
:options="options"
|
|
5
5
|
:value="currentValue"
|
|
6
|
+
:is-customized="isCustomized"
|
|
6
7
|
@change="apply"
|
|
7
8
|
v-tooltip="{ text: 'Font Size', hotkey: 'Mod Shift +/-' }"
|
|
8
9
|
/>
|
|
@@ -13,6 +14,7 @@ import { computed, inject } from 'vue';
|
|
|
13
14
|
import { Dropdown } from '../../base';
|
|
14
15
|
import { InjectionTokens } from '../../../injectionTokens';
|
|
15
16
|
import { tooltip } from '../../../directives';
|
|
17
|
+
import { TextSettings } from '../../../enums';
|
|
16
18
|
|
|
17
19
|
export default {
|
|
18
20
|
name: 'FontSizeControl',
|
|
@@ -34,11 +36,14 @@ export default {
|
|
|
34
36
|
});
|
|
35
37
|
|
|
36
38
|
const currentValue = editor.commands.getFontSize();
|
|
39
|
+
const isCustomized = editor.commands.isSettingCustomized('marks', TextSettings.FONT_SIZE);
|
|
40
|
+
|
|
37
41
|
const apply = (value) => editor.chain().focus().applyFontSize(value).run();
|
|
38
42
|
|
|
39
43
|
return {
|
|
40
44
|
options,
|
|
41
45
|
currentValue,
|
|
46
|
+
isCustomized,
|
|
42
47
|
apply
|
|
43
48
|
};
|
|
44
49
|
}
|
|
@@ -47,6 +52,6 @@ export default {
|
|
|
47
52
|
|
|
48
53
|
<style scoped>
|
|
49
54
|
.zw-font-size-control {
|
|
50
|
-
width:
|
|
55
|
+
width: 72px;
|
|
51
56
|
}
|
|
52
57
|
</style>
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<Dropdown
|
|
3
|
+
class="zw-font-weight-control"
|
|
3
4
|
:options="options"
|
|
4
5
|
:value="currentValue"
|
|
6
|
+
:is-customized="isCustomized"
|
|
5
7
|
@change="apply"
|
|
6
8
|
v-tooltip="{ text: 'Font Weight', hotkey: 'Mod B' }"
|
|
7
9
|
/>
|
|
@@ -12,6 +14,7 @@ import { computed, inject, unref } from 'vue';
|
|
|
12
14
|
import { InjectionTokens } from '../../../injectionTokens';
|
|
13
15
|
import { Dropdown } from '../../base';
|
|
14
16
|
import { tooltip } from '../../../directives';
|
|
17
|
+
import { TextSettings } from '../../../enums';
|
|
15
18
|
|
|
16
19
|
export default {
|
|
17
20
|
name: 'FontWeightControl',
|
|
@@ -29,15 +32,24 @@ export default {
|
|
|
29
32
|
const font = editor.commands.getFont();
|
|
30
33
|
|
|
31
34
|
const options = computed(() => unref(font).weights.map((style) => ({ id: style })));
|
|
35
|
+
|
|
32
36
|
const currentValue = editor.commands.getFontWeight();
|
|
37
|
+
const isCustomized = editor.commands.isSettingCustomized('marks', TextSettings.FONT_WEIGHT);
|
|
33
38
|
|
|
34
39
|
const apply = (value) => editor.chain().focus().applyFontWeight(value).run();
|
|
35
40
|
|
|
36
41
|
return {
|
|
37
42
|
options,
|
|
38
43
|
currentValue,
|
|
44
|
+
isCustomized,
|
|
39
45
|
apply
|
|
40
46
|
};
|
|
41
47
|
}
|
|
42
48
|
};
|
|
43
49
|
</script>
|
|
50
|
+
|
|
51
|
+
<style scoped>
|
|
52
|
+
.zw-font-weight-control {
|
|
53
|
+
width: 60px;
|
|
54
|
+
}
|
|
55
|
+
</style>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<Button
|
|
3
|
+
class="zw-position--relative"
|
|
3
4
|
skin="toolbar"
|
|
4
5
|
icon
|
|
5
6
|
:active="currentValue"
|
|
@@ -8,6 +9,15 @@
|
|
|
8
9
|
v-tooltip="{ text: 'Italic', hotkey: 'Mod I' }"
|
|
9
10
|
>
|
|
10
11
|
<Icon name="italic" size="28px" auto-color />
|
|
12
|
+
|
|
13
|
+
<Icon
|
|
14
|
+
v-if="isCustomized"
|
|
15
|
+
class="zw-button__customized-indicator"
|
|
16
|
+
name="indicator"
|
|
17
|
+
size="9px"
|
|
18
|
+
data-test-selector="customizedIndicator"
|
|
19
|
+
v-tooltip.xs="'Default parameter setting is changed'"
|
|
20
|
+
/>
|
|
11
21
|
</Button>
|
|
12
22
|
</template>
|
|
13
23
|
|
|
@@ -16,6 +26,7 @@ import { inject } from 'vue';
|
|
|
16
26
|
import { Button, Icon } from '../../base';
|
|
17
27
|
import { InjectionTokens } from '../../../injectionTokens';
|
|
18
28
|
import { tooltip } from '../../../directives';
|
|
29
|
+
import { TextSettings } from '../../../enums';
|
|
19
30
|
|
|
20
31
|
export default {
|
|
21
32
|
name: 'ItalicControl',
|
|
@@ -33,12 +44,15 @@ export default {
|
|
|
33
44
|
const editor = inject(InjectionTokens.EDITOR);
|
|
34
45
|
|
|
35
46
|
const currentValue = editor.commands.isItalic();
|
|
47
|
+
const isCustomized = editor.commands.isSettingCustomized('marks', TextSettings.FONT_STYLE);
|
|
48
|
+
|
|
36
49
|
const isAvailable = editor.commands.isItalicAvailable();
|
|
37
50
|
const apply = () => editor.chain().focus().toggleItalic().run();
|
|
38
51
|
|
|
39
52
|
return {
|
|
40
53
|
isAvailable,
|
|
41
54
|
currentValue,
|
|
55
|
+
isCustomized,
|
|
42
56
|
apply
|
|
43
57
|
};
|
|
44
58
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="zw-position--relative" ref="wrapperRef">
|
|
3
3
|
<Button
|
|
4
|
+
class="zw-position--relative"
|
|
4
5
|
icon
|
|
5
6
|
skin="toolbar"
|
|
6
7
|
:active="isOpened"
|
|
@@ -8,6 +9,15 @@
|
|
|
8
9
|
v-tooltip="'Line Height'"
|
|
9
10
|
>
|
|
10
11
|
<Icon name="line-height" size="28px" auto-color />
|
|
12
|
+
|
|
13
|
+
<Icon
|
|
14
|
+
v-if="isCustomized"
|
|
15
|
+
class="zw-button__customized-indicator"
|
|
16
|
+
name="indicator"
|
|
17
|
+
size="9px"
|
|
18
|
+
data-test-selector="customizedIndicator"
|
|
19
|
+
v-tooltip.xs="'Default parameter setting is changed'"
|
|
20
|
+
/>
|
|
11
21
|
</Button>
|
|
12
22
|
|
|
13
23
|
<Modal class="zw-line-height-control__modal" ref="modalRef" :toggler="toggler">
|
|
@@ -44,6 +54,7 @@ import { inject, ref } from 'vue';
|
|
|
44
54
|
import { Button, Icon, Modal, Range, NumberField, FieldLabel, useModalToggler } from '../../base';
|
|
45
55
|
import { InjectionTokens } from '../../../injectionTokens';
|
|
46
56
|
import { tooltip } from '../../../directives';
|
|
57
|
+
import { TextSettings } from '../../../enums';
|
|
47
58
|
|
|
48
59
|
export default {
|
|
49
60
|
name: 'LineHeightControl',
|
|
@@ -66,13 +77,17 @@ export default {
|
|
|
66
77
|
const modalRef = ref(null);
|
|
67
78
|
const editor = inject(InjectionTokens.EDITOR);
|
|
68
79
|
const toggler = useModalToggler({ wrapperRef, modalRef });
|
|
80
|
+
|
|
69
81
|
const currentValue = editor.commands.getLineHeight();
|
|
82
|
+
const isCustomized = editor.commands.isSettingCustomized('attributes', TextSettings.LINE_HEIGHT);
|
|
83
|
+
|
|
70
84
|
const apply = (value) => editor.commands.applyLineHeight(String(value));
|
|
71
85
|
|
|
72
86
|
return {
|
|
73
87
|
wrapperRef,
|
|
74
88
|
modalRef,
|
|
75
89
|
isOpened: toggler.isOpened,
|
|
90
|
+
isCustomized,
|
|
76
91
|
toggler,
|
|
77
92
|
currentValue,
|
|
78
93
|
apply
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<Button
|
|
3
|
+
class="zw-position--relative"
|
|
3
4
|
skin="toolbar"
|
|
4
5
|
icon
|
|
5
6
|
:active="currentValue"
|
|
@@ -7,6 +8,15 @@
|
|
|
7
8
|
v-tooltip="{ text: 'Underline', hotkey: 'Mod U' }"
|
|
8
9
|
>
|
|
9
10
|
<Icon name="underline" size="28px" auto-color />
|
|
11
|
+
|
|
12
|
+
<Icon
|
|
13
|
+
v-if="isCustomized"
|
|
14
|
+
class="zw-button__customized-indicator"
|
|
15
|
+
name="indicator"
|
|
16
|
+
size="9px"
|
|
17
|
+
data-test-selector="customizedIndicator"
|
|
18
|
+
v-tooltip.xs="'Default parameter setting is changed'"
|
|
19
|
+
/>
|
|
10
20
|
</Button>
|
|
11
21
|
</template>
|
|
12
22
|
|
|
@@ -32,10 +42,13 @@ export default {
|
|
|
32
42
|
const editor = inject(InjectionTokens.EDITOR);
|
|
33
43
|
|
|
34
44
|
const currentValue = editor.commands.isUnderline();
|
|
45
|
+
const isCustomized = editor.commands.isUnderlineCustomized();
|
|
46
|
+
|
|
35
47
|
const apply = () => editor.chain().focus().toggleUnderline().run();
|
|
36
48
|
|
|
37
49
|
return {
|
|
38
50
|
currentValue,
|
|
51
|
+
isCustomized,
|
|
39
52
|
apply
|
|
40
53
|
};
|
|
41
54
|
}
|
|
@@ -5,9 +5,14 @@ import { Alignments } from '../../../../enums';
|
|
|
5
5
|
import { ButtonToggle } from '../../../base';
|
|
6
6
|
import AlignmentControl from '../AlignmentControl';
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const SELECTORS = {
|
|
9
|
+
INDICATOR: '[data-test-selector="customizedIndicator"]'
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const createEditor = ({ alignment, isSettingCustomized } = {}) => ({
|
|
9
13
|
commands: {
|
|
10
14
|
getAlignment: () => ref(alignment),
|
|
15
|
+
isSettingCustomized: () => ref(isSettingCustomized ?? false),
|
|
11
16
|
focus: jest.fn().mockReturnThis(),
|
|
12
17
|
applyAlignment: jest.fn().mockReturnThis(),
|
|
13
18
|
run: jest.fn()
|
|
@@ -18,11 +23,18 @@ const createEditor = ({ alignment } = {}) => ({
|
|
|
18
23
|
}
|
|
19
24
|
});
|
|
20
25
|
|
|
21
|
-
function createComponent({ editor }) {
|
|
26
|
+
function createComponent({ editor, slotParams }) {
|
|
22
27
|
return shallowMount(AlignmentControl, {
|
|
23
28
|
stubs: {
|
|
24
29
|
ButtonToggle: {
|
|
25
|
-
render
|
|
30
|
+
render() {
|
|
31
|
+
const children = this.$scopedSlots.option({
|
|
32
|
+
...slotParams,
|
|
33
|
+
activate: jest.fn()
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
return h('div', null, children);
|
|
37
|
+
},
|
|
26
38
|
props: ['value']
|
|
27
39
|
}
|
|
28
40
|
},
|
|
@@ -33,7 +45,16 @@ function createComponent({ editor }) {
|
|
|
33
45
|
describe('selection value', () => {
|
|
34
46
|
test('should render value from selection', () => {
|
|
35
47
|
const editor = createEditor({ alignment: Alignments.RIGHT });
|
|
36
|
-
const wrapper = createComponent({
|
|
48
|
+
const wrapper = createComponent({
|
|
49
|
+
editor,
|
|
50
|
+
slotParams: {
|
|
51
|
+
option: {
|
|
52
|
+
id: Alignments.RIGHT,
|
|
53
|
+
tooltip: { text: 'Align Right', hotkey: 'Mod Shift R' }
|
|
54
|
+
},
|
|
55
|
+
isActive: true
|
|
56
|
+
}
|
|
57
|
+
});
|
|
37
58
|
const buttonWrapper = wrapper.findComponent(ButtonToggle);
|
|
38
59
|
|
|
39
60
|
expect(buttonWrapper.props('value')).toBe(Alignments.RIGHT);
|
|
@@ -41,7 +62,16 @@ describe('selection value', () => {
|
|
|
41
62
|
|
|
42
63
|
test('should apply new value', () => {
|
|
43
64
|
const editor = createEditor({ alignment: Alignments.RIGHT });
|
|
44
|
-
const wrapper = createComponent({
|
|
65
|
+
const wrapper = createComponent({
|
|
66
|
+
editor,
|
|
67
|
+
slotParams: {
|
|
68
|
+
option: {
|
|
69
|
+
id: Alignments.RIGHT,
|
|
70
|
+
tooltip: { text: 'Align Right', hotkey: 'Mod Shift R' }
|
|
71
|
+
},
|
|
72
|
+
isActive: true
|
|
73
|
+
}
|
|
74
|
+
});
|
|
45
75
|
const buttonWrapper = wrapper.findComponent(ButtonToggle);
|
|
46
76
|
|
|
47
77
|
buttonWrapper.vm.$emit('change', Alignments.CENTER);
|
|
@@ -49,3 +79,40 @@ describe('selection value', () => {
|
|
|
49
79
|
expect(editor.commands.applyAlignment).toHaveBeenCalledWith(Alignments.CENTER);
|
|
50
80
|
});
|
|
51
81
|
});
|
|
82
|
+
|
|
83
|
+
describe('render indicator of customized styles', () => {
|
|
84
|
+
test('should render indicator', () => {
|
|
85
|
+
const editor = createEditor({
|
|
86
|
+
alignment: Alignments.LEFT,
|
|
87
|
+
isSettingCustomized: true
|
|
88
|
+
});
|
|
89
|
+
const wrapper = createComponent({
|
|
90
|
+
editor,
|
|
91
|
+
slotParams: {
|
|
92
|
+
option: {
|
|
93
|
+
id: Alignments.LEFT,
|
|
94
|
+
tooltip: { text: 'Align Left', hotkey: 'Mod Shift L' }
|
|
95
|
+
},
|
|
96
|
+
isActive: true
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
expect(wrapper).toVueContainComponent(SELECTORS.INDICATOR);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test('should not render indicator', () => {
|
|
104
|
+
const editor = createEditor({ alignment: Alignments.LEFT });
|
|
105
|
+
const wrapper = createComponent({
|
|
106
|
+
editor,
|
|
107
|
+
slotParams: {
|
|
108
|
+
option: {
|
|
109
|
+
id: Alignments.LEFT,
|
|
110
|
+
tooltip: { text: 'Align Left', hotkey: 'Mod Shift L' }
|
|
111
|
+
},
|
|
112
|
+
isActive: true
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
expect(wrapper).not.toVueContainComponent(SELECTORS.INDICATOR);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
@@ -4,9 +4,14 @@ import { InjectionTokens } from '../../../../injectionTokens';
|
|
|
4
4
|
import { ColorPicker } from '../../../base';
|
|
5
5
|
import FontColorControl from '../FontColorControl';
|
|
6
6
|
|
|
7
|
-
const
|
|
7
|
+
const SELECTORS = {
|
|
8
|
+
INDICATOR: '[data-test-selector="customizedIndicator"]'
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const createEditor = ({ fontColor, isSettingCustomized } = {}) => ({
|
|
8
12
|
commands: {
|
|
9
13
|
getFontColor: () => ref(fontColor),
|
|
14
|
+
isSettingCustomized: () => ref( isSettingCustomized ?? false),
|
|
10
15
|
focus: jest.fn().mockReturnThis(),
|
|
11
16
|
applyFontColor: jest.fn().mockReturnThis(),
|
|
12
17
|
run: jest.fn()
|
|
@@ -57,3 +62,19 @@ describe('selection value', () => {
|
|
|
57
62
|
expect(editor.commands.applyFontColor).toHaveBeenCalledWith('green');
|
|
58
63
|
});
|
|
59
64
|
});
|
|
65
|
+
|
|
66
|
+
describe('render indicator of customized styles', () => {
|
|
67
|
+
test('should render indicator', () => {
|
|
68
|
+
const editor = createEditor({ fontColor: 'red', isSettingCustomized: true });
|
|
69
|
+
const wrapper = createComponent({ editor });
|
|
70
|
+
|
|
71
|
+
expect(wrapper).toVueContainComponent(SELECTORS.INDICATOR);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('should not render indicator', () => {
|
|
75
|
+
const editor = createEditor({ fontColor: 'red' });
|
|
76
|
+
const wrapper = createComponent({ editor });
|
|
77
|
+
|
|
78
|
+
expect(wrapper).not.toVueContainComponent(SELECTORS.INDICATOR);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -7,6 +7,7 @@ import FontFamilyControl from '../FontFamilyControl';
|
|
|
7
7
|
const createEditor = ({ fontFamily } = {}) => ({
|
|
8
8
|
commands: {
|
|
9
9
|
getFontFamily: () => ref(fontFamily),
|
|
10
|
+
isSettingCustomized: () => ref(false),
|
|
10
11
|
focus: jest.fn().mockReturnThis(),
|
|
11
12
|
applyFontFamily: jest.fn().mockReturnThis(),
|
|
12
13
|
run: jest.fn()
|
|
@@ -7,6 +7,7 @@ import FontSizeControl from '../FontSizeControl';
|
|
|
7
7
|
const createEditor = ({ fontSize } = {}) => ({
|
|
8
8
|
commands: {
|
|
9
9
|
getFontSize: () => ref(fontSize),
|
|
10
|
+
isSettingCustomized: () => ref(false),
|
|
10
11
|
focus: jest.fn().mockReturnThis(),
|
|
11
12
|
applyFontSize: jest.fn().mockReturnThis(),
|
|
12
13
|
run: jest.fn()
|
|
@@ -7,6 +7,7 @@ import FontWeightControl from '../FontWeightControl';
|
|
|
7
7
|
const createEditor = ({ fontWeight, fontWeightList } = {}) => ({
|
|
8
8
|
commands: {
|
|
9
9
|
getFontWeight: () => ref(fontWeight ?? '400'),
|
|
10
|
+
isSettingCustomized: () => ref(false),
|
|
10
11
|
getFont: () => ref({ weights: fontWeightList ?? ['400', '700'] }),
|
|
11
12
|
focus: jest.fn().mockReturnThis(),
|
|
12
13
|
applyFontWeight: jest.fn().mockReturnThis(),
|