@ckeditor/ckeditor5-font 37.1.0 → 38.0.0-rc.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/LICENSE.md +6 -0
- package/build/font.js +2 -2
- package/build/translations/ar.js +1 -1
- package/build/translations/az.js +1 -1
- package/build/translations/bg.js +1 -1
- package/build/translations/bn.js +1 -1
- package/build/translations/bs.js +1 -1
- package/build/translations/ca.js +1 -1
- package/build/translations/cs.js +1 -1
- package/build/translations/da.js +1 -1
- package/build/translations/de-ch.js +1 -1
- package/build/translations/de.js +1 -1
- package/build/translations/el.js +1 -1
- package/build/translations/en-au.js +1 -1
- package/build/translations/en-gb.js +1 -1
- package/build/translations/es.js +1 -1
- package/build/translations/et.js +1 -1
- package/build/translations/fa.js +1 -1
- package/build/translations/fi.js +1 -1
- package/build/translations/fr.js +1 -1
- package/build/translations/gl.js +1 -1
- package/build/translations/he.js +1 -1
- package/build/translations/hi.js +1 -1
- package/build/translations/hr.js +1 -1
- package/build/translations/hu.js +1 -1
- package/build/translations/id.js +1 -1
- package/build/translations/it.js +1 -1
- package/build/translations/ja.js +1 -1
- package/build/translations/jv.js +1 -1
- package/build/translations/ko.js +1 -1
- package/build/translations/ku.js +1 -1
- package/build/translations/lt.js +1 -1
- package/build/translations/lv.js +1 -1
- package/build/translations/ms.js +1 -1
- package/build/translations/nb.js +1 -1
- package/build/translations/ne.js +1 -1
- package/build/translations/nl.js +1 -1
- package/build/translations/no.js +1 -1
- package/build/translations/pl.js +1 -1
- package/build/translations/pt-br.js +1 -1
- package/build/translations/pt.js +1 -1
- package/build/translations/ro.js +1 -1
- package/build/translations/ru.js +1 -1
- package/build/translations/sk.js +1 -1
- package/build/translations/sl.js +1 -1
- package/build/translations/sq.js +1 -1
- package/build/translations/sr-latn.js +1 -1
- package/build/translations/sr.js +1 -1
- package/build/translations/sv.js +1 -1
- package/build/translations/th.js +1 -1
- package/build/translations/tk.js +1 -1
- package/build/translations/tr.js +1 -1
- package/build/translations/ug.js +1 -1
- package/build/translations/uk.js +1 -1
- package/build/translations/ur.js +1 -1
- package/build/translations/uz.js +1 -1
- package/build/translations/vi.js +1 -1
- package/build/translations/zh-cn.js +1 -1
- package/build/translations/zh.js +1 -1
- package/lang/contexts.json +2 -1
- package/lang/translations/ar.po +5 -1
- package/lang/translations/az.po +5 -1
- package/lang/translations/bg.po +5 -1
- package/lang/translations/bn.po +5 -1
- package/lang/translations/bs.po +5 -1
- package/lang/translations/ca.po +5 -1
- package/lang/translations/cs.po +5 -1
- package/lang/translations/da.po +5 -1
- package/lang/translations/de-ch.po +5 -1
- package/lang/translations/de.po +5 -1
- package/lang/translations/el.po +5 -1
- package/lang/translations/en-au.po +5 -1
- package/lang/translations/en-gb.po +5 -1
- package/lang/translations/en.po +4 -0
- package/lang/translations/es.po +5 -1
- package/lang/translations/et.po +5 -1
- package/lang/translations/fa.po +5 -1
- package/lang/translations/fi.po +5 -1
- package/lang/translations/fr.po +5 -1
- package/lang/translations/gl.po +5 -1
- package/lang/translations/he.po +5 -1
- package/lang/translations/hi.po +5 -1
- package/lang/translations/hr.po +5 -1
- package/lang/translations/hu.po +5 -1
- package/lang/translations/id.po +5 -1
- package/lang/translations/it.po +5 -1
- package/lang/translations/ja.po +5 -1
- package/lang/translations/jv.po +5 -1
- package/lang/translations/ko.po +5 -1
- package/lang/translations/ku.po +5 -1
- package/lang/translations/lt.po +5 -1
- package/lang/translations/lv.po +5 -1
- package/lang/translations/ms.po +5 -1
- package/lang/translations/nb.po +5 -1
- package/lang/translations/ne.po +5 -1
- package/lang/translations/nl.po +5 -1
- package/lang/translations/no.po +5 -1
- package/lang/translations/pl.po +5 -1
- package/lang/translations/pt-br.po +5 -1
- package/lang/translations/pt.po +5 -1
- package/lang/translations/ro.po +5 -1
- package/lang/translations/ru.po +5 -1
- package/lang/translations/sk.po +5 -1
- package/lang/translations/sl.po +5 -1
- package/lang/translations/sq.po +5 -1
- package/lang/translations/sr-latn.po +5 -1
- package/lang/translations/sr.po +5 -1
- package/lang/translations/sv.po +5 -1
- package/lang/translations/th.po +5 -1
- package/lang/translations/tk.po +5 -1
- package/lang/translations/tr.po +5 -1
- package/lang/translations/ug.po +5 -1
- package/lang/translations/uk.po +5 -1
- package/lang/translations/ur.po +5 -1
- package/lang/translations/uz.po +5 -1
- package/lang/translations/vi.po +5 -1
- package/lang/translations/zh-cn.po +5 -1
- package/lang/translations/zh.po +5 -1
- package/package.json +12 -11
- package/src/fontcommand.d.ts +2 -0
- package/src/fontcommand.js +14 -2
- package/src/fontconfig.d.ts +7 -1
- package/src/fontfamily/fontfamilyui.js +7 -2
- package/src/fontsize/fontsizeui.js +7 -2
- package/src/ui/colortableview.d.ts +326 -34
- package/src/ui/colortableview.js +432 -47
- package/src/ui/colorui.d.ts +5 -1
- package/src/ui/colorui.js +40 -8
- package/src/utils.d.ts +4 -2
- package/src/utils.js +10 -3
- package/theme/fontcolor.css +62 -1
package/src/ui/colortableview.js
CHANGED
|
@@ -6,16 +6,15 @@
|
|
|
6
6
|
* @module font/ui/colortableview
|
|
7
7
|
*/
|
|
8
8
|
import { icons } from 'ckeditor5/src/core';
|
|
9
|
-
import { ButtonView, ColorGridView, ColorTileView, FocusCycler, LabelView, Template, View, ViewCollection } from 'ckeditor5/src/ui';
|
|
9
|
+
import { ButtonView, ColorGridView, ColorTileView, FocusCycler, LabelView, Template, View, ViewCollection, ColorPickerView, ColorPaletteIcon } from 'ckeditor5/src/ui';
|
|
10
10
|
import { FocusTracker, KeystrokeHandler } from 'ckeditor5/src/utils';
|
|
11
11
|
import DocumentColorCollection from '../documentcolorcollection';
|
|
12
12
|
import '../../theme/fontcolor.css';
|
|
13
13
|
/**
|
|
14
14
|
* A class which represents a view with the following sub–components:
|
|
15
15
|
*
|
|
16
|
-
* * A
|
|
17
|
-
* * A
|
|
18
|
-
* * A dynamic {@link module:ui/colorgrid/colorgridview~ColorGridView} of colors used in the document.
|
|
16
|
+
* * A {@link module:font/ui/colortableview~ColorTableView#colorGridsPageView color grids component},
|
|
17
|
+
* * A {@link module:font/ui/colortableview~ColorTableView#colorPickerPageView color picker component}.
|
|
19
18
|
*/
|
|
20
19
|
export default class ColorTableView extends View {
|
|
21
20
|
/**
|
|
@@ -25,21 +24,18 @@ export default class ColorTableView extends View {
|
|
|
25
24
|
* @param colors An array with definitions of colors to be displayed in the table.
|
|
26
25
|
* @param columns The number of columns in the color grid.
|
|
27
26
|
* @param removeButtonLabel The label of the button responsible for removing the color.
|
|
27
|
+
* @param colorPickerLabel The label of the button responsible for color picker appearing.
|
|
28
28
|
* @param documentColorsLabel The label for the section with the document colors.
|
|
29
29
|
* @param documentColorsCount The number of colors in the document colors section inside the color dropdown.
|
|
30
|
+
* @param colorPickerConfig The configuration of color picker feature.
|
|
30
31
|
*/
|
|
31
|
-
constructor(locale, { colors, columns, removeButtonLabel, documentColorsLabel, documentColorsCount }) {
|
|
32
|
+
constructor(locale, { colors, columns, removeButtonLabel, documentColorsLabel, documentColorsCount, colorPickerLabel, colorPickerConfig }) {
|
|
32
33
|
super(locale);
|
|
33
34
|
this.items = this.createCollection();
|
|
34
|
-
this.colorDefinitions = colors;
|
|
35
35
|
this.focusTracker = new FocusTracker();
|
|
36
36
|
this.keystrokes = new KeystrokeHandler();
|
|
37
|
-
this.set('selectedColor', undefined);
|
|
38
|
-
this.removeButtonLabel = removeButtonLabel;
|
|
39
|
-
this.columns = columns;
|
|
40
|
-
this.documentColors = new DocumentColorCollection();
|
|
41
|
-
this.documentColorsCount = documentColorsCount;
|
|
42
37
|
this._focusables = new ViewCollection();
|
|
38
|
+
this._colorPickerConfig = colorPickerConfig;
|
|
43
39
|
this._focusCycler = new FocusCycler({
|
|
44
40
|
focusables: this._focusables,
|
|
45
41
|
focusTracker: this.focusTracker,
|
|
@@ -51,7 +47,36 @@ export default class ColorTableView extends View {
|
|
|
51
47
|
focusNext: 'tab'
|
|
52
48
|
}
|
|
53
49
|
});
|
|
54
|
-
this.
|
|
50
|
+
this.colorGridsPageView = new ColorGridsPageView(locale, {
|
|
51
|
+
colors, columns, removeButtonLabel, documentColorsLabel, documentColorsCount, colorPickerLabel,
|
|
52
|
+
focusTracker: this.focusTracker,
|
|
53
|
+
focusables: this._focusables
|
|
54
|
+
});
|
|
55
|
+
this.colorPickerPageView = new ColorPickerPageView(locale, {
|
|
56
|
+
focusables: this._focusables,
|
|
57
|
+
focusTracker: this.focusTracker,
|
|
58
|
+
keystrokes: this.keystrokes,
|
|
59
|
+
colorPickerConfig
|
|
60
|
+
});
|
|
61
|
+
this.set('_isColorGridsPageVisible', true);
|
|
62
|
+
this.set('_isColorPickerPageVisible', false);
|
|
63
|
+
this.set('selectedColor', undefined);
|
|
64
|
+
this.colorGridsPageView.bind('isVisible').to(this, '_isColorGridsPageVisible');
|
|
65
|
+
this.colorPickerPageView.bind('isVisible').to(this, '_isColorPickerPageVisible');
|
|
66
|
+
/**
|
|
67
|
+
* This is kind of bindings. Unfortunately we could not use this.bind() method because the same property
|
|
68
|
+
* can not be binded twice. So this is work around how to bind 'selectedColor' property between components.
|
|
69
|
+
*/
|
|
70
|
+
this.on('change:selectedColor', (evt, evtName, data) => {
|
|
71
|
+
this.colorGridsPageView.set('selectedColor', data);
|
|
72
|
+
this.colorPickerPageView.set('selectedColor', data);
|
|
73
|
+
});
|
|
74
|
+
this.colorGridsPageView.on('change:selectedColor', (evt, evtName, data) => {
|
|
75
|
+
this.set('selectedColor', data);
|
|
76
|
+
});
|
|
77
|
+
this.colorPickerPageView.on('change:selectedColor', (evt, evtName, data) => {
|
|
78
|
+
this.set('selectedColor', data);
|
|
79
|
+
});
|
|
55
80
|
this.setTemplate({
|
|
56
81
|
tag: 'div',
|
|
57
82
|
attributes: {
|
|
@@ -62,7 +87,160 @@ export default class ColorTableView extends View {
|
|
|
62
87
|
},
|
|
63
88
|
children: this.items
|
|
64
89
|
});
|
|
65
|
-
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* @inheritDoc
|
|
93
|
+
*/
|
|
94
|
+
render() {
|
|
95
|
+
super.render();
|
|
96
|
+
// Start listening for the keystrokes coming from #element.
|
|
97
|
+
this.keystrokes.listenTo(this.element);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* @inheritDoc
|
|
101
|
+
*/
|
|
102
|
+
destroy() {
|
|
103
|
+
super.destroy();
|
|
104
|
+
this.focusTracker.destroy();
|
|
105
|
+
this.keystrokes.destroy();
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Appends static and document color grid views.
|
|
109
|
+
*/
|
|
110
|
+
appendGrids() {
|
|
111
|
+
if (this.items.length) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
this.items.add(this.colorGridsPageView);
|
|
115
|
+
this.colorGridsPageView.delegate('execute').to(this);
|
|
116
|
+
this.colorGridsPageView.delegate('showColorPicker').to(this);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Renders UI in dropdown. Which sub-components are rendered
|
|
120
|
+
* depends on the component configuration.
|
|
121
|
+
*/
|
|
122
|
+
appendUI() {
|
|
123
|
+
this.appendGrids();
|
|
124
|
+
if (this._colorPickerConfig) {
|
|
125
|
+
this._appendColorPicker();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Show "Color picker" and hide "Color grids".
|
|
130
|
+
*/
|
|
131
|
+
showColorPicker() {
|
|
132
|
+
if (!this.colorPickerPageView.colorPickerView) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
this.set('_isColorPickerPageVisible', true);
|
|
136
|
+
this.colorPickerPageView.focus();
|
|
137
|
+
this.set('_isColorGridsPageVisible', false);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Show "Color grids" and hide "Color picker".
|
|
141
|
+
*/
|
|
142
|
+
showColorGrids() {
|
|
143
|
+
this.set('_isColorGridsPageVisible', true);
|
|
144
|
+
this.set('_isColorPickerPageVisible', false);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Focuses the first focusable element in {@link #items}.
|
|
148
|
+
*/
|
|
149
|
+
focus() {
|
|
150
|
+
this._focusCycler.focusFirst();
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Focuses the last focusable element in {@link #items}.
|
|
154
|
+
*/
|
|
155
|
+
focusLast() {
|
|
156
|
+
this._focusCycler.focusLast();
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Scans through the editor model and searches for text node attributes with the given attribute name.
|
|
160
|
+
* Found entries are set as document colors.
|
|
161
|
+
*
|
|
162
|
+
* All the previously stored document colors will be lost in the process.
|
|
163
|
+
*
|
|
164
|
+
* @param model The model used as a source to obtain the document colors.
|
|
165
|
+
* @param attributeName Determines the name of the related model's attribute for a given dropdown.
|
|
166
|
+
*/
|
|
167
|
+
updateDocumentColors(model, attributeName) {
|
|
168
|
+
this.colorGridsPageView.updateDocumentColors(model, attributeName);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Refreshes the state of the selected color in one or both {@link module:ui/colorgrid/colorgridview~ColorGridView}s
|
|
172
|
+
* available in the {@link module:font/ui/colortableview~ColorTableView}. It guarantees that the selection will occur only in one
|
|
173
|
+
* of them.
|
|
174
|
+
*/
|
|
175
|
+
updateSelectedColors() {
|
|
176
|
+
this.colorGridsPageView.updateSelectedColors();
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Appends the color picker view.
|
|
180
|
+
*/
|
|
181
|
+
_appendColorPicker() {
|
|
182
|
+
if (this.items.length === 2) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
this.items.add(this.colorPickerPageView);
|
|
186
|
+
if (this.colorGridsPageView.colorPickerButtonView) {
|
|
187
|
+
this.colorGridsPageView.colorPickerButtonView.on('execute', () => {
|
|
188
|
+
this.showColorPicker();
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
this.colorGridsPageView.addColorPickerButton();
|
|
192
|
+
this.colorPickerPageView.delegate('execute').to(this);
|
|
193
|
+
this.colorPickerPageView.delegate('cancel').to(this);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* A class which represents a view with the following sub–components:
|
|
198
|
+
*
|
|
199
|
+
* * A remove color button,
|
|
200
|
+
* * A static {@link module:ui/colorgrid/colorgridview~ColorGridView} of colors defined in the configuration,
|
|
201
|
+
* * A dynamic {@link module:ui/colorgrid/colorgridview~ColorGridView} of colors used in the document.
|
|
202
|
+
* * If color picker is configured, the "Color Picker" button is visible too.
|
|
203
|
+
*/
|
|
204
|
+
class ColorGridsPageView extends View {
|
|
205
|
+
/**
|
|
206
|
+
* Creates a view to be inserted as a child of {@link module:ui/dropdown/dropdownview~DropdownView}.
|
|
207
|
+
*
|
|
208
|
+
* @param locale The localization services instance.
|
|
209
|
+
* @param colors An array with definitions of colors to be displayed in the table.
|
|
210
|
+
* @param columns The number of columns in the color grid.
|
|
211
|
+
* @param removeButtonLabel The label of the button responsible for removing the color.
|
|
212
|
+
* @param colorPickerLabel The label of the button responsible for color picker appearing.
|
|
213
|
+
* @param documentColorsLabel The label for the section with the document colors.
|
|
214
|
+
* @param documentColorsCount The number of colors in the document colors section inside the color dropdown.
|
|
215
|
+
* @param focusTracker Tracks information about the DOM focus in the list.
|
|
216
|
+
* @param focusables A collection of views that can be focused in the view.
|
|
217
|
+
*/
|
|
218
|
+
constructor(locale, { colors, columns, removeButtonLabel, documentColorsLabel, documentColorsCount, colorPickerLabel, focusTracker, focusables }) {
|
|
219
|
+
super(locale);
|
|
220
|
+
const bind = this.bindTemplate;
|
|
221
|
+
this.set('isVisible', true);
|
|
222
|
+
this.focusTracker = focusTracker;
|
|
223
|
+
this.items = this.createCollection();
|
|
224
|
+
this.colorDefinitions = colors;
|
|
225
|
+
this.columns = columns;
|
|
226
|
+
this.documentColors = new DocumentColorCollection();
|
|
227
|
+
this.documentColorsCount = documentColorsCount;
|
|
228
|
+
this._focusables = focusables;
|
|
229
|
+
this._removeButtonLabel = removeButtonLabel;
|
|
230
|
+
this._colorPickerLabel = colorPickerLabel;
|
|
231
|
+
this._documentColorsLabel = documentColorsLabel;
|
|
232
|
+
this.setTemplate({
|
|
233
|
+
tag: 'div',
|
|
234
|
+
attributes: {
|
|
235
|
+
class: [
|
|
236
|
+
'ck-color-grids-page-view',
|
|
237
|
+
bind.if('isVisible', 'ck-hidden', value => !value)
|
|
238
|
+
]
|
|
239
|
+
},
|
|
240
|
+
children: this.items
|
|
241
|
+
});
|
|
242
|
+
this.removeColorButtonView = this._createRemoveColorButton();
|
|
243
|
+
this.items.add(this.removeColorButtonView);
|
|
66
244
|
}
|
|
67
245
|
/**
|
|
68
246
|
* Scans through the editor model and searches for text node attributes with the given attribute name.
|
|
@@ -109,28 +287,8 @@ export default class ColorTableView extends View {
|
|
|
109
287
|
*/
|
|
110
288
|
render() {
|
|
111
289
|
super.render();
|
|
112
|
-
// Start listening for the keystrokes coming from #element.
|
|
113
|
-
this.keystrokes.listenTo(this.element);
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* @inheritDoc
|
|
117
|
-
*/
|
|
118
|
-
destroy() {
|
|
119
|
-
super.destroy();
|
|
120
|
-
this.focusTracker.destroy();
|
|
121
|
-
this.keystrokes.destroy();
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Appends {@link #staticColorsGrid} and {@link #documentColorsGrid} views.
|
|
125
|
-
*/
|
|
126
|
-
appendGrids() {
|
|
127
|
-
if (this.staticColorsGrid) {
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
290
|
this.staticColorsGrid = this._createStaticColorsGrid();
|
|
131
291
|
this.items.add(this.staticColorsGrid);
|
|
132
|
-
this.focusTracker.add(this.staticColorsGrid.element);
|
|
133
|
-
this._focusables.add(this.staticColorsGrid);
|
|
134
292
|
if (this.documentColorsCount) {
|
|
135
293
|
// Create a label for document colors.
|
|
136
294
|
const bind = Template.bind(this.documentColors, this.documentColors);
|
|
@@ -148,21 +306,62 @@ export default class ColorTableView extends View {
|
|
|
148
306
|
this.items.add(label);
|
|
149
307
|
this.documentColorsGrid = this._createDocumentColorsGrid();
|
|
150
308
|
this.items.add(this.documentColorsGrid);
|
|
151
|
-
this.focusTracker.add(this.documentColorsGrid.element);
|
|
152
|
-
this._focusables.add(this.documentColorsGrid);
|
|
153
309
|
}
|
|
310
|
+
this._createColorPickerButton();
|
|
311
|
+
this._addColorTablesElementsToFocusTracker();
|
|
312
|
+
this.focus();
|
|
154
313
|
}
|
|
155
314
|
/**
|
|
156
|
-
* Focuses the
|
|
315
|
+
* Focuses the component.
|
|
157
316
|
*/
|
|
158
317
|
focus() {
|
|
159
|
-
this.
|
|
318
|
+
this.removeColorButtonView.focus();
|
|
160
319
|
}
|
|
161
320
|
/**
|
|
162
|
-
*
|
|
321
|
+
* @inheritDoc
|
|
163
322
|
*/
|
|
164
|
-
|
|
165
|
-
|
|
323
|
+
destroy() {
|
|
324
|
+
super.destroy();
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Handles displaying the color picker button (if it was previously created) and making it focusable.
|
|
328
|
+
*/
|
|
329
|
+
addColorPickerButton() {
|
|
330
|
+
if (this.colorPickerButtonView) {
|
|
331
|
+
this.items.add(this.colorPickerButtonView);
|
|
332
|
+
this.focusTracker.add(this.colorPickerButtonView.element);
|
|
333
|
+
this._focusables.add(this.colorPickerButtonView);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Adds color table elements to focus tracker.
|
|
338
|
+
*/
|
|
339
|
+
_addColorTablesElementsToFocusTracker() {
|
|
340
|
+
this.focusTracker.add(this.removeColorButtonView.element);
|
|
341
|
+
this._focusables.add(this.removeColorButtonView);
|
|
342
|
+
if (this.staticColorsGrid) {
|
|
343
|
+
this.focusTracker.add(this.staticColorsGrid.element);
|
|
344
|
+
this._focusables.add(this.staticColorsGrid);
|
|
345
|
+
}
|
|
346
|
+
if (this.documentColorsGrid) {
|
|
347
|
+
this.focusTracker.add(this.documentColorsGrid.element);
|
|
348
|
+
this._focusables.add(this.documentColorsGrid);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Creates the button responsible for displaying the color picker component.
|
|
353
|
+
*/
|
|
354
|
+
_createColorPickerButton() {
|
|
355
|
+
this.colorPickerButtonView = new ButtonView();
|
|
356
|
+
this.colorPickerButtonView.set({
|
|
357
|
+
label: this._colorPickerLabel,
|
|
358
|
+
withText: true,
|
|
359
|
+
icon: ColorPaletteIcon,
|
|
360
|
+
class: 'ck-color-table__color-picker'
|
|
361
|
+
});
|
|
362
|
+
this.colorPickerButtonView.on('execute', () => {
|
|
363
|
+
this.fire('showColorPicker');
|
|
364
|
+
});
|
|
166
365
|
}
|
|
167
366
|
/**
|
|
168
367
|
* Adds the remove color button as a child of the current view.
|
|
@@ -172,15 +371,16 @@ export default class ColorTableView extends View {
|
|
|
172
371
|
buttonView.set({
|
|
173
372
|
withText: true,
|
|
174
373
|
icon: icons.eraser,
|
|
175
|
-
label: this.
|
|
374
|
+
label: this._removeButtonLabel
|
|
176
375
|
});
|
|
177
376
|
buttonView.class = 'ck-color-table__remove-color';
|
|
178
377
|
buttonView.on('execute', () => {
|
|
179
|
-
this.fire('execute', {
|
|
378
|
+
this.fire('execute', {
|
|
379
|
+
value: null,
|
|
380
|
+
source: 'removeColorButton'
|
|
381
|
+
});
|
|
180
382
|
});
|
|
181
383
|
buttonView.render();
|
|
182
|
-
this.focusTracker.add(buttonView.element);
|
|
183
|
-
this._focusables.add(buttonView);
|
|
184
384
|
return buttonView;
|
|
185
385
|
}
|
|
186
386
|
/**
|
|
@@ -191,7 +391,12 @@ export default class ColorTableView extends View {
|
|
|
191
391
|
colorDefinitions: this.colorDefinitions,
|
|
192
392
|
columns: this.columns
|
|
193
393
|
});
|
|
194
|
-
colorGrid.
|
|
394
|
+
colorGrid.on('execute', (evt, data) => {
|
|
395
|
+
this.fire('execute', {
|
|
396
|
+
value: data.value,
|
|
397
|
+
source: 'staticColorsGrid'
|
|
398
|
+
});
|
|
399
|
+
});
|
|
195
400
|
return colorGrid;
|
|
196
401
|
}
|
|
197
402
|
/**
|
|
@@ -202,7 +407,6 @@ export default class ColorTableView extends View {
|
|
|
202
407
|
const documentColorsGrid = new ColorGridView(this.locale, {
|
|
203
408
|
columns: this.columns
|
|
204
409
|
});
|
|
205
|
-
documentColorsGrid.delegate('execute').to(this);
|
|
206
410
|
documentColorsGrid.extendTemplate({
|
|
207
411
|
attributes: {
|
|
208
412
|
class: bind.if('isEmpty', 'ck-hidden')
|
|
@@ -222,7 +426,8 @@ export default class ColorTableView extends View {
|
|
|
222
426
|
}
|
|
223
427
|
colorTile.on('execute', () => {
|
|
224
428
|
this.fire('execute', {
|
|
225
|
-
value: colorObj.color
|
|
429
|
+
value: colorObj.color,
|
|
430
|
+
source: 'documentColorsGrid'
|
|
226
431
|
});
|
|
227
432
|
});
|
|
228
433
|
return colorTile;
|
|
@@ -258,3 +463,183 @@ export default class ColorTableView extends View {
|
|
|
258
463
|
}
|
|
259
464
|
}
|
|
260
465
|
}
|
|
466
|
+
/**
|
|
467
|
+
* A class which represents a color picker component view with the following sub–components:
|
|
468
|
+
*
|
|
469
|
+
* * Color picker saturation and hue sliders,
|
|
470
|
+
* * Input accepting colors in HEX format,
|
|
471
|
+
* * "Save" and "Cancel" action buttons.
|
|
472
|
+
*/
|
|
473
|
+
class ColorPickerPageView extends View {
|
|
474
|
+
/**
|
|
475
|
+
* @param locale The localization services instance.
|
|
476
|
+
* @param focusTracker Tracks information about the DOM focus in the list.
|
|
477
|
+
* @param focusables A collection of views that can be focused in the view..
|
|
478
|
+
* @param keystrokes An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
|
|
479
|
+
* @param colorPickerConfig The configuration of color picker feature.
|
|
480
|
+
*/
|
|
481
|
+
constructor(locale, { focusTracker, focusables, keystrokes, colorPickerConfig }) {
|
|
482
|
+
super(locale);
|
|
483
|
+
this.items = this.createCollection();
|
|
484
|
+
this.focusTracker = focusTracker;
|
|
485
|
+
this.keystrokes = keystrokes;
|
|
486
|
+
this.set('isVisible', false);
|
|
487
|
+
this.set('selectedColor', undefined);
|
|
488
|
+
this._focusables = focusables;
|
|
489
|
+
this._pickerConfig = colorPickerConfig;
|
|
490
|
+
const bind = this.bindTemplate;
|
|
491
|
+
const { saveButtonView, cancelButtonView } = this._createActionButtons();
|
|
492
|
+
this.saveButtonView = saveButtonView;
|
|
493
|
+
this.cancelButtonView = cancelButtonView;
|
|
494
|
+
this.actionBarView = this._createActionBarView({ saveButtonView, cancelButtonView });
|
|
495
|
+
this.setTemplate({
|
|
496
|
+
tag: 'div',
|
|
497
|
+
attributes: {
|
|
498
|
+
class: [
|
|
499
|
+
'ck-color-picker-page-view',
|
|
500
|
+
bind.if('isVisible', 'ck-hidden', value => !value)
|
|
501
|
+
]
|
|
502
|
+
},
|
|
503
|
+
children: this.items
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* @inheritDoc
|
|
508
|
+
*/
|
|
509
|
+
render() {
|
|
510
|
+
super.render();
|
|
511
|
+
const colorPickerView = new ColorPickerView(this.locale, this._pickerConfig);
|
|
512
|
+
this.colorPickerView = colorPickerView;
|
|
513
|
+
this.colorPickerView.render();
|
|
514
|
+
if (this.selectedColor) {
|
|
515
|
+
colorPickerView.color = this.selectedColor;
|
|
516
|
+
}
|
|
517
|
+
this.listenTo(this, 'change:selectedColor', (evt, name, value) => {
|
|
518
|
+
colorPickerView.color = value;
|
|
519
|
+
});
|
|
520
|
+
this.items.add(this.colorPickerView);
|
|
521
|
+
this.items.add(this.actionBarView);
|
|
522
|
+
this._addColorPickersElementsToFocusTracker();
|
|
523
|
+
this._stopPropagationOnArrowsKeys();
|
|
524
|
+
this._executeOnEnterPress();
|
|
525
|
+
this._executeUponColorChange();
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* @inheritDoc
|
|
529
|
+
*/
|
|
530
|
+
destroy() {
|
|
531
|
+
super.destroy();
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* Focuses the color picker.
|
|
535
|
+
*/
|
|
536
|
+
focus() {
|
|
537
|
+
this.colorPickerView.focus();
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* When color picker is focused and "enter" is pressed it executes command.
|
|
541
|
+
*/
|
|
542
|
+
_executeOnEnterPress() {
|
|
543
|
+
this.keystrokes.set('enter', evt => {
|
|
544
|
+
if (this.isVisible && this.focusTracker.focusedElement !== this.cancelButtonView.element) {
|
|
545
|
+
this.fire('execute', {
|
|
546
|
+
value: this.selectedColor
|
|
547
|
+
});
|
|
548
|
+
evt.stopPropagation();
|
|
549
|
+
evt.preventDefault();
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Removes default behavior of arrow keys in dropdown.
|
|
555
|
+
*/
|
|
556
|
+
_stopPropagationOnArrowsKeys() {
|
|
557
|
+
const stopPropagation = (data) => data.stopPropagation();
|
|
558
|
+
this.keystrokes.set('arrowright', stopPropagation);
|
|
559
|
+
this.keystrokes.set('arrowleft', stopPropagation);
|
|
560
|
+
this.keystrokes.set('arrowup', stopPropagation);
|
|
561
|
+
this.keystrokes.set('arrowdown', stopPropagation);
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* Adds color picker elements to focus tracker.
|
|
565
|
+
*/
|
|
566
|
+
_addColorPickersElementsToFocusTracker() {
|
|
567
|
+
for (const slider of this.colorPickerView.slidersView) {
|
|
568
|
+
this.focusTracker.add(slider.element);
|
|
569
|
+
this._focusables.add(slider);
|
|
570
|
+
}
|
|
571
|
+
this.focusTracker.add(this.colorPickerView.hexInputRow.children.get(1).element);
|
|
572
|
+
this._focusables.add(this.colorPickerView.hexInputRow.children.get(1));
|
|
573
|
+
this.focusTracker.add(this.saveButtonView.element);
|
|
574
|
+
this._focusables.add(this.saveButtonView);
|
|
575
|
+
this.focusTracker.add(this.cancelButtonView.element);
|
|
576
|
+
this._focusables.add(this.cancelButtonView);
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Creates bar containing "Save" and "Cancel" buttons.
|
|
580
|
+
*/
|
|
581
|
+
_createActionBarView({ saveButtonView, cancelButtonView }) {
|
|
582
|
+
const actionBarRow = new View();
|
|
583
|
+
const children = this.createCollection();
|
|
584
|
+
children.add(saveButtonView);
|
|
585
|
+
children.add(cancelButtonView);
|
|
586
|
+
actionBarRow.setTemplate({
|
|
587
|
+
tag: 'div',
|
|
588
|
+
attributes: {
|
|
589
|
+
class: [
|
|
590
|
+
'ck',
|
|
591
|
+
'ck-color-table_action-bar'
|
|
592
|
+
]
|
|
593
|
+
},
|
|
594
|
+
children
|
|
595
|
+
});
|
|
596
|
+
return actionBarRow;
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Creates "Save" and "Cancel" buttons.
|
|
600
|
+
*/
|
|
601
|
+
_createActionButtons() {
|
|
602
|
+
const locale = this.locale;
|
|
603
|
+
const t = locale.t;
|
|
604
|
+
const saveButtonView = new ButtonView(locale);
|
|
605
|
+
const cancelButtonView = new ButtonView(locale);
|
|
606
|
+
saveButtonView.set({
|
|
607
|
+
icon: icons.check,
|
|
608
|
+
class: 'ck-button-save',
|
|
609
|
+
withText: false,
|
|
610
|
+
label: t('Accept'),
|
|
611
|
+
type: 'submit'
|
|
612
|
+
});
|
|
613
|
+
cancelButtonView.set({
|
|
614
|
+
icon: icons.cancel,
|
|
615
|
+
class: 'ck-button-cancel',
|
|
616
|
+
withText: false,
|
|
617
|
+
label: t('Cancel')
|
|
618
|
+
});
|
|
619
|
+
saveButtonView.on('execute', () => {
|
|
620
|
+
this.fire('execute', {
|
|
621
|
+
source: 'saveButton',
|
|
622
|
+
value: this.selectedColor
|
|
623
|
+
});
|
|
624
|
+
});
|
|
625
|
+
cancelButtonView.on('execute', () => {
|
|
626
|
+
this.fire('cancel');
|
|
627
|
+
});
|
|
628
|
+
return {
|
|
629
|
+
saveButtonView, cancelButtonView
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Fires the `execute` event if color in color picker changed.
|
|
634
|
+
*
|
|
635
|
+
* @fires execute
|
|
636
|
+
*/
|
|
637
|
+
_executeUponColorChange() {
|
|
638
|
+
this.colorPickerView.on('change:color', (evt, evtName, newValue) => {
|
|
639
|
+
this.fire('execute', {
|
|
640
|
+
value: newValue,
|
|
641
|
+
source: 'colorPicker'
|
|
642
|
+
});
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
}
|
package/src/ui/colorui.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { Plugin, type Editor } from 'ckeditor5/src/core';
|
|
9
9
|
import { type FONT_BACKGROUND_COLOR, type FONT_COLOR } from '../utils';
|
|
10
|
-
import type ColorTableView from './colortableview';
|
|
10
|
+
import { type default as ColorTableView } from './colortableview';
|
|
11
11
|
/**
|
|
12
12
|
* The color UI plugin which isolates the common logic responsible for displaying dropdowns with color grids.
|
|
13
13
|
*
|
|
@@ -40,6 +40,10 @@ export default class ColorUI extends Plugin {
|
|
|
40
40
|
* Keeps a reference to {@link module:font/ui/colortableview~ColorTableView}.
|
|
41
41
|
*/
|
|
42
42
|
colorTableView: ColorTableView | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* Keeps all changes in color picker in one batch while dropdown is open.
|
|
45
|
+
*/
|
|
46
|
+
private _undoStepBatch;
|
|
43
47
|
/**
|
|
44
48
|
* Creates a plugin which introduces a dropdown with a pre–configured {@link module:font/ui/colortableview~ColorTableView}.
|
|
45
49
|
*
|
package/src/ui/colorui.js
CHANGED
|
@@ -42,12 +42,16 @@ export default class ColorUI extends Plugin {
|
|
|
42
42
|
const locale = editor.locale;
|
|
43
43
|
const t = locale.t;
|
|
44
44
|
const command = editor.commands.get(this.commandName);
|
|
45
|
-
const
|
|
45
|
+
const componentConfig = editor.config.get(this.componentName);
|
|
46
|
+
const colorsConfig = normalizeColorOptions(componentConfig.colors);
|
|
46
47
|
const localizedColors = getLocalizedColorOptions(locale, colorsConfig);
|
|
47
|
-
const documentColorsCount =
|
|
48
|
+
const documentColorsCount = componentConfig.documentColors;
|
|
49
|
+
const hasColorPicker = componentConfig.colorPicker !== false;
|
|
48
50
|
// Register the UI component.
|
|
49
51
|
editor.ui.componentFactory.add(this.componentName, locale => {
|
|
50
52
|
const dropdownView = createDropdown(locale);
|
|
53
|
+
// Font color dropdown rendering is deferred once it gets open to improve performance (#6192).
|
|
54
|
+
let dropdownContentRendered = false;
|
|
51
55
|
this.colorTableView = addColorTableToDropdown({
|
|
52
56
|
dropdownView,
|
|
53
57
|
colors: localizedColors.map(option => ({
|
|
@@ -59,8 +63,10 @@ export default class ColorUI extends Plugin {
|
|
|
59
63
|
})),
|
|
60
64
|
columns: this.columns,
|
|
61
65
|
removeButtonLabel: t('Remove color'),
|
|
66
|
+
colorPickerLabel: t('Color picker'),
|
|
62
67
|
documentColorsLabel: documentColorsCount !== 0 ? t('Document colors') : '',
|
|
63
|
-
documentColorsCount: documentColorsCount === undefined ? this.columns : documentColorsCount
|
|
68
|
+
documentColorsCount: documentColorsCount === undefined ? this.columns : documentColorsCount,
|
|
69
|
+
colorPickerConfig: hasColorPicker ? (componentConfig.colorPicker || {}) : false
|
|
64
70
|
});
|
|
65
71
|
this.colorTableView.bind('selectedColor').to(command, 'value');
|
|
66
72
|
dropdownView.buttonView.set({
|
|
@@ -74,22 +80,48 @@ export default class ColorUI extends Plugin {
|
|
|
74
80
|
}
|
|
75
81
|
});
|
|
76
82
|
dropdownView.bind('isEnabled').to(command);
|
|
77
|
-
|
|
78
|
-
|
|
83
|
+
this.colorTableView.on('execute', (evt, data) => {
|
|
84
|
+
if (dropdownView.isOpen) {
|
|
85
|
+
editor.execute(this.commandName, {
|
|
86
|
+
value: data.value,
|
|
87
|
+
batch: this._undoStepBatch
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (data.source !== 'colorPicker') {
|
|
91
|
+
editor.editing.view.focus();
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
this.colorTableView.on('showColorPicker', () => {
|
|
95
|
+
this._undoStepBatch = editor.model.createBatch();
|
|
96
|
+
});
|
|
97
|
+
this.colorTableView.on('cancel', () => {
|
|
98
|
+
if (this._undoStepBatch.operations.length) {
|
|
99
|
+
// We need to close the dropdown before the undo batch.
|
|
100
|
+
// Otherwise, ColorUI treats undo as a selected color change,
|
|
101
|
+
// propagating the update to the whole selection.
|
|
102
|
+
// That's an issue if spans with various colors were selected.
|
|
103
|
+
dropdownView.isOpen = false;
|
|
104
|
+
editor.execute('undo', this._undoStepBatch);
|
|
105
|
+
}
|
|
79
106
|
editor.editing.view.focus();
|
|
80
107
|
});
|
|
81
108
|
dropdownView.on('change:isOpen', (evt, name, isVisible) => {
|
|
82
|
-
|
|
83
|
-
|
|
109
|
+
if (!dropdownContentRendered) {
|
|
110
|
+
dropdownContentRendered = true;
|
|
111
|
+
dropdownView.colorTableView.appendUI();
|
|
112
|
+
}
|
|
84
113
|
if (isVisible) {
|
|
85
114
|
if (documentColorsCount !== 0) {
|
|
86
115
|
this.colorTableView.updateDocumentColors(editor.model, this.componentName);
|
|
87
116
|
}
|
|
88
117
|
this.colorTableView.updateSelectedColors();
|
|
89
118
|
}
|
|
119
|
+
else {
|
|
120
|
+
this.colorTableView.showColorGrids();
|
|
121
|
+
}
|
|
90
122
|
});
|
|
91
123
|
// Accessibility: focus the first active color when opening the dropdown.
|
|
92
|
-
focusChildOnDropdownOpen(dropdownView, () => dropdownView.colorTableView.staticColorsGrid.items.find((item) => item.isOn));
|
|
124
|
+
focusChildOnDropdownOpen(dropdownView, () => dropdownView.colorTableView.colorGridsPageView.staticColorsGrid.items.find((item) => item.isOn));
|
|
93
125
|
return dropdownView;
|
|
94
126
|
});
|
|
95
127
|
}
|