@vaadin/rich-text-editor 25.0.0-alpha12 → 25.0.0-alpha13
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/package.json +13 -13
- package/src/styles/vaadin-rich-text-editor-base-styles.js +43 -12
- package/src/styles/vaadin-rich-text-editor-popup-overlay-base-styles.js +1 -1
- package/src/vaadin-rich-text-editor-mixin.js +33 -56
- package/src/vaadin-rich-text-editor.d.ts +1 -1
- package/src/vaadin-rich-text-editor.js +1 -1
- package/vendor/vaadin-quill.js +4 -3
- package/vendor/vaadin-quill.js.map +1 -1
- package/web-types.json +2 -2
- package/web-types.lit.json +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/rich-text-editor",
|
|
3
|
-
"version": "25.0.0-
|
|
3
|
+
"version": "25.0.0-alpha13",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -35,21 +35,21 @@
|
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@open-wc/dedupe-mixin": "^1.3.0",
|
|
38
|
-
"@vaadin/button": "25.0.0-
|
|
39
|
-
"@vaadin/component-base": "25.0.0-
|
|
40
|
-
"@vaadin/confirm-dialog": "25.0.0-
|
|
41
|
-
"@vaadin/overlay": "25.0.0-
|
|
42
|
-
"@vaadin/text-field": "25.0.0-
|
|
43
|
-
"@vaadin/tooltip": "25.0.0-
|
|
44
|
-
"@vaadin/vaadin-themable-mixin": "25.0.0-
|
|
38
|
+
"@vaadin/button": "25.0.0-alpha13",
|
|
39
|
+
"@vaadin/component-base": "25.0.0-alpha13",
|
|
40
|
+
"@vaadin/confirm-dialog": "25.0.0-alpha13",
|
|
41
|
+
"@vaadin/overlay": "25.0.0-alpha13",
|
|
42
|
+
"@vaadin/text-field": "25.0.0-alpha13",
|
|
43
|
+
"@vaadin/tooltip": "25.0.0-alpha13",
|
|
44
|
+
"@vaadin/vaadin-themable-mixin": "25.0.0-alpha13",
|
|
45
45
|
"lit": "^3.0.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@vaadin/a11y-base": "25.0.0-
|
|
49
|
-
"@vaadin/chai-plugins": "25.0.0-
|
|
50
|
-
"@vaadin/test-runner-commands": "25.0.0-
|
|
48
|
+
"@vaadin/a11y-base": "25.0.0-alpha13",
|
|
49
|
+
"@vaadin/chai-plugins": "25.0.0-alpha13",
|
|
50
|
+
"@vaadin/test-runner-commands": "25.0.0-alpha13",
|
|
51
51
|
"@vaadin/testing-helpers": "^2.0.0",
|
|
52
|
-
"@vaadin/vaadin-lumo-styles": "25.0.0-
|
|
52
|
+
"@vaadin/vaadin-lumo-styles": "25.0.0-alpha13",
|
|
53
53
|
"sinon": "^18.0.0"
|
|
54
54
|
},
|
|
55
55
|
"cvdlName": "vaadin-rich-text-editor",
|
|
@@ -57,5 +57,5 @@
|
|
|
57
57
|
"web-types.json",
|
|
58
58
|
"web-types.lit.json"
|
|
59
59
|
],
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "182de596226343392135468f021bbce9e6402011"
|
|
61
61
|
}
|
|
@@ -15,7 +15,7 @@ const base = css`
|
|
|
15
15
|
:host {
|
|
16
16
|
background: var(--vaadin-rich-text-editor-background, var(--vaadin-background-color));
|
|
17
17
|
border: var(--vaadin-input-field-border-width, 1px) solid
|
|
18
|
-
var(--vaadin-input-field-border-color, var(--vaadin-border-color
|
|
18
|
+
var(--vaadin-input-field-border-color, var(--vaadin-border-color));
|
|
19
19
|
border-radius: var(--vaadin-input-field-border-radius, var(--vaadin-radius-m));
|
|
20
20
|
box-sizing: border-box;
|
|
21
21
|
display: flex;
|
|
@@ -118,30 +118,61 @@ export const content = css`
|
|
|
118
118
|
.ql-align-right {
|
|
119
119
|
text-align: right;
|
|
120
120
|
}
|
|
121
|
+
|
|
122
|
+
.ql-code-block-container {
|
|
123
|
+
font-family: monospace;
|
|
124
|
+
background-color: var(--vaadin-background-container);
|
|
125
|
+
border-radius: var(--vaadin-radius-s);
|
|
126
|
+
white-space: pre-wrap;
|
|
127
|
+
margin-block: var(--vaadin-padding-s);
|
|
128
|
+
padding: var(--vaadin-padding-container);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.ql-editor li {
|
|
132
|
+
list-style-type: none;
|
|
133
|
+
position: relative;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.ql-editor li > .ql-ui::before {
|
|
137
|
+
display: inline-block;
|
|
138
|
+
margin-left: -1.5em;
|
|
139
|
+
margin-right: 0.3em;
|
|
140
|
+
text-align: right;
|
|
141
|
+
white-space: nowrap;
|
|
142
|
+
width: 1.2em;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.ql-editor li[data-list='bullet'] {
|
|
146
|
+
list-style-type: disc;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.ql-editor li[data-list='ordered'] {
|
|
150
|
+
counter-increment: list-0;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.ql-editor li[data-list='ordered'] > .ql-ui::before {
|
|
154
|
+
content: counter(list-0, decimal) '. ';
|
|
155
|
+
}
|
|
121
156
|
/* quill core end */
|
|
122
157
|
|
|
123
158
|
blockquote {
|
|
124
|
-
border-inline-start: 4px solid var(--vaadin-border-color);
|
|
159
|
+
border-inline-start: 4px solid var(--vaadin-border-color-subtle);
|
|
125
160
|
margin: var(--vaadin-padding-container);
|
|
126
|
-
padding-inline-start: var(--vaadin-padding);
|
|
161
|
+
padding-inline-start: var(--vaadin-padding-s);
|
|
127
162
|
}
|
|
128
163
|
|
|
129
|
-
code
|
|
130
|
-
pre {
|
|
164
|
+
code {
|
|
131
165
|
background-color: var(--vaadin-background-container);
|
|
132
166
|
border-radius: var(--vaadin-radius-s);
|
|
167
|
+
padding: 0.125rem 0.25rem;
|
|
133
168
|
}
|
|
134
169
|
|
|
135
170
|
pre {
|
|
136
171
|
white-space: pre-wrap;
|
|
137
|
-
margin-block: var(--vaadin-padding);
|
|
172
|
+
margin-block: var(--vaadin-padding-s);
|
|
138
173
|
padding: var(--vaadin-padding-container);
|
|
139
174
|
}
|
|
140
175
|
|
|
141
|
-
code {
|
|
142
|
-
padding: 0.125rem 0.25rem;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
176
|
img {
|
|
146
177
|
max-width: 100%;
|
|
147
178
|
}
|
|
@@ -159,8 +190,8 @@ const toolbar = css`
|
|
|
159
190
|
display: flex;
|
|
160
191
|
flex-shrink: 0;
|
|
161
192
|
flex-wrap: wrap;
|
|
162
|
-
gap: var(--vaadin-rich-text-editor-toolbar-gap, var(--vaadin-gap-
|
|
163
|
-
padding: var(--vaadin-rich-text-editor-toolbar-padding, var(--vaadin-padding));
|
|
193
|
+
gap: var(--vaadin-rich-text-editor-toolbar-gap, var(--vaadin-gap-s));
|
|
194
|
+
padding: var(--vaadin-rich-text-editor-toolbar-padding, var(--vaadin-padding-s));
|
|
164
195
|
}
|
|
165
196
|
|
|
166
197
|
[part~='toolbar-group'] {
|
|
@@ -18,7 +18,7 @@ export const richTextEditorPopupOverlay = css`
|
|
|
18
18
|
|
|
19
19
|
[part='content'] {
|
|
20
20
|
display: grid;
|
|
21
|
-
gap: var(--vaadin-rich-text-editor-overlay-gap, var(--vaadin-gap-
|
|
21
|
+
gap: var(--vaadin-rich-text-editor-overlay-gap, var(--vaadin-gap-s));
|
|
22
22
|
grid-template-columns: repeat(7, minmax(0, 1fr));
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -15,34 +15,26 @@ import { I18nMixin } from '@vaadin/component-base/src/i18n-mixin.js';
|
|
|
15
15
|
|
|
16
16
|
const Quill = window.Quill;
|
|
17
17
|
|
|
18
|
-
//
|
|
19
|
-
// See https://github.com/
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
this.remove();
|
|
37
|
-
|
|
38
|
-
return span; // eslint-disable-line no-constructor-return
|
|
18
|
+
// There are some issues e.g. `spellcheck="false"` not preserved
|
|
19
|
+
// See https://github.com/slab/quill/issues/4289
|
|
20
|
+
// Fix to add `spellcheck="false"` on the `<pre>` tag removed by Quill
|
|
21
|
+
const QuillCodeBlockContainer = Quill.import('formats/code-block-container');
|
|
22
|
+
|
|
23
|
+
class CodeBlockContainer extends QuillCodeBlockContainer {
|
|
24
|
+
html(index, length) {
|
|
25
|
+
const markup = super.html(index, length);
|
|
26
|
+
const tempDiv = document.createElement('div');
|
|
27
|
+
tempDiv.innerHTML = markup;
|
|
28
|
+
const preTag = tempDiv.querySelector('pre');
|
|
29
|
+
if (preTag) {
|
|
30
|
+
preTag.setAttribute('spellcheck', 'false');
|
|
31
|
+
return preTag.outerHTML;
|
|
32
|
+
}
|
|
33
|
+
return markup; // fallback
|
|
39
34
|
}
|
|
40
35
|
}
|
|
41
36
|
|
|
42
|
-
|
|
43
|
-
CustomColor.tagName = 'FONT';
|
|
44
|
-
|
|
45
|
-
Quill.register(CustomColor, true);
|
|
37
|
+
Quill.register('formats/code-block-container', CodeBlockContainer, true);
|
|
46
38
|
|
|
47
39
|
const HANDLERS = [
|
|
48
40
|
'bold',
|
|
@@ -69,8 +61,6 @@ const STATE = {
|
|
|
69
61
|
CLICKED: 2,
|
|
70
62
|
};
|
|
71
63
|
|
|
72
|
-
const TAB_KEY = 9;
|
|
73
|
-
|
|
74
64
|
const DEFAULT_I18N = {
|
|
75
65
|
undo: 'undo',
|
|
76
66
|
redo: 'redo',
|
|
@@ -374,23 +364,21 @@ export const RichTextEditorMixin = (superClass) =>
|
|
|
374
364
|
}
|
|
375
365
|
});
|
|
376
366
|
|
|
377
|
-
const TAB_KEY = 9;
|
|
378
|
-
|
|
379
367
|
editorContent.addEventListener('keydown', (e) => {
|
|
380
368
|
if (e.key === 'Escape') {
|
|
381
369
|
if (!this.__tabBindings) {
|
|
382
|
-
this.__tabBindings = this._editor.keyboard.bindings
|
|
383
|
-
this._editor.keyboard.bindings
|
|
370
|
+
this.__tabBindings = this._editor.keyboard.bindings.Tab;
|
|
371
|
+
this._editor.keyboard.bindings.Tab = null;
|
|
384
372
|
}
|
|
385
373
|
} else if (this.__tabBindings) {
|
|
386
|
-
this._editor.keyboard.bindings
|
|
374
|
+
this._editor.keyboard.bindings.Tab = this.__tabBindings;
|
|
387
375
|
this.__tabBindings = null;
|
|
388
376
|
}
|
|
389
377
|
});
|
|
390
378
|
|
|
391
379
|
editorContent.addEventListener('blur', () => {
|
|
392
380
|
if (this.__tabBindings) {
|
|
393
|
-
this._editor.keyboard.bindings
|
|
381
|
+
this._editor.keyboard.bindings.Tab = this.__tabBindings;
|
|
394
382
|
this.__tabBindings = null;
|
|
395
383
|
}
|
|
396
384
|
});
|
|
@@ -496,7 +484,7 @@ export const RichTextEditorMixin = (superClass) =>
|
|
|
496
484
|
buttons[index].focus();
|
|
497
485
|
}
|
|
498
486
|
// Esc and Tab focuses the content
|
|
499
|
-
if (e.keyCode === 27 || (e.
|
|
487
|
+
if (e.keyCode === 27 || (e.key === 'Tab' && !e.shiftKey)) {
|
|
500
488
|
e.preventDefault();
|
|
501
489
|
this._editor.focus();
|
|
502
490
|
}
|
|
@@ -552,19 +540,19 @@ export const RichTextEditorMixin = (superClass) =>
|
|
|
552
540
|
this._toolbar.querySelector('button:not([tabindex])').focus();
|
|
553
541
|
};
|
|
554
542
|
|
|
555
|
-
const keyboard = this._editor.
|
|
556
|
-
const bindings = keyboard.bindings
|
|
543
|
+
const keyboard = this._editor.keyboard;
|
|
544
|
+
const bindings = keyboard.bindings.Tab;
|
|
557
545
|
|
|
558
546
|
// Exclude Quill shift-tab bindings, except for code block,
|
|
559
547
|
// as some of those are breaking when on a newline in the list
|
|
560
548
|
// https://github.com/vaadin/vaadin-rich-text-editor/issues/67
|
|
561
549
|
const originalBindings = bindings.filter((b) => !b.shiftKey || (b.format && b.format['code-block']));
|
|
562
|
-
const moveFocusBinding = { key:
|
|
550
|
+
const moveFocusBinding = { key: 'Tab', shiftKey: true, handler: focusToolbar };
|
|
563
551
|
|
|
564
|
-
keyboard.bindings
|
|
552
|
+
keyboard.bindings.Tab = [...originalBindings, moveFocusBinding];
|
|
565
553
|
|
|
566
554
|
// Alt-f10 focuses a toolbar button
|
|
567
|
-
keyboard.addBinding({ key:
|
|
555
|
+
keyboard.addBinding({ key: 'F10', altKey: true, handler: focusToolbar });
|
|
568
556
|
}
|
|
569
557
|
|
|
570
558
|
/** @private */
|
|
@@ -603,6 +591,7 @@ export const RichTextEditorMixin = (superClass) =>
|
|
|
603
591
|
_applyLink(link) {
|
|
604
592
|
if (link) {
|
|
605
593
|
this._markToolbarClicked();
|
|
594
|
+
this._editor.focus();
|
|
606
595
|
this._editor.format('link', link, SOURCE.USER);
|
|
607
596
|
this._editor.getModule('toolbar').update(this._editor.selection.savedRange);
|
|
608
597
|
}
|
|
@@ -686,6 +675,7 @@ export const RichTextEditorMixin = (superClass) =>
|
|
|
686
675
|
const color = event.detail.color;
|
|
687
676
|
this._colorValue = color === '#000000' ? null : color;
|
|
688
677
|
this._markToolbarClicked();
|
|
678
|
+
this._editor.focus();
|
|
689
679
|
this._editor.format('color', this._colorValue, SOURCE.USER);
|
|
690
680
|
this._toolbar.style.setProperty('--_color-value', this._colorValue);
|
|
691
681
|
this._colorEditing = false;
|
|
@@ -701,6 +691,7 @@ export const RichTextEditorMixin = (superClass) =>
|
|
|
701
691
|
const color = event.detail.color;
|
|
702
692
|
this._backgroundValue = color === '#ffffff' ? null : color;
|
|
703
693
|
this._markToolbarClicked();
|
|
694
|
+
this._editor.focus();
|
|
704
695
|
this._editor.format('background', this._backgroundValue, SOURCE.USER);
|
|
705
696
|
this._toolbar.style.setProperty('--_background-value', this._backgroundValue);
|
|
706
697
|
this._backgroundEditing = false;
|
|
@@ -708,19 +699,8 @@ export const RichTextEditorMixin = (superClass) =>
|
|
|
708
699
|
|
|
709
700
|
/** @private */
|
|
710
701
|
__updateHtmlValue() {
|
|
711
|
-
|
|
712
|
-
let content =
|
|
713
|
-
|
|
714
|
-
// Remove Quill classes, e.g. ql-syntax, except for align
|
|
715
|
-
content = content.replace(/class="([^"]*)"/gu, (_match, group1) => {
|
|
716
|
-
const classes = group1.split(' ').filter((className) => {
|
|
717
|
-
return !className.startsWith('ql-') || className.startsWith('ql-align');
|
|
718
|
-
});
|
|
719
|
-
return `class="${classes.join(' ')}"`;
|
|
720
|
-
});
|
|
721
|
-
// Remove meta spans, e.g. cursor which are empty after Quill classes removed
|
|
722
|
-
content = content.replace(/<span[^>]*><\/span>/gu, '');
|
|
723
|
-
|
|
702
|
+
// We have to use this instead of `innerHTML` to get correct tags like `<pre>` etc.
|
|
703
|
+
let content = this._editor.getSemanticHTML();
|
|
724
704
|
// Replace Quill align classes with inline styles
|
|
725
705
|
[this.__dir === 'rtl' ? 'left' : 'right', 'center', 'justify'].forEach((align) => {
|
|
726
706
|
content = content.replace(
|
|
@@ -728,9 +708,6 @@ export const RichTextEditorMixin = (superClass) =>
|
|
|
728
708
|
` style="text-align: ${align}"`,
|
|
729
709
|
);
|
|
730
710
|
});
|
|
731
|
-
|
|
732
|
-
content = content.replace(/ class=""/gu, '');
|
|
733
|
-
|
|
734
711
|
this._setHtmlValue(content);
|
|
735
712
|
}
|
|
736
713
|
|
|
@@ -778,7 +755,7 @@ export const RichTextEditorMixin = (superClass) =>
|
|
|
778
755
|
htmlValue = htmlValue.replaceAll(/>[^<]*</gu, (match) => match.replaceAll(character, replacement)); // NOSONAR
|
|
779
756
|
});
|
|
780
757
|
|
|
781
|
-
const deltaFromHtml = this._editor.clipboard.convert(htmlValue);
|
|
758
|
+
const deltaFromHtml = this._editor.clipboard.convert({ html: htmlValue });
|
|
782
759
|
|
|
783
760
|
// Restore whitespace characters after the conversion
|
|
784
761
|
Object.entries(whitespaceCharacters).forEach(([character, replacement]) => {
|
|
@@ -59,7 +59,7 @@ export interface RichTextEditorEventMap extends HTMLElementEventMap, RichTextEdi
|
|
|
59
59
|
* `toolbar-group-heading` | The group for heading controls
|
|
60
60
|
* `toolbar-group-style` | The group for style controls
|
|
61
61
|
* `toolbar-group-glyph-transformation` | The group for glyph transformation controls
|
|
62
|
-
* `toolbar-group-
|
|
62
|
+
* `toolbar-group-list` | The group for list controls
|
|
63
63
|
* `toolbar-group-alignment` | The group for alignment controls
|
|
64
64
|
* `toolbar-group-rich-text` | The group for rich text controls
|
|
65
65
|
* `toolbar-group-block` | The group for preformatted block controls
|
|
@@ -57,7 +57,7 @@ import { RichTextEditorMixin } from './vaadin-rich-text-editor-mixin.js';
|
|
|
57
57
|
* `toolbar-group-heading` | The group for heading controls
|
|
58
58
|
* `toolbar-group-style` | The group for style controls
|
|
59
59
|
* `toolbar-group-glyph-transformation` | The group for glyph transformation controls
|
|
60
|
-
* `toolbar-group-
|
|
60
|
+
* `toolbar-group-list` | The group for list controls
|
|
61
61
|
* `toolbar-group-alignment` | The group for alignment controls
|
|
62
62
|
* `toolbar-group-rich-text` | The group for rich text controls
|
|
63
63
|
* `toolbar-group-block` | The group for preformatted block controls
|