@zipify/wysiwyg 1.0.0-dev.9 → 1.0.0-dev.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +1 -1
- package/.eslintrc.js +2 -2
- package/.github/dependabot.yaml +1 -0
- package/.lintstagedrc +2 -2
- package/.release-it.json +3 -1
- package/.stylelintrc +0 -4
- package/README.md +2 -2
- package/config/jest/setupTests.js +0 -3
- package/config/vite/example.config.js +25 -0
- package/config/vite/lib.config.js +30 -0
- package/config/{webpack → vite}/settings.js +0 -0
- package/dist/wysiwyg.css +404 -373
- package/dist/wysiwyg.mjs +26014 -0
- package/example/ExampleApp.vue +35 -4
- package/example/example.js +0 -3
- package/example/{example.html → index.html} +1 -0
- package/example/pageBlocks.js +31 -0
- package/example/presets.js +2 -2
- package/example/tooltip/Tooltip.js +1 -1
- package/jest.config.js +3 -1
- package/lib/Wysiwyg.vue +73 -14
- package/lib/__tests__/utils/index.js +0 -1
- package/lib/__tests__/utils/withComponentContext.js +1 -1
- package/lib/assets/icons/background-color.svg +3 -1
- package/lib/assets/icons/font-color.svg +1 -3
- package/lib/assets/icons/link.svg +3 -0
- package/lib/assets/icons/unlink.svg +3 -0
- package/lib/components/base/Button.vue +23 -2
- package/lib/components/base/Checkbox.vue +89 -0
- package/lib/components/base/FieldLabel.vue +2 -1
- package/lib/components/base/Icon.vue +3 -3
- package/lib/components/base/Modal.vue +1 -2
- package/lib/components/base/NumberField.vue +2 -2
- package/lib/components/base/Range.vue +1 -1
- package/lib/components/base/ScrollView.vue +1 -3
- package/lib/components/base/TextField.vue +108 -0
- package/lib/components/base/__tests__/Modal.test.js +7 -2
- package/lib/components/base/__tests__/TextField.test.js +57 -0
- package/lib/components/base/__tests__/__snapshots__/TextField.test.js.snap +9 -0
- package/lib/components/base/colorPicker/ColorPicker.vue +14 -12
- package/lib/components/base/colorPicker/composables/__tests__/usePickerApi.test.js +6 -6
- package/lib/components/base/colorPicker/composables/usePickerApi.js +15 -8
- package/lib/components/base/colorPicker/composables/usePickerHotkeys.js +3 -2
- package/lib/components/base/composables/__tests__/useActivatedListener.test.js +1 -1
- package/lib/components/base/composables/__tests__/useDeselectionLock.test.js +1 -1
- package/lib/components/base/composables/__tests__/useElementRef.test.js +1 -1
- package/lib/components/base/composables/__tests__/useModalToggler.test.js +1 -1
- package/lib/components/base/composables/__tests__/useNumberValue.test.js +1 -1
- package/lib/components/base/composables/__tests__/useScrollView.test.js +1 -1
- package/lib/components/base/composables/__tests__/useTempValue.test.js +1 -1
- package/lib/components/base/composables/__tests__/useValidator.test.js +44 -0
- package/lib/components/base/composables/index.js +1 -0
- package/lib/components/base/composables/useActivatedListener.js +1 -1
- package/lib/components/base/composables/useDeselectionLock.js +1 -1
- package/lib/components/base/composables/useElementRef.js +1 -1
- package/lib/components/base/composables/useModalToggler.js +6 -2
- package/lib/components/base/composables/useScrollView.js +1 -1
- package/lib/components/base/composables/useTempValue.js +1 -1
- package/lib/components/base/composables/useValidator.js +23 -0
- package/lib/components/base/dropdown/Dropdown.vue +16 -4
- package/lib/components/base/dropdown/DropdownActivator.vue +19 -3
- package/lib/components/base/dropdown/DropdownGroup.vue +1 -1
- package/lib/components/base/dropdown/DropdownMenu.vue +1 -1
- package/lib/components/base/dropdown/DropdownOption.vue +1 -1
- package/lib/components/base/dropdown/__tests__/DropdownActivator.test.js +1 -1
- package/lib/components/base/dropdown/__tests__/DropdownMenu.test.js +1 -1
- package/lib/components/base/dropdown/__tests__/DropdownOption.test.js +1 -1
- package/lib/components/base/dropdown/composables/__tests__/useActiveOptionManager.test.js +1 -1
- package/lib/components/base/dropdown/composables/__tests__/useDropdownEntityTitle.test.js +1 -1
- package/lib/components/base/dropdown/composables/useActiveOptionManager.js +1 -1
- package/lib/components/base/dropdown/composables/useDropdownEntityTitle.js +1 -1
- package/lib/components/base/index.js +3 -1
- package/lib/components/toolbar/Toolbar.vue +51 -9
- package/lib/components/toolbar/ToolbarDivider.vue +1 -1
- package/lib/components/toolbar/ToolbarFull.vue +41 -10
- package/lib/components/toolbar/ToolbarRow.vue +1 -0
- package/lib/components/toolbar/__tests__/Toolbar.test.js +6 -0
- package/lib/components/toolbar/controls/AlignmentControl.vue +1 -1
- package/lib/components/toolbar/controls/AlignmentDeviceControl.vue +1 -1
- package/lib/components/toolbar/controls/BackgroundColorControl.vue +1 -1
- package/lib/components/toolbar/controls/CaseStyleControl.vue +1 -1
- package/lib/components/toolbar/controls/FontColorControl.vue +1 -1
- package/lib/components/toolbar/controls/FontFamilyControl.vue +1 -1
- package/lib/components/toolbar/controls/FontSizeControl.vue +8 -1
- package/lib/components/toolbar/controls/FontWeightControl.vue +1 -1
- package/lib/components/toolbar/controls/ItalicControl.vue +1 -1
- package/lib/components/toolbar/controls/LineHeightControl.vue +1 -1
- package/lib/components/toolbar/controls/ListControl.vue +68 -34
- package/lib/components/toolbar/controls/RemoveFormatControl.vue +1 -1
- package/lib/components/toolbar/controls/StrikeThroughControl.vue +1 -1
- package/lib/components/toolbar/controls/StylePresetControl.vue +15 -2
- package/lib/components/toolbar/controls/SuperscriptControl.vue +1 -1
- package/lib/components/toolbar/controls/UnderlineControl.vue +2 -2
- package/lib/components/toolbar/controls/__tests__/AlignmentControl.test.js +1 -1
- package/lib/components/toolbar/controls/__tests__/AlignmentDeviceControl.test.js +1 -1
- package/lib/components/toolbar/controls/__tests__/BackgroundColorControl.test.js +1 -1
- package/lib/components/toolbar/controls/__tests__/CaseStyleControl.test.js +1 -1
- package/lib/components/toolbar/controls/__tests__/FontColorControl.test.js +1 -1
- package/lib/components/toolbar/controls/__tests__/FontFamilyControl.test.js +1 -1
- package/lib/components/toolbar/controls/__tests__/FontSizeControl.test.js +1 -1
- package/lib/components/toolbar/controls/__tests__/FontWeightControl.test.js +1 -1
- package/lib/components/toolbar/controls/__tests__/ItalicControl.test.js +1 -1
- package/lib/components/toolbar/controls/__tests__/LineHeightControl.test.js +1 -1
- package/lib/components/toolbar/controls/__tests__/ListControl.test.js +18 -3
- package/lib/components/toolbar/controls/__tests__/StrikeThroughControl.test.js +1 -1
- package/lib/components/toolbar/controls/__tests__/StylePresetControl.test.js +17 -1
- package/lib/components/toolbar/controls/__tests__/UnderlineControl.test.js +5 -1
- package/lib/components/toolbar/controls/composables/useRecentFonts.js +1 -1
- package/lib/components/toolbar/controls/index.js +1 -0
- package/lib/components/toolbar/controls/link/LinkControl.vue +160 -0
- package/lib/components/toolbar/controls/link/LinkControlApply.vue +35 -0
- package/lib/components/toolbar/controls/link/LinkControlHeader.vue +69 -0
- package/lib/components/toolbar/controls/link/__tests__/LinkControl.test.js +79 -0
- package/lib/components/toolbar/controls/link/__tests__/LinkControlHeader.test.js +42 -0
- package/lib/components/toolbar/controls/link/composables/__tests__/__snapshots__/useLink.test.js.snap +15 -0
- package/lib/components/toolbar/controls/link/composables/__tests__/useLink.test.js +172 -0
- package/lib/components/toolbar/controls/link/composables/index.js +1 -0
- package/lib/components/toolbar/controls/link/composables/useLink.js +82 -0
- package/lib/components/toolbar/controls/link/destination/LinkControlDestination.vue +103 -0
- package/lib/components/toolbar/controls/link/destination/LinkControlPageBlock.vue +54 -0
- package/lib/components/toolbar/controls/link/destination/LinkControlUrl.vue +52 -0
- package/lib/components/toolbar/controls/link/destination/__tests__/LinkControlPageBlock.test.js +36 -0
- package/lib/components/toolbar/controls/link/destination/__tests__/LinkControlUrl.test.js +46 -0
- package/lib/components/toolbar/controls/link/destination/__tests__/__snapshots__/LinkControlPageBlock.test.js.snap +9 -0
- package/lib/components/toolbar/controls/link/destination/__tests__/__snapshots__/LinkControlUrl.test.js.snap +17 -0
- package/lib/components/toolbar/controls/link/destination/index.js +1 -0
- package/lib/components/toolbar/controls/link/index.js +1 -0
- package/lib/composables/__tests__/__snapshots__/useEditor.test.js.snap +1 -0
- package/lib/composables/__tests__/useEditor.test.js +5 -4
- package/lib/composables/useEditor.js +12 -9
- package/lib/composables/useToolbar.js +26 -19
- package/lib/directives/__tests__/outClick.test.js +6 -0
- package/lib/directives/outClick.js +19 -6
- package/lib/enums/Alignments.js +10 -1
- package/lib/enums/LinkDestinations.js +4 -0
- package/lib/enums/LinkTargets.js +4 -0
- package/lib/enums/TextSettings.js +3 -1
- package/lib/enums/index.js +2 -0
- package/lib/extensions/Alignment.js +22 -8
- package/lib/extensions/BackgroundColor.js +15 -7
- package/lib/extensions/DeviceManager.js +2 -5
- package/lib/extensions/FontColor.js +15 -7
- package/lib/extensions/FontFamily.js +26 -9
- package/lib/extensions/FontSize.js +33 -13
- package/lib/extensions/FontStyle.js +24 -14
- package/lib/extensions/FontWeight.js +25 -15
- package/lib/extensions/LineHeight.js +33 -29
- package/lib/extensions/Link.js +90 -0
- package/lib/extensions/StylePreset.js +20 -19
- package/lib/extensions/Superscript.js +5 -1
- package/lib/extensions/TextDecoration.js +46 -13
- package/lib/extensions/__tests__/Alignment.test.js +14 -9
- package/lib/extensions/__tests__/BackgroundColor.test.js +13 -8
- package/lib/extensions/__tests__/CaseStyle.test.js +4 -7
- package/lib/extensions/__tests__/FontColor.test.js +13 -8
- package/lib/extensions/__tests__/FontFamily.test.js +34 -10
- package/lib/extensions/__tests__/FontSize.test.js +16 -10
- package/lib/extensions/__tests__/FontStyle.test.js +13 -8
- package/lib/extensions/__tests__/FontWeight.test.js +21 -8
- package/lib/extensions/__tests__/LineHeight.test.js +25 -14
- package/lib/extensions/__tests__/Link.test.js +101 -0
- package/lib/extensions/__tests__/StylePreset.test.js +72 -10
- package/lib/extensions/__tests__/TextDecoration.test.js +53 -8
- package/lib/extensions/__tests__/__snapshots__/Alignment.test.js.snap +26 -2
- package/lib/extensions/__tests__/__snapshots__/BackgroundColor.test.js.snap +30 -1
- package/lib/extensions/__tests__/__snapshots__/FontColor.test.js.snap +18 -1
- package/lib/extensions/__tests__/__snapshots__/FontFamily.test.js.snap +88 -1
- package/lib/extensions/__tests__/__snapshots__/FontSize.test.js.snap +33 -2
- package/lib/extensions/__tests__/__snapshots__/FontStyle.test.js.snap +25 -4
- package/lib/extensions/__tests__/__snapshots__/FontWeight.test.js.snap +47 -1
- package/lib/extensions/__tests__/__snapshots__/LineHeight.test.js.snap +26 -2
- package/lib/extensions/__tests__/__snapshots__/Link.test.js.snap +225 -0
- package/lib/extensions/__tests__/__snapshots__/StylePreset.test.js.snap +6 -2
- package/lib/extensions/__tests__/__snapshots__/TextDecoration.test.js.snap +183 -3
- package/lib/extensions/core/CopyPasteProcessor.js +10 -0
- package/lib/extensions/core/NodeProcessor.js +1 -1
- package/lib/extensions/core/TextProcessor.js +11 -24
- package/lib/extensions/core/__tests__/NodeProcessor.test.js +4 -7
- package/lib/extensions/core/__tests__/SelectionProcessor.test.js +4 -7
- package/lib/extensions/core/__tests__/TextProcessor.test.js +139 -14
- package/lib/extensions/core/__tests__/__snapshots__/TextProcessor.test.js.snap +26 -0
- package/lib/extensions/core/index.js +11 -2
- package/lib/extensions/core/plugins/PastePlugin.js +57 -0
- package/lib/extensions/core/plugins/ProseMirrorPlugin.js +20 -0
- package/lib/extensions/core/plugins/index.js +1 -0
- package/lib/extensions/index.js +46 -34
- package/lib/extensions/list/List.js +5 -4
- package/lib/extensions/list/__tests__/List.test.js +6 -10
- package/lib/extensions/list/__tests__/__snapshots__/List.test.js.snap +60 -20
- package/lib/index.js +3 -0
- package/lib/injectionTokens.js +3 -1
- package/lib/services/ContentNormalizer.js +144 -28
- package/lib/services/ContextWidnow.js +23 -0
- package/lib/{__tests__/utils → services}/NodeFactory.js +5 -1
- package/lib/services/__tests__/ContentNormalizer.test.js +124 -8
- package/lib/services/__tests__/FavoriteColors.test.js +1 -1
- package/lib/services/index.js +2 -0
- package/lib/styles/content.css +108 -13
- package/lib/styles/helpers/offsets.css +16 -0
- package/lib/styles/variables.css +6 -0
- package/lib/utils/__tests__/__snapshots__/renderInlineSetting.test.js.snap +4 -4
- package/lib/utils/__tests__/convertAlignment.test.js +16 -0
- package/lib/utils/__tests__/convertFontSize.test.js +21 -0
- package/lib/utils/__tests__/convertLineHeight.test.js +21 -0
- package/lib/utils/convertAlignment.js +12 -0
- package/lib/utils/convertColor.js +1 -1
- package/lib/utils/convertFontSize.js +8 -0
- package/lib/utils/convertLineHeight.js +17 -0
- package/lib/utils/importIcon.js +7 -6
- package/lib/utils/index.js +4 -0
- package/lib/utils/isWysiwygContent.js +12 -0
- package/lib/utils/renderInlineSetting.js +1 -1
- package/package.json +26 -30
- package/config/webpack/example.config.js +0 -88
- package/config/webpack/lib.config.js +0 -44
- package/config/webpack/loaders/index.js +0 -6
- package/config/webpack/loaders/js-loader.js +0 -5
- package/config/webpack/loaders/style-loader.js +0 -9
- package/config/webpack/loaders/svg-loader.js +0 -4
- package/config/webpack/loaders/vue-loader.js +0 -4
- package/dist/wysiwyg.js +0 -2
- package/dist/wysiwyg.js.LICENSE.txt +0 -1
- package/lib/extensions/core/inputRules/closeDoubleQuote.js +0 -6
- package/lib/extensions/core/inputRules/closeSingleQuote.js +0 -6
- package/lib/extensions/core/inputRules/copyright.js +0 -6
- package/lib/extensions/core/inputRules/ellipsis.js +0 -6
- package/lib/extensions/core/inputRules/emDash.js +0 -6
- package/lib/extensions/core/inputRules/index.js +0 -9
- package/lib/extensions/core/inputRules/openDoubleQuote.js +0 -6
- package/lib/extensions/core/inputRules/openSingleQuote.js +0 -6
- package/lib/extensions/core/inputRules/registeredTrademark.js +0 -6
- package/lib/extensions/core/inputRules/trademark.js +0 -6
|
@@ -14,7 +14,9 @@ Object {
|
|
|
14
14
|
"content": Array [
|
|
15
15
|
Object {
|
|
16
16
|
"attrs": Object {
|
|
17
|
-
"preset":
|
|
17
|
+
"preset": Object {
|
|
18
|
+
"id": "regular-1",
|
|
19
|
+
},
|
|
18
20
|
},
|
|
19
21
|
"content": Array [
|
|
20
22
|
Object {
|
|
@@ -49,7 +51,9 @@ Object {
|
|
|
49
51
|
"content": Array [
|
|
50
52
|
Object {
|
|
51
53
|
"attrs": Object {
|
|
52
|
-
"preset":
|
|
54
|
+
"preset": Object {
|
|
55
|
+
"id": "regular-1",
|
|
56
|
+
},
|
|
53
57
|
},
|
|
54
58
|
"content": Array [
|
|
55
59
|
Object {
|
|
@@ -66,7 +70,9 @@ Object {
|
|
|
66
70
|
"content": Array [
|
|
67
71
|
Object {
|
|
68
72
|
"attrs": Object {
|
|
69
|
-
"preset":
|
|
73
|
+
"preset": Object {
|
|
74
|
+
"id": "regular-1",
|
|
75
|
+
},
|
|
70
76
|
},
|
|
71
77
|
"content": Array [
|
|
72
78
|
Object {
|
|
@@ -92,7 +98,9 @@ Object {
|
|
|
92
98
|
"content": Array [
|
|
93
99
|
Object {
|
|
94
100
|
"attrs": Object {
|
|
95
|
-
"preset":
|
|
101
|
+
"preset": Object {
|
|
102
|
+
"id": "regular-1",
|
|
103
|
+
},
|
|
96
104
|
},
|
|
97
105
|
"content": Array [
|
|
98
106
|
Object {
|
|
@@ -104,7 +112,9 @@ Object {
|
|
|
104
112
|
},
|
|
105
113
|
Object {
|
|
106
114
|
"attrs": Object {
|
|
107
|
-
"preset":
|
|
115
|
+
"preset": Object {
|
|
116
|
+
"id": "regular-1",
|
|
117
|
+
},
|
|
108
118
|
},
|
|
109
119
|
"content": Array [
|
|
110
120
|
Object {
|
|
@@ -133,7 +143,9 @@ Object {
|
|
|
133
143
|
"content": Array [
|
|
134
144
|
Object {
|
|
135
145
|
"attrs": Object {
|
|
136
|
-
"preset":
|
|
146
|
+
"preset": Object {
|
|
147
|
+
"id": "regular-1",
|
|
148
|
+
},
|
|
137
149
|
},
|
|
138
150
|
"content": Array [
|
|
139
151
|
Object {
|
|
@@ -150,7 +162,9 @@ Object {
|
|
|
150
162
|
"content": Array [
|
|
151
163
|
Object {
|
|
152
164
|
"attrs": Object {
|
|
153
|
-
"preset":
|
|
165
|
+
"preset": Object {
|
|
166
|
+
"id": "regular-1",
|
|
167
|
+
},
|
|
154
168
|
},
|
|
155
169
|
"content": Array [
|
|
156
170
|
Object {
|
|
@@ -221,7 +235,9 @@ Object {
|
|
|
221
235
|
"content": Array [
|
|
222
236
|
Object {
|
|
223
237
|
"attrs": Object {
|
|
224
|
-
"preset":
|
|
238
|
+
"preset": Object {
|
|
239
|
+
"id": "regular-1",
|
|
240
|
+
},
|
|
225
241
|
},
|
|
226
242
|
"content": Array [
|
|
227
243
|
Object {
|
|
@@ -256,7 +272,9 @@ Object {
|
|
|
256
272
|
"content": Array [
|
|
257
273
|
Object {
|
|
258
274
|
"attrs": Object {
|
|
259
|
-
"preset":
|
|
275
|
+
"preset": Object {
|
|
276
|
+
"id": "regular-1",
|
|
277
|
+
},
|
|
260
278
|
},
|
|
261
279
|
"content": Array [
|
|
262
280
|
Object {
|
|
@@ -291,7 +309,9 @@ Object {
|
|
|
291
309
|
"content": Array [
|
|
292
310
|
Object {
|
|
293
311
|
"attrs": Object {
|
|
294
|
-
"preset":
|
|
312
|
+
"preset": Object {
|
|
313
|
+
"id": "regular-1",
|
|
314
|
+
},
|
|
295
315
|
},
|
|
296
316
|
"content": Array [
|
|
297
317
|
Object {
|
|
@@ -326,7 +346,9 @@ Object {
|
|
|
326
346
|
"content": Array [
|
|
327
347
|
Object {
|
|
328
348
|
"attrs": Object {
|
|
329
|
-
"preset":
|
|
349
|
+
"preset": Object {
|
|
350
|
+
"id": "regular-1",
|
|
351
|
+
},
|
|
330
352
|
},
|
|
331
353
|
"content": Array [
|
|
332
354
|
Object {
|
|
@@ -361,7 +383,9 @@ Object {
|
|
|
361
383
|
"content": Array [
|
|
362
384
|
Object {
|
|
363
385
|
"attrs": Object {
|
|
364
|
-
"preset":
|
|
386
|
+
"preset": Object {
|
|
387
|
+
"id": "regular-1",
|
|
388
|
+
},
|
|
365
389
|
},
|
|
366
390
|
"content": Array [
|
|
367
391
|
Object {
|
|
@@ -396,7 +420,9 @@ Object {
|
|
|
396
420
|
"content": Array [
|
|
397
421
|
Object {
|
|
398
422
|
"attrs": Object {
|
|
399
|
-
"preset":
|
|
423
|
+
"preset": Object {
|
|
424
|
+
"id": "regular-1",
|
|
425
|
+
},
|
|
400
426
|
},
|
|
401
427
|
"content": Array [
|
|
402
428
|
Object {
|
|
@@ -431,7 +457,9 @@ Object {
|
|
|
431
457
|
"content": Array [
|
|
432
458
|
Object {
|
|
433
459
|
"attrs": Object {
|
|
434
|
-
"preset":
|
|
460
|
+
"preset": Object {
|
|
461
|
+
"id": "regular-1",
|
|
462
|
+
},
|
|
435
463
|
},
|
|
436
464
|
"content": Array [
|
|
437
465
|
Object {
|
|
@@ -466,7 +494,9 @@ Object {
|
|
|
466
494
|
"content": Array [
|
|
467
495
|
Object {
|
|
468
496
|
"attrs": Object {
|
|
469
|
-
"preset":
|
|
497
|
+
"preset": Object {
|
|
498
|
+
"id": "regular-1",
|
|
499
|
+
},
|
|
470
500
|
},
|
|
471
501
|
"content": Array [
|
|
472
502
|
Object {
|
|
@@ -501,7 +531,9 @@ Object {
|
|
|
501
531
|
"content": Array [
|
|
502
532
|
Object {
|
|
503
533
|
"attrs": Object {
|
|
504
|
-
"preset":
|
|
534
|
+
"preset": Object {
|
|
535
|
+
"id": "regular-1",
|
|
536
|
+
},
|
|
505
537
|
},
|
|
506
538
|
"content": Array [
|
|
507
539
|
Object {
|
|
@@ -536,7 +568,9 @@ Object {
|
|
|
536
568
|
"content": Array [
|
|
537
569
|
Object {
|
|
538
570
|
"attrs": Object {
|
|
539
|
-
"preset":
|
|
571
|
+
"preset": Object {
|
|
572
|
+
"id": "regular-1",
|
|
573
|
+
},
|
|
540
574
|
},
|
|
541
575
|
"content": Array [
|
|
542
576
|
Object {
|
|
@@ -571,7 +605,9 @@ Object {
|
|
|
571
605
|
"content": Array [
|
|
572
606
|
Object {
|
|
573
607
|
"attrs": Object {
|
|
574
|
-
"preset":
|
|
608
|
+
"preset": Object {
|
|
609
|
+
"id": "regular-1",
|
|
610
|
+
},
|
|
575
611
|
},
|
|
576
612
|
"content": Array [
|
|
577
613
|
Object {
|
|
@@ -606,7 +642,9 @@ Object {
|
|
|
606
642
|
"content": Array [
|
|
607
643
|
Object {
|
|
608
644
|
"attrs": Object {
|
|
609
|
-
"preset":
|
|
645
|
+
"preset": Object {
|
|
646
|
+
"id": "regular-1",
|
|
647
|
+
},
|
|
610
648
|
},
|
|
611
649
|
"content": Array [
|
|
612
650
|
Object {
|
|
@@ -641,7 +679,9 @@ Object {
|
|
|
641
679
|
"content": Array [
|
|
642
680
|
Object {
|
|
643
681
|
"attrs": Object {
|
|
644
|
-
"preset":
|
|
682
|
+
"preset": Object {
|
|
683
|
+
"id": "regular-1",
|
|
684
|
+
},
|
|
645
685
|
},
|
|
646
686
|
"content": Array [
|
|
647
687
|
Object {
|
package/lib/index.js
CHANGED
package/lib/injectionTokens.js
CHANGED
|
@@ -3,5 +3,7 @@ export const InjectionTokens = Object.freeze({
|
|
|
3
3
|
FONT_SIZES: Symbol('fontSizes'),
|
|
4
4
|
EDITOR: Symbol('editor'),
|
|
5
5
|
LOCAL_STORAGE: Symbol('localStorage'),
|
|
6
|
-
FAVORITE_COLORS: Symbol('favoriteColors')
|
|
6
|
+
FAVORITE_COLORS: Symbol('favoriteColors'),
|
|
7
|
+
PAGE_BLOCKS: Symbol('pageBlocks'),
|
|
8
|
+
POPUP_MODE: Symbol('popupMode')
|
|
7
9
|
});
|
|
@@ -1,42 +1,108 @@
|
|
|
1
1
|
export class ContentNormalizer {
|
|
2
|
-
static
|
|
2
|
+
static PARSER = new DOMParser();
|
|
3
|
+
static BLOCK_STYLES = ['text-align', 'line-height'];
|
|
4
|
+
static BLOCK_NODE_NAMES = ['P', 'H1', 'H2', 'H3', 'H4'];
|
|
5
|
+
|
|
6
|
+
static ASSIGN_STYLE_RULES = [
|
|
7
|
+
{
|
|
8
|
+
tag: /^(b|strong)$/,
|
|
9
|
+
ignore: /font-weight/
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
tag: /^i$/,
|
|
13
|
+
ignore: /font-style/
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
tag: /^s$/,
|
|
17
|
+
ignore: /text-decoration(.+)?/
|
|
18
|
+
}
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
static normalize(content) {
|
|
22
|
+
const options = { content, parser: ContentNormalizer.PARSER };
|
|
23
|
+
|
|
24
|
+
return new ContentNormalizer(options).normalize();
|
|
25
|
+
}
|
|
3
26
|
|
|
4
|
-
|
|
5
|
-
|
|
27
|
+
constructor({ content, parser }) {
|
|
28
|
+
this._content = content;
|
|
29
|
+
this._parser = parser;
|
|
30
|
+
this._dom = null;
|
|
31
|
+
}
|
|
6
32
|
|
|
7
|
-
|
|
33
|
+
normalize() {
|
|
34
|
+
if (typeof this._content !== 'string') {
|
|
35
|
+
return this._content;
|
|
36
|
+
}
|
|
37
|
+
return this._normalizeTextContent();
|
|
8
38
|
}
|
|
9
39
|
|
|
10
|
-
_normalizeTextContent(
|
|
11
|
-
|
|
12
|
-
const dom = parser.parseFromString(content, 'text/html');
|
|
40
|
+
_normalizeTextContent() {
|
|
41
|
+
this._dom = this._parser.parseFromString(this._content.replace(/(\r)?\n/g, ''), 'text/html');
|
|
13
42
|
|
|
14
|
-
this._iterateNodes(
|
|
15
|
-
this._iterateNodes(
|
|
43
|
+
this._iterateNodes(this._normalizeBreakLines, (node) => node.tagName === 'BR');
|
|
44
|
+
this._iterateNodes(this._removeEmptyNodes, this._isBlockNode);
|
|
45
|
+
this._iterateNodes(this._normalizeListItems, (node) => node.tagName === 'LI');
|
|
46
|
+
this._iterateNodes(this._normalizeSettingsStructure, (node) => node.tagName === 'SPAN');
|
|
47
|
+
this._iterateNodes(this._normalizeStyles, (node) => node.tagName !== 'SPAN');
|
|
16
48
|
|
|
17
|
-
return
|
|
49
|
+
return this._dom.body.innerHTML;
|
|
18
50
|
}
|
|
19
51
|
|
|
20
|
-
_iterateNodes(
|
|
21
|
-
const iterator =
|
|
22
|
-
acceptNode: (node) => condition(node) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT
|
|
52
|
+
_iterateNodes(handler, condition = () => true) {
|
|
53
|
+
const iterator = this._dom.createNodeIterator(this._dom.body, NodeFilter.SHOW_ELEMENT, {
|
|
54
|
+
acceptNode: (node) => condition.call(this, node) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT
|
|
23
55
|
});
|
|
24
56
|
let currentNode = iterator.nextNode();
|
|
25
57
|
|
|
26
58
|
while (currentNode) {
|
|
27
|
-
handler(currentNode);
|
|
59
|
+
handler.call(this, currentNode);
|
|
28
60
|
currentNode = iterator.nextNode();
|
|
29
61
|
}
|
|
30
62
|
}
|
|
31
63
|
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
.every((node) => node.nodeType === Node.TEXT_NODE);
|
|
64
|
+
_removeEmptyNodes(node) {
|
|
65
|
+
const html = node.innerHTML.replace(/ /g, '').trim();
|
|
35
66
|
|
|
36
|
-
if (
|
|
67
|
+
if (!html) node.remove();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
_normalizeListItems(itemEl) {
|
|
71
|
+
const fragment = new DocumentFragment();
|
|
72
|
+
const children = Array.from(itemEl.childNodes);
|
|
73
|
+
let capturingParagraph;
|
|
74
|
+
|
|
75
|
+
const append = (node) => {
|
|
76
|
+
this._assignElementProperties(node, itemEl, ContentNormalizer.BLOCK_STYLES);
|
|
77
|
+
fragment.append(node);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
this._assignElementProperties(itemEl, itemEl.parentElement, ContentNormalizer.BLOCK_STYLES);
|
|
81
|
+
|
|
82
|
+
for (const node of children) {
|
|
83
|
+
if (this._isBlockNode(node)) {
|
|
84
|
+
append(node);
|
|
85
|
+
capturingParagraph = null;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (!capturingParagraph) {
|
|
90
|
+
capturingParagraph = document.createElement('p');
|
|
91
|
+
append(capturingParagraph);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
capturingParagraph.append(node);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
itemEl.append(fragment);
|
|
98
|
+
this._removeStyleProperties(itemEl, ContentNormalizer.BLOCK_STYLES);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
_normalizeSettingsStructure(element) {
|
|
102
|
+
if (this._isOnlyTextContent(element)) return;
|
|
37
103
|
|
|
38
104
|
const cloned = element.cloneNode(true);
|
|
39
|
-
const migratingStyles = this._getMigratingStyles(element);
|
|
105
|
+
const migratingStyles = this._getMigratingStyles(element, { customProperties: true });
|
|
40
106
|
const content = [];
|
|
41
107
|
|
|
42
108
|
for (const node of cloned.childNodes) {
|
|
@@ -54,8 +120,12 @@ export class ContentNormalizer {
|
|
|
54
120
|
}
|
|
55
121
|
|
|
56
122
|
_normalizeStyles(element) {
|
|
123
|
+
if (!this._isBlockNode(element) && this._isOnlyTextContent(element)) return;
|
|
124
|
+
|
|
57
125
|
const properties = this._getMigratingStyles(element);
|
|
58
126
|
|
|
127
|
+
if (!properties.length) return;
|
|
128
|
+
|
|
59
129
|
for (const node of element.childNodes) {
|
|
60
130
|
const child = this._wrapTextNode(element, node);
|
|
61
131
|
|
|
@@ -65,16 +135,25 @@ export class ContentNormalizer {
|
|
|
65
135
|
this._removeStyleProperties(element, properties);
|
|
66
136
|
}
|
|
67
137
|
|
|
68
|
-
|
|
69
|
-
|
|
138
|
+
_isOnlyTextContent(node) {
|
|
139
|
+
return Array.from(node.childNodes).every((node) => node.nodeType === Node.TEXT_NODE);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
_isBlockNode(node) {
|
|
143
|
+
return ContentNormalizer.BLOCK_NODE_NAMES.includes(node.tagName);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
_getMigratingStyles(element, { customProperties } = {}) {
|
|
147
|
+
const blacklist = ContentNormalizer.BLOCK_STYLES;
|
|
70
148
|
const properties = [];
|
|
71
149
|
|
|
72
150
|
for (let index = 0; index < element.style.length; index++) {
|
|
73
151
|
const property = element.style.item(index);
|
|
74
152
|
|
|
75
|
-
if (
|
|
76
|
-
|
|
77
|
-
|
|
153
|
+
if (blacklist.includes(property)) continue;
|
|
154
|
+
if (!customProperties && property.startsWith('--')) continue;
|
|
155
|
+
|
|
156
|
+
properties.push(property);
|
|
78
157
|
}
|
|
79
158
|
|
|
80
159
|
return properties;
|
|
@@ -93,14 +172,24 @@ export class ContentNormalizer {
|
|
|
93
172
|
|
|
94
173
|
_assignElementProperties(target, source, properties) {
|
|
95
174
|
for (const property of properties) {
|
|
96
|
-
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
175
|
+
const value = source.style.getPropertyValue(property);
|
|
99
176
|
|
|
100
|
-
|
|
177
|
+
if (value && this._canAssignElementProperty(target, source, property)) {
|
|
178
|
+
target.style.setProperty(property, value);
|
|
179
|
+
}
|
|
101
180
|
}
|
|
102
181
|
}
|
|
103
182
|
|
|
183
|
+
_canAssignElementProperty(target, source, property) {
|
|
184
|
+
if (target.style.getPropertyValue(property)) return false;
|
|
185
|
+
|
|
186
|
+
return ContentNormalizer.ASSIGN_STYLE_RULES.every((rule) => {
|
|
187
|
+
if (!rule.tag.test(target.tagName.toLowerCase())) return true;
|
|
188
|
+
|
|
189
|
+
return !rule.ignore.test(property);
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
104
193
|
_removeStyleProperties(element, properties) {
|
|
105
194
|
for (const property of properties) {
|
|
106
195
|
element.style.removeProperty(property);
|
|
@@ -110,4 +199,31 @@ export class ContentNormalizer {
|
|
|
110
199
|
element.removeAttribute('style');
|
|
111
200
|
}
|
|
112
201
|
}
|
|
202
|
+
|
|
203
|
+
_normalizeBreakLines({ parentElement }) {
|
|
204
|
+
if (!this._isBlockNode(parentElement)) return;
|
|
205
|
+
if (!parentElement.textContent) return;
|
|
206
|
+
|
|
207
|
+
const fragment = new DocumentFragment();
|
|
208
|
+
const children = Array.from(parentElement.childNodes);
|
|
209
|
+
let capturingParagraph = document.createElement('p');
|
|
210
|
+
|
|
211
|
+
const append = (node) => {
|
|
212
|
+
this._assignElementProperties(node, parentElement, ContentNormalizer.BLOCK_STYLES);
|
|
213
|
+
fragment.append(node);
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
for (const child of children) {
|
|
217
|
+
if (child.tagName === 'BR') {
|
|
218
|
+
append(capturingParagraph);
|
|
219
|
+
capturingParagraph = document.createElement('p');
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
capturingParagraph.append(child);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
fragment.append(capturingParagraph);
|
|
227
|
+
parentElement.replaceWith(fragment);
|
|
228
|
+
}
|
|
113
229
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export class ContextWindow {
|
|
2
|
+
static window = window;
|
|
3
|
+
|
|
4
|
+
static use(window) {
|
|
5
|
+
this.window = window;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
static get document() {
|
|
9
|
+
return this.window.document;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static get body() {
|
|
13
|
+
return this.document.body;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static get head() {
|
|
17
|
+
return this.document.head;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static getComputedStyle(element) {
|
|
21
|
+
return this.window.getComputedStyle(element);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NodeTypes } from '
|
|
1
|
+
import { NodeTypes } from '../enums';
|
|
2
2
|
|
|
3
3
|
export class NodeFactory {
|
|
4
4
|
static doc(content) {
|
|
@@ -64,4 +64,8 @@ export class NodeFactory {
|
|
|
64
64
|
static mark(type, attrs) {
|
|
65
65
|
return { type, attrs };
|
|
66
66
|
}
|
|
67
|
+
|
|
68
|
+
static populateAllDevices(value) {
|
|
69
|
+
return { mobile: value, tablet: value, desktop: value };
|
|
70
|
+
}
|
|
67
71
|
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { ContentNormalizer } from '../ContentNormalizer';
|
|
2
|
-
import { NodeFactory } from '
|
|
2
|
+
import { NodeFactory } from '../NodeFactory';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
describe('normalize text settings', () => {
|
|
4
|
+
describe('normalize text content', () => {
|
|
7
5
|
test('should ignore json content', () => {
|
|
8
6
|
const content = NodeFactory.doc([NodeFactory.paragraph('Test')]);
|
|
9
7
|
|
|
10
|
-
expect(normalize(content)).toBe(content);
|
|
8
|
+
expect(ContentNormalizer.normalize(content)).toBe(content);
|
|
11
9
|
});
|
|
12
10
|
|
|
13
11
|
test('should flat structure', () => {
|
|
@@ -18,14 +16,14 @@ describe('normalize text settings', () => {
|
|
|
18
16
|
'<span style="background-color: rgb(255, 0, 0); color: rgb(255, 255, 255);">sum</span>' +
|
|
19
17
|
'</p>';
|
|
20
18
|
|
|
21
|
-
expect(normalize(input)).toBe(output);
|
|
19
|
+
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
22
20
|
});
|
|
23
21
|
|
|
24
22
|
test('should move styles from paragraph to text', () => {
|
|
25
23
|
const input = '<p style="background-color: red;">lorem ipsum</p>';
|
|
26
24
|
const output = '<p><span style="background-color: red;">lorem ipsum</span></p>';
|
|
27
25
|
|
|
28
|
-
expect(normalize(input)).toBe(output);
|
|
26
|
+
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
29
27
|
});
|
|
30
28
|
|
|
31
29
|
test('should move styles from paragraph to unstyled text', () => {
|
|
@@ -36,6 +34,124 @@ describe('normalize text settings', () => {
|
|
|
36
34
|
'<span style="color: white; background-color: red;">one</span' +
|
|
37
35
|
'></p>';
|
|
38
36
|
|
|
39
|
-
expect(normalize(input)).toBe(output);
|
|
37
|
+
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('should wrap list content in paragraph', () => {
|
|
41
|
+
const input = '<ul><li style="line-height: 2;">lorem impsum</li></ul>';
|
|
42
|
+
const output = '<ul><li><p style="line-height: 2;">lorem impsum</p></li></ul>';
|
|
43
|
+
|
|
44
|
+
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('should keep order in list nodes', () => {
|
|
48
|
+
const input = '<ul><li style="line-height: 2;"><span style="font-weight: 700">lorem</span> impsum</li></ul>';
|
|
49
|
+
const output = '<ul>' +
|
|
50
|
+
'<li>' +
|
|
51
|
+
'<p style="line-height: 2;"><span style="font-weight: 700">lorem</span> impsum</p>' +
|
|
52
|
+
'</li>' +
|
|
53
|
+
'</ul>';
|
|
54
|
+
|
|
55
|
+
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('should wrap non paragraph list content', () => {
|
|
59
|
+
const input = '<ul>' +
|
|
60
|
+
'<li style="line-height: 2;">' +
|
|
61
|
+
'<span style="font-weight: 700">lorem</span> impsum' +
|
|
62
|
+
'<p>paragraph text</p>' +
|
|
63
|
+
'</li>' +
|
|
64
|
+
'</ul>';
|
|
65
|
+
const output = '<ul>' +
|
|
66
|
+
'<li>' +
|
|
67
|
+
'<p style="line-height: 2;"><span style="font-weight: 700">lorem</span> impsum</p>' +
|
|
68
|
+
'<p style="line-height: 2;">paragraph text</p>' +
|
|
69
|
+
'</li>' +
|
|
70
|
+
'</ul>';
|
|
71
|
+
|
|
72
|
+
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test('should allow using heading in list', () => {
|
|
76
|
+
const input = '<ul><li><h2>lorem ipsum</h2></li></ul>';
|
|
77
|
+
|
|
78
|
+
expect(ContentNormalizer.normalize(input)).toBe(input);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test('should ignore empty nodes', () => {
|
|
82
|
+
const input = '<p>lorem ipsum 1</p><p></p><p>lorem ipsum 2</p>';
|
|
83
|
+
const output = '<p>lorem ipsum 1</p><p>lorem ipsum 2</p>';
|
|
84
|
+
|
|
85
|
+
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test('should ignore space only nodes', () => {
|
|
89
|
+
const input = '<p>lorem ipsum 1</p><p> </p><p>lorem ipsum 2</p>';
|
|
90
|
+
const output = '<p>lorem ipsum 1</p><p>lorem ipsum 2</p>';
|
|
91
|
+
|
|
92
|
+
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test('should ignore non-breaking space only nodes', () => {
|
|
96
|
+
const input = '<p>lorem ipsum 1</p><p> </p><p>lorem ipsum 2</p>';
|
|
97
|
+
const output = '<p>lorem ipsum 1</p><p>lorem ipsum 2</p>';
|
|
98
|
+
|
|
99
|
+
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test('should ignore newline chapters only nodes', () => {
|
|
103
|
+
const input = '<p>lorem ipsum 1</p><p>\n</p><p>lorem ipsum 2</p>';
|
|
104
|
+
const output = '<p>lorem ipsum 1</p><p>lorem ipsum 2</p>';
|
|
105
|
+
|
|
106
|
+
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test('should not ignore setting', () => {
|
|
110
|
+
const input = '<p style="text-decoration-line: underline;">lorem ipsum</p>';
|
|
111
|
+
const output = '<p><span style="text-decoration-line: underline;">lorem ipsum</span></p>';
|
|
112
|
+
|
|
113
|
+
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test('should not assign font-weight to b tag', () => {
|
|
117
|
+
const input = '<p style="font-weight: 400;"><b>lorem ipsum</b></p>';
|
|
118
|
+
const output = '<p><b>lorem ipsum</b></p>';
|
|
119
|
+
|
|
120
|
+
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test('should not assign font-style to i tag', () => {
|
|
124
|
+
const input = '<p style="font-style: normal;"><i>lorem ipsum</i></p>';
|
|
125
|
+
const output = '<p><i>lorem ipsum</i></p>';
|
|
126
|
+
|
|
127
|
+
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test('should not assign text-decoration to s tag', () => {
|
|
131
|
+
const input = '<p style="text-decoration-line: initial;"><s>lorem ipsum</s></p>';
|
|
132
|
+
const output = '<p><s>lorem ipsum</s></p>';
|
|
133
|
+
|
|
134
|
+
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
test('should assign block styles from list to paragraph', () => {
|
|
138
|
+
const input = '<ul style="line-height: 2;"><li>lorem ipsum</li></ul>';
|
|
139
|
+
const output = '<ul style="line-height: 2;"><li><p style="line-height: 2;">lorem ipsum</p></li></ul>';
|
|
140
|
+
|
|
141
|
+
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test('should migrate br to paragraphs', () => {
|
|
145
|
+
const input = '<p><b>lorem</b><br>ipsum</p>';
|
|
146
|
+
const output = '<p><b>lorem</b></p><p>ipsum</p>';
|
|
147
|
+
|
|
148
|
+
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test('should not migrate single br to paragraph', () => {
|
|
152
|
+
const input = '<p><br></p>';
|
|
153
|
+
const output = '<p><br></p>';
|
|
154
|
+
|
|
155
|
+
expect(ContentNormalizer.normalize(input)).toBe(output);
|
|
40
156
|
});
|
|
41
157
|
});
|
package/lib/services/index.js
CHANGED
|
@@ -2,3 +2,5 @@ export { JsonSerializer } from './JsonSerializer';
|
|
|
2
2
|
export { Storage } from './Storage';
|
|
3
3
|
export { FavoriteColors } from './FavoriteColors';
|
|
4
4
|
export { ContentNormalizer } from './ContentNormalizer';
|
|
5
|
+
export { ContextWindow } from './ContextWidnow';
|
|
6
|
+
export { NodeFactory } from './NodeFactory';
|