@ckeditor/ckeditor5-style 34.0.0 → 35.0.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/CHANGELOG.md +4 -0
- package/LICENSE.md +2 -2
- package/build/style.js +1 -1
- package/build/translations/ar.js +1 -0
- package/build/translations/bg.js +1 -0
- package/build/translations/bn.js +1 -0
- package/build/translations/ca.js +1 -0
- package/build/translations/cs.js +1 -0
- package/build/translations/da.js +1 -0
- package/build/translations/de.js +1 -0
- package/build/translations/el.js +1 -0
- package/build/translations/en-au.js +1 -0
- package/build/translations/es.js +1 -0
- package/build/translations/et.js +1 -0
- package/build/translations/fi.js +1 -0
- package/build/translations/fr.js +1 -0
- package/build/translations/gl.js +1 -0
- package/build/translations/he.js +1 -0
- package/build/translations/hi.js +1 -0
- package/build/translations/hr.js +1 -0
- package/build/translations/hu.js +1 -0
- package/build/translations/id.js +1 -0
- package/build/translations/it.js +1 -0
- package/build/translations/ja.js +1 -0
- package/build/translations/ko.js +1 -0
- package/build/translations/lt.js +1 -0
- package/build/translations/lv.js +1 -0
- package/build/translations/ms.js +1 -0
- package/build/translations/nl.js +1 -0
- package/build/translations/no.js +1 -0
- package/build/translations/pl.js +1 -0
- package/build/translations/pt-br.js +1 -0
- package/build/translations/pt.js +1 -0
- package/build/translations/ro.js +1 -0
- package/build/translations/ru.js +1 -0
- package/build/translations/sk.js +1 -0
- package/build/translations/sr-latn.js +1 -0
- package/build/translations/sr.js +1 -0
- package/build/translations/sv.js +1 -0
- package/build/translations/th.js +1 -0
- package/build/translations/tr.js +1 -0
- package/build/translations/uk.js +1 -0
- package/build/translations/vi.js +1 -0
- package/build/translations/zh-cn.js +1 -0
- package/build/translations/zh.js +1 -0
- package/ckeditor5-metadata.json +3 -0
- package/lang/translations/ar.po +33 -0
- package/lang/translations/bg.po +33 -0
- package/lang/translations/bn.po +33 -0
- package/lang/translations/ca.po +33 -0
- package/lang/translations/cs.po +33 -0
- package/lang/translations/da.po +33 -0
- package/lang/translations/de.po +33 -0
- package/lang/translations/el.po +33 -0
- package/lang/translations/en-au.po +33 -0
- package/lang/translations/es.po +33 -0
- package/lang/translations/et.po +33 -0
- package/lang/translations/fi.po +33 -0
- package/lang/translations/fr.po +33 -0
- package/lang/translations/gl.po +33 -0
- package/lang/translations/he.po +33 -0
- package/lang/translations/hi.po +33 -0
- package/lang/translations/hr.po +33 -0
- package/lang/translations/hu.po +33 -0
- package/lang/translations/id.po +33 -0
- package/lang/translations/it.po +33 -0
- package/lang/translations/ja.po +33 -0
- package/lang/translations/ko.po +33 -0
- package/lang/translations/lt.po +33 -0
- package/lang/translations/lv.po +33 -0
- package/lang/translations/ms.po +33 -0
- package/lang/translations/nl.po +33 -0
- package/lang/translations/no.po +33 -0
- package/lang/translations/pl.po +33 -0
- package/lang/translations/pt-br.po +33 -0
- package/lang/translations/pt.po +33 -0
- package/lang/translations/ro.po +33 -0
- package/lang/translations/ru.po +33 -0
- package/lang/translations/sk.po +33 -0
- package/lang/translations/sr-latn.po +33 -0
- package/lang/translations/sr.po +33 -0
- package/lang/translations/sv.po +33 -0
- package/lang/translations/th.po +33 -0
- package/lang/translations/tr.po +33 -0
- package/lang/translations/uk.po +33 -0
- package/lang/translations/vi.po +33 -0
- package/lang/translations/zh-cn.po +33 -0
- package/lang/translations/zh.po +33 -0
- package/package.json +36 -34
- package/src/stylecommand.js +150 -153
- package/src/styleediting.js +1 -85
- package/src/styleui.js +6 -3
- package/src/ui/stylegridbuttonview.js +1 -1
- package/src/utils.js +13 -6
- package/theme/stylegrid.css +1 -0
package/src/stylecommand.js
CHANGED
|
@@ -18,29 +18,28 @@ import { logWarning, first } from 'ckeditor5/src/utils';
|
|
|
18
18
|
* @extends module:core/command~Command
|
|
19
19
|
*/
|
|
20
20
|
export default class StyleCommand extends Command {
|
|
21
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Creates an instance of the command.
|
|
23
|
+
*
|
|
24
|
+
* @param {module:core/editor/editor~Editor} editor Editor on which this command will be used.
|
|
25
|
+
* @param {Object} styleDefinitions Normalized definitions of the styles.
|
|
26
|
+
* @param {Array.<module:style/style~StyleDefinition>} styleDefinitions.block Definitions of block styles.
|
|
27
|
+
* @param {Array.<module:style/style~StyleDefinition>} styleDefinitions.inline Definitions of inline styles.
|
|
28
|
+
*/
|
|
29
|
+
constructor( editor, styleDefinitions ) {
|
|
22
30
|
super( editor );
|
|
23
31
|
|
|
24
32
|
/**
|
|
25
|
-
* Set of currently applied styles on current selection.
|
|
33
|
+
* Set of currently applied styles on the current selection.
|
|
26
34
|
*
|
|
27
35
|
* Names of styles correspond to the `name` property of
|
|
28
36
|
* {@link module:style/style~StyleDefinition configured definitions}.
|
|
29
37
|
*
|
|
30
|
-
* @observable
|
|
31
38
|
* @readonly
|
|
32
|
-
* @
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Styles object. Helps in getting styles definitions by
|
|
37
|
-
* class name, style name and model element name.
|
|
38
|
-
*
|
|
39
|
-
* @private
|
|
40
|
-
* @readonly
|
|
41
|
-
* @member {module:style/styleediting~Styles}
|
|
39
|
+
* @observable
|
|
40
|
+
* @member {Array.<String>} #value
|
|
42
41
|
*/
|
|
43
|
-
this.
|
|
42
|
+
this.set( 'value', [] );
|
|
44
43
|
|
|
45
44
|
/**
|
|
46
45
|
* Names of enabled styles (styles that can be applied to the current selection).
|
|
@@ -55,33 +54,80 @@ export default class StyleCommand extends Command {
|
|
|
55
54
|
this.set( 'enabledStyles', [] );
|
|
56
55
|
|
|
57
56
|
/**
|
|
58
|
-
*
|
|
57
|
+
* Normalized definitions of the styles.
|
|
58
|
+
*
|
|
59
|
+
* @private
|
|
60
|
+
* @readonly
|
|
61
|
+
* @member {Object} #styleDefinitions
|
|
59
62
|
*/
|
|
60
|
-
this.
|
|
63
|
+
this._styleDefinitions = styleDefinitions;
|
|
61
64
|
}
|
|
62
65
|
|
|
63
66
|
/**
|
|
64
67
|
* @inheritDoc
|
|
65
68
|
*/
|
|
66
69
|
refresh() {
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
const selection = editor.model.document.selection;
|
|
70
|
-
const block = first( selection.getSelectedBlocks() );
|
|
70
|
+
const model = this.editor.model;
|
|
71
|
+
const selection = model.document.selection;
|
|
71
72
|
|
|
72
|
-
|
|
73
|
+
const value = new Set();
|
|
74
|
+
const enabledStyles = new Set();
|
|
73
75
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
// Inline styles.
|
|
77
|
+
for ( const definition of this._styleDefinitions.inline ) {
|
|
78
|
+
for ( const ghsAttributeName of definition.ghsAttributes ) {
|
|
79
|
+
// Check if this inline style is enabled.
|
|
80
|
+
if ( model.schema.checkAttributeInSelection( selection, ghsAttributeName ) ) {
|
|
81
|
+
enabledStyles.add( definition.name );
|
|
82
|
+
}
|
|
77
83
|
|
|
78
|
-
|
|
79
|
-
|
|
84
|
+
// Check if this inline style is active.
|
|
85
|
+
const ghsAttributeValue = this._getValueFromFirstAllowedNode( ghsAttributeName );
|
|
86
|
+
|
|
87
|
+
if ( hasAllClasses( ghsAttributeValue, definition.classes ) ) {
|
|
88
|
+
value.add( definition.name );
|
|
89
|
+
}
|
|
80
90
|
}
|
|
81
91
|
}
|
|
82
92
|
|
|
93
|
+
// Block styles.
|
|
94
|
+
const firstBlock = first( selection.getSelectedBlocks() );
|
|
95
|
+
|
|
96
|
+
if ( firstBlock ) {
|
|
97
|
+
const ancestorBlocks = firstBlock.getAncestors( { includeSelf: true, parentFirst: true } );
|
|
98
|
+
|
|
99
|
+
for ( const block of ancestorBlocks ) {
|
|
100
|
+
// E.g. reached a model table when the selection is in a cell. The command should not modify
|
|
101
|
+
// ancestors of a table.
|
|
102
|
+
if ( model.schema.isLimit( block ) ) {
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if ( !model.schema.checkAttribute( block, 'htmlAttributes' ) ) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
for ( const definition of this._styleDefinitions.block ) {
|
|
111
|
+
// Check if this block style is enabled.
|
|
112
|
+
if ( !definition.modelElements.includes( block.name ) ) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
enabledStyles.add( definition.name );
|
|
117
|
+
|
|
118
|
+
// Check if this block style is active.
|
|
119
|
+
const ghsAttributeValue = block.getAttribute( 'htmlAttributes' );
|
|
120
|
+
|
|
121
|
+
if ( hasAllClasses( ghsAttributeValue, definition.classes ) ) {
|
|
122
|
+
value.add( definition.name );
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
this.enabledStyles = Array.from( enabledStyles ).sort();
|
|
83
129
|
this.isEnabled = this.enabledStyles.length > 0;
|
|
84
|
-
this.value = this.isEnabled ? value : [];
|
|
130
|
+
this.value = this.isEnabled ? Array.from( value ).sort() : [];
|
|
85
131
|
}
|
|
86
132
|
|
|
87
133
|
/**
|
|
@@ -95,145 +141,74 @@ export default class StyleCommand extends Command {
|
|
|
95
141
|
* * When applying inline styles:
|
|
96
142
|
* * If the selection is on a range, the command applies the style classes to all nodes in that range.
|
|
97
143
|
* * If the selection is collapsed in a non-empty node, the command applies the style classes to the
|
|
98
|
-
* {@link module:engine/model/document~Document#selection}
|
|
144
|
+
* {@link module:engine/model/document~Document#selection}.
|
|
99
145
|
*
|
|
100
146
|
* * When applying block styles:
|
|
101
147
|
* * If the selection is on a range, the command applies the style classes to the nearest block parent element.
|
|
102
148
|
*
|
|
103
|
-
* * When selection is set on a widget object:
|
|
104
|
-
* * Do nothing. Widgets are not yet supported by the style command.
|
|
105
|
-
*
|
|
106
149
|
* @fires execute
|
|
107
|
-
* @param {
|
|
150
|
+
* @param {Object} [options] Command options.
|
|
151
|
+
* @param {String} options.styleName Style name matching the one defined in the
|
|
152
|
+
* {@link module:style/style~StyleConfig#definitions configuration}.
|
|
153
|
+
* @param {Boolean} [options.forceValue] Whether the command should add given style (`true`) or remove it (`false`) from the selection.
|
|
154
|
+
* If not set (default), the command will toggle the style basing on the first selected node. Note, that this will not force
|
|
155
|
+
* setting a style on an element that cannot receive given style.
|
|
108
156
|
*/
|
|
109
|
-
execute( styleName ) {
|
|
157
|
+
execute( { styleName, forceValue } ) {
|
|
110
158
|
if ( !this.enabledStyles.includes( styleName ) ) {
|
|
111
159
|
/**
|
|
112
|
-
* Style command can be executed only
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
160
|
+
* Style command can be executed only with a correct style name.
|
|
161
|
+
*
|
|
162
|
+
* This warning may be caused by:
|
|
163
|
+
*
|
|
164
|
+
* * passing a name that is not specified in the {@link module:style/style~StyleConfig#definitions configuration}
|
|
165
|
+
* (e.g. a CSS class name),
|
|
166
|
+
* * when trying to apply a style that is not allowed on a given element.
|
|
116
167
|
*
|
|
117
168
|
* @error style-command-executed-with-incorrect-style-name
|
|
118
169
|
*/
|
|
119
170
|
logWarning( 'style-command-executed-with-incorrect-style-name' );
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const editor = this.editor;
|
|
124
|
-
const model = editor.model;
|
|
125
|
-
const doc = model.document;
|
|
126
|
-
const selection = doc.selection;
|
|
127
|
-
|
|
128
|
-
const selectedBlockElement = first( selection.getSelectedBlocks() );
|
|
129
|
-
const definition = this.styles.getDefinitionsByName( styleName );
|
|
130
171
|
|
|
131
|
-
|
|
132
|
-
this._handleStyleUpdate( definition, selectedBlockElement );
|
|
133
|
-
} else {
|
|
134
|
-
this._handleStyleUpdate( definition, selection );
|
|
172
|
+
return;
|
|
135
173
|
}
|
|
136
|
-
}
|
|
137
174
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
*
|
|
141
|
-
* @private
|
|
142
|
-
* @param {Object} definition Style definition object.
|
|
143
|
-
* @param {module:engine/model/selection~Selectable} selectable Selection, range or element to update the style on.
|
|
144
|
-
*/
|
|
145
|
-
_handleStyleUpdate( definition, selectable ) {
|
|
146
|
-
const { name, element, classes } = definition;
|
|
175
|
+
const model = this.editor.model;
|
|
176
|
+
const selection = model.document.selection;
|
|
147
177
|
const htmlSupport = this.editor.plugins.get( 'GeneralHtmlSupport' );
|
|
148
178
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Returns inline element value.
|
|
158
|
-
*
|
|
159
|
-
* @private
|
|
160
|
-
* @param {Array} value
|
|
161
|
-
* @param {module:engine/model/selection~Selection} selection
|
|
162
|
-
*/
|
|
163
|
-
_prepareNewInlineElementValue( value, selection ) {
|
|
164
|
-
let newValue = [ ...value ];
|
|
165
|
-
|
|
166
|
-
const attributes = selection.getAttributes();
|
|
167
|
-
|
|
168
|
-
for ( const [ attribute ] of attributes ) {
|
|
169
|
-
newValue = [ ...newValue, ...this._getAttributeValue( attribute ) ];
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
return newValue;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Returns element value and sets enabled styles.
|
|
177
|
-
*
|
|
178
|
-
* @private
|
|
179
|
-
* @param {Array} value
|
|
180
|
-
* @param {Object|null} element
|
|
181
|
-
* @return {Array} Current block element styles value.
|
|
182
|
-
*/
|
|
183
|
-
_prepareNewBlockElementValue( value, element ) {
|
|
184
|
-
const availableDefinitions = this.styles.getDefinitionsByElementName( element.name );
|
|
185
|
-
|
|
186
|
-
if ( availableDefinitions ) {
|
|
187
|
-
const blockStyleNames = availableDefinitions.map( ( { name } ) => name );
|
|
188
|
-
this.enabledStyles = [ ...this.enabledStyles, ...blockStyleNames ];
|
|
189
|
-
}
|
|
179
|
+
const definition = [
|
|
180
|
+
...this._styleDefinitions.inline,
|
|
181
|
+
...this._styleDefinitions.block
|
|
182
|
+
].find( ( { name } ) => name == styleName );
|
|
190
183
|
|
|
191
|
-
|
|
192
|
-
}
|
|
184
|
+
const shouldAddStyle = forceValue === undefined ? !this.value.includes( definition.name ) : forceValue;
|
|
193
185
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
*
|
|
197
|
-
* @private
|
|
198
|
-
* @param {String} attribute
|
|
199
|
-
*/
|
|
200
|
-
_getAttributeValue( attribute ) {
|
|
201
|
-
const value = [];
|
|
202
|
-
const classes = attribute === 'htmlAttributes' ?
|
|
203
|
-
this._getValueFromBlockElement() :
|
|
204
|
-
this._getValueFromFirstAllowedNode( attribute );
|
|
186
|
+
model.change( () => {
|
|
187
|
+
let selectables;
|
|
205
188
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
return value;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Gets classes from currently selected block element.
|
|
217
|
-
*
|
|
218
|
-
* @private
|
|
219
|
-
*/
|
|
220
|
-
_getValueFromBlockElement() {
|
|
221
|
-
const selection = this.editor.model.document.selection;
|
|
222
|
-
const block = first( selection.getSelectedBlocks() );
|
|
223
|
-
const attributes = block.getAttribute( 'htmlAttributes' );
|
|
224
|
-
|
|
225
|
-
if ( attributes ) {
|
|
226
|
-
return attributes.classes;
|
|
227
|
-
}
|
|
189
|
+
if ( definition.isBlock ) {
|
|
190
|
+
selectables = getAffectedBlocks( selection.getSelectedBlocks(), definition.modelElements, model.schema );
|
|
191
|
+
} else {
|
|
192
|
+
selectables = [ selection ];
|
|
193
|
+
}
|
|
228
194
|
|
|
229
|
-
|
|
195
|
+
for ( const selectable of selectables ) {
|
|
196
|
+
if ( shouldAddStyle ) {
|
|
197
|
+
htmlSupport.addModelHtmlClass( definition.element, definition.classes, selectable );
|
|
198
|
+
} else {
|
|
199
|
+
htmlSupport.removeModelHtmlClass( definition.element, definition.classes, selectable );
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
} );
|
|
230
203
|
}
|
|
231
204
|
|
|
232
205
|
/**
|
|
233
|
-
*
|
|
206
|
+
* Checks the attribute value of the first node in the selection that allows the attribute.
|
|
207
|
+
* For the collapsed selection, returns the selection attribute.
|
|
234
208
|
*
|
|
235
209
|
* @private
|
|
236
|
-
* @param {String} attributeName
|
|
210
|
+
* @param {String} attributeName Name of the GHS attribute.
|
|
211
|
+
* @returns {Object|null} The attribute value.
|
|
237
212
|
*/
|
|
238
213
|
_getValueFromFirstAllowedNode( attributeName ) {
|
|
239
214
|
const model = this.editor.model;
|
|
@@ -241,27 +216,49 @@ export default class StyleCommand extends Command {
|
|
|
241
216
|
const selection = model.document.selection;
|
|
242
217
|
|
|
243
218
|
if ( selection.isCollapsed ) {
|
|
244
|
-
|
|
245
|
-
const { classes } = selection.getAttribute( attributeName ) || {};
|
|
246
|
-
|
|
247
|
-
/* istanbul ignore next */
|
|
248
|
-
return classes || [];
|
|
219
|
+
return selection.getAttribute( attributeName );
|
|
249
220
|
}
|
|
250
221
|
|
|
251
222
|
for ( const range of selection.getRanges() ) {
|
|
252
223
|
for ( const item of range.getItems() ) {
|
|
253
|
-
/* istanbul ignore else */
|
|
254
224
|
if ( schema.checkAttribute( item, attributeName ) ) {
|
|
255
|
-
|
|
256
|
-
const { classes } = item.getAttribute( attributeName ) || {};
|
|
257
|
-
|
|
258
|
-
/* istanbul ignore next */
|
|
259
|
-
return classes || [];
|
|
225
|
+
return item.getAttribute( attributeName );
|
|
260
226
|
}
|
|
261
227
|
}
|
|
262
228
|
}
|
|
263
229
|
|
|
264
|
-
|
|
265
|
-
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Verifies if all classes are present in the given GHS attribute.
|
|
235
|
+
function hasAllClasses( ghsAttributeValue, classes ) {
|
|
236
|
+
if ( !ghsAttributeValue || !ghsAttributeValue.classes ) {
|
|
237
|
+
return false;
|
|
266
238
|
}
|
|
239
|
+
|
|
240
|
+
return classes.every( className => ghsAttributeValue.classes.includes( className ) );
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Returns a set of elements that should be affected by the block-style change.
|
|
244
|
+
function getAffectedBlocks( selectedBlocks, elementNames, schema ) {
|
|
245
|
+
const blocks = new Set();
|
|
246
|
+
|
|
247
|
+
for ( const selectedBlock of selectedBlocks ) {
|
|
248
|
+
const ancestorBlocks = selectedBlock.getAncestors( { includeSelf: true, parentFirst: true } );
|
|
249
|
+
|
|
250
|
+
for ( const block of ancestorBlocks ) {
|
|
251
|
+
if ( schema.isLimit( block ) ) {
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if ( elementNames.includes( block.name ) ) {
|
|
256
|
+
blocks.add( block );
|
|
257
|
+
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return blocks;
|
|
267
264
|
}
|
package/src/styleediting.js
CHANGED
|
@@ -43,9 +43,8 @@ export default class StyleEditing extends Plugin {
|
|
|
43
43
|
const editor = this.editor;
|
|
44
44
|
const dataSchema = editor.plugins.get( 'DataSchema' );
|
|
45
45
|
const normalizedStyleDefinitions = normalizeConfig( dataSchema, editor.config.get( 'style.definitions' ) );
|
|
46
|
-
const styles = new Styles( normalizedStyleDefinitions );
|
|
47
46
|
|
|
48
|
-
editor.commands.add( 'style', new StyleCommand( editor,
|
|
47
|
+
editor.commands.add( 'style', new StyleCommand( editor, normalizedStyleDefinitions ) );
|
|
49
48
|
|
|
50
49
|
this._configureGHSDataFilter( normalizedStyleDefinitions );
|
|
51
50
|
}
|
|
@@ -66,89 +65,6 @@ export default class StyleEditing extends Plugin {
|
|
|
66
65
|
}
|
|
67
66
|
}
|
|
68
67
|
|
|
69
|
-
/**
|
|
70
|
-
* The helper class storing various mappings based on
|
|
71
|
-
* {@link module:style/style~StyleConfig#definitions configured style definitions}. Used internally by
|
|
72
|
-
* {@link module:style/stylecommand~StyleCommand}.
|
|
73
|
-
*
|
|
74
|
-
* @private
|
|
75
|
-
*/
|
|
76
|
-
class Styles {
|
|
77
|
-
/**
|
|
78
|
-
* @param {Object} An object with normalized style definitions grouped into `block` and `inline` categories (arrays).
|
|
79
|
-
*/
|
|
80
|
-
constructor( styleDefinitions ) {
|
|
81
|
-
this.styleTypes = [ 'inline', 'block' ];
|
|
82
|
-
this.styleDefinitions = styleDefinitions;
|
|
83
|
-
this.elementToDefinition = new Map();
|
|
84
|
-
this.classToDefinition = new Map();
|
|
85
|
-
this.nameToDefinition = new Map();
|
|
86
|
-
|
|
87
|
-
this._prepareDefinitionsMapping();
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Populates various maps to simplify getting config definitions
|
|
92
|
-
* by model name,class name and style name.
|
|
93
|
-
*
|
|
94
|
-
* @private
|
|
95
|
-
*/
|
|
96
|
-
_prepareDefinitionsMapping() {
|
|
97
|
-
for ( const type of this.styleTypes ) {
|
|
98
|
-
for ( const { modelElements, name, element, classes, isBlock } of this.styleDefinitions[ type ] ) {
|
|
99
|
-
for ( const modelElement of modelElements ) {
|
|
100
|
-
const currentValue = this.elementToDefinition.get( modelElement ) || [];
|
|
101
|
-
const newValue = [ ...currentValue, { name, element, classes } ];
|
|
102
|
-
this.elementToDefinition.set( modelElement, newValue );
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
this.classToDefinition.set( classes.join( ' ' ), { name, element, classes } );
|
|
106
|
-
this.nameToDefinition.set( name, { name, element, classes, isBlock } );
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Returns all inline definitions elements names.
|
|
113
|
-
*
|
|
114
|
-
* @protected
|
|
115
|
-
* @return {Array.<String>} Inline elements names.
|
|
116
|
-
*/
|
|
117
|
-
getInlineElementsNames() {
|
|
118
|
-
return this.styleDefinitions.inline.map( ( { name } ) => name );
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Returns the style config definitions by the model element name.
|
|
123
|
-
*
|
|
124
|
-
* @protected
|
|
125
|
-
* @return {Object} Style config definition.
|
|
126
|
-
*/
|
|
127
|
-
getDefinitionsByElementName( elementName ) {
|
|
128
|
-
return this.elementToDefinition.get( elementName );
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Returns the style config definitions by the style name.
|
|
133
|
-
*
|
|
134
|
-
* @protected
|
|
135
|
-
* @return {Object} Style config definition.
|
|
136
|
-
*/
|
|
137
|
-
getDefinitionsByName( name ) {
|
|
138
|
-
return this.nameToDefinition.get( name );
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Returns the style config definitions by the style name.
|
|
143
|
-
*
|
|
144
|
-
* @protected
|
|
145
|
-
* @return {Object} Style config definition.
|
|
146
|
-
*/
|
|
147
|
-
getDefinitionsByClassName( className ) {
|
|
148
|
-
return this.classToDefinition.get( className );
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
68
|
// Translates a normalized style definition to a view matcher pattern.
|
|
153
69
|
//
|
|
154
70
|
// @param {Object} definition A normalized style definition.
|
package/src/styleui.js
CHANGED
|
@@ -39,7 +39,7 @@ export default class StyleUI extends Plugin {
|
|
|
39
39
|
const dataSchema = editor.plugins.get( 'DataSchema' );
|
|
40
40
|
const normalizedStyleDefinitions = normalizeConfig( dataSchema, editor.config.get( 'style.definitions' ) );
|
|
41
41
|
|
|
42
|
-
// Add the dropdown
|
|
42
|
+
// Add the dropdown to the component factory.
|
|
43
43
|
editor.ui.componentFactory.add( 'style', locale => {
|
|
44
44
|
const t = locale.t;
|
|
45
45
|
const dropdown = createDropdown( locale );
|
|
@@ -85,8 +85,11 @@ export default class StyleUI extends Plugin {
|
|
|
85
85
|
panelView.delegate( 'execute' ).to( dropdown );
|
|
86
86
|
|
|
87
87
|
// Execute the command when a style is selected in the styles panel.
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
// Also focus the editable after executing the command.
|
|
89
|
+
// It overrides a default behaviour where the focus is moved to the dropdown button (#12125).
|
|
90
|
+
dropdown.on( 'execute', evt => {
|
|
91
|
+
editor.execute( 'style', { styleName: evt.source.styleDefinition.name } );
|
|
92
|
+
editor.editing.view.focus();
|
|
90
93
|
} );
|
|
91
94
|
|
|
92
95
|
// Bind the state of the styles panel to the command.
|
|
@@ -109,7 +109,7 @@ export default class StyleGridButtonView extends ButtonView {
|
|
|
109
109
|
* be used instead. This avoids previewing a standalone `<td>`, `<li>`, etc. without a parent.
|
|
110
110
|
*
|
|
111
111
|
* @private
|
|
112
|
-
* @param {
|
|
112
|
+
* @param {String} elementName
|
|
113
113
|
* @returns {Boolean} `true` when the element can be rendered. `false` otherwise.
|
|
114
114
|
*/
|
|
115
115
|
_isPreviewable( elementName ) {
|
package/src/utils.js
CHANGED
|
@@ -36,14 +36,21 @@ export function normalizeConfig( dataSchema, styleDefinitions = [] ) {
|
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
for ( const definition of styleDefinitions ) {
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
const isBlock = matchingDefinitions.some( ( { isBlock } ) => isBlock );
|
|
39
|
+
const modelElements = [];
|
|
40
|
+
const ghsAttributes = [];
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
for ( const ghsDefinition of dataSchema.getDefinitionsForView( definition.element ) ) {
|
|
43
|
+
if ( ghsDefinition.isBlock ) {
|
|
44
|
+
modelElements.push( ghsDefinition.model );
|
|
45
|
+
} else {
|
|
46
|
+
ghsAttributes.push( ghsDefinition.model );
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if ( modelElements.length ) {
|
|
51
|
+
normalizedDefinitions.block.push( { ...definition, modelElements, isBlock: true } );
|
|
45
52
|
} else {
|
|
46
|
-
normalizedDefinitions.inline.push( {
|
|
53
|
+
normalizedDefinitions.inline.push( { ...definition, ghsAttributes } );
|
|
47
54
|
}
|
|
48
55
|
}
|
|
49
56
|
return normalizedDefinitions;
|