@ckeditor/ckeditor5-font 48.8.1-alpha.3 → 49.0.0-alpha.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/dist/augmentation.d.ts +56 -56
- package/dist/font.d.ts +32 -32
- package/dist/fontbackgroundcolor/fontbackgroundcolorcommand.d.ts +21 -21
- package/dist/fontbackgroundcolor/fontbackgroundcolorediting.d.ts +25 -25
- package/dist/fontbackgroundcolor/fontbackgroundcolorui.d.ts +15 -15
- package/dist/fontbackgroundcolor.d.ts +29 -29
- package/dist/fontcolor/fontcolorcommand.d.ts +20 -20
- package/dist/fontcolor/fontcolorediting.d.ts +25 -25
- package/dist/fontcolor/fontcolorui.d.ts +15 -15
- package/dist/fontcolor.d.ts +28 -28
- package/dist/fontcommand.d.ts +43 -43
- package/dist/fontconfig.d.ts +289 -356
- package/dist/fontfamily/fontfamilycommand.d.ts +20 -20
- package/dist/fontfamily/fontfamilyediting.d.ts +38 -38
- package/dist/fontfamily/fontfamilyui.d.ts +29 -29
- package/dist/fontfamily/utils.d.ts +16 -16
- package/dist/fontfamily.d.ts +28 -28
- package/dist/fontsize/fontsizecommand.d.ts +20 -20
- package/dist/fontsize/fontsizeediting.d.ts +43 -43
- package/dist/fontsize/fontsizeui.d.ts +29 -30
- package/dist/fontsize/utils.d.ts +10 -10
- package/dist/fontsize.d.ts +36 -36
- package/dist/index-content.css +20 -16
- package/dist/index-content.css.map +1 -0
- package/dist/index-editor.css +3 -6
- package/dist/index-editor.css.map +1 -0
- package/dist/index.css +14 -12
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +31 -29
- package/dist/index.js +1465 -1568
- package/dist/index.js.map +1 -1
- package/dist/translations/af.js +1 -1
- package/dist/translations/af.umd.js +5 -3
- package/dist/translations/ar.js +1 -1
- package/dist/translations/ar.umd.js +5 -3
- package/dist/translations/ast.js +1 -1
- package/dist/translations/ast.umd.js +5 -3
- package/dist/translations/az.js +1 -1
- package/dist/translations/az.umd.js +5 -3
- package/dist/translations/be.js +1 -1
- package/dist/translations/be.umd.js +5 -3
- package/dist/translations/bg.js +1 -1
- package/dist/translations/bg.umd.js +5 -3
- package/dist/translations/bn.js +1 -1
- package/dist/translations/bn.umd.js +5 -3
- package/dist/translations/bs.js +1 -1
- package/dist/translations/bs.umd.js +5 -3
- package/dist/translations/ca.js +1 -1
- package/dist/translations/ca.umd.js +5 -3
- package/dist/translations/cs.js +1 -1
- package/dist/translations/cs.umd.js +5 -3
- package/dist/translations/da.js +1 -1
- package/dist/translations/da.umd.js +5 -3
- package/dist/translations/de-ch.js +1 -1
- package/dist/translations/de-ch.umd.js +5 -3
- package/dist/translations/de.js +1 -1
- package/dist/translations/de.umd.js +5 -3
- package/dist/translations/el.js +1 -1
- package/dist/translations/el.umd.js +5 -3
- package/dist/translations/en-au.js +1 -1
- package/dist/translations/en-au.umd.js +5 -3
- package/dist/translations/en-gb.js +1 -1
- package/dist/translations/en-gb.umd.js +5 -3
- package/dist/translations/en.js +1 -1
- package/dist/translations/en.umd.js +5 -3
- package/dist/translations/eo.js +1 -1
- package/dist/translations/eo.umd.js +5 -3
- package/dist/translations/es-co.js +1 -1
- package/dist/translations/es-co.umd.js +5 -3
- package/dist/translations/es.js +1 -1
- package/dist/translations/es.umd.js +5 -3
- package/dist/translations/et.js +1 -1
- package/dist/translations/et.umd.js +5 -3
- package/dist/translations/eu.js +1 -1
- package/dist/translations/eu.umd.js +5 -3
- package/dist/translations/fa.js +1 -1
- package/dist/translations/fa.umd.js +5 -3
- package/dist/translations/fi.js +1 -1
- package/dist/translations/fi.umd.js +5 -3
- package/dist/translations/fr.js +1 -1
- package/dist/translations/fr.umd.js +5 -3
- package/dist/translations/gl.js +1 -1
- package/dist/translations/gl.umd.js +5 -3
- package/dist/translations/gu.js +1 -1
- package/dist/translations/gu.umd.js +5 -3
- package/dist/translations/he.js +1 -1
- package/dist/translations/he.umd.js +5 -3
- package/dist/translations/hi.js +1 -1
- package/dist/translations/hi.umd.js +5 -3
- package/dist/translations/hr.js +1 -1
- package/dist/translations/hr.umd.js +5 -3
- package/dist/translations/hu.js +1 -1
- package/dist/translations/hu.umd.js +5 -3
- package/dist/translations/hy.js +1 -1
- package/dist/translations/hy.umd.js +5 -3
- package/dist/translations/id.js +1 -1
- package/dist/translations/id.umd.js +5 -3
- package/dist/translations/it.js +1 -1
- package/dist/translations/it.umd.js +5 -3
- package/dist/translations/ja.js +1 -1
- package/dist/translations/ja.umd.js +5 -3
- package/dist/translations/jv.js +1 -1
- package/dist/translations/jv.umd.js +5 -3
- package/dist/translations/kk.js +1 -1
- package/dist/translations/kk.umd.js +5 -3
- package/dist/translations/km.js +1 -1
- package/dist/translations/km.umd.js +5 -3
- package/dist/translations/kn.js +1 -1
- package/dist/translations/kn.umd.js +5 -3
- package/dist/translations/ko.js +1 -1
- package/dist/translations/ko.umd.js +5 -3
- package/dist/translations/ku.js +1 -1
- package/dist/translations/ku.umd.js +5 -3
- package/dist/translations/lt.js +1 -1
- package/dist/translations/lt.umd.js +5 -3
- package/dist/translations/lv.js +1 -1
- package/dist/translations/lv.umd.js +5 -3
- package/dist/translations/ms.js +1 -1
- package/dist/translations/ms.umd.js +5 -3
- package/dist/translations/nb.js +1 -1
- package/dist/translations/nb.umd.js +5 -3
- package/dist/translations/ne.js +1 -1
- package/dist/translations/ne.umd.js +5 -3
- package/dist/translations/nl.js +1 -1
- package/dist/translations/nl.umd.js +5 -3
- package/dist/translations/no.js +1 -1
- package/dist/translations/no.umd.js +5 -3
- package/dist/translations/oc.js +1 -1
- package/dist/translations/oc.umd.js +5 -3
- package/dist/translations/pl.js +1 -1
- package/dist/translations/pl.umd.js +5 -3
- package/dist/translations/pt-br.js +1 -1
- package/dist/translations/pt-br.umd.js +5 -3
- package/dist/translations/pt.js +1 -1
- package/dist/translations/pt.umd.js +5 -3
- package/dist/translations/ro.js +1 -1
- package/dist/translations/ro.umd.js +5 -3
- package/dist/translations/ru.js +1 -1
- package/dist/translations/ru.umd.js +5 -3
- package/dist/translations/si.js +1 -1
- package/dist/translations/si.umd.js +5 -3
- package/dist/translations/sk.js +1 -1
- package/dist/translations/sk.umd.js +5 -3
- package/dist/translations/sl.js +1 -1
- package/dist/translations/sl.umd.js +5 -3
- package/dist/translations/sq.js +1 -1
- package/dist/translations/sq.umd.js +5 -3
- package/dist/translations/sr-latn.js +1 -1
- package/dist/translations/sr-latn.umd.js +5 -3
- package/dist/translations/sr.js +1 -1
- package/dist/translations/sr.umd.js +5 -3
- package/dist/translations/sv.js +1 -1
- package/dist/translations/sv.umd.js +5 -3
- package/dist/translations/th.js +1 -1
- package/dist/translations/th.umd.js +5 -3
- package/dist/translations/ti.js +1 -1
- package/dist/translations/ti.umd.js +5 -3
- package/dist/translations/tk.js +1 -1
- package/dist/translations/tk.umd.js +5 -3
- package/dist/translations/tr.js +1 -1
- package/dist/translations/tr.umd.js +5 -3
- package/dist/translations/tt.js +1 -1
- package/dist/translations/tt.umd.js +5 -3
- package/dist/translations/ug.js +1 -1
- package/dist/translations/ug.umd.js +5 -3
- package/dist/translations/uk.js +1 -1
- package/dist/translations/uk.umd.js +5 -3
- package/dist/translations/ur.js +1 -1
- package/dist/translations/ur.umd.js +5 -3
- package/dist/translations/uz.js +1 -1
- package/dist/translations/uz.umd.js +5 -3
- package/dist/translations/vi.js +1 -1
- package/dist/translations/vi.umd.js +5 -3
- package/dist/translations/zh-cn.js +1 -1
- package/dist/translations/zh-cn.umd.js +5 -3
- package/dist/translations/zh.js +1 -1
- package/dist/translations/zh.umd.js +5 -3
- package/dist/ui/colorui.d.ts +59 -59
- package/dist/utils.d.ts +69 -69
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -2,1656 +2,1553 @@
|
|
|
2
2
|
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
4
|
*/
|
|
5
|
-
import { Command, Plugin } from
|
|
6
|
-
import { ModelDocumentSelection, isLengthStyleValue, isPercentageStyleValue
|
|
7
|
-
import { ColorSelectorView,
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
5
|
+
import { Command, Plugin } from "@ckeditor/ckeditor5-core";
|
|
6
|
+
import { ModelDocumentSelection, addBackgroundStylesRules, isLengthStyleValue, isPercentageStyleValue } from "@ckeditor/ckeditor5-engine";
|
|
7
|
+
import { ColorSelectorView, MenuBarMenuListItemButtonView, MenuBarMenuListItemView, MenuBarMenuListView, MenuBarMenuView, UIModel, _DEFAULT_COLORS, _DEFAULT_COLOR_GRID_COLUMNS, addListToDropdown, createDropdown, focusChildOnDropdownOpen, getLocalizedColorOptions, normalizeColorOptions } from "@ckeditor/ckeditor5-ui";
|
|
8
|
+
import { CKEditorError, Collection } from "@ckeditor/ckeditor5-utils";
|
|
9
|
+
import { IconFontBackground, IconFontColor, IconFontFamily, IconFontSize } from "@ckeditor/ckeditor5-icons";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
12
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
13
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* @module font/fontcommand
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* The base font command.
|
|
20
|
+
*/
|
|
21
|
+
var FontCommand = class extends Command {
|
|
22
|
+
/**
|
|
23
|
+
* A model attribute on which this command operates.
|
|
24
|
+
*/
|
|
25
|
+
attributeKey;
|
|
26
|
+
/**
|
|
27
|
+
* Creates an instance of the command.
|
|
28
|
+
*
|
|
29
|
+
* @param editor Editor instance.
|
|
30
|
+
* @param attributeKey The name of a model attribute on which this command operates.
|
|
31
|
+
*/
|
|
32
|
+
constructor(editor, attributeKey) {
|
|
33
|
+
super(editor);
|
|
34
|
+
this.attributeKey = attributeKey;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* @inheritDoc
|
|
38
|
+
*/
|
|
39
|
+
refresh() {
|
|
40
|
+
const model = this.editor.model;
|
|
41
|
+
const doc = model.document;
|
|
42
|
+
this.value = doc.selection.getAttribute(this.attributeKey);
|
|
43
|
+
this.isEnabled = model.schema.checkAttributeInSelection(doc.selection, this.attributeKey);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Executes the command. Applies the `value` of the {@link #attributeKey} to the selection.
|
|
47
|
+
* If no `value` is passed, it removes the attribute from the selection.
|
|
48
|
+
*
|
|
49
|
+
* @param options Options for the executed command.
|
|
50
|
+
* @param options.value The value to apply.
|
|
51
|
+
* @fires execute
|
|
52
|
+
*/
|
|
53
|
+
execute(options = {}) {
|
|
54
|
+
const model = this.editor.model;
|
|
55
|
+
const selection = model.document.selection;
|
|
56
|
+
const value = options.value;
|
|
57
|
+
const batch = options.batch;
|
|
58
|
+
const updateAttribute = (writer) => {
|
|
59
|
+
if (selection.isCollapsed) {
|
|
60
|
+
if (value) writer.setSelectionAttribute(this.attributeKey, value);
|
|
61
|
+
else writer.removeSelectionAttribute(this.attributeKey);
|
|
62
|
+
} else {
|
|
63
|
+
const ranges = model.schema.getValidRanges(selection.getRanges(), this.attributeKey, { includeEmptyRanges: true });
|
|
64
|
+
for (const range of ranges) {
|
|
65
|
+
let itemOrRange = range;
|
|
66
|
+
let attributeKey = this.attributeKey;
|
|
67
|
+
if (range.isCollapsed) {
|
|
68
|
+
itemOrRange = range.start.parent;
|
|
69
|
+
attributeKey = ModelDocumentSelection._getStoreAttributeKey(this.attributeKey);
|
|
70
|
+
}
|
|
71
|
+
if (value) writer.setAttribute(attributeKey, value, itemOrRange);
|
|
72
|
+
else writer.removeAttribute(attributeKey, itemOrRange);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
if (batch) model.enqueueChange(batch, (writer) => {
|
|
77
|
+
updateAttribute(writer);
|
|
78
|
+
});
|
|
79
|
+
else model.change((writer) => {
|
|
80
|
+
updateAttribute(writer);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
};
|
|
85
84
|
|
|
86
85
|
/**
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
86
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
87
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
88
|
+
*/
|
|
89
|
+
/**
|
|
90
|
+
* The name of the font size plugin.
|
|
91
|
+
*/
|
|
92
|
+
const FONT_SIZE = "fontSize";
|
|
93
|
+
/**
|
|
94
|
+
* The name of the font family plugin.
|
|
95
|
+
*/
|
|
96
|
+
const FONT_FAMILY = "fontFamily";
|
|
97
|
+
/**
|
|
98
|
+
* The name of the font color plugin.
|
|
99
|
+
*/
|
|
100
|
+
const FONT_COLOR = "fontColor";
|
|
101
|
+
/**
|
|
102
|
+
* The name of the font background color plugin.
|
|
103
|
+
*/
|
|
104
|
+
const FONT_BACKGROUND_COLOR = "fontBackgroundColor";
|
|
105
|
+
/**
|
|
106
|
+
* Builds a proper converter definition out of input data.
|
|
107
|
+
*
|
|
108
|
+
* @internal
|
|
109
|
+
*/
|
|
110
|
+
function buildDefinition(modelAttributeKey, options) {
|
|
111
|
+
const definition = {
|
|
112
|
+
model: {
|
|
113
|
+
key: modelAttributeKey,
|
|
114
|
+
values: []
|
|
115
|
+
},
|
|
116
|
+
view: {},
|
|
117
|
+
upcastAlso: {}
|
|
118
|
+
};
|
|
119
|
+
for (const option of options) {
|
|
120
|
+
definition.model.values.push(option.model);
|
|
121
|
+
definition.view[option.model] = option.view;
|
|
122
|
+
if (option.upcastAlso) definition.upcastAlso[option.model] = option.upcastAlso;
|
|
123
|
+
}
|
|
124
|
+
return definition;
|
|
119
125
|
}
|
|
120
126
|
/**
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
* A {@link module:font/fontcolor~FontColor font color} and
|
|
128
|
+
* {@link module:font/fontbackgroundcolor~FontBackgroundColor font background color} helper
|
|
129
|
+
* responsible for upcasting data to the model.
|
|
130
|
+
*
|
|
131
|
+
* **Note**: The `styleAttr` parameter should be either `'color'` or `'background-color'`.
|
|
132
|
+
*
|
|
133
|
+
* @internal
|
|
134
|
+
*/
|
|
135
|
+
function renderUpcastAttribute(styleAttr) {
|
|
136
|
+
return (viewElement) => normalizeColorCode(viewElement.getStyle(styleAttr));
|
|
130
137
|
}
|
|
131
138
|
/**
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}, {
|
|
143
|
-
priority: 7
|
|
144
|
-
});
|
|
139
|
+
* A {@link module:font/fontcolor~FontColor font color} and
|
|
140
|
+
* {@link module:font/fontbackgroundcolor~FontBackgroundColor font background color} helper
|
|
141
|
+
* responsible for downcasting a color attribute to a `<span>` element.
|
|
142
|
+
*
|
|
143
|
+
* **Note**: The `styleAttr` parameter should be either `'color'` or `'background-color'`.
|
|
144
|
+
*
|
|
145
|
+
* @internal
|
|
146
|
+
*/
|
|
147
|
+
function renderDowncastElement(styleAttr) {
|
|
148
|
+
return (modelAttributeValue, { writer }) => writer.createAttributeElement("span", { style: `${styleAttr}:${modelAttributeValue}` }, { priority: 7 });
|
|
145
149
|
}
|
|
146
150
|
/**
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
151
|
+
* A helper that adds {@link module:ui/colorselector/colorselectorview~ColorSelectorView} to the color dropdown with proper initial values.
|
|
152
|
+
*
|
|
153
|
+
* @param options Configuration options
|
|
154
|
+
* @param options.dropdownView The dropdown view to which a {@link module:ui/colorselector/colorselectorview~ColorSelectorView}
|
|
155
|
+
* will be added.
|
|
156
|
+
* @param options.colors An array with definitions representing colors to be displayed in the color selector.
|
|
157
|
+
* @param options.columns The number of columns in the color grid.
|
|
158
|
+
* @param options.removeButtonLabel The label for the button responsible for removing the color.
|
|
159
|
+
* @param options.colorPickerLabel The label for the color picker button.
|
|
160
|
+
* @param options.documentColorsLabel The label for the section with document colors.
|
|
161
|
+
* @param options.documentColorsCount The number of document colors inside the dropdown.
|
|
162
|
+
* @param options.colorPickerViewConfig Configuration of the color picker view.
|
|
163
|
+
* @returns The new color selector view.
|
|
164
|
+
* @internal
|
|
165
|
+
*/
|
|
166
|
+
function addColorSelectorToDropdown({ dropdownView, colors, columns, removeButtonLabel, colorPickerLabel, documentColorsLabel, documentColorsCount, colorPickerViewConfig }) {
|
|
167
|
+
const locale = dropdownView.locale;
|
|
168
|
+
const colorSelectorView = new ColorSelectorView(locale, {
|
|
169
|
+
colors,
|
|
170
|
+
columns,
|
|
171
|
+
removeButtonLabel,
|
|
172
|
+
colorPickerLabel,
|
|
173
|
+
documentColorsLabel,
|
|
174
|
+
documentColorsCount,
|
|
175
|
+
colorPickerViewConfig
|
|
176
|
+
});
|
|
177
|
+
dropdownView.colorSelectorView = colorSelectorView;
|
|
178
|
+
dropdownView.panelView.children.add(colorSelectorView);
|
|
179
|
+
return colorSelectorView;
|
|
175
180
|
}
|
|
176
181
|
/**
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
182
|
+
* Fixes the color value string.
|
|
183
|
+
*/
|
|
184
|
+
function normalizeColorCode(value) {
|
|
185
|
+
return value.replace(/\s/g, "");
|
|
180
186
|
}
|
|
181
187
|
|
|
182
188
|
/**
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
189
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
190
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
191
|
+
*/
|
|
192
|
+
/**
|
|
193
|
+
* The font family command. It is used by {@link module:font/fontfamily/fontfamilyediting~FontFamilyEditing}
|
|
194
|
+
* to apply the font family.
|
|
195
|
+
*
|
|
196
|
+
* ```ts
|
|
197
|
+
* editor.execute( 'fontFamily', { value: 'Arial' } );
|
|
198
|
+
* ```
|
|
199
|
+
*
|
|
200
|
+
* **Note**: Executing the command without the value removes the attribute from the model.
|
|
201
|
+
*/
|
|
202
|
+
var FontFamilyCommand = class extends FontCommand {
|
|
203
|
+
/**
|
|
204
|
+
* @inheritDoc
|
|
205
|
+
*/
|
|
206
|
+
constructor(editor) {
|
|
207
|
+
super(editor, FONT_FAMILY);
|
|
208
|
+
}
|
|
209
|
+
};
|
|
198
210
|
|
|
199
211
|
/**
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
return configuredOptions.map(getOptionDefinition$1)// Filter out undefined values that `getOptionDefinition` might return.
|
|
213
|
-
.filter((option)=>option !== undefined);
|
|
212
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
213
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
214
|
+
*/
|
|
215
|
+
/**
|
|
216
|
+
* Normalizes the {@link module:font/fontconfig~FontFamilyConfig#options configuration options}
|
|
217
|
+
* to the {@link module:font/fontconfig~FontFamilyOption} format.
|
|
218
|
+
*
|
|
219
|
+
* @param configuredOptions An array of options taken from the configuration.
|
|
220
|
+
* @internal
|
|
221
|
+
*/
|
|
222
|
+
function normalizeOptions(configuredOptions) {
|
|
223
|
+
return configuredOptions.map(getOptionDefinition$1).filter((option) => option !== void 0);
|
|
214
224
|
}
|
|
215
225
|
/**
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
226
|
+
* Normalizes the CSS `font-family` property value to an array of unquoted and trimmed font faces.
|
|
227
|
+
*
|
|
228
|
+
* @internal
|
|
229
|
+
*/
|
|
230
|
+
function normalizeFontFamilies(fontDefinition) {
|
|
231
|
+
return fontDefinition.replace(/["']/g, "").split(",").map((name) => name.trim());
|
|
221
232
|
}
|
|
222
233
|
/**
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
model: undefined
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
// Ignore values that we cannot parse to a definition.
|
|
239
|
-
if (typeof option !== 'string') {
|
|
240
|
-
return undefined;
|
|
241
|
-
}
|
|
242
|
-
// Return font family definition from font string.
|
|
243
|
-
return generateFontPreset(option);
|
|
234
|
+
* Returns an option definition either created from string shortcut.
|
|
235
|
+
* If object is passed then this method will return it without alternating it. Returns undefined for item than cannot be parsed.
|
|
236
|
+
*
|
|
237
|
+
*/
|
|
238
|
+
function getOptionDefinition$1(option) {
|
|
239
|
+
if (typeof option === "object") return option;
|
|
240
|
+
if (option === "default") return {
|
|
241
|
+
title: "Default",
|
|
242
|
+
model: void 0
|
|
243
|
+
};
|
|
244
|
+
if (typeof option !== "string") return;
|
|
245
|
+
return generateFontPreset(option);
|
|
244
246
|
}
|
|
245
247
|
/**
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
},
|
|
265
|
-
priority: 7
|
|
266
|
-
}
|
|
267
|
-
};
|
|
248
|
+
* Creates a predefined preset for pixel size. It deconstructs font-family like string into full configuration option.
|
|
249
|
+
* A font definition is passed as coma delimited set of font family names. Font names might be quoted.
|
|
250
|
+
*
|
|
251
|
+
* @param fontDefinition A font definition form configuration.
|
|
252
|
+
*/
|
|
253
|
+
function generateFontPreset(fontDefinition) {
|
|
254
|
+
const fontNames = normalizeFontFamilies(fontDefinition);
|
|
255
|
+
const firstFontName = fontNames[0];
|
|
256
|
+
const cssFontNames = fontNames.map(normalizeFontNameForCSS).join(", ");
|
|
257
|
+
return {
|
|
258
|
+
title: firstFontName,
|
|
259
|
+
model: cssFontNames,
|
|
260
|
+
view: {
|
|
261
|
+
name: "span",
|
|
262
|
+
styles: { "font-family": cssFontNames },
|
|
263
|
+
priority: 7
|
|
264
|
+
}
|
|
265
|
+
};
|
|
268
266
|
}
|
|
269
267
|
/**
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
}
|
|
277
|
-
return fontName;
|
|
268
|
+
* Normalizes font name for the style attribute. It adds braces (') if font name contains spaces.
|
|
269
|
+
*/
|
|
270
|
+
function normalizeFontNameForCSS(fontName) {
|
|
271
|
+
fontName = fontName.trim();
|
|
272
|
+
if (fontName.indexOf(" ") > 0) fontName = `'${fontName}'`;
|
|
273
|
+
return fontName;
|
|
278
274
|
}
|
|
279
275
|
|
|
280
276
|
/**
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
}
|
|
277
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
278
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
279
|
+
*/
|
|
280
|
+
/**
|
|
281
|
+
* @module font/fontfamily/fontfamilyediting
|
|
282
|
+
*/
|
|
283
|
+
/**
|
|
284
|
+
* The font family editing feature.
|
|
285
|
+
*
|
|
286
|
+
* It introduces the {@link module:font/fontfamily/fontfamilycommand~FontFamilyCommand command} and
|
|
287
|
+
* the `fontFamily` attribute in the {@link module:engine/model/model~Model model} which renders
|
|
288
|
+
* in the {@link module:engine/view/view view} as an inline `<span>` element (`<span style="font-family: Arial">`),
|
|
289
|
+
* depending on the {@link module:font/fontconfig~FontFamilyConfig configuration}.
|
|
290
|
+
*/
|
|
291
|
+
var FontFamilyEditing = class extends Plugin {
|
|
292
|
+
/**
|
|
293
|
+
* @inheritDoc
|
|
294
|
+
*/
|
|
295
|
+
static get pluginName() {
|
|
296
|
+
return "FontFamilyEditing";
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* @inheritDoc
|
|
300
|
+
*/
|
|
301
|
+
static get isOfficialPlugin() {
|
|
302
|
+
return true;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* @inheritDoc
|
|
306
|
+
*/
|
|
307
|
+
constructor(editor) {
|
|
308
|
+
super(editor);
|
|
309
|
+
editor.config.define(FONT_FAMILY, {
|
|
310
|
+
options: [
|
|
311
|
+
"default",
|
|
312
|
+
"Arial, Helvetica, sans-serif",
|
|
313
|
+
"Courier New, Courier, monospace",
|
|
314
|
+
"Georgia, serif",
|
|
315
|
+
"Lucida Sans Unicode, Lucida Grande, sans-serif",
|
|
316
|
+
"Tahoma, Geneva, sans-serif",
|
|
317
|
+
"Times New Roman, Times, serif",
|
|
318
|
+
"Trebuchet MS, Helvetica, sans-serif",
|
|
319
|
+
"Verdana, Geneva, sans-serif"
|
|
320
|
+
],
|
|
321
|
+
supportAllValues: false
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* @inheritDoc
|
|
326
|
+
*/
|
|
327
|
+
init() {
|
|
328
|
+
const editor = this.editor;
|
|
329
|
+
editor.model.schema.extend("$text", { allowAttributes: FONT_FAMILY });
|
|
330
|
+
editor.model.schema.setAttributeProperties(FONT_FAMILY, {
|
|
331
|
+
isFormatting: true,
|
|
332
|
+
copyOnEnter: true
|
|
333
|
+
});
|
|
334
|
+
const options = normalizeOptions(editor.config.get("fontFamily.options")).filter((item) => item.model);
|
|
335
|
+
const definition = buildDefinition(FONT_FAMILY, options);
|
|
336
|
+
if (editor.config.get("fontFamily.supportAllValues")) {
|
|
337
|
+
this._prepareAnyValueConverters();
|
|
338
|
+
this._prepareCompatibilityConverter();
|
|
339
|
+
} else editor.conversion.attributeToElement(definition);
|
|
340
|
+
editor.commands.add(FONT_FAMILY, new FontFamilyCommand(editor));
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* These converters enable keeping any value found as `style="font-family: *"` as a value of an attribute on a text even
|
|
344
|
+
* if it is not defined in the plugin configuration.
|
|
345
|
+
*/
|
|
346
|
+
_prepareAnyValueConverters() {
|
|
347
|
+
const editor = this.editor;
|
|
348
|
+
editor.conversion.for("downcast").attributeToElement({
|
|
349
|
+
model: FONT_FAMILY,
|
|
350
|
+
view: (attributeValue, { writer }) => {
|
|
351
|
+
return writer.createAttributeElement("span", { style: "font-family:" + attributeValue }, { priority: 7 });
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
editor.conversion.for("upcast").elementToAttribute({
|
|
355
|
+
model: {
|
|
356
|
+
key: FONT_FAMILY,
|
|
357
|
+
value: (viewElement) => viewElement.getStyle("font-family")
|
|
358
|
+
},
|
|
359
|
+
view: {
|
|
360
|
+
name: "span",
|
|
361
|
+
styles: { "font-family": /.*/ }
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Adds support for legacy `<font face="..">` formatting.
|
|
367
|
+
*/
|
|
368
|
+
_prepareCompatibilityConverter() {
|
|
369
|
+
this.editor.conversion.for("upcast").elementToAttribute({
|
|
370
|
+
view: {
|
|
371
|
+
name: "font",
|
|
372
|
+
attributes: { "face": /.*/ }
|
|
373
|
+
},
|
|
374
|
+
model: {
|
|
375
|
+
key: FONT_FAMILY,
|
|
376
|
+
value: (viewElement) => viewElement.getAttribute("face")
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
};
|
|
388
381
|
|
|
389
382
|
/**
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
}
|
|
487
|
-
}
|
|
383
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
384
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
385
|
+
*/
|
|
386
|
+
/**
|
|
387
|
+
* @module font/fontfamily/fontfamilyui
|
|
388
|
+
*/
|
|
389
|
+
/**
|
|
390
|
+
* The font family UI plugin. It introduces the `'fontFamily'` dropdown.
|
|
391
|
+
*/
|
|
392
|
+
var FontFamilyUI = class extends Plugin {
|
|
393
|
+
/**
|
|
394
|
+
* @inheritDoc
|
|
395
|
+
*/
|
|
396
|
+
static get pluginName() {
|
|
397
|
+
return "FontFamilyUI";
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* @inheritDoc
|
|
401
|
+
*/
|
|
402
|
+
static get isOfficialPlugin() {
|
|
403
|
+
return true;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* @inheritDoc
|
|
407
|
+
*/
|
|
408
|
+
init() {
|
|
409
|
+
const editor = this.editor;
|
|
410
|
+
const t = editor.t;
|
|
411
|
+
const options = this._getLocalizedOptions();
|
|
412
|
+
const command = editor.commands.get(FONT_FAMILY);
|
|
413
|
+
const accessibleLabel = t("Font Family");
|
|
414
|
+
const listOptions = _prepareListOptions$1(options, command);
|
|
415
|
+
editor.ui.componentFactory.add(FONT_FAMILY, (locale) => {
|
|
416
|
+
const dropdownView = createDropdown(locale);
|
|
417
|
+
addListToDropdown(dropdownView, listOptions, {
|
|
418
|
+
role: "menu",
|
|
419
|
+
ariaLabel: accessibleLabel
|
|
420
|
+
});
|
|
421
|
+
dropdownView.buttonView.set({
|
|
422
|
+
label: accessibleLabel,
|
|
423
|
+
icon: IconFontFamily,
|
|
424
|
+
tooltip: true
|
|
425
|
+
});
|
|
426
|
+
dropdownView.extendTemplate({ attributes: { class: "ck-font-family-dropdown" } });
|
|
427
|
+
dropdownView.bind("isEnabled").to(command);
|
|
428
|
+
this.listenTo(dropdownView, "execute", (evt) => {
|
|
429
|
+
editor.execute(evt.source.commandName, { value: evt.source.commandParam });
|
|
430
|
+
editor.editing.view.focus();
|
|
431
|
+
});
|
|
432
|
+
return dropdownView;
|
|
433
|
+
});
|
|
434
|
+
editor.ui.componentFactory.add(`menuBar:${FONT_FAMILY}`, (locale) => {
|
|
435
|
+
const menuView = new MenuBarMenuView(locale);
|
|
436
|
+
menuView.buttonView.set({
|
|
437
|
+
label: accessibleLabel,
|
|
438
|
+
icon: IconFontFamily
|
|
439
|
+
});
|
|
440
|
+
menuView.bind("isEnabled").to(command);
|
|
441
|
+
const listView = new MenuBarMenuListView(locale);
|
|
442
|
+
for (const definition of listOptions) {
|
|
443
|
+
const listItemView = new MenuBarMenuListItemView(locale, menuView);
|
|
444
|
+
const buttonView = new MenuBarMenuListItemButtonView(locale);
|
|
445
|
+
buttonView.set({
|
|
446
|
+
role: "menuitemradio",
|
|
447
|
+
isToggleable: true
|
|
448
|
+
});
|
|
449
|
+
buttonView.bind(...Object.keys(definition.model)).to(definition.model);
|
|
450
|
+
buttonView.delegate("execute").to(menuView);
|
|
451
|
+
buttonView.on("execute", () => {
|
|
452
|
+
editor.execute(definition.model.commandName, { value: definition.model.commandParam });
|
|
453
|
+
editor.editing.view.focus();
|
|
454
|
+
});
|
|
455
|
+
listItemView.children.add(buttonView);
|
|
456
|
+
listView.items.add(listItemView);
|
|
457
|
+
}
|
|
458
|
+
menuView.panelView.children.add(listView);
|
|
459
|
+
return menuView;
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Returns options as defined in `config.fontFamily.options` but processed to account for
|
|
464
|
+
* editor localization, i.e. to display {@link module:font/fontconfig~FontFamilyOption}
|
|
465
|
+
* in the correct language.
|
|
466
|
+
*
|
|
467
|
+
* Note: The reason behind this method is that there is no way to use {@link module:utils/locale~Locale#t}
|
|
468
|
+
* when the user configuration is defined because the editor does not exist yet.
|
|
469
|
+
*/
|
|
470
|
+
_getLocalizedOptions() {
|
|
471
|
+
const editor = this.editor;
|
|
472
|
+
const t = editor.t;
|
|
473
|
+
return normalizeOptions(editor.config.get(FONT_FAMILY).options).map((option) => {
|
|
474
|
+
if (option.title === "Default") option.title = t("Default");
|
|
475
|
+
return option;
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
};
|
|
488
479
|
/**
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
const optionNormalized = normalizeFontFamilies(option.model)[0].toLowerCase();
|
|
514
|
-
return valueNormalized === optionNormalized;
|
|
515
|
-
});
|
|
516
|
-
// Try to set a dropdown list item style.
|
|
517
|
-
if (option.view && typeof option.view !== 'string' && option.view.styles) {
|
|
518
|
-
def.model.set('labelStyle', `font-family: ${option.view.styles['font-family']}`);
|
|
519
|
-
}
|
|
520
|
-
itemDefinitions.add(def);
|
|
521
|
-
}
|
|
522
|
-
return itemDefinitions;
|
|
480
|
+
* Prepares FontFamily dropdown items.
|
|
481
|
+
*/
|
|
482
|
+
function _prepareListOptions$1(options, command) {
|
|
483
|
+
const itemDefinitions = new Collection();
|
|
484
|
+
for (const option of options) {
|
|
485
|
+
const def = {
|
|
486
|
+
type: "button",
|
|
487
|
+
model: new UIModel({
|
|
488
|
+
commandName: FONT_FAMILY,
|
|
489
|
+
commandParam: option.model,
|
|
490
|
+
label: option.title,
|
|
491
|
+
role: "menuitemradio",
|
|
492
|
+
withText: true
|
|
493
|
+
})
|
|
494
|
+
};
|
|
495
|
+
def.model.bind("isOn").to(command, "value", (value) => {
|
|
496
|
+
if (value === option.model) return true;
|
|
497
|
+
if (!value || !option.model) return false;
|
|
498
|
+
return normalizeFontFamilies(value)[0].toLowerCase() === normalizeFontFamilies(option.model)[0].toLowerCase();
|
|
499
|
+
});
|
|
500
|
+
if (option.view && typeof option.view !== "string" && option.view.styles) def.model.set("labelStyle", `font-family: ${option.view.styles["font-family"]}`);
|
|
501
|
+
itemDefinitions.add(def);
|
|
502
|
+
}
|
|
503
|
+
return itemDefinitions;
|
|
523
504
|
}
|
|
524
505
|
|
|
525
506
|
/**
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
507
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
508
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
509
|
+
*/
|
|
510
|
+
/**
|
|
511
|
+
* @module font/fontfamily
|
|
512
|
+
*/
|
|
513
|
+
/**
|
|
514
|
+
* The font family plugin.
|
|
515
|
+
*
|
|
516
|
+
* For a detailed overview, check the {@glink features/font font feature} documentatiom
|
|
517
|
+
* and the {@glink api/font package page}.
|
|
518
|
+
*
|
|
519
|
+
* This is a "glue" plugin which loads the {@link module:font/fontfamily/fontfamilyediting~FontFamilyEditing} and
|
|
520
|
+
* {@link module:font/fontfamily/fontfamilyui~FontFamilyUI} features in the editor.
|
|
521
|
+
*/
|
|
522
|
+
var FontFamily = class extends Plugin {
|
|
523
|
+
/**
|
|
524
|
+
* @inheritDoc
|
|
525
|
+
*/
|
|
526
|
+
static get requires() {
|
|
527
|
+
return [FontFamilyEditing, FontFamilyUI];
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* @inheritDoc
|
|
531
|
+
*/
|
|
532
|
+
static get pluginName() {
|
|
533
|
+
return "FontFamily";
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* @inheritDoc
|
|
537
|
+
*/
|
|
538
|
+
static get isOfficialPlugin() {
|
|
539
|
+
return true;
|
|
540
|
+
}
|
|
541
|
+
};
|
|
553
542
|
|
|
554
543
|
/**
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
544
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
545
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
546
|
+
*/
|
|
547
|
+
/**
|
|
548
|
+
* The font size command. It is used by {@link module:font/fontsize/fontsizeediting~FontSizeEditing}
|
|
549
|
+
* to apply the font size.
|
|
550
|
+
*
|
|
551
|
+
* ```ts
|
|
552
|
+
* editor.execute( 'fontSize', { value: 'small' } );
|
|
553
|
+
* ```
|
|
554
|
+
*
|
|
555
|
+
* **Note**: Executing the command without the value removes the attribute from the model.
|
|
556
|
+
*/
|
|
557
|
+
var FontSizeCommand = class extends FontCommand {
|
|
558
|
+
/**
|
|
559
|
+
* @inheritDoc
|
|
560
|
+
*/
|
|
561
|
+
constructor(editor) {
|
|
562
|
+
super(editor, FONT_SIZE);
|
|
563
|
+
}
|
|
564
|
+
};
|
|
570
565
|
|
|
571
566
|
/**
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
567
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
568
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
569
|
+
*/
|
|
570
|
+
/**
|
|
571
|
+
* @module font/fontsize/utils
|
|
572
|
+
*/
|
|
573
|
+
/**
|
|
574
|
+
* Normalizes and translates the {@link module:font/fontconfig~FontSizeConfig#options configuration options}
|
|
575
|
+
* to the {@link module:font/fontconfig~FontSizeOption} format.
|
|
576
|
+
*
|
|
577
|
+
* @param configuredOptions An array of options taken from the configuration.
|
|
578
|
+
* @internal
|
|
579
|
+
*/
|
|
580
|
+
function normalizeOptions$1(configuredOptions) {
|
|
581
|
+
return configuredOptions.map((item) => getOptionDefinition(item)).filter((option) => option !== void 0);
|
|
581
582
|
}
|
|
582
|
-
// Default named presets map. Always create a new instance of the preset object in order to avoid modifying references.
|
|
583
583
|
const namedPresets = {
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
584
|
+
get tiny() {
|
|
585
|
+
return {
|
|
586
|
+
title: "Tiny",
|
|
587
|
+
model: "tiny",
|
|
588
|
+
view: {
|
|
589
|
+
name: "span",
|
|
590
|
+
classes: "text-tiny",
|
|
591
|
+
priority: 7
|
|
592
|
+
}
|
|
593
|
+
};
|
|
594
|
+
},
|
|
595
|
+
get small() {
|
|
596
|
+
return {
|
|
597
|
+
title: "Small",
|
|
598
|
+
model: "small",
|
|
599
|
+
view: {
|
|
600
|
+
name: "span",
|
|
601
|
+
classes: "text-small",
|
|
602
|
+
priority: 7
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
},
|
|
606
|
+
get big() {
|
|
607
|
+
return {
|
|
608
|
+
title: "Big",
|
|
609
|
+
model: "big",
|
|
610
|
+
view: {
|
|
611
|
+
name: "span",
|
|
612
|
+
classes: "text-big",
|
|
613
|
+
priority: 7
|
|
614
|
+
}
|
|
615
|
+
};
|
|
616
|
+
},
|
|
617
|
+
get huge() {
|
|
618
|
+
return {
|
|
619
|
+
title: "Huge",
|
|
620
|
+
model: "huge",
|
|
621
|
+
view: {
|
|
622
|
+
name: "span",
|
|
623
|
+
classes: "text-huge",
|
|
624
|
+
priority: 7
|
|
625
|
+
}
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
628
|
};
|
|
629
629
|
/**
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
}
|
|
645
|
-
// 'Default' font size. It will be used to remove the fontSize attribute.
|
|
646
|
-
if (option === 'default') {
|
|
647
|
-
return {
|
|
648
|
-
model: undefined,
|
|
649
|
-
title: 'Default'
|
|
650
|
-
};
|
|
651
|
-
}
|
|
652
|
-
// At this stage we probably have numerical value to generate a preset so parse it's value.
|
|
653
|
-
// Discard any faulty values.
|
|
654
|
-
if (isNumericalDefinition(option)) {
|
|
655
|
-
return undefined;
|
|
656
|
-
}
|
|
657
|
-
// Return font size definition from size value.
|
|
658
|
-
return generatePixelPreset(option);
|
|
630
|
+
* Returns an option definition either from preset or creates one from number shortcut.
|
|
631
|
+
* If object is passed then this method will return it without alternating it. Returns undefined for item than cannot be parsed.
|
|
632
|
+
*/
|
|
633
|
+
function getOptionDefinition(option) {
|
|
634
|
+
if (typeof option === "number") option = String(option);
|
|
635
|
+
if (typeof option === "object" && isFullItemDefinition(option)) return attachPriority(option);
|
|
636
|
+
const preset = findPreset(option);
|
|
637
|
+
if (preset) return attachPriority(preset);
|
|
638
|
+
if (option === "default") return {
|
|
639
|
+
model: void 0,
|
|
640
|
+
title: "Default"
|
|
641
|
+
};
|
|
642
|
+
if (isNumericalDefinition(option)) return;
|
|
643
|
+
return generatePixelPreset(option);
|
|
659
644
|
}
|
|
660
645
|
/**
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
'font-size': definition.model
|
|
676
|
-
}
|
|
677
|
-
};
|
|
678
|
-
return attachPriority(definition);
|
|
646
|
+
* Creates a predefined preset for pixel size.
|
|
647
|
+
* @param definition Font size in pixels.
|
|
648
|
+
* @returns
|
|
649
|
+
*/
|
|
650
|
+
function generatePixelPreset(definition) {
|
|
651
|
+
if (typeof definition === "string") definition = {
|
|
652
|
+
title: definition,
|
|
653
|
+
model: `${parseFloat(definition)}px`
|
|
654
|
+
};
|
|
655
|
+
definition.view = {
|
|
656
|
+
name: "span",
|
|
657
|
+
styles: { "font-size": definition.model }
|
|
658
|
+
};
|
|
659
|
+
return attachPriority(definition);
|
|
679
660
|
}
|
|
680
661
|
/**
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
return definition;
|
|
662
|
+
* Adds the priority to the view element definition if missing. It's required due to https://github.com/ckeditor/ckeditor5/issues/2291
|
|
663
|
+
*/
|
|
664
|
+
function attachPriority(definition) {
|
|
665
|
+
if (definition.view && typeof definition.view !== "string" && !definition.view.priority) definition.view.priority = 7;
|
|
666
|
+
return definition;
|
|
687
667
|
}
|
|
688
668
|
/**
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
669
|
+
* Returns a prepared preset definition. If passed an object, a name of preset should be defined as `model` value.
|
|
670
|
+
*
|
|
671
|
+
* @param definition.model A preset name.
|
|
672
|
+
*/
|
|
673
|
+
function findPreset(definition) {
|
|
674
|
+
return typeof definition === "string" ? namedPresets[definition] : namedPresets[definition.model];
|
|
694
675
|
}
|
|
695
676
|
/**
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
677
|
+
* We treat `definition` as completed if it is an object that contains `title`, `model` and `view` values.
|
|
678
|
+
*/
|
|
679
|
+
function isFullItemDefinition(definition) {
|
|
680
|
+
return definition.title && definition.model && definition.view;
|
|
699
681
|
}
|
|
700
682
|
function isNumericalDefinition(definition) {
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
numberValue = parseFloat(definition);
|
|
716
|
-
}
|
|
717
|
-
return isNaN(numberValue);
|
|
683
|
+
let numberValue;
|
|
684
|
+
if (typeof definition === "object") {
|
|
685
|
+
if (!definition.model)
|
|
686
|
+
/**
|
|
687
|
+
* Provided value as an option for {@link module:font/fontsize~FontSize} seems to invalid.
|
|
688
|
+
*
|
|
689
|
+
* See valid examples described in the {@link module:font/fontconfig~FontSizeConfig#options plugin configuration}.
|
|
690
|
+
*
|
|
691
|
+
* @error font-size-invalid-definition
|
|
692
|
+
*/
|
|
693
|
+
throw new CKEditorError("font-size-invalid-definition", null, definition);
|
|
694
|
+
else numberValue = parseFloat(definition.model);
|
|
695
|
+
} else numberValue = parseFloat(definition);
|
|
696
|
+
return isNaN(numberValue);
|
|
718
697
|
}
|
|
719
698
|
|
|
720
|
-
|
|
699
|
+
/**
|
|
700
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
701
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
702
|
+
*/
|
|
703
|
+
/**
|
|
704
|
+
* @module font/fontsize/fontsizeediting
|
|
705
|
+
*/
|
|
721
706
|
const styleFontSize = [
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
707
|
+
"x-small",
|
|
708
|
+
"x-small",
|
|
709
|
+
"small",
|
|
710
|
+
"medium",
|
|
711
|
+
"large",
|
|
712
|
+
"x-large",
|
|
713
|
+
"xx-large",
|
|
714
|
+
"xxx-large"
|
|
730
715
|
];
|
|
731
716
|
/**
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
// up to 999 but clamp it to the valid range. Why 999? It should cover accidental values
|
|
854
|
-
// similar to percentage, e.g. 100%, 200% which could be the usual mistake for font size.
|
|
855
|
-
'size': /^[+-]?\d{1,3}$/
|
|
856
|
-
}
|
|
857
|
-
},
|
|
858
|
-
model: {
|
|
859
|
-
key: FONT_SIZE,
|
|
860
|
-
value: (viewElement)=>{
|
|
861
|
-
const value = viewElement.getAttribute('size');
|
|
862
|
-
const isRelative = value[0] === '-' || value[0] === '+';
|
|
863
|
-
let size = parseInt(value, 10);
|
|
864
|
-
if (isRelative) {
|
|
865
|
-
// Add relative size (which can be negative) to the default size = 3.
|
|
866
|
-
size = 3 + size;
|
|
867
|
-
}
|
|
868
|
-
const maxSize = styleFontSize.length - 1;
|
|
869
|
-
const clampedSize = Math.min(Math.max(size, 0), maxSize);
|
|
870
|
-
return styleFontSize[clampedSize];
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
});
|
|
874
|
-
}
|
|
875
|
-
}
|
|
717
|
+
* The font size editing feature.
|
|
718
|
+
*
|
|
719
|
+
* It introduces the {@link module:font/fontsize/fontsizecommand~FontSizeCommand command} and the `fontSize`
|
|
720
|
+
* attribute in the {@link module:engine/model/model~Model model} which renders in the {@link module:engine/view/view view}
|
|
721
|
+
* as a `<span>` element with either:
|
|
722
|
+
* * a style attribute (`<span style="font-size:12px">...</span>`),
|
|
723
|
+
* * or a class attribute (`<span class="text-small">...</span>`)
|
|
724
|
+
*
|
|
725
|
+
* depending on the {@link module:font/fontconfig~FontSizeConfig configuration}.
|
|
726
|
+
*/
|
|
727
|
+
var FontSizeEditing = class extends Plugin {
|
|
728
|
+
/**
|
|
729
|
+
* @inheritDoc
|
|
730
|
+
*/
|
|
731
|
+
static get pluginName() {
|
|
732
|
+
return "FontSizeEditing";
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* @inheritDoc
|
|
736
|
+
*/
|
|
737
|
+
static get isOfficialPlugin() {
|
|
738
|
+
return true;
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* @inheritDoc
|
|
742
|
+
*/
|
|
743
|
+
constructor(editor) {
|
|
744
|
+
super(editor);
|
|
745
|
+
editor.config.define(FONT_SIZE, {
|
|
746
|
+
options: [
|
|
747
|
+
"tiny",
|
|
748
|
+
"small",
|
|
749
|
+
"default",
|
|
750
|
+
"big",
|
|
751
|
+
"huge"
|
|
752
|
+
],
|
|
753
|
+
supportAllValues: false
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
/**
|
|
757
|
+
* @inheritDoc
|
|
758
|
+
*/
|
|
759
|
+
init() {
|
|
760
|
+
const editor = this.editor;
|
|
761
|
+
editor.model.schema.extend("$text", { allowAttributes: FONT_SIZE });
|
|
762
|
+
editor.model.schema.setAttributeProperties(FONT_SIZE, {
|
|
763
|
+
isFormatting: true,
|
|
764
|
+
copyOnEnter: true
|
|
765
|
+
});
|
|
766
|
+
const supportAllValues = editor.config.get("fontSize.supportAllValues");
|
|
767
|
+
const options = normalizeOptions$1(this.editor.config.get("fontSize.options")).filter((item) => item.model);
|
|
768
|
+
const definition = buildDefinition(FONT_SIZE, options);
|
|
769
|
+
if (supportAllValues) {
|
|
770
|
+
this._prepareAnyValueConverters(definition);
|
|
771
|
+
this._prepareCompatibilityConverter();
|
|
772
|
+
} else editor.conversion.attributeToElement(definition);
|
|
773
|
+
editor.commands.add(FONT_SIZE, new FontSizeCommand(editor));
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* These converters enable keeping any value found as `style="font-size: *"` as a value of an attribute on a text even
|
|
777
|
+
* if it is not defined in the plugin configuration.
|
|
778
|
+
*
|
|
779
|
+
* @param definition Converter definition out of input data.
|
|
780
|
+
*/
|
|
781
|
+
_prepareAnyValueConverters(definition) {
|
|
782
|
+
const editor = this.editor;
|
|
783
|
+
const presets = definition.model.values.filter((value) => {
|
|
784
|
+
return !isLengthStyleValue(String(value)) && !isPercentageStyleValue(String(value));
|
|
785
|
+
});
|
|
786
|
+
if (presets.length)
|
|
787
|
+
/**
|
|
788
|
+
* If {@link module:font/fontconfig~FontSizeConfig#supportAllValues `config.fontSize.supportAllValues`} is `true`,
|
|
789
|
+
* you need to use numerical values as font size options.
|
|
790
|
+
*
|
|
791
|
+
* See valid examples described in the {@link module:font/fontconfig~FontSizeConfig#options plugin configuration}.
|
|
792
|
+
*
|
|
793
|
+
* @error font-size-invalid-use-of-named-presets
|
|
794
|
+
* @param {Array.<string>} presets Invalid values.
|
|
795
|
+
*/
|
|
796
|
+
throw new CKEditorError("font-size-invalid-use-of-named-presets", null, { presets });
|
|
797
|
+
editor.conversion.for("downcast").attributeToElement({
|
|
798
|
+
model: FONT_SIZE,
|
|
799
|
+
view: (attributeValue, { writer }) => {
|
|
800
|
+
if (!attributeValue) return;
|
|
801
|
+
return writer.createAttributeElement("span", { style: "font-size:" + attributeValue }, { priority: 7 });
|
|
802
|
+
}
|
|
803
|
+
});
|
|
804
|
+
editor.conversion.for("upcast").elementToAttribute({
|
|
805
|
+
model: {
|
|
806
|
+
key: FONT_SIZE,
|
|
807
|
+
value: (viewElement) => viewElement.getStyle("font-size")
|
|
808
|
+
},
|
|
809
|
+
view: {
|
|
810
|
+
name: "span",
|
|
811
|
+
styles: { "font-size": /.*/ }
|
|
812
|
+
}
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
816
|
+
* Adds support for legacy `<font size="..">` formatting.
|
|
817
|
+
*/
|
|
818
|
+
_prepareCompatibilityConverter() {
|
|
819
|
+
this.editor.conversion.for("upcast").elementToAttribute({
|
|
820
|
+
view: {
|
|
821
|
+
name: "font",
|
|
822
|
+
attributes: { "size": /^[+-]?\d{1,3}$/ }
|
|
823
|
+
},
|
|
824
|
+
model: {
|
|
825
|
+
key: FONT_SIZE,
|
|
826
|
+
value: (viewElement) => {
|
|
827
|
+
const value = viewElement.getAttribute("size");
|
|
828
|
+
const isRelative = value[0] === "-" || value[0] === "+";
|
|
829
|
+
let size = parseInt(value, 10);
|
|
830
|
+
if (isRelative) size = 3 + size;
|
|
831
|
+
const maxSize = styleFontSize.length - 1;
|
|
832
|
+
return styleFontSize[Math.min(Math.max(size, 0), maxSize)];
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
});
|
|
836
|
+
}
|
|
837
|
+
};
|
|
876
838
|
|
|
877
839
|
/**
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
title
|
|
983
|
-
});
|
|
984
|
-
}
|
|
985
|
-
return option;
|
|
986
|
-
});
|
|
987
|
-
}
|
|
988
|
-
}
|
|
840
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
841
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
842
|
+
*/
|
|
843
|
+
/**
|
|
844
|
+
* @module font/fontsize/fontsizeui
|
|
845
|
+
*/
|
|
846
|
+
/**
|
|
847
|
+
* The font size UI plugin. It introduces the `'fontSize'` dropdown.
|
|
848
|
+
*/
|
|
849
|
+
var FontSizeUI = class extends Plugin {
|
|
850
|
+
/**
|
|
851
|
+
* @inheritDoc
|
|
852
|
+
*/
|
|
853
|
+
static get pluginName() {
|
|
854
|
+
return "FontSizeUI";
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* @inheritDoc
|
|
858
|
+
*/
|
|
859
|
+
static get isOfficialPlugin() {
|
|
860
|
+
return true;
|
|
861
|
+
}
|
|
862
|
+
/**
|
|
863
|
+
* @inheritDoc
|
|
864
|
+
*/
|
|
865
|
+
init() {
|
|
866
|
+
const editor = this.editor;
|
|
867
|
+
const t = editor.t;
|
|
868
|
+
const options = this._getLocalizedOptions();
|
|
869
|
+
const command = editor.commands.get(FONT_SIZE);
|
|
870
|
+
const accessibleLabel = t("Font Size");
|
|
871
|
+
const listOptions = _prepareListOptions(options, command);
|
|
872
|
+
editor.ui.componentFactory.add(FONT_SIZE, (locale) => {
|
|
873
|
+
const dropdownView = createDropdown(locale);
|
|
874
|
+
addListToDropdown(dropdownView, listOptions, {
|
|
875
|
+
role: "menu",
|
|
876
|
+
ariaLabel: accessibleLabel
|
|
877
|
+
});
|
|
878
|
+
dropdownView.buttonView.set({
|
|
879
|
+
label: accessibleLabel,
|
|
880
|
+
icon: IconFontSize,
|
|
881
|
+
tooltip: true
|
|
882
|
+
});
|
|
883
|
+
dropdownView.extendTemplate({ attributes: { class: ["ck-font-size-dropdown"] } });
|
|
884
|
+
dropdownView.bind("isEnabled").to(command);
|
|
885
|
+
this.listenTo(dropdownView, "execute", (evt) => {
|
|
886
|
+
editor.execute(evt.source.commandName, { value: evt.source.commandParam });
|
|
887
|
+
editor.editing.view.focus();
|
|
888
|
+
});
|
|
889
|
+
return dropdownView;
|
|
890
|
+
});
|
|
891
|
+
editor.ui.componentFactory.add(`menuBar:${FONT_SIZE}`, (locale) => {
|
|
892
|
+
const menuView = new MenuBarMenuView(locale);
|
|
893
|
+
menuView.buttonView.set({
|
|
894
|
+
label: accessibleLabel,
|
|
895
|
+
icon: IconFontSize
|
|
896
|
+
});
|
|
897
|
+
menuView.bind("isEnabled").to(command);
|
|
898
|
+
const listView = new MenuBarMenuListView(locale);
|
|
899
|
+
for (const definition of listOptions) {
|
|
900
|
+
const listItemView = new MenuBarMenuListItemView(locale, menuView);
|
|
901
|
+
const buttonView = new MenuBarMenuListItemButtonView(locale);
|
|
902
|
+
buttonView.set({
|
|
903
|
+
role: "menuitemradio",
|
|
904
|
+
isToggleable: true
|
|
905
|
+
});
|
|
906
|
+
buttonView.bind(...Object.keys(definition.model)).to(definition.model);
|
|
907
|
+
buttonView.delegate("execute").to(menuView);
|
|
908
|
+
buttonView.on("execute", () => {
|
|
909
|
+
editor.execute(definition.model.commandName, { value: definition.model.commandParam });
|
|
910
|
+
editor.editing.view.focus();
|
|
911
|
+
});
|
|
912
|
+
listItemView.children.add(buttonView);
|
|
913
|
+
listView.items.add(listItemView);
|
|
914
|
+
}
|
|
915
|
+
menuView.panelView.children.add(listView);
|
|
916
|
+
return menuView;
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
/**
|
|
920
|
+
* Returns options as defined in `config.fontSize.options` but processed to account for
|
|
921
|
+
* editor localization, i.e. to display {@link module:font/fontconfig~FontSizeOption}
|
|
922
|
+
* in the correct language.
|
|
923
|
+
*
|
|
924
|
+
* Note: The reason behind this method is that there is no way to use {@link module:utils/locale~Locale#t}
|
|
925
|
+
* when the user configuration is defined because the editor does not exist yet.
|
|
926
|
+
*/
|
|
927
|
+
_getLocalizedOptions() {
|
|
928
|
+
const editor = this.editor;
|
|
929
|
+
const t = editor.t;
|
|
930
|
+
const localizedTitles = {
|
|
931
|
+
Default: t("Default"),
|
|
932
|
+
Tiny: t("Tiny"),
|
|
933
|
+
Small: t("Small"),
|
|
934
|
+
Big: t("Big"),
|
|
935
|
+
Huge: t("Huge")
|
|
936
|
+
};
|
|
937
|
+
return normalizeOptions$1(editor.config.get(FONT_SIZE).options).map((option) => {
|
|
938
|
+
const title = localizedTitles[option.title];
|
|
939
|
+
if (title && title != option.title) option = Object.assign({}, option, { title });
|
|
940
|
+
return option;
|
|
941
|
+
});
|
|
942
|
+
}
|
|
943
|
+
};
|
|
989
944
|
/**
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
// Add the option to the collection.
|
|
1015
|
-
itemDefinitions.add(def);
|
|
1016
|
-
}
|
|
1017
|
-
return itemDefinitions;
|
|
945
|
+
* Prepares FontSize dropdown items.
|
|
946
|
+
*/
|
|
947
|
+
function _prepareListOptions(options, command) {
|
|
948
|
+
const itemDefinitions = new Collection();
|
|
949
|
+
for (const option of options) {
|
|
950
|
+
const def = {
|
|
951
|
+
type: "button",
|
|
952
|
+
model: new UIModel({
|
|
953
|
+
commandName: FONT_SIZE,
|
|
954
|
+
commandParam: option.model,
|
|
955
|
+
label: option.title,
|
|
956
|
+
class: "ck-fontsize-option",
|
|
957
|
+
role: "menuitemradio",
|
|
958
|
+
withText: true
|
|
959
|
+
})
|
|
960
|
+
};
|
|
961
|
+
if (option.view && typeof option.view !== "string") {
|
|
962
|
+
if (option.view.styles) def.model.set("labelStyle", `font-size:${option.view.styles["font-size"]}`);
|
|
963
|
+
if (option.view.classes) def.model.set("class", `${def.model.class} ${option.view.classes}`);
|
|
964
|
+
}
|
|
965
|
+
def.model.bind("isOn").to(command, "value", (value) => value === option.model);
|
|
966
|
+
itemDefinitions.add(def);
|
|
967
|
+
}
|
|
968
|
+
return itemDefinitions;
|
|
1018
969
|
}
|
|
1019
970
|
|
|
1020
971
|
/**
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
972
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
973
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
974
|
+
*/
|
|
975
|
+
/**
|
|
976
|
+
* @module font/fontsize
|
|
977
|
+
*/
|
|
978
|
+
/**
|
|
979
|
+
* The font size plugin.
|
|
980
|
+
*
|
|
981
|
+
* For a detailed overview, check the {@glink features/font font feature} documentation
|
|
982
|
+
* and the {@glink api/font package page}.
|
|
983
|
+
*
|
|
984
|
+
* This is a "glue" plugin which loads the {@link module:font/fontsize/fontsizeediting~FontSizeEditing} and
|
|
985
|
+
* {@link module:font/fontsize/fontsizeui~FontSizeUI} features in the editor.
|
|
986
|
+
*/
|
|
987
|
+
var FontSize = class extends Plugin {
|
|
988
|
+
/**
|
|
989
|
+
* @inheritDoc
|
|
990
|
+
*/
|
|
991
|
+
static get requires() {
|
|
992
|
+
return [FontSizeEditing, FontSizeUI];
|
|
993
|
+
}
|
|
994
|
+
/**
|
|
995
|
+
* @inheritDoc
|
|
996
|
+
*/
|
|
997
|
+
static get pluginName() {
|
|
998
|
+
return "FontSize";
|
|
999
|
+
}
|
|
1000
|
+
/**
|
|
1001
|
+
* @inheritDoc
|
|
1002
|
+
*/
|
|
1003
|
+
static get isOfficialPlugin() {
|
|
1004
|
+
return true;
|
|
1005
|
+
}
|
|
1006
|
+
/**
|
|
1007
|
+
* Normalizes and translates the {@link module:font/fontconfig~FontSizeConfig#options configuration options}
|
|
1008
|
+
* to the {@link module:font/fontconfig~FontSizeOption} format.
|
|
1009
|
+
*
|
|
1010
|
+
* @param options An array of options taken from the configuration.
|
|
1011
|
+
*/
|
|
1012
|
+
normalizeSizeOptions(options) {
|
|
1013
|
+
return normalizeOptions$1(options);
|
|
1014
|
+
}
|
|
1015
|
+
};
|
|
1056
1016
|
|
|
1057
1017
|
/**
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1018
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
1019
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
1020
|
+
*/
|
|
1021
|
+
/**
|
|
1022
|
+
* The font color command. It is used by {@link module:font/fontcolor/fontcolorediting~FontColorEditing}
|
|
1023
|
+
* to apply the font color.
|
|
1024
|
+
*
|
|
1025
|
+
* ```ts
|
|
1026
|
+
* editor.execute( 'fontColor', { value: 'rgb(250, 20, 20)' } );
|
|
1027
|
+
* ```
|
|
1028
|
+
*
|
|
1029
|
+
* **Note**: Executing the command with the `null` value removes the attribute from the model.
|
|
1030
|
+
*/
|
|
1031
|
+
var FontColorCommand = class extends FontCommand {
|
|
1032
|
+
/**
|
|
1033
|
+
* @inheritDoc
|
|
1034
|
+
*/
|
|
1035
|
+
constructor(editor) {
|
|
1036
|
+
super(editor, FONT_COLOR);
|
|
1037
|
+
}
|
|
1038
|
+
};
|
|
1073
1039
|
|
|
1074
1040
|
/**
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
{
|
|
1144
|
-
color: 'hsl(180, 75%, 60%)',
|
|
1145
|
-
label: 'Turquoise'
|
|
1146
|
-
},
|
|
1147
|
-
{
|
|
1148
|
-
color: 'hsl(210, 75%, 60%)',
|
|
1149
|
-
label: 'Light blue'
|
|
1150
|
-
},
|
|
1151
|
-
{
|
|
1152
|
-
color: 'hsl(240, 75%, 60%)',
|
|
1153
|
-
label: 'Blue'
|
|
1154
|
-
},
|
|
1155
|
-
{
|
|
1156
|
-
color: 'hsl(270, 75%, 60%)',
|
|
1157
|
-
label: 'Purple'
|
|
1158
|
-
}
|
|
1159
|
-
],
|
|
1160
|
-
columns: 5
|
|
1161
|
-
});
|
|
1162
|
-
editor.conversion.for('upcast').elementToAttribute({
|
|
1163
|
-
view: {
|
|
1164
|
-
name: 'span',
|
|
1165
|
-
styles: {
|
|
1166
|
-
'color': /[\s\S]+/
|
|
1167
|
-
}
|
|
1168
|
-
},
|
|
1169
|
-
model: {
|
|
1170
|
-
key: FONT_COLOR,
|
|
1171
|
-
value: renderUpcastAttribute('color')
|
|
1172
|
-
}
|
|
1173
|
-
});
|
|
1174
|
-
// Support legacy `<font color="..">` formatting.
|
|
1175
|
-
editor.conversion.for('upcast').elementToAttribute({
|
|
1176
|
-
view: {
|
|
1177
|
-
name: 'font',
|
|
1178
|
-
attributes: {
|
|
1179
|
-
'color': /^#?\w+$/
|
|
1180
|
-
}
|
|
1181
|
-
},
|
|
1182
|
-
model: {
|
|
1183
|
-
key: FONT_COLOR,
|
|
1184
|
-
value: (viewElement)=>viewElement.getAttribute('color')
|
|
1185
|
-
}
|
|
1186
|
-
});
|
|
1187
|
-
editor.conversion.for('downcast').attributeToElement({
|
|
1188
|
-
model: FONT_COLOR,
|
|
1189
|
-
view: renderDowncastElement('color')
|
|
1190
|
-
});
|
|
1191
|
-
editor.commands.add(FONT_COLOR, new FontColorCommand(editor));
|
|
1192
|
-
// Allow the font color attribute on text nodes.
|
|
1193
|
-
editor.model.schema.extend('$text', {
|
|
1194
|
-
allowAttributes: FONT_COLOR
|
|
1195
|
-
});
|
|
1196
|
-
editor.model.schema.setAttributeProperties(FONT_COLOR, {
|
|
1197
|
-
isFormatting: true,
|
|
1198
|
-
copyOnEnter: true
|
|
1199
|
-
});
|
|
1200
|
-
}
|
|
1201
|
-
}
|
|
1041
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
1042
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
1043
|
+
*/
|
|
1044
|
+
/**
|
|
1045
|
+
* @module font/fontcolor/fontcolorediting
|
|
1046
|
+
*/
|
|
1047
|
+
/**
|
|
1048
|
+
* The font color editing feature.
|
|
1049
|
+
*
|
|
1050
|
+
* It introduces the {@link module:font/fontcolor/fontcolorcommand~FontColorCommand command} and
|
|
1051
|
+
* the `fontColor` attribute in the {@link module:engine/model/model~Model model} which renders
|
|
1052
|
+
* in the {@link module:engine/view/view view} as a `<span>` element (`<span style="color: ...">`),
|
|
1053
|
+
* depending on the {@link module:font/fontconfig~FontColorConfig configuration}.
|
|
1054
|
+
*/
|
|
1055
|
+
var FontColorEditing = class extends Plugin {
|
|
1056
|
+
/**
|
|
1057
|
+
* @inheritDoc
|
|
1058
|
+
*/
|
|
1059
|
+
static get pluginName() {
|
|
1060
|
+
return "FontColorEditing";
|
|
1061
|
+
}
|
|
1062
|
+
/**
|
|
1063
|
+
* @inheritDoc
|
|
1064
|
+
*/
|
|
1065
|
+
static get isOfficialPlugin() {
|
|
1066
|
+
return true;
|
|
1067
|
+
}
|
|
1068
|
+
/**
|
|
1069
|
+
* @inheritDoc
|
|
1070
|
+
*/
|
|
1071
|
+
constructor(editor) {
|
|
1072
|
+
super(editor);
|
|
1073
|
+
editor.config.define(FONT_COLOR, {
|
|
1074
|
+
colors: _DEFAULT_COLORS,
|
|
1075
|
+
columns: _DEFAULT_COLOR_GRID_COLUMNS
|
|
1076
|
+
});
|
|
1077
|
+
editor.conversion.for("upcast").elementToAttribute({
|
|
1078
|
+
view: {
|
|
1079
|
+
name: "span",
|
|
1080
|
+
styles: { "color": /[\s\S]+/ }
|
|
1081
|
+
},
|
|
1082
|
+
model: {
|
|
1083
|
+
key: FONT_COLOR,
|
|
1084
|
+
value: renderUpcastAttribute("color")
|
|
1085
|
+
}
|
|
1086
|
+
});
|
|
1087
|
+
editor.conversion.for("upcast").elementToAttribute({
|
|
1088
|
+
view: {
|
|
1089
|
+
name: "font",
|
|
1090
|
+
attributes: { "color": /^#?\w+$/ }
|
|
1091
|
+
},
|
|
1092
|
+
model: {
|
|
1093
|
+
key: FONT_COLOR,
|
|
1094
|
+
value: (viewElement) => viewElement.getAttribute("color")
|
|
1095
|
+
}
|
|
1096
|
+
});
|
|
1097
|
+
editor.conversion.for("downcast").attributeToElement({
|
|
1098
|
+
model: FONT_COLOR,
|
|
1099
|
+
view: renderDowncastElement("color")
|
|
1100
|
+
});
|
|
1101
|
+
editor.commands.add(FONT_COLOR, new FontColorCommand(editor));
|
|
1102
|
+
editor.model.schema.extend("$text", { allowAttributes: FONT_COLOR });
|
|
1103
|
+
editor.model.schema.setAttributeProperties(FONT_COLOR, {
|
|
1104
|
+
isFormatting: true,
|
|
1105
|
+
copyOnEnter: true
|
|
1106
|
+
});
|
|
1107
|
+
}
|
|
1108
|
+
};
|
|
1202
1109
|
|
|
1203
1110
|
/**
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1111
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
1112
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
1113
|
+
*/
|
|
1114
|
+
/**
|
|
1115
|
+
* @module font/ui/colorui
|
|
1116
|
+
*/
|
|
1117
|
+
/**
|
|
1118
|
+
* The color UI plugin which isolates the common logic responsible for displaying dropdowns with color grids.
|
|
1119
|
+
*
|
|
1120
|
+
* It is used to create the `'fontBackgroundColor'` and `'fontColor'` dropdowns, each hosting
|
|
1121
|
+
* a {@link module:ui/colorselector/colorselectorview~ColorSelectorView}.
|
|
1122
|
+
*/
|
|
1123
|
+
var FontColorUIBase = class extends Plugin {
|
|
1124
|
+
/**
|
|
1125
|
+
* The name of the command which will be executed when a color tile is clicked.
|
|
1126
|
+
*/
|
|
1127
|
+
commandName;
|
|
1128
|
+
/**
|
|
1129
|
+
* The name of this component in the {@link module:ui/componentfactory~ComponentFactory}.
|
|
1130
|
+
* Also the configuration scope name in `editor.config`.
|
|
1131
|
+
*/
|
|
1132
|
+
componentName;
|
|
1133
|
+
/**
|
|
1134
|
+
* The SVG icon used by the dropdown.
|
|
1135
|
+
*/
|
|
1136
|
+
icon;
|
|
1137
|
+
/**
|
|
1138
|
+
* The label used by the dropdown.
|
|
1139
|
+
*/
|
|
1140
|
+
dropdownLabel;
|
|
1141
|
+
/**
|
|
1142
|
+
* The number of columns in the color grid.
|
|
1143
|
+
*/
|
|
1144
|
+
columns;
|
|
1145
|
+
/**
|
|
1146
|
+
* Creates a plugin which introduces a dropdown with a pre–configured
|
|
1147
|
+
* {@link module:ui/colorselector/colorselectorview~ColorSelectorView}.
|
|
1148
|
+
*
|
|
1149
|
+
* @param editor An editor instance.
|
|
1150
|
+
* @param config The configuration object.
|
|
1151
|
+
* @param config.commandName The name of the command which will be executed when a color tile is clicked.
|
|
1152
|
+
* @param config.componentName The name of the dropdown in the {@link module:ui/componentfactory~ComponentFactory}
|
|
1153
|
+
* and the configuration scope name in `editor.config`.
|
|
1154
|
+
* @param config.icon The SVG icon used by the dropdown.
|
|
1155
|
+
* @param config.dropdownLabel The label used by the dropdown.
|
|
1156
|
+
*/
|
|
1157
|
+
constructor(editor, { commandName, componentName, icon, dropdownLabel }) {
|
|
1158
|
+
super(editor);
|
|
1159
|
+
this.commandName = commandName;
|
|
1160
|
+
this.componentName = componentName;
|
|
1161
|
+
this.icon = icon;
|
|
1162
|
+
this.dropdownLabel = dropdownLabel;
|
|
1163
|
+
this.columns = editor.config.get(`${this.componentName}.columns`);
|
|
1164
|
+
}
|
|
1165
|
+
/**
|
|
1245
1166
|
* @inheritDoc
|
|
1246
|
-
*/
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
colorSelectorView.delegate('execute').to(menuView);
|
|
1361
|
-
colorSelectorView.on('execute', (evt, data)=>{
|
|
1362
|
-
editor.execute(this.commandName, {
|
|
1363
|
-
value: data.value,
|
|
1364
|
-
batch: this._undoStepBatch
|
|
1365
|
-
});
|
|
1366
|
-
editor.editing.view.focus();
|
|
1367
|
-
});
|
|
1368
|
-
menuView.on('change:isOpen', (evt, name, isVisible)=>{
|
|
1369
|
-
if (!contentRendered) {
|
|
1370
|
-
contentRendered = true;
|
|
1371
|
-
colorSelectorView.appendUI();
|
|
1372
|
-
}
|
|
1373
|
-
if (isVisible) {
|
|
1374
|
-
if (documentColorsCount !== 0) {
|
|
1375
|
-
colorSelectorView.updateDocumentColors(editor.model, this.componentName);
|
|
1376
|
-
}
|
|
1377
|
-
colorSelectorView.updateSelectedColors();
|
|
1378
|
-
colorSelectorView.showColorGridsFragment();
|
|
1379
|
-
}
|
|
1380
|
-
});
|
|
1381
|
-
menuView.panelView.children.add(colorSelectorView);
|
|
1382
|
-
return menuView;
|
|
1383
|
-
});
|
|
1384
|
-
}
|
|
1385
|
-
}
|
|
1167
|
+
*/
|
|
1168
|
+
init() {
|
|
1169
|
+
const editor = this.editor;
|
|
1170
|
+
const locale = editor.locale;
|
|
1171
|
+
const t = locale.t;
|
|
1172
|
+
const command = editor.commands.get(this.commandName);
|
|
1173
|
+
const componentConfig = editor.config.get(this.componentName);
|
|
1174
|
+
const colorsConfig = normalizeColorOptions(componentConfig.colors);
|
|
1175
|
+
const localizedColors = getLocalizedColorOptions(locale, colorsConfig);
|
|
1176
|
+
const documentColorsCount = componentConfig.documentColors;
|
|
1177
|
+
const hasColorPicker = componentConfig.colorPicker !== false;
|
|
1178
|
+
editor.ui.componentFactory.add(this.componentName, (locale) => {
|
|
1179
|
+
const dropdownView = createDropdown(locale);
|
|
1180
|
+
let dropdownContentRendered = false;
|
|
1181
|
+
const colorSelectorView = addColorSelectorToDropdown({
|
|
1182
|
+
dropdownView,
|
|
1183
|
+
colors: localizedColors.map((option) => ({
|
|
1184
|
+
label: option.label,
|
|
1185
|
+
color: option.model,
|
|
1186
|
+
options: { hasBorder: option.hasBorder }
|
|
1187
|
+
})),
|
|
1188
|
+
columns: this.columns,
|
|
1189
|
+
removeButtonLabel: t("Remove color"),
|
|
1190
|
+
colorPickerLabel: t("Color picker"),
|
|
1191
|
+
documentColorsLabel: documentColorsCount !== 0 ? t("Document colors") : "",
|
|
1192
|
+
documentColorsCount: documentColorsCount === void 0 ? this.columns : documentColorsCount,
|
|
1193
|
+
colorPickerViewConfig: hasColorPicker ? componentConfig.colorPicker || {} : false
|
|
1194
|
+
});
|
|
1195
|
+
colorSelectorView.bind("selectedColor").to(command, "value");
|
|
1196
|
+
dropdownView.buttonView.set({
|
|
1197
|
+
label: this.dropdownLabel,
|
|
1198
|
+
icon: this.icon,
|
|
1199
|
+
tooltip: true
|
|
1200
|
+
});
|
|
1201
|
+
dropdownView.extendTemplate({ attributes: { class: "ck-color-ui-dropdown" } });
|
|
1202
|
+
dropdownView.bind("isEnabled").to(command);
|
|
1203
|
+
colorSelectorView.on("execute", (evt, data) => {
|
|
1204
|
+
if (dropdownView.isOpen) editor.execute(this.commandName, {
|
|
1205
|
+
value: data.value,
|
|
1206
|
+
batch: this._undoStepBatch
|
|
1207
|
+
});
|
|
1208
|
+
if (data.source !== "colorPicker") editor.editing.view.focus();
|
|
1209
|
+
if (data.source === "colorPickerSaveButton") dropdownView.isOpen = false;
|
|
1210
|
+
});
|
|
1211
|
+
colorSelectorView.on("colorPicker:show", () => {
|
|
1212
|
+
this._undoStepBatch = editor.model.createBatch();
|
|
1213
|
+
});
|
|
1214
|
+
colorSelectorView.on("colorPicker:cancel", () => {
|
|
1215
|
+
if (this._undoStepBatch.operations.length) {
|
|
1216
|
+
dropdownView.isOpen = false;
|
|
1217
|
+
editor.execute("undo", this._undoStepBatch);
|
|
1218
|
+
}
|
|
1219
|
+
editor.editing.view.focus();
|
|
1220
|
+
});
|
|
1221
|
+
dropdownView.on("change:isOpen", (evt, name, isVisible) => {
|
|
1222
|
+
if (!dropdownContentRendered) {
|
|
1223
|
+
dropdownContentRendered = true;
|
|
1224
|
+
dropdownView.colorSelectorView.appendUI();
|
|
1225
|
+
}
|
|
1226
|
+
if (isVisible) {
|
|
1227
|
+
if (documentColorsCount !== 0) colorSelectorView.updateDocumentColors(editor.model, this.componentName);
|
|
1228
|
+
colorSelectorView.updateSelectedColors();
|
|
1229
|
+
colorSelectorView.showColorGridsFragment();
|
|
1230
|
+
}
|
|
1231
|
+
});
|
|
1232
|
+
focusChildOnDropdownOpen(dropdownView, () => dropdownView.colorSelectorView.colorGridsFragmentView.staticColorsGrid.items.find((item) => item.isOn));
|
|
1233
|
+
return dropdownView;
|
|
1234
|
+
});
|
|
1235
|
+
editor.ui.componentFactory.add(`menuBar:${this.componentName}`, (locale) => {
|
|
1236
|
+
const menuView = new MenuBarMenuView(locale);
|
|
1237
|
+
menuView.buttonView.set({
|
|
1238
|
+
label: this.dropdownLabel,
|
|
1239
|
+
icon: this.icon
|
|
1240
|
+
});
|
|
1241
|
+
menuView.bind("isEnabled").to(command);
|
|
1242
|
+
let contentRendered = false;
|
|
1243
|
+
const colorSelectorView = new ColorSelectorView(locale, {
|
|
1244
|
+
colors: localizedColors.map((option) => ({
|
|
1245
|
+
label: option.label,
|
|
1246
|
+
color: option.model,
|
|
1247
|
+
options: { hasBorder: option.hasBorder }
|
|
1248
|
+
})),
|
|
1249
|
+
columns: this.columns,
|
|
1250
|
+
removeButtonLabel: t("Remove color"),
|
|
1251
|
+
colorPickerLabel: t("Color picker"),
|
|
1252
|
+
documentColorsLabel: documentColorsCount !== 0 ? t("Document colors") : "",
|
|
1253
|
+
documentColorsCount: documentColorsCount === void 0 ? this.columns : documentColorsCount,
|
|
1254
|
+
colorPickerViewConfig: false
|
|
1255
|
+
});
|
|
1256
|
+
colorSelectorView.bind("selectedColor").to(command, "value");
|
|
1257
|
+
colorSelectorView.delegate("execute").to(menuView);
|
|
1258
|
+
colorSelectorView.on("execute", (evt, data) => {
|
|
1259
|
+
editor.execute(this.commandName, {
|
|
1260
|
+
value: data.value,
|
|
1261
|
+
batch: this._undoStepBatch
|
|
1262
|
+
});
|
|
1263
|
+
editor.editing.view.focus();
|
|
1264
|
+
});
|
|
1265
|
+
menuView.on("change:isOpen", (evt, name, isVisible) => {
|
|
1266
|
+
if (!contentRendered) {
|
|
1267
|
+
contentRendered = true;
|
|
1268
|
+
colorSelectorView.appendUI();
|
|
1269
|
+
}
|
|
1270
|
+
if (isVisible) {
|
|
1271
|
+
if (documentColorsCount !== 0) colorSelectorView.updateDocumentColors(editor.model, this.componentName);
|
|
1272
|
+
colorSelectorView.updateSelectedColors();
|
|
1273
|
+
colorSelectorView.showColorGridsFragment();
|
|
1274
|
+
}
|
|
1275
|
+
});
|
|
1276
|
+
menuView.panelView.children.add(colorSelectorView);
|
|
1277
|
+
return menuView;
|
|
1278
|
+
});
|
|
1279
|
+
}
|
|
1280
|
+
};
|
|
1386
1281
|
|
|
1387
1282
|
/**
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1283
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
1284
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
1285
|
+
*/
|
|
1286
|
+
/**
|
|
1287
|
+
* @module font/fontcolor/fontcolorui
|
|
1288
|
+
*/
|
|
1289
|
+
/**
|
|
1290
|
+
* The font color UI plugin. It introduces the `'fontColor'` dropdown.
|
|
1291
|
+
*/
|
|
1292
|
+
var FontColorUI = class extends FontColorUIBase {
|
|
1293
|
+
/**
|
|
1294
|
+
* @inheritDoc
|
|
1295
|
+
*/
|
|
1296
|
+
constructor(editor) {
|
|
1297
|
+
const t = editor.locale.t;
|
|
1298
|
+
super(editor, {
|
|
1299
|
+
commandName: FONT_COLOR,
|
|
1300
|
+
componentName: FONT_COLOR,
|
|
1301
|
+
icon: IconFontColor,
|
|
1302
|
+
dropdownLabel: t("Font Color")
|
|
1303
|
+
});
|
|
1304
|
+
}
|
|
1305
|
+
/**
|
|
1306
|
+
* @inheritDoc
|
|
1307
|
+
*/
|
|
1308
|
+
static get pluginName() {
|
|
1309
|
+
return "FontColorUI";
|
|
1310
|
+
}
|
|
1311
|
+
};
|
|
1407
1312
|
|
|
1408
1313
|
/**
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1314
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
1315
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
1316
|
+
*/
|
|
1317
|
+
/**
|
|
1318
|
+
* @module font/fontcolor
|
|
1319
|
+
*/
|
|
1320
|
+
/**
|
|
1321
|
+
* The font color plugin.
|
|
1322
|
+
*
|
|
1323
|
+
* For a detailed overview, check the {@glink features/font font feature} documentation
|
|
1324
|
+
* and the {@glink api/font package page}.
|
|
1325
|
+
*
|
|
1326
|
+
* This is a "glue" plugin which loads the {@link module:font/fontcolor/fontcolorediting~FontColorEditing} and
|
|
1327
|
+
* {@link module:font/fontcolor/fontcolorui~FontColorUI} features in the editor.
|
|
1328
|
+
*/
|
|
1329
|
+
var FontColor = class extends Plugin {
|
|
1330
|
+
/**
|
|
1331
|
+
* @inheritDoc
|
|
1332
|
+
*/
|
|
1333
|
+
static get requires() {
|
|
1334
|
+
return [FontColorEditing, FontColorUI];
|
|
1335
|
+
}
|
|
1336
|
+
/**
|
|
1337
|
+
* @inheritDoc
|
|
1338
|
+
*/
|
|
1339
|
+
static get pluginName() {
|
|
1340
|
+
return "FontColor";
|
|
1341
|
+
}
|
|
1342
|
+
/**
|
|
1343
|
+
* @inheritDoc
|
|
1344
|
+
*/
|
|
1345
|
+
static get isOfficialPlugin() {
|
|
1346
|
+
return true;
|
|
1347
|
+
}
|
|
1348
|
+
};
|
|
1436
1349
|
|
|
1437
1350
|
/**
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1351
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
1352
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
1353
|
+
*/
|
|
1354
|
+
/**
|
|
1355
|
+
* The font background color command. It is used by
|
|
1356
|
+
* {@link module:font/fontbackgroundcolor/fontbackgroundcolorediting~FontBackgroundColorEditing}
|
|
1357
|
+
* to apply the font background color.
|
|
1358
|
+
*
|
|
1359
|
+
* ```ts
|
|
1360
|
+
* editor.execute( 'fontBackgroundColor', { value: 'rgb(250, 20, 20)' } );
|
|
1361
|
+
* ```
|
|
1362
|
+
*
|
|
1363
|
+
* **Note**: Executing the command with the `null` value removes the attribute from the model.
|
|
1364
|
+
*/
|
|
1365
|
+
var FontBackgroundColorCommand = class extends FontCommand {
|
|
1366
|
+
/**
|
|
1367
|
+
* @inheritDoc
|
|
1368
|
+
*/
|
|
1369
|
+
constructor(editor) {
|
|
1370
|
+
super(editor, FONT_BACKGROUND_COLOR);
|
|
1371
|
+
}
|
|
1372
|
+
};
|
|
1454
1373
|
|
|
1455
1374
|
/**
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
},
|
|
1516
|
-
{
|
|
1517
|
-
color: 'hsl(120, 75%, 60%)',
|
|
1518
|
-
label: 'Green'
|
|
1519
|
-
},
|
|
1520
|
-
{
|
|
1521
|
-
color: 'hsl(150, 75%, 60%)',
|
|
1522
|
-
label: 'Aquamarine'
|
|
1523
|
-
},
|
|
1524
|
-
{
|
|
1525
|
-
color: 'hsl(180, 75%, 60%)',
|
|
1526
|
-
label: 'Turquoise'
|
|
1527
|
-
},
|
|
1528
|
-
{
|
|
1529
|
-
color: 'hsl(210, 75%, 60%)',
|
|
1530
|
-
label: 'Light blue'
|
|
1531
|
-
},
|
|
1532
|
-
{
|
|
1533
|
-
color: 'hsl(240, 75%, 60%)',
|
|
1534
|
-
label: 'Blue'
|
|
1535
|
-
},
|
|
1536
|
-
{
|
|
1537
|
-
color: 'hsl(270, 75%, 60%)',
|
|
1538
|
-
label: 'Purple'
|
|
1539
|
-
}
|
|
1540
|
-
],
|
|
1541
|
-
columns: 5
|
|
1542
|
-
});
|
|
1543
|
-
editor.data.addStyleProcessorRules(addBackgroundStylesRules);
|
|
1544
|
-
editor.conversion.for('upcast').elementToAttribute({
|
|
1545
|
-
view: {
|
|
1546
|
-
name: 'span',
|
|
1547
|
-
styles: {
|
|
1548
|
-
'background-color': /[\s\S]+/
|
|
1549
|
-
}
|
|
1550
|
-
},
|
|
1551
|
-
model: {
|
|
1552
|
-
key: FONT_BACKGROUND_COLOR,
|
|
1553
|
-
value: renderUpcastAttribute('background-color')
|
|
1554
|
-
}
|
|
1555
|
-
});
|
|
1556
|
-
editor.conversion.for('downcast').attributeToElement({
|
|
1557
|
-
model: FONT_BACKGROUND_COLOR,
|
|
1558
|
-
view: renderDowncastElement('background-color')
|
|
1559
|
-
});
|
|
1560
|
-
editor.commands.add(FONT_BACKGROUND_COLOR, new FontBackgroundColorCommand(editor));
|
|
1561
|
-
// Allow the font backgroundColor attribute on text nodes.
|
|
1562
|
-
editor.model.schema.extend('$text', {
|
|
1563
|
-
allowAttributes: FONT_BACKGROUND_COLOR
|
|
1564
|
-
});
|
|
1565
|
-
editor.model.schema.setAttributeProperties(FONT_BACKGROUND_COLOR, {
|
|
1566
|
-
isFormatting: true,
|
|
1567
|
-
copyOnEnter: true
|
|
1568
|
-
});
|
|
1569
|
-
}
|
|
1570
|
-
}
|
|
1375
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
1376
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
1377
|
+
*/
|
|
1378
|
+
/**
|
|
1379
|
+
* @module font/fontbackgroundcolor/fontbackgroundcolorediting
|
|
1380
|
+
*/
|
|
1381
|
+
/**
|
|
1382
|
+
* The font background color editing feature.
|
|
1383
|
+
*
|
|
1384
|
+
* It introduces the {@link module:font/fontbackgroundcolor/fontbackgroundcolorcommand~FontBackgroundColorCommand command} and
|
|
1385
|
+
* the `fontBackgroundColor` attribute in the {@link module:engine/model/model~Model model} which renders
|
|
1386
|
+
* in the {@link module:engine/view/view view} as a `<span>` element (`<span style="background-color: ...">`),
|
|
1387
|
+
* depending on the {@link module:font/fontconfig~FontColorConfig configuration}.
|
|
1388
|
+
*/
|
|
1389
|
+
var FontBackgroundColorEditing = class extends Plugin {
|
|
1390
|
+
/**
|
|
1391
|
+
* @inheritDoc
|
|
1392
|
+
*/
|
|
1393
|
+
static get pluginName() {
|
|
1394
|
+
return "FontBackgroundColorEditing";
|
|
1395
|
+
}
|
|
1396
|
+
/**
|
|
1397
|
+
* @inheritDoc
|
|
1398
|
+
*/
|
|
1399
|
+
static get isOfficialPlugin() {
|
|
1400
|
+
return true;
|
|
1401
|
+
}
|
|
1402
|
+
/**
|
|
1403
|
+
* @inheritDoc
|
|
1404
|
+
*/
|
|
1405
|
+
constructor(editor) {
|
|
1406
|
+
super(editor);
|
|
1407
|
+
editor.config.define(FONT_BACKGROUND_COLOR, {
|
|
1408
|
+
colors: _DEFAULT_COLORS,
|
|
1409
|
+
columns: _DEFAULT_COLOR_GRID_COLUMNS
|
|
1410
|
+
});
|
|
1411
|
+
editor.data.addStyleProcessorRules(addBackgroundStylesRules);
|
|
1412
|
+
editor.conversion.for("upcast").elementToAttribute({
|
|
1413
|
+
view: {
|
|
1414
|
+
name: "span",
|
|
1415
|
+
styles: { "background-color": /[\s\S]+/ }
|
|
1416
|
+
},
|
|
1417
|
+
model: {
|
|
1418
|
+
key: FONT_BACKGROUND_COLOR,
|
|
1419
|
+
value: renderUpcastAttribute("background-color")
|
|
1420
|
+
}
|
|
1421
|
+
});
|
|
1422
|
+
editor.conversion.for("downcast").attributeToElement({
|
|
1423
|
+
model: FONT_BACKGROUND_COLOR,
|
|
1424
|
+
view: renderDowncastElement("background-color")
|
|
1425
|
+
});
|
|
1426
|
+
editor.commands.add(FONT_BACKGROUND_COLOR, new FontBackgroundColorCommand(editor));
|
|
1427
|
+
editor.model.schema.extend("$text", { allowAttributes: FONT_BACKGROUND_COLOR });
|
|
1428
|
+
editor.model.schema.setAttributeProperties(FONT_BACKGROUND_COLOR, {
|
|
1429
|
+
isFormatting: true,
|
|
1430
|
+
copyOnEnter: true
|
|
1431
|
+
});
|
|
1432
|
+
}
|
|
1433
|
+
};
|
|
1571
1434
|
|
|
1572
1435
|
/**
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1436
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
1437
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
1438
|
+
*/
|
|
1439
|
+
/**
|
|
1440
|
+
* @module font/fontbackgroundcolor/fontbackgroundcolorui
|
|
1441
|
+
*/
|
|
1442
|
+
/**
|
|
1443
|
+
* The font background color UI plugin. It introduces the `'fontBackgroundColor'` dropdown.
|
|
1444
|
+
*/
|
|
1445
|
+
var FontBackgroundColorUI = class extends FontColorUIBase {
|
|
1446
|
+
/**
|
|
1447
|
+
* @inheritDoc
|
|
1448
|
+
*/
|
|
1449
|
+
constructor(editor) {
|
|
1450
|
+
const t = editor.locale.t;
|
|
1451
|
+
super(editor, {
|
|
1452
|
+
commandName: FONT_BACKGROUND_COLOR,
|
|
1453
|
+
componentName: FONT_BACKGROUND_COLOR,
|
|
1454
|
+
icon: IconFontBackground,
|
|
1455
|
+
dropdownLabel: t("Font Background Color")
|
|
1456
|
+
});
|
|
1457
|
+
}
|
|
1458
|
+
/**
|
|
1459
|
+
* @inheritDoc
|
|
1460
|
+
*/
|
|
1461
|
+
static get pluginName() {
|
|
1462
|
+
return "FontBackgroundColorUI";
|
|
1463
|
+
}
|
|
1464
|
+
};
|
|
1592
1465
|
|
|
1593
1466
|
/**
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1467
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
1468
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
1469
|
+
*/
|
|
1470
|
+
/**
|
|
1471
|
+
* @module font/fontbackgroundcolor
|
|
1472
|
+
*/
|
|
1473
|
+
/**
|
|
1474
|
+
* The font background color plugin.
|
|
1475
|
+
*
|
|
1476
|
+
* For a detailed overview, check the {@glink features/font font feature} documentation
|
|
1477
|
+
* and the {@glink api/font package page}.
|
|
1478
|
+
*
|
|
1479
|
+
* This is a "glue" plugin which loads
|
|
1480
|
+
* the {@link module:font/fontbackgroundcolor/fontbackgroundcolorediting~FontBackgroundColorEditing} and
|
|
1481
|
+
* {@link module:font/fontbackgroundcolor/fontbackgroundcolorui~FontBackgroundColorUI} features in the editor.
|
|
1482
|
+
*/
|
|
1483
|
+
var FontBackgroundColor = class extends Plugin {
|
|
1484
|
+
/**
|
|
1485
|
+
* @inheritDoc
|
|
1486
|
+
*/
|
|
1487
|
+
static get requires() {
|
|
1488
|
+
return [FontBackgroundColorEditing, FontBackgroundColorUI];
|
|
1489
|
+
}
|
|
1490
|
+
/**
|
|
1491
|
+
* @inheritDoc
|
|
1492
|
+
*/
|
|
1493
|
+
static get pluginName() {
|
|
1494
|
+
return "FontBackgroundColor";
|
|
1495
|
+
}
|
|
1496
|
+
/**
|
|
1497
|
+
* @inheritDoc
|
|
1498
|
+
*/
|
|
1499
|
+
static get isOfficialPlugin() {
|
|
1500
|
+
return true;
|
|
1501
|
+
}
|
|
1502
|
+
};
|
|
1622
1503
|
|
|
1623
1504
|
/**
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1505
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
1506
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
1507
|
+
*/
|
|
1508
|
+
/**
|
|
1509
|
+
* @module font/font
|
|
1510
|
+
*/
|
|
1511
|
+
/**
|
|
1512
|
+
* A plugin that enables a set of text styling features:
|
|
1513
|
+
*
|
|
1514
|
+
* * {@link module:font/fontsize~FontSize},
|
|
1515
|
+
* * {@link module:font/fontfamily~FontFamily}.
|
|
1516
|
+
* * {@link module:font/fontcolor~FontColor},
|
|
1517
|
+
* * {@link module:font/fontbackgroundcolor~FontBackgroundColor}.
|
|
1518
|
+
*
|
|
1519
|
+
* For a detailed overview, check the {@glink features/font Font feature} documentation
|
|
1520
|
+
* and the {@glink api/font package page}.
|
|
1521
|
+
*/
|
|
1522
|
+
var Font = class extends Plugin {
|
|
1523
|
+
/**
|
|
1524
|
+
* @inheritDoc
|
|
1525
|
+
*/
|
|
1526
|
+
static get requires() {
|
|
1527
|
+
return [
|
|
1528
|
+
FontFamily,
|
|
1529
|
+
FontSize,
|
|
1530
|
+
FontColor,
|
|
1531
|
+
FontBackgroundColor
|
|
1532
|
+
];
|
|
1533
|
+
}
|
|
1534
|
+
/**
|
|
1535
|
+
* @inheritDoc
|
|
1536
|
+
*/
|
|
1537
|
+
static get pluginName() {
|
|
1538
|
+
return "Font";
|
|
1539
|
+
}
|
|
1540
|
+
/**
|
|
1541
|
+
* @inheritDoc
|
|
1542
|
+
*/
|
|
1543
|
+
static get isOfficialPlugin() {
|
|
1544
|
+
return true;
|
|
1545
|
+
}
|
|
1546
|
+
};
|
|
1547
|
+
|
|
1548
|
+
/**
|
|
1549
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
1550
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
1551
|
+
*/
|
|
1655
1552
|
|
|
1656
|
-
export { Font, FontBackgroundColor, FontBackgroundColorCommand, FontBackgroundColorEditing, FontBackgroundColorUI, FontColor, FontColorCommand, FontColorEditing, FontColorUI, FontColorUIBase, FontCommand, FontFamily, FontFamilyCommand, FontFamilyEditing, FontFamilyUI, FontSize, FontSizeCommand, FontSizeEditing, FontSizeUI, addColorSelectorToDropdown as _addFontColorSelectorToDropdown, buildDefinition as _buildFontDefinition, normalizeOptions
|
|
1657
|
-
//# sourceMappingURL=index.js.map
|
|
1553
|
+
export { Font, FontBackgroundColor, FontBackgroundColorCommand, FontBackgroundColorEditing, FontBackgroundColorUI, FontColor, FontColorCommand, FontColorEditing, FontColorUI, FontColorUIBase, FontCommand, FontFamily, FontFamilyCommand, FontFamilyEditing, FontFamilyUI, FontSize, FontSizeCommand, FontSizeEditing, FontSizeUI, addColorSelectorToDropdown as _addFontColorSelectorToDropdown, buildDefinition as _buildFontDefinition, normalizeOptions as _normalizeFontFamilyOptions, normalizeOptions$1 as _normalizeFontSizeOptions, renderDowncastElement as _renderDowncastFontElement, renderUpcastAttribute as _renderUpcastFontColorAttribute };
|
|
1554
|
+
//# sourceMappingURL=index.js.map
|