neiki-editor 3.7.0 → 3.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/dist/neiki-editor.css +1 -1
- package/dist/neiki-editor.js +134 -10
- package/dist/neiki-editor.min.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<img src="https://img.shields.io/badge/web%20components-29ABE2.svg?style=for-the-badge&logo=webcomponentsdotorg&logoColor=white" alt="Web Components">
|
|
12
12
|
<br>
|
|
13
13
|
<img src="https://img.shields.io/badge/License-AGPL--3.0-2563EB?style=for-the-badge&logo=open-source-initiative&logoColor=white&labelColor=000F15&logoWidth=20" alt="License">
|
|
14
|
-
<img src="https://img.shields.io/badge/Version-3.
|
|
14
|
+
<img src="https://img.shields.io/badge/Version-3.8.0-2563EB?style=for-the-badge&logo=semantic-release&logoColor=white&labelColor=000F15&logoWidth=20" alt="Version">
|
|
15
15
|
</p>
|
|
16
16
|
|
|
17
17
|
<p align="center">
|
|
@@ -140,7 +140,7 @@ The recommended install is the single bundled script from the CDN. CSS is includ
|
|
|
140
140
|
**Pin a specific version**
|
|
141
141
|
|
|
142
142
|
```html
|
|
143
|
-
<script src="https://cdn.neikiri.dev/neiki-editor/3.
|
|
143
|
+
<script src="https://cdn.neikiri.dev/neiki-editor/3.8.0/neiki-editor.min.js"></script>
|
|
144
144
|
```
|
|
145
145
|
|
|
146
146
|
**Load CSS and JS separately**
|
|
@@ -151,8 +151,8 @@ The recommended install is the single bundled script from the CDN. CSS is includ
|
|
|
151
151
|
<script src="https://cdn.neikiri.dev/neiki-editor/neiki-editor.js"></script>
|
|
152
152
|
|
|
153
153
|
<!-- Or pinned -->
|
|
154
|
-
<link rel="stylesheet" href="https://cdn.neikiri.dev/neiki-editor/3.
|
|
155
|
-
<script src="https://cdn.neikiri.dev/neiki-editor/3.
|
|
154
|
+
<link rel="stylesheet" href="https://cdn.neikiri.dev/neiki-editor/3.8.0/neiki-editor.css">
|
|
155
|
+
<script src="https://cdn.neikiri.dev/neiki-editor/3.8.0/neiki-editor.js"></script>
|
|
156
156
|
```
|
|
157
157
|
|
|
158
158
|
**Alternative CDN — jsDelivr**
|
|
@@ -160,7 +160,7 @@ The recommended install is the single bundled script from the CDN. CSS is includ
|
|
|
160
160
|
```html
|
|
161
161
|
<script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@latest/dist/neiki-editor.min.js"></script>
|
|
162
162
|
<!-- Pinned -->
|
|
163
|
-
<script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@3.
|
|
163
|
+
<script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@3.8.0/dist/neiki-editor.min.js"></script>
|
|
164
164
|
```
|
|
165
165
|
|
|
166
166
|
**Package manager**
|
|
@@ -293,7 +293,7 @@ new NeikiEditor('#editor', {
|
|
|
293
293
|
});
|
|
294
294
|
```
|
|
295
295
|
|
|
296
|
-
Available identifiers include text formatting (`bold`, `italic`, `underline`, `strikethrough`, `subscript`, `superscript`, `code`, `removeFormat`), style (`heading`, `fontFamily`, `fontSize`, `foreColor`, `backColor`), alignment and lists (`alignLeft`, `alignCenter`, `alignRight`, `alignJustify`, `bulletList`, `numberedList`, `indent`, `outdent`), structure (`blockquote`, `horizontalRule`), tools (`undo`, `redo`, `findReplace`, `viewCode`), the grouped `insertDropdown`, the right-aligned `moreMenu`, and a standalone `themeToggle`. See the [Toolbar Reference](https://github.com/neikiri/neiki-editor/wiki/Toolbar-Reference) for the full list.
|
|
296
|
+
Available identifiers include text formatting (`bold`, `italic`, `underline`, `strikethrough`, `subscript`, `superscript`, `code`, `formatPainter`, `removeFormat`), style (`heading`, `fontFamily`, `fontSize`, `foreColor`, `backColor`), alignment and lists (`alignLeft`, `alignCenter`, `alignRight`, `alignJustify`, `bulletList`, `numberedList`, `indent`, `outdent`), structure (`blockquote`, `horizontalRule`), tools (`undo`, `redo`, `findReplace`, `viewCode`), the grouped `insertDropdown`, the right-aligned `moreMenu`, and a standalone `themeToggle`. See the [Toolbar Reference](https://github.com/neikiri/neiki-editor/wiki/Toolbar-Reference) for the full list.
|
|
297
297
|
|
|
298
298
|
### Customizing the floating toolbar
|
|
299
299
|
|
package/dist/neiki-editor.css
CHANGED
package/dist/neiki-editor.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* NeikiEditor - A Modern WYSIWYG Editor
|
|
3
|
-
* Version: 3.
|
|
3
|
+
* Version: 3.8.0
|
|
4
4
|
*
|
|
5
5
|
* A lightweight, feature-rich text editor with support for:
|
|
6
6
|
* - Rich text formatting (bold, italic, underline, etc.)
|
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
'toolbar.horizontalRule': 'Horizontal Line',
|
|
61
61
|
'toolbar.subscript': 'Subscript',
|
|
62
62
|
'toolbar.superscript': 'Superscript',
|
|
63
|
+
'toolbar.formatPainter': 'Copy Formatting',
|
|
63
64
|
'toolbar.removeFormat': 'Remove Formatting',
|
|
64
65
|
'toolbar.findReplace': 'Find & Replace',
|
|
65
66
|
'toolbar.emoji': 'Insert Emoji',
|
|
@@ -260,6 +261,7 @@
|
|
|
260
261
|
'toolbar.horizontalRule': 'Vodorovná čára',
|
|
261
262
|
'toolbar.subscript': 'Dolní index',
|
|
262
263
|
'toolbar.superscript': 'Horní index',
|
|
264
|
+
'toolbar.formatPainter': 'Kopírovat formátování',
|
|
263
265
|
'toolbar.removeFormat': 'Odstranit formátování',
|
|
264
266
|
'toolbar.findReplace': 'Najít a nahradit',
|
|
265
267
|
'toolbar.emoji': 'Vložit emoji',
|
|
@@ -453,6 +455,7 @@
|
|
|
453
455
|
'toolbar.horizontalRule': '水平线',
|
|
454
456
|
'toolbar.subscript': '下标',
|
|
455
457
|
'toolbar.superscript': '上标',
|
|
458
|
+
'toolbar.formatPainter': '复制格式',
|
|
456
459
|
'toolbar.removeFormat': '清除格式',
|
|
457
460
|
'toolbar.findReplace': '查找和替换',
|
|
458
461
|
'toolbar.emoji': '插入表情',
|
|
@@ -621,6 +624,7 @@
|
|
|
621
624
|
'toolbar.horizontalRule': 'Línea horizontal',
|
|
622
625
|
'toolbar.subscript': 'Subíndice',
|
|
623
626
|
'toolbar.superscript': 'Superíndice',
|
|
627
|
+
'toolbar.formatPainter': 'Copiar formato',
|
|
624
628
|
'toolbar.removeFormat': 'Eliminar formato',
|
|
625
629
|
'toolbar.findReplace': 'Buscar y reemplazar',
|
|
626
630
|
'toolbar.emoji': 'Insertar emoji',
|
|
@@ -789,6 +793,7 @@
|
|
|
789
793
|
'toolbar.horizontalRule': 'Horizontale Linie',
|
|
790
794
|
'toolbar.subscript': 'Tiefgestellt',
|
|
791
795
|
'toolbar.superscript': 'Hochgestellt',
|
|
796
|
+
'toolbar.formatPainter': 'Format kopieren',
|
|
792
797
|
'toolbar.removeFormat': 'Formatierung entfernen',
|
|
793
798
|
'toolbar.findReplace': 'Suchen und Ersetzen',
|
|
794
799
|
'toolbar.emoji': 'Emoji einfügen',
|
|
@@ -957,6 +962,7 @@
|
|
|
957
962
|
'toolbar.horizontalRule': 'Ligne horizontale',
|
|
958
963
|
'toolbar.subscript': 'Indice',
|
|
959
964
|
'toolbar.superscript': 'Exposant',
|
|
965
|
+
'toolbar.formatPainter': 'Copier la mise en forme',
|
|
960
966
|
'toolbar.removeFormat': 'Supprimer la mise en forme',
|
|
961
967
|
'toolbar.findReplace': 'Rechercher et remplacer',
|
|
962
968
|
'toolbar.emoji': 'Insérer un emoji',
|
|
@@ -1125,6 +1131,7 @@
|
|
|
1125
1131
|
'toolbar.horizontalRule': 'Linha horizontal',
|
|
1126
1132
|
'toolbar.subscript': 'Subscrito',
|
|
1127
1133
|
'toolbar.superscript': 'Sobrescrito',
|
|
1134
|
+
'toolbar.formatPainter': 'Copiar formatação',
|
|
1128
1135
|
'toolbar.removeFormat': 'Remover formatação',
|
|
1129
1136
|
'toolbar.findReplace': 'Localizar e substituir',
|
|
1130
1137
|
'toolbar.emoji': 'Inserir emoji',
|
|
@@ -1293,6 +1300,7 @@
|
|
|
1293
1300
|
'toolbar.horizontalRule': '水平線',
|
|
1294
1301
|
'toolbar.subscript': '下付き',
|
|
1295
1302
|
'toolbar.superscript': '上付き',
|
|
1303
|
+
'toolbar.formatPainter': '書式のコピー',
|
|
1296
1304
|
'toolbar.removeFormat': '書式解除',
|
|
1297
1305
|
'toolbar.findReplace': '検索と置換',
|
|
1298
1306
|
'toolbar.emoji': '絵文字挿入',
|
|
@@ -1473,7 +1481,7 @@
|
|
|
1473
1481
|
const DEFAULT_CONFIG = {
|
|
1474
1482
|
toolbar: [
|
|
1475
1483
|
'viewCode', 'undo', 'redo', 'findReplace', '|',
|
|
1476
|
-
'bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript', 'code', 'removeFormat', '|',
|
|
1484
|
+
'bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript', 'code', 'formatPainter', 'removeFormat', '|',
|
|
1477
1485
|
'heading', 'fontFamily', 'fontSize', '|',
|
|
1478
1486
|
'foreColor', 'backColor', '|',
|
|
1479
1487
|
'alignLeft', 'alignCenter', 'alignRight', 'alignJustify', '|',
|
|
@@ -1536,6 +1544,7 @@
|
|
|
1536
1544
|
subscript: { icon: 'subscript', titleKey: 'toolbar.subscript', command: 'subscript' },
|
|
1537
1545
|
superscript: { icon: 'superscript', titleKey: 'toolbar.superscript', command: 'superscript' },
|
|
1538
1546
|
code: { icon: 'code-inline', titleKey: 'toolbar.code', command: 'toggleCode' },
|
|
1547
|
+
formatPainter: { icon: 'format-painter', titleKey: 'toolbar.formatPainter', command: 'copyFormat' },
|
|
1539
1548
|
removeFormat: { icon: 'eraser', titleKey: 'toolbar.removeFormat', command: 'removeFormat' },
|
|
1540
1549
|
findReplace: { icon: 'search', titleKey: 'toolbar.findReplace', command: 'findReplace', modal: true },
|
|
1541
1550
|
emoji: { icon: 'emoji', titleKey: 'toolbar.emoji', command: 'emoji', picker: 'emoji' },
|
|
@@ -2097,6 +2106,7 @@
|
|
|
2097
2106
|
quote: '<svg viewBox="0 0 24 24"><path d="M6 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z"/></svg>',
|
|
2098
2107
|
code: '<svg viewBox="0 0 24 24"><path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"/></svg>',
|
|
2099
2108
|
'code-inline': '<svg viewBox="0 0 256 256"><path d="M0 0h256v256H0z" fill="none"/><path fill="currentColor" d="M71.68 97.22L34.74 128l36.94 30.78a12 12 0 1 1-15.36 18.44l-48-40a12 12 0 0 1 0-18.44l48-40a12 12 0 0 1 15.36 18.44m176 21.56l-48-40a12 12 0 1 0-15.36 18.44L221.26 128l-36.94 30.78a12 12 0 1 0 15.36 18.44l48-40a12 12 0 0 0 0-18.44M164.1 28.72a12 12 0 0 0-15.38 7.18l-64 176a12 12 0 0 0 7.18 15.37a11.8 11.8 0 0 0 4.1.73a12 12 0 0 0 11.28-7.9l64-176a12 12 0 0 0-7.18-15.38"/></svg>',
|
|
2109
|
+
'format-painter': '<svg width="1em" height="1em" viewBox="0 0 32 32"><g transform="translate(0 32) scale(1 -1)"><path d="M0 0h32v32H0z" fill="none"/><path fill="currentColor" d="M28.83 23.17L23 17.33V13a1 1 0 0 0-.29-.71l-10-10a1 1 0 0 0-1.42 0l-9 9a1 1 0 0 0 0 1.42l10 10A1 1 0 0 0 13 23h4.34l5.83 5.84a4 4 0 0 0 5.66-5.66ZM6 10.41l2.29 2.3l1.42-1.42L7.41 9L9 7.41l4.29 4.3l1.42-1.42L10.41 6L12 4.41L18.59 11L11 18.59L4.41 12Zm21.41 17a2 2 0 0 1-2.82 0l-6.13-6.12a1.8 1.8 0 0 0-.71-.29h-4.34l-1-1L20 12.41l1 1v4.34a1 1 0 0 0 .29.7l6.12 6.14a2 2 0 0 1 0 2.82" stroke-width="0.45" stroke="currentColor"/></g></svg>',
|
|
2100
2110
|
minus: '<svg viewBox="0 0 24 24"><path d="M19 13H5v-2h14v2z"/></svg>',
|
|
2101
2111
|
eraser: '<svg viewBox="0 0 24 24"><path d="M16.24 3.56l4.95 4.94c.78.79.78 2.05 0 2.84L12 20.53a4.008 4.008 0 01-5.66 0L2.81 17c-.78-.79-.78-2.05 0-2.84l10.6-10.6c.79-.78 2.05-.78 2.83 0zm-1.41 1.42L6.93 12.9l4.24 4.24 7.9-7.9-4.24-4.26z"/></svg>',
|
|
2102
2112
|
fullscreen: '<svg viewBox="0 0 24 24"><path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/></svg>',
|
|
@@ -3115,7 +3125,7 @@
|
|
|
3115
3125
|
<img src="https://github.com/neikiri/neiki-editor/raw/main/assets/logo.svg" alt="Neiki's Editor" style="width: 240px; height: auto; margin: 0 auto 16px; display: block;">
|
|
3116
3126
|
<div style="font-size: 14px; line-height: 2; color: var(--neiki-text-primary);">
|
|
3117
3127
|
<div><strong>${Utils.escapeHTML(t('help.author'))}:</strong> neikiri (Jindřich Stoklasa)</div>
|
|
3118
|
-
<div><strong>${Utils.escapeHTML(t('help.version'))}:</strong> 3.
|
|
3128
|
+
<div><strong>${Utils.escapeHTML(t('help.version'))}:</strong> 3.8.0</div>
|
|
3119
3129
|
<div><strong>${Utils.escapeHTML(t('help.github'))}:</strong> <a href="https://github.com/neikiri/neiki-editor" target="_blank" rel="noopener noreferrer" style="color: var(--neiki-accent);">github.com/neikiri/neiki-editor</a></div>
|
|
3120
3130
|
<div><strong>${Utils.escapeHTML(t('help.documentation'))}:</strong> <a href="https://github.com/neikiri/neiki-editor/wiki" target="_blank" rel="noopener noreferrer" style="color: var(--neiki-accent);">Wiki</a></div>
|
|
3121
3131
|
</div>
|
|
@@ -3533,6 +3543,7 @@
|
|
|
3533
3543
|
class Commands {
|
|
3534
3544
|
constructor(editor) {
|
|
3535
3545
|
this.editor = editor;
|
|
3546
|
+
this.formatPainter = null;
|
|
3536
3547
|
}
|
|
3537
3548
|
|
|
3538
3549
|
exec(command, value = null) {
|
|
@@ -3693,6 +3704,102 @@
|
|
|
3693
3704
|
|
|
3694
3705
|
removeFormat() { this.exec('removeFormat'); }
|
|
3695
3706
|
|
|
3707
|
+
isFormatPainterActive() {
|
|
3708
|
+
return !!this.formatPainter;
|
|
3709
|
+
}
|
|
3710
|
+
|
|
3711
|
+
copyFormat() {
|
|
3712
|
+
if (this.formatPainter) {
|
|
3713
|
+
this.formatPainter = null;
|
|
3714
|
+
this.editor.updateToolbar();
|
|
3715
|
+
return;
|
|
3716
|
+
}
|
|
3717
|
+
|
|
3718
|
+
if (!this.editor.restoreSavedSelection()) return;
|
|
3719
|
+
this._expandToWordIfCollapsed();
|
|
3720
|
+
|
|
3721
|
+
const selection = window.getSelection();
|
|
3722
|
+
if (!selection || !selection.rangeCount) return;
|
|
3723
|
+
const range = selection.getRangeAt(0);
|
|
3724
|
+
if (!Utils.isRangeInside(range, this.editor.contentArea) || range.collapsed) return;
|
|
3725
|
+
|
|
3726
|
+
let sourceNode = range.startContainer;
|
|
3727
|
+
if (sourceNode.nodeType === Node.TEXT_NODE) sourceNode = sourceNode.parentNode;
|
|
3728
|
+
const sourceStyle = window.getComputedStyle(sourceNode);
|
|
3729
|
+
const inlineCommands = ['bold', 'italic', 'underline', 'strikeThrough', 'subscript', 'superscript'];
|
|
3730
|
+
const states = {};
|
|
3731
|
+
|
|
3732
|
+
inlineCommands.forEach(command => {
|
|
3733
|
+
try {
|
|
3734
|
+
states[command] = document.queryCommandState(command);
|
|
3735
|
+
} catch (e) {
|
|
3736
|
+
states[command] = false;
|
|
3737
|
+
}
|
|
3738
|
+
});
|
|
3739
|
+
|
|
3740
|
+
this.formatPainter = {
|
|
3741
|
+
sourceRange: range.cloneRange(),
|
|
3742
|
+
states,
|
|
3743
|
+
fontFamily: sourceStyle.fontFamily,
|
|
3744
|
+
fontSize: sourceStyle.fontSize,
|
|
3745
|
+
color: sourceStyle.color,
|
|
3746
|
+
backgroundColor: sourceStyle.backgroundColor
|
|
3747
|
+
};
|
|
3748
|
+
this.editor.saveCurrentSelection();
|
|
3749
|
+
this.editor.updateToolbar();
|
|
3750
|
+
}
|
|
3751
|
+
|
|
3752
|
+
applyCopiedFormat() {
|
|
3753
|
+
if (!this.formatPainter) return false;
|
|
3754
|
+
|
|
3755
|
+
const selection = window.getSelection();
|
|
3756
|
+
if (!selection || !selection.rangeCount) return false;
|
|
3757
|
+
const range = selection.getRangeAt(0);
|
|
3758
|
+
if (!Utils.isRangeInside(range, this.editor.contentArea) || this._areRangesEqual(range, this.formatPainter.sourceRange)) {
|
|
3759
|
+
return false;
|
|
3760
|
+
}
|
|
3761
|
+
|
|
3762
|
+
this._expandToWordIfCollapsed();
|
|
3763
|
+
const style = this.formatPainter;
|
|
3764
|
+
this.formatPainter = null;
|
|
3765
|
+
|
|
3766
|
+
Object.entries(style.states).forEach(([command, shouldBeActive]) => {
|
|
3767
|
+
try {
|
|
3768
|
+
if (document.queryCommandState(command) !== shouldBeActive) {
|
|
3769
|
+
document.execCommand(command, false, null);
|
|
3770
|
+
}
|
|
3771
|
+
} catch (e) { /* Ignore unsupported command states. */ }
|
|
3772
|
+
});
|
|
3773
|
+
|
|
3774
|
+
if (style.fontFamily) document.execCommand('fontName', false, style.fontFamily);
|
|
3775
|
+
if (style.fontSize) this._applyFontSize(style.fontSize);
|
|
3776
|
+
if (style.color) document.execCommand('foreColor', false, style.color);
|
|
3777
|
+
if (this._isTransparentColor(style.backgroundColor)) {
|
|
3778
|
+
this._resetColorProperty('backgroundColor', false);
|
|
3779
|
+
} else if (style.backgroundColor) {
|
|
3780
|
+
document.execCommand('backColor', false, style.backgroundColor);
|
|
3781
|
+
}
|
|
3782
|
+
|
|
3783
|
+
this.editor.history.record();
|
|
3784
|
+
this.editor.updateToolbar();
|
|
3785
|
+
this.editor.triggerChange();
|
|
3786
|
+
return true;
|
|
3787
|
+
}
|
|
3788
|
+
|
|
3789
|
+
_areRangesEqual(first, second) {
|
|
3790
|
+
if (!first || !second) return false;
|
|
3791
|
+
try {
|
|
3792
|
+
return first.compareBoundaryPoints(Range.START_TO_START, second) === 0 &&
|
|
3793
|
+
first.compareBoundaryPoints(Range.END_TO_END, second) === 0;
|
|
3794
|
+
} catch (e) {
|
|
3795
|
+
return false;
|
|
3796
|
+
}
|
|
3797
|
+
}
|
|
3798
|
+
|
|
3799
|
+
_isTransparentColor(color) {
|
|
3800
|
+
return !color || color === 'transparent' || /^rgba\(0,\s*0,\s*0,\s*0\)$/.test(color);
|
|
3801
|
+
}
|
|
3802
|
+
|
|
3696
3803
|
insertHorizontalRule() { this.exec('insertHorizontalRule'); }
|
|
3697
3804
|
|
|
3698
3805
|
formatBlock(tag) {
|
|
@@ -3774,9 +3881,7 @@
|
|
|
3774
3881
|
return ['ADDRESS', 'ARTICLE', 'ASIDE', 'BLOCKQUOTE', 'DIV', 'DL', 'FIGURE', 'FOOTER', 'FORM', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'HEADER', 'HR', 'MAIN', 'OL', 'P', 'PRE', 'SECTION', 'TABLE', 'UL'].includes(node.tagName);
|
|
3775
3882
|
}
|
|
3776
3883
|
|
|
3777
|
-
|
|
3778
|
-
this.editor.focus();
|
|
3779
|
-
this._expandToWordIfCollapsed();
|
|
3884
|
+
_applyFontSize(sizeStr) {
|
|
3780
3885
|
document.execCommand('fontSize', false, '7');
|
|
3781
3886
|
const marked = this.editor.contentArea.querySelectorAll('font[size="7"]');
|
|
3782
3887
|
const spans = [];
|
|
@@ -3799,6 +3904,12 @@
|
|
|
3799
3904
|
sel.addRange(range);
|
|
3800
3905
|
} catch (e) { /* ignore */ }
|
|
3801
3906
|
}
|
|
3907
|
+
}
|
|
3908
|
+
|
|
3909
|
+
fontSize(sizeStr) {
|
|
3910
|
+
this.editor.focus();
|
|
3911
|
+
this._expandToWordIfCollapsed();
|
|
3912
|
+
this._applyFontSize(sizeStr);
|
|
3802
3913
|
this.editor.history.record();
|
|
3803
3914
|
this.editor.updateToolbar();
|
|
3804
3915
|
this.editor.triggerChange();
|
|
@@ -3824,7 +3935,7 @@
|
|
|
3824
3935
|
this._resetColorProperty('backgroundColor');
|
|
3825
3936
|
}
|
|
3826
3937
|
|
|
3827
|
-
_resetColorProperty(cssProp) {
|
|
3938
|
+
_resetColorProperty(cssProp, shouldRecord = true) {
|
|
3828
3939
|
this.editor.focus();
|
|
3829
3940
|
const sel = window.getSelection();
|
|
3830
3941
|
if (!sel || !sel.rangeCount) return;
|
|
@@ -3873,9 +3984,11 @@
|
|
|
3873
3984
|
sel.removeAllRanges();
|
|
3874
3985
|
sel.addRange(range);
|
|
3875
3986
|
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3987
|
+
if (shouldRecord) {
|
|
3988
|
+
this.editor.history.record();
|
|
3989
|
+
this.editor.updateToolbar();
|
|
3990
|
+
this.editor.triggerChange();
|
|
3991
|
+
}
|
|
3879
3992
|
}
|
|
3880
3993
|
|
|
3881
3994
|
viewCode() {
|
|
@@ -4831,6 +4944,13 @@
|
|
|
4831
4944
|
}
|
|
4832
4945
|
});
|
|
4833
4946
|
|
|
4947
|
+
// Format Painter applies its copied inline formatting once the target selection is complete.
|
|
4948
|
+
this.contentArea.addEventListener('mouseup', () => {
|
|
4949
|
+
if (this.commands && this.commands.isFormatPainterActive()) {
|
|
4950
|
+
this.commands.applyCopiedFormat();
|
|
4951
|
+
}
|
|
4952
|
+
});
|
|
4953
|
+
|
|
4834
4954
|
// Focus/Blur
|
|
4835
4955
|
this.contentArea.addEventListener('focus', () => {
|
|
4836
4956
|
if (this.config.onFocus) this.config.onFocus(this);
|
|
@@ -5176,6 +5296,10 @@
|
|
|
5176
5296
|
if (this.toolbarButtons.viewCode) {
|
|
5177
5297
|
this.toolbarButtons.viewCode.classList.toggle('active', this.isCodeViewOpen);
|
|
5178
5298
|
}
|
|
5299
|
+
if (this.toolbarButtons.formatPainter) {
|
|
5300
|
+
this.toolbarButtons.formatPainter.classList.toggle('active',
|
|
5301
|
+
!!(this.commands && this.commands.isFormatPainterActive()));
|
|
5302
|
+
}
|
|
5179
5303
|
|
|
5180
5304
|
// Sync heading select
|
|
5181
5305
|
if (this.toolbarSelects.heading) {
|