@zipify/wysiwyg 1.0.0-dev.3 → 1.0.0-dev.6
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/.eslintignore +1 -0
- package/.stylelintignore +1 -0
- package/README.md +3 -1
- package/config/jest/setupTests.js +7 -1
- package/config/webpack/example.config.js +2 -0
- package/config/webpack/lib.config.js +40 -0
- package/config/webpack/loaders/style-loader.js +3 -1
- package/config/webpack/loaders/svg-loader.js +1 -1
- package/dist/wysiwyg.css +837 -0
- package/dist/wysiwyg.js +2 -0
- package/dist/wysiwyg.js.LICENSE.txt +1 -0
- package/example/ExampleApp.vue +39 -31
- package/example/example.js +26 -0
- package/example/presets.js +2 -0
- package/lib/Wysiwyg.vue +6 -0
- package/lib/assets/icons/alignment-center.svg +3 -0
- package/lib/assets/icons/alignment-justify.svg +3 -0
- package/lib/assets/icons/alignment-left.svg +3 -0
- package/lib/assets/icons/alignment-right.svg +3 -0
- package/lib/assets/icons/arrow.svg +3 -0
- package/lib/assets/icons/background-color.svg +3 -0
- package/lib/assets/icons/case-style.svg +3 -0
- package/lib/assets/icons/font-color.svg +5 -0
- package/lib/assets/icons/italic.svg +3 -0
- package/lib/assets/icons/line-height.svg +3 -0
- package/lib/assets/icons/list-circle.svg +3 -0
- package/lib/assets/icons/list-decimal.svg +3 -0
- package/lib/assets/icons/list-disc.svg +3 -0
- package/lib/assets/icons/list-latin.svg +3 -0
- package/lib/assets/icons/list-roman.svg +3 -0
- package/lib/assets/icons/list-square.svg +3 -0
- package/lib/assets/icons/remove-format.svg +3 -0
- package/lib/assets/icons/reset-styles.svg +3 -0
- package/lib/assets/icons/strike-through.svg +3 -0
- package/lib/assets/icons/superscript.svg +3 -0
- package/lib/assets/icons/underline.svg +3 -0
- package/lib/components/base/Icon.vue +17 -9
- package/lib/components/base/__tests__/Icon.test.js +6 -13
- package/lib/composables/__tests__/useEditor.test.js +12 -3
- package/lib/composables/useEditor.js +12 -5
- package/lib/extensions/Alignment.js +6 -0
- package/lib/extensions/BackgroundColor.js +8 -1
- package/lib/extensions/FontColor.js +8 -1
- package/lib/extensions/FontFamily.js +7 -0
- package/lib/extensions/FontSize.js +12 -0
- package/lib/extensions/FontStyle.js +11 -0
- package/lib/extensions/FontWeight.js +25 -1
- package/lib/extensions/LineHeight.js +17 -0
- package/lib/extensions/StylePreset.js +30 -3
- package/lib/extensions/TextDecoration.js +11 -0
- package/lib/extensions/__tests__/Alignment.test.js +22 -1
- package/lib/extensions/__tests__/BackgroundColor.test.js +30 -1
- package/lib/extensions/__tests__/CaseStyle.test.js +4 -1
- package/lib/extensions/__tests__/FontColor.test.js +30 -1
- package/lib/extensions/__tests__/FontFamily.test.js +30 -1
- package/lib/extensions/__tests__/FontSize.test.js +30 -1
- package/lib/extensions/__tests__/FontStyle.test.js +38 -1
- package/lib/extensions/__tests__/FontWeight.test.js +58 -1
- package/lib/extensions/__tests__/LineHeight.test.js +41 -1
- package/lib/extensions/__tests__/StylePreset.test.js +76 -1
- package/lib/extensions/__tests__/TextDecoration.test.js +63 -1
- package/lib/extensions/__tests__/__snapshots__/Alignment.test.js.snap +44 -0
- package/lib/extensions/__tests__/__snapshots__/BackgroundColor.test.js.snap +91 -0
- package/lib/extensions/__tests__/__snapshots__/FontColor.test.js.snap +91 -0
- package/lib/extensions/__tests__/__snapshots__/FontFamily.test.js.snap +91 -0
- package/lib/extensions/__tests__/__snapshots__/FontSize.test.js.snap +99 -0
- package/lib/extensions/__tests__/__snapshots__/FontStyle.test.js.snap +120 -0
- package/lib/extensions/__tests__/__snapshots__/FontWeight.test.js.snap +149 -0
- package/lib/extensions/__tests__/__snapshots__/LineHeight.test.js.snap +92 -0
- package/lib/extensions/__tests__/__snapshots__/StylePreset.test.js.snap +167 -2
- package/lib/extensions/__tests__/__snapshots__/TextDecoration.test.js.snap +207 -0
- package/lib/extensions/core/__tests__/NodeProcessor.test.js +4 -1
- package/lib/extensions/core/__tests__/SelectionProcessor.test.js +9 -4
- package/lib/extensions/core/__tests__/TextProcessor.test.js +4 -1
- package/lib/extensions/index.js +1 -0
- package/lib/extensions/list/List.js +34 -0
- package/lib/extensions/list/__tests__/List.test.js +115 -3
- package/lib/extensions/list/__tests__/__snapshots__/List.test.js.snap +457 -6
- package/lib/services/ContentNormalizer.js +113 -0
- package/lib/services/Storage.js +1 -13
- package/lib/services/__tests__/ContentNormalizer.test.js +41 -0
- package/lib/services/__tests__/FavoriteColors.test.js +20 -0
- package/lib/services/__tests__/JsonSerializer.test.js +23 -0
- package/lib/services/__tests__/Storage.test.js +79 -0
- package/lib/services/index.js +1 -0
- package/lib/utils/__tests__/convertColor.test.js +19 -0
- package/lib/utils/__tests__/createKeyboardShortcut.test.js +25 -0
- package/lib/utils/__tests__/renderInlineSetting.test.js +26 -0
- package/lib/utils/convertColor.js +7 -0
- package/lib/utils/importIcon.js +12 -0
- package/lib/utils/index.js +2 -0
- package/lib/utils/renderInlineSetting.js +1 -1
- package/package.json +8 -5
- package/lib/assets/icons.svg +0 -69
|
@@ -19,6 +19,23 @@ export const LineHeight = Extension.create({
|
|
|
19
19
|
[TextSettings.LINE_HEIGHT]: {
|
|
20
20
|
isRequired: false,
|
|
21
21
|
|
|
22
|
+
parseHTML(element) {
|
|
23
|
+
const value = element.style.lineHeight;
|
|
24
|
+
|
|
25
|
+
if (!value) return null;
|
|
26
|
+
|
|
27
|
+
if (!value.includes('px')) {
|
|
28
|
+
return { desktop: value, tablet: value, mobile: value };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// element is not connected to window so getComputedStyle is not working on element
|
|
32
|
+
const childFontSize = element.firstElementChild.style.fontSize;
|
|
33
|
+
const fontSize = childFontSize || window.getComputedStyle(document.body).fontSize;
|
|
34
|
+
const relative = (parseFloat(value) / parseFloat(fontSize)).toFixed(2);
|
|
35
|
+
|
|
36
|
+
return { desktop: relative, tablet: relative, mobile: relative };
|
|
37
|
+
},
|
|
38
|
+
|
|
22
39
|
renderHTML(attrs) {
|
|
23
40
|
if (!attrs.line_height) return null;
|
|
24
41
|
|
|
@@ -4,6 +4,12 @@ import { Heading } from '@tiptap/extension-heading';
|
|
|
4
4
|
import { createCommand } from '../utils';
|
|
5
5
|
import { Devices, NodeTypes, TextSettings } from '../enums';
|
|
6
6
|
|
|
7
|
+
function makePresetClass(base, preset) {
|
|
8
|
+
const baseClass = base.split(' ').map((part) => `.${part}`).join('');
|
|
9
|
+
|
|
10
|
+
return baseClass + preset.id;
|
|
11
|
+
}
|
|
12
|
+
|
|
7
13
|
export const StylePreset = Extension.create({
|
|
8
14
|
name: 'style_preset',
|
|
9
15
|
|
|
@@ -17,6 +23,7 @@ export const StylePreset = Extension.create({
|
|
|
17
23
|
addOptions: () => ({
|
|
18
24
|
presetsRef: null,
|
|
19
25
|
defaultId: null,
|
|
26
|
+
baseClass: null,
|
|
20
27
|
makeVariable: null
|
|
21
28
|
}),
|
|
22
29
|
|
|
@@ -31,11 +38,30 @@ export const StylePreset = Extension.create({
|
|
|
31
38
|
attributes: {
|
|
32
39
|
preset: {
|
|
33
40
|
isRequired: false,
|
|
34
|
-
default:
|
|
41
|
+
default: null,
|
|
42
|
+
|
|
43
|
+
parseHTML: (element) => {
|
|
44
|
+
const presets = this.options.presetsRef.value;
|
|
45
|
+
|
|
46
|
+
for (const { id, node, fallbackClass } of presets) {
|
|
47
|
+
const isFallback = fallbackClass && element.classList.contains(fallbackClass);
|
|
48
|
+
|
|
49
|
+
if (isFallback) return { id };
|
|
50
|
+
|
|
51
|
+
const className = makePresetClass(this.options.baseClass, { id });
|
|
52
|
+
|
|
53
|
+
if (element.matches(className)) return { id };
|
|
54
|
+
if (element.tagName === `H${node?.level}`) return { id };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Matches all paragraphs without classes to default preset
|
|
58
|
+
return element.tagName === 'P' ? { id: this.options.defaultId } : null;
|
|
59
|
+
},
|
|
60
|
+
|
|
35
61
|
renderHTML: (attrs) => {
|
|
36
62
|
if (!attrs.preset) return null;
|
|
37
63
|
|
|
38
|
-
return { class:
|
|
64
|
+
return { class: this.options.baseClass + attrs.preset.id };
|
|
39
65
|
}
|
|
40
66
|
}
|
|
41
67
|
}
|
|
@@ -147,7 +173,8 @@ export const StylePreset = Extension.create({
|
|
|
147
173
|
this.storage.presetStyleEl.dataset.zwStyles = '';
|
|
148
174
|
|
|
149
175
|
for (const preset of this.options.presetsRef.value) {
|
|
150
|
-
const
|
|
176
|
+
const className = makePresetClass(this.options.baseClass, preset);
|
|
177
|
+
const css = [` ${className} {`];
|
|
151
178
|
|
|
152
179
|
for (const device of Devices.values) {
|
|
153
180
|
for (const setting of Object.keys(preset[device])) {
|
|
@@ -86,6 +86,17 @@ export const TextDecoration = Mark.create({
|
|
|
86
86
|
'Mod-U': createKeyboardShortcut('toggleUnderline')
|
|
87
87
|
}),
|
|
88
88
|
|
|
89
|
+
parseHTML: () => [
|
|
90
|
+
{
|
|
91
|
+
style: 'text-decoration-line',
|
|
92
|
+
|
|
93
|
+
getAttrs: (value) => ({
|
|
94
|
+
underline: value.includes('underline'),
|
|
95
|
+
strike_through: value.includes('line-through')
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
|
|
89
100
|
renderHTML({ HTMLAttributes: attrs }) {
|
|
90
101
|
const decorations = [];
|
|
91
102
|
|
|
@@ -6,6 +6,7 @@ import { CORE_EXTENSIONS } from '../core';
|
|
|
6
6
|
import { Alignment } from '../Alignment';
|
|
7
7
|
import { DeviceManager } from '../DeviceManager';
|
|
8
8
|
import { Alignments } from '../../enums';
|
|
9
|
+
import { ContentNormalizer } from '../../services';
|
|
9
10
|
|
|
10
11
|
const MockStylePreset = Extension.create({
|
|
11
12
|
name: 'style_preset',
|
|
@@ -22,8 +23,10 @@ const MockStylePreset = Extension.create({
|
|
|
22
23
|
});
|
|
23
24
|
|
|
24
25
|
function createEditor({ content }) {
|
|
26
|
+
const normalizer = new ContentNormalizer();
|
|
27
|
+
|
|
25
28
|
return new Editor({
|
|
26
|
-
content,
|
|
29
|
+
content: normalizer.normalize(content),
|
|
27
30
|
extensions: CORE_EXTENSIONS.concat(
|
|
28
31
|
MockStylePreset,
|
|
29
32
|
DeviceManager.configure({ deviceRef: ref('desktop') }),
|
|
@@ -105,3 +108,21 @@ describe('rendering', () => {
|
|
|
105
108
|
expect(editor.getHTML()).toMatchSnapshot();
|
|
106
109
|
});
|
|
107
110
|
});
|
|
111
|
+
|
|
112
|
+
describe('parsing html', () => {
|
|
113
|
+
test('should get alignment from text', () => {
|
|
114
|
+
const editor = createEditor({
|
|
115
|
+
content: '<p style="text-align:center">test</p>'
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test('should set null if no alignment', () => {
|
|
122
|
+
const editor = createEditor({
|
|
123
|
+
content: '<p>test</p>'
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
127
|
+
});
|
|
128
|
+
});
|
|
@@ -4,6 +4,7 @@ import { NodeFactory } from '../../__tests__/utils';
|
|
|
4
4
|
import { createCommand } from '../../utils';
|
|
5
5
|
import { CORE_EXTENSIONS } from '../core';
|
|
6
6
|
import { BackgroundColor } from '../BackgroundColor';
|
|
7
|
+
import { ContentNormalizer } from '../../services';
|
|
7
8
|
|
|
8
9
|
const MockStylePreset = Extension.create({
|
|
9
10
|
name: 'style_preset',
|
|
@@ -18,8 +19,10 @@ const MockStylePreset = Extension.create({
|
|
|
18
19
|
});
|
|
19
20
|
|
|
20
21
|
function createEditor({ content }) {
|
|
22
|
+
const normalizer = new ContentNormalizer();
|
|
23
|
+
|
|
21
24
|
return new Editor({
|
|
22
|
-
content,
|
|
25
|
+
content: normalizer.normalize(content),
|
|
23
26
|
extensions: CORE_EXTENSIONS.concat(MockStylePreset, BackgroundColor)
|
|
24
27
|
});
|
|
25
28
|
}
|
|
@@ -73,3 +76,29 @@ describe('rendering', () => {
|
|
|
73
76
|
expect(editor.getHTML()).toMatchSnapshot();
|
|
74
77
|
});
|
|
75
78
|
});
|
|
79
|
+
|
|
80
|
+
describe('parsing html', () => {
|
|
81
|
+
test('should get value from paragraph', () => {
|
|
82
|
+
const editor = createEditor({
|
|
83
|
+
content: '<p style="background-color: red">test</p>'
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('should get value from text', () => {
|
|
90
|
+
const editor = createEditor({
|
|
91
|
+
content: '<p><span style="background-color: red">lorem</span> ipsum</p>'
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test('should merge paragraph and text settings', () => {
|
|
98
|
+
const editor = createEditor({
|
|
99
|
+
content: '<p style="background-color: red"><span style="background-color: #000">lorem</span> ipsum</p>'
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
103
|
+
});
|
|
104
|
+
});
|
|
@@ -3,10 +3,13 @@ import { NodeFactory } from '../../__tests__/utils';
|
|
|
3
3
|
import { CaseStyles } from '../../enums';
|
|
4
4
|
import { CORE_EXTENSIONS } from '../core';
|
|
5
5
|
import { CaseStyle } from '../CaseStyle';
|
|
6
|
+
import { ContentNormalizer } from '../../services';
|
|
6
7
|
|
|
7
8
|
function createEditor({ content }) {
|
|
9
|
+
const normalizer = new ContentNormalizer();
|
|
10
|
+
|
|
8
11
|
return new Editor({
|
|
9
|
-
content,
|
|
12
|
+
content: normalizer.normalize(content),
|
|
10
13
|
extensions: CORE_EXTENSIONS.concat(CaseStyle)
|
|
11
14
|
});
|
|
12
15
|
}
|
|
@@ -4,6 +4,7 @@ import { NodeFactory } from '../../__tests__/utils';
|
|
|
4
4
|
import { createCommand } from '../../utils';
|
|
5
5
|
import { CORE_EXTENSIONS } from '../core';
|
|
6
6
|
import { FontColor } from '../FontColor';
|
|
7
|
+
import { ContentNormalizer } from '../../services';
|
|
7
8
|
|
|
8
9
|
const MockStylePreset = Extension.create({
|
|
9
10
|
name: 'style_preset',
|
|
@@ -18,8 +19,10 @@ const MockStylePreset = Extension.create({
|
|
|
18
19
|
});
|
|
19
20
|
|
|
20
21
|
function createEditor({ content }) {
|
|
22
|
+
const normalizer = new ContentNormalizer();
|
|
23
|
+
|
|
21
24
|
return new Editor({
|
|
22
|
-
content,
|
|
25
|
+
content: normalizer.normalize(content),
|
|
23
26
|
extensions: CORE_EXTENSIONS.concat(MockStylePreset, FontColor)
|
|
24
27
|
});
|
|
25
28
|
}
|
|
@@ -83,3 +86,29 @@ describe('rendering', () => {
|
|
|
83
86
|
expect(editor.getHTML()).toMatchSnapshot();
|
|
84
87
|
});
|
|
85
88
|
});
|
|
89
|
+
|
|
90
|
+
describe('parsing html', () => {
|
|
91
|
+
test('should get value from paragraph', () => {
|
|
92
|
+
const editor = createEditor({
|
|
93
|
+
content: '<p style="color: red">test</p>'
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test('should get value from text', () => {
|
|
100
|
+
const editor = createEditor({
|
|
101
|
+
content: '<p><span style="color: red">lorem</span> ipsum</p>'
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test('should merge paragraph and text settings', () => {
|
|
108
|
+
const editor = createEditor({
|
|
109
|
+
content: '<p style="color: red"><span style="color: #000">lorem</span> ipsum</p>'
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
113
|
+
});
|
|
114
|
+
});
|
|
@@ -7,6 +7,7 @@ import { Font } from '../../models';
|
|
|
7
7
|
import { FontFamily } from '../FontFamily';
|
|
8
8
|
import { FontWeight } from '../FontWeight';
|
|
9
9
|
import { FontStyle } from '../FontStyle';
|
|
10
|
+
import { ContentNormalizer } from '../../services';
|
|
10
11
|
|
|
11
12
|
const MockStylePreset = Extension.create({
|
|
12
13
|
name: 'style_preset',
|
|
@@ -24,8 +25,10 @@ const MockStylePreset = Extension.create({
|
|
|
24
25
|
});
|
|
25
26
|
|
|
26
27
|
function createEditor({ content }) {
|
|
28
|
+
const normalizer = new ContentNormalizer();
|
|
29
|
+
|
|
27
30
|
return new Editor({
|
|
28
|
-
content,
|
|
31
|
+
content: normalizer.normalize(content),
|
|
29
32
|
extensions: CORE_EXTENSIONS.concat(
|
|
30
33
|
MockStylePreset,
|
|
31
34
|
FontFamily.configure({
|
|
@@ -169,3 +172,29 @@ describe('rendering', () => {
|
|
|
169
172
|
expect(editor.getHTML()).toMatchSnapshot();
|
|
170
173
|
});
|
|
171
174
|
});
|
|
175
|
+
|
|
176
|
+
describe('parsing html', () => {
|
|
177
|
+
test('should get value from paragraph', () => {
|
|
178
|
+
const editor = createEditor({
|
|
179
|
+
content: '<p style="font-family: Lato">test</p>'
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
test('should get value from text', () => {
|
|
186
|
+
const editor = createEditor({
|
|
187
|
+
content: '<p><span style="font-family: Lato">lorem</span> ipsum</p>'
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
test('should merge paragraph and text settings', () => {
|
|
194
|
+
const editor = createEditor({
|
|
195
|
+
content: '<p style="font-family: Lato"><span style="font-family: Roboto">lorem</span> ipsum</p>'
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
199
|
+
});
|
|
200
|
+
});
|
|
@@ -5,6 +5,7 @@ import { createCommand } from '../../utils';
|
|
|
5
5
|
import { CORE_EXTENSIONS } from '../core';
|
|
6
6
|
import { FontSize } from '../FontSize';
|
|
7
7
|
import { DeviceManager } from '../DeviceManager';
|
|
8
|
+
import { ContentNormalizer } from '../../services';
|
|
8
9
|
|
|
9
10
|
const MockStylePreset = Extension.create({
|
|
10
11
|
name: 'style_preset',
|
|
@@ -21,8 +22,10 @@ const MockStylePreset = Extension.create({
|
|
|
21
22
|
});
|
|
22
23
|
|
|
23
24
|
function createEditor({ content }) {
|
|
25
|
+
const normalizer = new ContentNormalizer();
|
|
26
|
+
|
|
24
27
|
return new Editor({
|
|
25
|
-
content,
|
|
28
|
+
content: normalizer.normalize(content),
|
|
26
29
|
extensions: CORE_EXTENSIONS.concat(
|
|
27
30
|
MockStylePreset,
|
|
28
31
|
DeviceManager.configure({
|
|
@@ -181,3 +184,29 @@ describe('rendering', () => {
|
|
|
181
184
|
expect(editor.getHTML()).toMatchSnapshot();
|
|
182
185
|
});
|
|
183
186
|
});
|
|
187
|
+
|
|
188
|
+
describe('parsing html', () => {
|
|
189
|
+
test('should get value from paragraph', () => {
|
|
190
|
+
const editor = createEditor({
|
|
191
|
+
content: '<p style="font-size: 24px">test</p>'
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
test('should get value from text', () => {
|
|
198
|
+
const editor = createEditor({
|
|
199
|
+
content: '<p><span style="font-size: 24px">lorem</span> ipsum</p>'
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test('should merge paragraph and text settings', () => {
|
|
206
|
+
const editor = createEditor({
|
|
207
|
+
content: '<p style="font-size: 24px"><span style="font-size: 20px">lorem</span> ipsum</p>'
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
211
|
+
});
|
|
212
|
+
});
|
|
@@ -7,6 +7,7 @@ import { FontStyle } from '../FontStyle';
|
|
|
7
7
|
import { FontFamily } from '../FontFamily';
|
|
8
8
|
import { Font } from '../../models';
|
|
9
9
|
import { FontWeight } from '../FontWeight';
|
|
10
|
+
import { ContentNormalizer } from '../../services';
|
|
10
11
|
|
|
11
12
|
const MockStylePreset = Extension.create({
|
|
12
13
|
name: 'style_preset',
|
|
@@ -25,8 +26,10 @@ const MockStylePreset = Extension.create({
|
|
|
25
26
|
});
|
|
26
27
|
|
|
27
28
|
function createEditor({ content }) {
|
|
29
|
+
const normalizer = new ContentNormalizer();
|
|
30
|
+
|
|
28
31
|
return new Editor({
|
|
29
|
-
content,
|
|
32
|
+
content: normalizer.normalize(content),
|
|
30
33
|
extensions: CORE_EXTENSIONS.concat(
|
|
31
34
|
MockStylePreset,
|
|
32
35
|
FontStyle,
|
|
@@ -134,3 +137,37 @@ describe('rendering', () => {
|
|
|
134
137
|
expect(editor.getHTML()).toMatchSnapshot();
|
|
135
138
|
});
|
|
136
139
|
});
|
|
140
|
+
|
|
141
|
+
describe('parsing html', () => {
|
|
142
|
+
test('should get value from paragraph', () => {
|
|
143
|
+
const editor = createEditor({
|
|
144
|
+
content: '<p style="font-style: italic">test</p>'
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
test('should get value from text', () => {
|
|
151
|
+
const editor = createEditor({
|
|
152
|
+
content: '<p><span style="font-style: italic">lorem</span> ipsum</p>'
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
test('should get value from i tag', () => {
|
|
159
|
+
const editor = createEditor({
|
|
160
|
+
content: '<p><i>lorem</i> ipsum</p>'
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
test('should merge paragraph and text settings', () => {
|
|
167
|
+
const editor = createEditor({
|
|
168
|
+
content: '<p style="font-style: italic"><span style="font-style: normal">lorem</span> ipsum</p>'
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
172
|
+
});
|
|
173
|
+
});
|
|
@@ -7,6 +7,7 @@ import { Font } from '../../models';
|
|
|
7
7
|
import { FontWeight } from '../FontWeight';
|
|
8
8
|
import { FontFamily } from '../FontFamily';
|
|
9
9
|
import { FontStyle } from '../FontStyle';
|
|
10
|
+
import { ContentNormalizer } from '../../services';
|
|
10
11
|
|
|
11
12
|
const MockStylePreset = Extension.create({
|
|
12
13
|
name: 'style_preset',
|
|
@@ -24,8 +25,10 @@ const MockStylePreset = Extension.create({
|
|
|
24
25
|
});
|
|
25
26
|
|
|
26
27
|
function createEditor({ content }) {
|
|
28
|
+
const normalizer = new ContentNormalizer();
|
|
29
|
+
|
|
27
30
|
return new Editor({
|
|
28
|
-
content,
|
|
31
|
+
content: normalizer.normalize(content),
|
|
29
32
|
extensions: CORE_EXTENSIONS.concat(
|
|
30
33
|
MockStylePreset,
|
|
31
34
|
FontFamily.configure({
|
|
@@ -74,6 +77,18 @@ describe('get font weight', () => {
|
|
|
74
77
|
|
|
75
78
|
expect(editor.commands.getFontWeight().value).toEqual('400');
|
|
76
79
|
});
|
|
80
|
+
|
|
81
|
+
test('should get closest available font weight', () => {
|
|
82
|
+
const editor = createEditor({
|
|
83
|
+
content: createContent(NodeFactory.text('hello world', [
|
|
84
|
+
NodeFactory.mark('font_weight', { value: '800' })
|
|
85
|
+
]))
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
editor.commands.selectAll();
|
|
89
|
+
|
|
90
|
+
expect(editor.commands.getFontWeight().value).toEqual('700');
|
|
91
|
+
});
|
|
77
92
|
});
|
|
78
93
|
|
|
79
94
|
describe('apply font weight', () => {
|
|
@@ -149,3 +164,45 @@ describe('rendering', () => {
|
|
|
149
164
|
expect(editor.getHTML()).toMatchSnapshot();
|
|
150
165
|
});
|
|
151
166
|
});
|
|
167
|
+
|
|
168
|
+
describe('parsing html', () => {
|
|
169
|
+
test('should get value from paragraph', () => {
|
|
170
|
+
const editor = createEditor({
|
|
171
|
+
content: '<p style="font-weight: 700">test</p>'
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
test('should get value from text', () => {
|
|
178
|
+
const editor = createEditor({
|
|
179
|
+
content: '<p><span style="font-weight: 700">lorem</span> ipsum</p>'
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
test('should get value from b tag', () => {
|
|
186
|
+
const editor = createEditor({
|
|
187
|
+
content: '<p><b>lorem</b> ipsum</p>'
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
test('should get value from strong tag', () => {
|
|
194
|
+
const editor = createEditor({
|
|
195
|
+
content: '<p><strong>lorem</strong> ipsum</p>'
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
test('should merge paragraph and text settings', () => {
|
|
202
|
+
const editor = createEditor({
|
|
203
|
+
content: '<p style="font-weight: 500"><span style="font-weight: 700">lorem</span> ipsum</p>'
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
207
|
+
});
|
|
208
|
+
});
|
|
@@ -5,6 +5,7 @@ import { createCommand } from '../../utils';
|
|
|
5
5
|
import { CORE_EXTENSIONS } from '../core';
|
|
6
6
|
import { DeviceManager } from '../DeviceManager';
|
|
7
7
|
import { LineHeight } from '../LineHeight';
|
|
8
|
+
import { ContentNormalizer } from '../../services';
|
|
8
9
|
|
|
9
10
|
const MockStylePreset = Extension.create({
|
|
10
11
|
name: 'style_preset',
|
|
@@ -21,8 +22,10 @@ const MockStylePreset = Extension.create({
|
|
|
21
22
|
});
|
|
22
23
|
|
|
23
24
|
function createEditor({ content }) {
|
|
25
|
+
const normalizer = new ContentNormalizer();
|
|
26
|
+
|
|
24
27
|
return new Editor({
|
|
25
|
-
content,
|
|
28
|
+
content: normalizer.normalize(content),
|
|
26
29
|
extensions: CORE_EXTENSIONS.concat(
|
|
27
30
|
MockStylePreset,
|
|
28
31
|
DeviceManager.configure({ deviceRef: ref('desktop') }),
|
|
@@ -104,3 +107,40 @@ describe('rendering', () => {
|
|
|
104
107
|
expect(editor.getHTML()).toMatchSnapshot();
|
|
105
108
|
});
|
|
106
109
|
});
|
|
110
|
+
|
|
111
|
+
describe('parsing html', () => {
|
|
112
|
+
test('should get value from text in relative units', () => {
|
|
113
|
+
const editor = createEditor({
|
|
114
|
+
content: '<p style="line-height: 1.2">test</p>'
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test('should get value from text in px units with font size', () => {
|
|
121
|
+
const editor = createEditor({
|
|
122
|
+
content: '<p style="line-height: 24px; font-size: 20px;">test</p>'
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test('should get value from text in px units with no font size', () => {
|
|
129
|
+
global.document.body.style.fontSize = '20px';
|
|
130
|
+
|
|
131
|
+
const editor = createEditor({
|
|
132
|
+
content: '<p style="line-height: 24px">test</p>'
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
136
|
+
global.document.body.style.removeProperty('font-size');
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test('should set null if no alignment', () => {
|
|
140
|
+
const editor = createEditor({
|
|
141
|
+
content: '<p>test</p>'
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
145
|
+
});
|
|
146
|
+
});
|
|
@@ -5,6 +5,7 @@ import { CORE_EXTENSIONS } from '../core';
|
|
|
5
5
|
import { StylePreset } from '../StylePreset';
|
|
6
6
|
import { List } from '../list';
|
|
7
7
|
import { ListTypes, NodeTypes, TextSettings } from '../../enums';
|
|
8
|
+
import { ContentNormalizer } from '../../services';
|
|
8
9
|
|
|
9
10
|
const MockFontSize = Mark.create({
|
|
10
11
|
name: TextSettings.FONT_SIZE,
|
|
@@ -44,13 +45,16 @@ const MockAlignment = Extension.create({
|
|
|
44
45
|
|
|
45
46
|
function createEditor({ content, presets, defaultId }) {
|
|
46
47
|
return new Promise((resolve) => {
|
|
48
|
+
const normalizer = new ContentNormalizer();
|
|
49
|
+
|
|
47
50
|
const editor = new Editor({
|
|
48
|
-
content,
|
|
51
|
+
content: normalizer.normalize(content),
|
|
49
52
|
onCreate: () => resolve(editor),
|
|
50
53
|
|
|
51
54
|
extensions: CORE_EXTENSIONS.concat(
|
|
52
55
|
StylePreset.configure({
|
|
53
56
|
presetsRef: ref(presets),
|
|
57
|
+
baseClass: 'zw ts-',
|
|
54
58
|
defaultId,
|
|
55
59
|
|
|
56
60
|
makeVariable({ device, preset, property }) {
|
|
@@ -398,3 +402,74 @@ describe('remove preset customization', () => {
|
|
|
398
402
|
);
|
|
399
403
|
});
|
|
400
404
|
});
|
|
405
|
+
|
|
406
|
+
describe('parsing html', () => {
|
|
407
|
+
test('should get by fallback class', async () => {
|
|
408
|
+
const editor = await createEditor({
|
|
409
|
+
content: '<p class="zpa-regular2">lorem ipsum</p>',
|
|
410
|
+
defaultId: 'regular-1',
|
|
411
|
+
presets: [
|
|
412
|
+
createPreset({ id: 'regular-1' }),
|
|
413
|
+
createPreset({ id: 'regular-2', fallbackClass: 'zpa-regular2' })
|
|
414
|
+
]
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
test('should get by preset class', async () => {
|
|
421
|
+
const editor = await createEditor({
|
|
422
|
+
content: '<p class="zw ts-regular-2">lorem ipsum</p>',
|
|
423
|
+
defaultId: 'regular-1',
|
|
424
|
+
presets: [
|
|
425
|
+
createPreset({ id: 'regular-1' }),
|
|
426
|
+
createPreset({ id: 'regular-2' })
|
|
427
|
+
]
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
test('should get by heading tag', async () => {
|
|
434
|
+
const editor = await createEditor({
|
|
435
|
+
content: '<h3>lorem ipsum</h3>',
|
|
436
|
+
defaultId: 'regular-1',
|
|
437
|
+
presets: [
|
|
438
|
+
createPreset({ id: 'regular-1' }),
|
|
439
|
+
createPreset({ id: 'h3', node: { type: 'heading', level: 3 } })
|
|
440
|
+
]
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
test('should set default preset to unstyled paragraph', async () => {
|
|
447
|
+
const editor = await createEditor({
|
|
448
|
+
content: '<p>lorem ipsum</p>',
|
|
449
|
+
defaultId: 'regular-1',
|
|
450
|
+
presets: [createPreset({ id: 'regular-1' })]
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
test('should set null to list item', async () => {
|
|
457
|
+
const editor = await createEditor({
|
|
458
|
+
content: '<ul><li>lorem ipsum</li></ul>',
|
|
459
|
+
defaultId: 'regular-1',
|
|
460
|
+
presets: [createPreset({ id: 'regular-1' })]
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
test('should set null to list item with preset', async () => {
|
|
467
|
+
const editor = await createEditor({
|
|
468
|
+
content: '<ul class="zw regular-1"><li>lorem ipsum</li></ul>',
|
|
469
|
+
defaultId: 'regular-1',
|
|
470
|
+
presets: [createPreset({ id: 'regular-1' })]
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
expect(editor.getJSON()).toMatchSnapshot();
|
|
474
|
+
});
|
|
475
|
+
});
|