@ckeditor/ckeditor5-alignment 48.2.0 → 48.3.0-alpha.1

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/index.js CHANGED
@@ -2,585 +2,540 @@
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 '@ckeditor/ckeditor5-core/dist/index.js';
6
- import { logWarning, CKEditorError, first } from '@ckeditor/ckeditor5-utils/dist/index.js';
7
- import { ButtonView, createDropdown, addToolbarToDropdown, MenuBarMenuView, MenuBarMenuListView, MenuBarMenuListItemView, MenuBarMenuListItemButtonView } from '@ckeditor/ckeditor5-ui/dist/index.js';
8
- import { IconAlignLeft, IconAlignRight, IconAlignCenter, IconAlignJustify } from '@ckeditor/ckeditor5-icons/dist/index.js';
5
+ import { Command, Plugin } from "@ckeditor/ckeditor5-core";
6
+ import { CKEditorError, first, logWarning } from "@ckeditor/ckeditor5-utils";
7
+ import { ButtonView, MenuBarMenuListItemButtonView, MenuBarMenuListItemView, MenuBarMenuListView, MenuBarMenuView, addToolbarToDropdown, createDropdown } from "@ckeditor/ckeditor5-ui";
8
+ import { IconAlignCenter, IconAlignJustify, IconAlignLeft, IconAlignRight } from "@ckeditor/ckeditor5-icons";
9
9
 
10
10
  /**
11
- * The list of supported alignment options:
12
- *
13
- * * `'left'`,
14
- * * `'right'`,
15
- * * `'center'`,
16
- * * `'justify'`
17
- *
18
- * @internal
19
- */ const supportedOptions = [
20
- 'left',
21
- 'right',
22
- 'center',
23
- 'justify'
11
+ * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
12
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
13
+ */
14
+ /**
15
+ * @module alignment/utils
16
+ */
17
+ /**
18
+ * The list of supported alignment options:
19
+ *
20
+ * * `'left'`,
21
+ * * `'right'`,
22
+ * * `'center'`,
23
+ * * `'justify'`
24
+ *
25
+ * @internal
26
+ */
27
+ const supportedOptions = [
28
+ "left",
29
+ "right",
30
+ "center",
31
+ "justify"
24
32
  ];
25
33
  /**
26
- * Checks whether the passed option is supported by {@link module:alignment/alignmentediting~AlignmentEditing}.
27
- *
28
- * @internal
29
- * @param option The option value to check.
30
- */ function isSupported(option) {
31
- return supportedOptions.includes(option);
34
+ * Checks whether the passed option is supported by {@link module:alignment/alignmentediting~AlignmentEditing}.
35
+ *
36
+ * @internal
37
+ * @param option The option value to check.
38
+ */
39
+ function isSupported(option) {
40
+ return supportedOptions.includes(option);
32
41
  }
33
42
  /**
34
- * Checks whether alignment is the default one considering the direction
35
- * of the editor content.
36
- *
37
- * @internal
38
- * @param alignment The name of the alignment to check.
39
- * @param locale The {@link module:core/editor/editor~Editor#locale} instance.
40
- */ function isDefault(alignment, locale) {
41
- // Right now only LTR is supported so the 'left' value is always the default one.
42
- if (locale.contentLanguageDirection == 'rtl') {
43
- return alignment === 'right';
44
- } else {
45
- return alignment === 'left';
46
- }
43
+ * Checks whether alignment is the default one considering the direction
44
+ * of the editor content.
45
+ *
46
+ * @internal
47
+ * @param alignment The name of the alignment to check.
48
+ * @param locale The {@link module:core/editor/editor~Editor#locale} instance.
49
+ */
50
+ function isDefault(alignment, locale) {
51
+ if (locale.contentLanguageDirection == "rtl") return alignment === "right";
52
+ else return alignment === "left";
47
53
  }
48
54
  /**
49
- * Brings the configuration to the common form, an array of objects.
50
- *
51
- * @internal
52
- * @param configuredOptions Alignment plugin configuration.
53
- * @returns Normalized object holding the configuration.
54
- */ function normalizeAlignmentOptions(configuredOptions) {
55
- const normalizedOptions = configuredOptions.map((option)=>{
56
- let result;
57
- if (typeof option == 'string') {
58
- result = {
59
- name: option
60
- };
61
- } else {
62
- result = option;
63
- }
64
- return result;
65
- })// Remove all unknown options.
66
- .filter((option)=>{
67
- const isNameValid = supportedOptions.includes(option.name);
68
- if (!isNameValid) {
69
- /**
70
- * The `name` in one of the `alignment.options` is not recognized.
71
- * The available options are: `'left'`, `'right'`, `'center'` and `'justify'`.
72
- *
73
- * @error alignment-config-name-not-recognized
74
- * @param {object} option Options with unknown value of the `name` property.
75
- */ logWarning('alignment-config-name-not-recognized', {
76
- option
77
- });
78
- }
79
- return isNameValid;
80
- });
81
- const classNameCount = normalizedOptions.filter((option)=>Boolean(option.className)).length;
82
- // We either use classes for all styling options or for none.
83
- if (classNameCount && classNameCount < normalizedOptions.length) {
84
- /**
85
- * The `className` property has to be defined for all options once at least one option declares `className`.
86
- *
87
- * @error alignment-config-classnames-are-missing
88
- * @param {object} configuredOptions Contents of `alignment.options`.
89
- */ throw new CKEditorError('alignment-config-classnames-are-missing', {
90
- configuredOptions
91
- });
92
- }
93
- // Validate resulting config.
94
- normalizedOptions.forEach((option, index, allOptions)=>{
95
- const succeedingOptions = allOptions.slice(index + 1);
96
- const nameAlreadyExists = succeedingOptions.some((item)=>item.name == option.name);
97
- if (nameAlreadyExists) {
98
- /**
99
- * The same `name` in one of the `alignment.options` was already declared.
100
- * Each `name` representing one alignment option can be set exactly once.
101
- *
102
- * @error alignment-config-name-already-defined
103
- * @param {object} option First option that declares given `name`.
104
- * @param {object} configuredOptions Contents of `alignment.options`.
105
- */ throw new CKEditorError('alignment-config-name-already-defined', {
106
- option,
107
- configuredOptions
108
- });
109
- }
110
- // The `className` property is present. Check for duplicates then.
111
- if (option.className) {
112
- const classNameAlreadyExists = succeedingOptions.some((item)=>item.className == option.className);
113
- if (classNameAlreadyExists) {
114
- /**
115
- * The same `className` in one of the `alignment.options` was already declared.
116
- *
117
- * @error alignment-config-classname-already-defined
118
- * @param {object} option First option that declares given `className`.
119
- * @param {object} configuredOptions
120
- * Contents of `alignment.options`.
121
- */ throw new CKEditorError('alignment-config-classname-already-defined', {
122
- option,
123
- configuredOptions
124
- });
125
- }
126
- }
127
- });
128
- return normalizedOptions;
55
+ * Brings the configuration to the common form, an array of objects.
56
+ *
57
+ * @internal
58
+ * @param configuredOptions Alignment plugin configuration.
59
+ * @returns Normalized object holding the configuration.
60
+ */
61
+ function normalizeAlignmentOptions(configuredOptions) {
62
+ const normalizedOptions = configuredOptions.map((option) => {
63
+ let result;
64
+ if (typeof option == "string") result = { name: option };
65
+ else result = option;
66
+ return result;
67
+ }).filter((option) => {
68
+ const isNameValid = supportedOptions.includes(option.name);
69
+ if (!isNameValid)
70
+ /**
71
+ * The `name` in one of the `alignment.options` is not recognized.
72
+ * The available options are: `'left'`, `'right'`, `'center'` and `'justify'`.
73
+ *
74
+ * @error alignment-config-name-not-recognized
75
+ * @param {object} option Options with unknown value of the `name` property.
76
+ */
77
+ logWarning("alignment-config-name-not-recognized", { option });
78
+ return isNameValid;
79
+ });
80
+ const classNameCount = normalizedOptions.filter((option) => Boolean(option.className)).length;
81
+ if (classNameCount && classNameCount < normalizedOptions.length)
82
+ /**
83
+ * The `className` property has to be defined for all options once at least one option declares `className`.
84
+ *
85
+ * @error alignment-config-classnames-are-missing
86
+ * @param {object} configuredOptions Contents of `alignment.options`.
87
+ */
88
+ throw new CKEditorError("alignment-config-classnames-are-missing", { configuredOptions });
89
+ normalizedOptions.forEach((option, index, allOptions) => {
90
+ const succeedingOptions = allOptions.slice(index + 1);
91
+ if (succeedingOptions.some((item) => item.name == option.name))
92
+ /**
93
+ * The same `name` in one of the `alignment.options` was already declared.
94
+ * Each `name` representing one alignment option can be set exactly once.
95
+ *
96
+ * @error alignment-config-name-already-defined
97
+ * @param {object} option First option that declares given `name`.
98
+ * @param {object} configuredOptions Contents of `alignment.options`.
99
+ */
100
+ throw new CKEditorError("alignment-config-name-already-defined", {
101
+ option,
102
+ configuredOptions
103
+ });
104
+ if (option.className) {
105
+ if (succeedingOptions.some((item) => item.className == option.className))
106
+ /**
107
+ * The same `className` in one of the `alignment.options` was already declared.
108
+ *
109
+ * @error alignment-config-classname-already-defined
110
+ * @param {object} option First option that declares given `className`.
111
+ * @param {object} configuredOptions
112
+ * Contents of `alignment.options`.
113
+ */
114
+ throw new CKEditorError("alignment-config-classname-already-defined", {
115
+ option,
116
+ configuredOptions
117
+ });
118
+ }
119
+ });
120
+ return normalizedOptions;
129
121
  }
130
122
 
131
- const ALIGNMENT = 'alignment';
132
123
  /**
133
- * The alignment command plugin.
134
- */ class AlignmentCommand extends Command {
135
- /**
136
- * @inheritDoc
137
- */ refresh() {
138
- const editor = this.editor;
139
- const locale = editor.locale;
140
- const firstBlock = first(this.editor.model.document.selection.getSelectedBlocks());
141
- // As first check whether to enable or disable the command as the value will always be false if the command cannot be enabled.
142
- this.isEnabled = Boolean(firstBlock) && this._canBeAligned(firstBlock);
143
- if (this.isEnabled && firstBlock.hasAttribute('alignment')) {
144
- this.value = firstBlock.getAttribute('alignment');
145
- } else {
146
- this.value = locale.contentLanguageDirection === 'rtl' ? 'right' : 'left';
147
- }
148
- }
149
- /**
150
- * Executes the command. Applies the alignment `value` to the selected blocks.
151
- * If no `value` is passed, the `value` is the default one or it is equal to the currently selected block's alignment attribute,
152
- * the command will remove the attribute from the selected blocks.
153
- *
154
- * @param options Options for the executed command.
155
- * @param options.value The value to apply.
156
- * @fires execute
157
- */ execute(options = {}) {
158
- const editor = this.editor;
159
- const locale = editor.locale;
160
- const model = editor.model;
161
- const doc = model.document;
162
- const value = options.value;
163
- model.change((writer)=>{
164
- // Get only those blocks from selected that can have alignment set
165
- const blocks = Array.from(doc.selection.getSelectedBlocks()).filter((block)=>this._canBeAligned(block));
166
- const currentAlignment = blocks[0].getAttribute('alignment');
167
- // Remove alignment attribute if current alignment is:
168
- // - default (should not be stored in model as it will bloat model data)
169
- // - equal to currently set
170
- // - or no value is passed - denotes default alignment.
171
- const removeAlignment = isDefault(value, locale) || currentAlignment === value || !value;
172
- if (removeAlignment) {
173
- removeAlignmentFromSelection(blocks, writer);
174
- } else {
175
- setAlignmentOnSelection(blocks, writer, value);
176
- }
177
- });
178
- }
179
- /**
180
- * Checks whether a block can have alignment set.
181
- *
182
- * @param block The block to be checked.
183
- */ _canBeAligned(block) {
184
- return this.editor.model.schema.checkAttribute(block, ALIGNMENT);
185
- }
186
- }
124
+ * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
125
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
126
+ */
127
+ /**
128
+ * @module alignment/alignmentcommand
129
+ */
130
+ const ALIGNMENT = "alignment";
187
131
  /**
188
- * Removes the alignment attribute from blocks.
189
- */ function removeAlignmentFromSelection(blocks, writer) {
190
- for (const block of blocks){
191
- writer.removeAttribute(ALIGNMENT, block);
192
- }
132
+ * The alignment command plugin.
133
+ */
134
+ var AlignmentCommand = class extends Command {
135
+ /**
136
+ * @inheritDoc
137
+ */
138
+ refresh() {
139
+ const locale = this.editor.locale;
140
+ const firstBlock = first(this.editor.model.document.selection.getSelectedBlocks());
141
+ this.isEnabled = Boolean(firstBlock) && this._canBeAligned(firstBlock);
142
+ if (this.isEnabled && firstBlock.hasAttribute("alignment")) this.value = firstBlock.getAttribute("alignment");
143
+ else this.value = locale.contentLanguageDirection === "rtl" ? "right" : "left";
144
+ }
145
+ /**
146
+ * Executes the command. Applies the alignment `value` to the selected blocks.
147
+ * If no `value` is passed, the `value` is the default one or it is equal to the currently selected block's alignment attribute,
148
+ * the command will remove the attribute from the selected blocks.
149
+ *
150
+ * @param options Options for the executed command.
151
+ * @param options.value The value to apply.
152
+ * @fires execute
153
+ */
154
+ execute(options = {}) {
155
+ const editor = this.editor;
156
+ const locale = editor.locale;
157
+ const model = editor.model;
158
+ const doc = model.document;
159
+ const value = options.value;
160
+ model.change((writer) => {
161
+ const blocks = Array.from(doc.selection.getSelectedBlocks()).filter((block) => this._canBeAligned(block));
162
+ const currentAlignment = blocks[0].getAttribute("alignment");
163
+ if (isDefault(value, locale) || currentAlignment === value || !value) removeAlignmentFromSelection(blocks, writer);
164
+ else setAlignmentOnSelection(blocks, writer, value);
165
+ });
166
+ }
167
+ /**
168
+ * Checks whether a block can have alignment set.
169
+ *
170
+ * @param block The block to be checked.
171
+ */
172
+ _canBeAligned(block) {
173
+ return this.editor.model.schema.checkAttribute(block, ALIGNMENT);
174
+ }
175
+ };
176
+ /**
177
+ * Removes the alignment attribute from blocks.
178
+ */
179
+ function removeAlignmentFromSelection(blocks, writer) {
180
+ for (const block of blocks) writer.removeAttribute(ALIGNMENT, block);
193
181
  }
194
182
  /**
195
- * Sets the alignment attribute on blocks.
196
- */ function setAlignmentOnSelection(blocks, writer, alignment) {
197
- for (const block of blocks){
198
- writer.setAttribute(ALIGNMENT, alignment, block);
199
- }
183
+ * Sets the alignment attribute on blocks.
184
+ */
185
+ function setAlignmentOnSelection(blocks, writer, alignment) {
186
+ for (const block of blocks) writer.setAttribute(ALIGNMENT, alignment, block);
200
187
  }
201
188
 
202
189
  /**
203
- * The alignment editing feature. It introduces the {@link module:alignment/alignmentcommand~AlignmentCommand command} and adds
204
- * the `alignment` attribute for block elements in the {@link module:engine/model/model~Model model}.
205
- */ class AlignmentEditing extends Plugin {
206
- /**
207
- * @inheritDoc
208
- */ static get pluginName() {
209
- return 'AlignmentEditing';
210
- }
211
- /**
212
- * @inheritDoc
213
- */ static get isOfficialPlugin() {
214
- return true;
215
- }
216
- /**
217
- * @inheritDoc
218
- */ constructor(editor){
219
- super(editor);
220
- editor.config.define('alignment', {
221
- options: supportedOptions.map((option)=>({
222
- name: option
223
- }))
224
- });
225
- }
226
- /**
227
- * @inheritDoc
228
- */ init() {
229
- const editor = this.editor;
230
- const locale = editor.locale;
231
- const schema = editor.model.schema;
232
- const options = normalizeAlignmentOptions(editor.config.get('alignment.options'));
233
- // Filter out unsupported options and those that are redundant, e.g. `left` in LTR / `right` in RTL mode.
234
- const optionsToConvert = options.filter((option)=>isSupported(option.name) && !isDefault(option.name, locale));
235
- // Once there is at least one `className` defined, we switch to alignment with classes.
236
- const shouldUseClasses = optionsToConvert.some((option)=>!!option.className);
237
- // Allow alignment attribute on all blocks.
238
- schema.extend('$block', {
239
- allowAttributes: 'alignment'
240
- });
241
- editor.model.schema.setAttributeProperties('alignment', {
242
- isFormatting: true,
243
- blockAlignment: getBlockAlignmentAttributeProperty(locale)
244
- });
245
- if (shouldUseClasses) {
246
- editor.conversion.attributeToAttribute(buildClassDefinition(optionsToConvert));
247
- } else {
248
- // Downcast inline styles.
249
- editor.conversion.for('downcast').attributeToAttribute(buildDowncastInlineDefinition(optionsToConvert));
250
- }
251
- const upcastInlineDefinitions = buildUpcastInlineDefinitions(optionsToConvert);
252
- // Always upcast from inline styles.
253
- for (const definition of upcastInlineDefinitions){
254
- editor.conversion.for('upcast').attributeToAttribute(definition);
255
- }
256
- const upcastCompatibilityDefinitions = buildUpcastCompatibilityDefinitions(optionsToConvert);
257
- // Always upcast from deprecated `align` attribute.
258
- for (const definition of upcastCompatibilityDefinitions){
259
- editor.conversion.for('upcast').attributeToAttribute(definition);
260
- }
261
- editor.commands.add('alignment', new AlignmentCommand(editor));
262
- }
263
- }
190
+ * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
191
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
192
+ */
193
+ /**
194
+ * @module alignment/alignmentediting
195
+ */
196
+ /**
197
+ * The alignment editing feature. It introduces the {@link module:alignment/alignmentcommand~AlignmentCommand command} and adds
198
+ * the `alignment` attribute for block elements in the {@link module:engine/model/model~Model model}.
199
+ */
200
+ var AlignmentEditing = class extends Plugin {
201
+ /**
202
+ * @inheritDoc
203
+ */
204
+ static get pluginName() {
205
+ return "AlignmentEditing";
206
+ }
207
+ /**
208
+ * @inheritDoc
209
+ */
210
+ static get isOfficialPlugin() {
211
+ return true;
212
+ }
213
+ /**
214
+ * @inheritDoc
215
+ */
216
+ constructor(editor) {
217
+ super(editor);
218
+ editor.config.define("alignment", { options: supportedOptions.map((option) => ({ name: option })) });
219
+ }
220
+ /**
221
+ * @inheritDoc
222
+ */
223
+ init() {
224
+ const editor = this.editor;
225
+ const locale = editor.locale;
226
+ const schema = editor.model.schema;
227
+ const optionsToConvert = normalizeAlignmentOptions(editor.config.get("alignment.options")).filter((option) => isSupported(option.name) && !isDefault(option.name, locale));
228
+ const shouldUseClasses = optionsToConvert.some((option) => !!option.className);
229
+ schema.extend("$block", { allowAttributes: "alignment" });
230
+ editor.model.schema.setAttributeProperties("alignment", {
231
+ isFormatting: true,
232
+ blockAlignment: getBlockAlignmentAttributeProperty(locale)
233
+ });
234
+ if (shouldUseClasses) editor.conversion.attributeToAttribute(buildClassDefinition(optionsToConvert));
235
+ else editor.conversion.for("downcast").attributeToAttribute(buildDowncastInlineDefinition(optionsToConvert));
236
+ const upcastInlineDefinitions = buildUpcastInlineDefinitions(optionsToConvert);
237
+ for (const definition of upcastInlineDefinitions) editor.conversion.for("upcast").attributeToAttribute(definition);
238
+ const upcastCompatibilityDefinitions = buildUpcastCompatibilityDefinitions(optionsToConvert);
239
+ for (const definition of upcastCompatibilityDefinitions) editor.conversion.for("upcast").attributeToAttribute(definition);
240
+ editor.commands.add("alignment", new AlignmentCommand(editor));
241
+ }
242
+ };
264
243
  /**
265
- * Prepare block alignment mapping for all possible alignment options.
266
- */ function getBlockAlignmentAttributeProperty(locale) {
267
- const blockAlignment = {
268
- left: {
269
- value: 'left'
270
- },
271
- right: {
272
- value: 'right'
273
- },
274
- center: {
275
- value: 'center'
276
- },
277
- justify: {
278
- value: 'justify'
279
- }
280
- };
281
- const defaultDirection = locale.contentLanguageDirection == 'rtl' ? 'right' : 'left';
282
- blockAlignment[defaultDirection].isDefault = true;
283
- return blockAlignment;
244
+ * Prepare block alignment mapping for all possible alignment options.
245
+ */
246
+ function getBlockAlignmentAttributeProperty(locale) {
247
+ const blockAlignment = {
248
+ left: { value: "left" },
249
+ right: { value: "right" },
250
+ center: { value: "center" },
251
+ justify: { value: "justify" }
252
+ };
253
+ const defaultDirection = locale.contentLanguageDirection == "rtl" ? "right" : "left";
254
+ blockAlignment[defaultDirection].isDefault = true;
255
+ return blockAlignment;
284
256
  }
285
257
  /**
286
- * Prepare downcast conversion definition for inline alignment styling.
287
- */ function buildDowncastInlineDefinition(options) {
288
- const view = {};
289
- for (const { name } of options){
290
- view[name] = {
291
- key: 'style',
292
- value: {
293
- 'text-align': name
294
- }
295
- };
296
- }
297
- const definition = {
298
- model: {
299
- key: 'alignment',
300
- values: options.map((option)=>option.name)
301
- },
302
- view
303
- };
304
- return definition;
258
+ * Prepare downcast conversion definition for inline alignment styling.
259
+ */
260
+ function buildDowncastInlineDefinition(options) {
261
+ const view = {};
262
+ for (const { name } of options) view[name] = {
263
+ key: "style",
264
+ value: { "text-align": name }
265
+ };
266
+ return {
267
+ model: {
268
+ key: "alignment",
269
+ values: options.map((option) => option.name)
270
+ },
271
+ view
272
+ };
305
273
  }
306
274
  /**
307
- * Prepare upcast definitions for inline alignment styles.
308
- */ function buildUpcastInlineDefinitions(options) {
309
- const definitions = [];
310
- for (const { name } of options){
311
- definitions.push({
312
- view: {
313
- key: 'style',
314
- value: {
315
- 'text-align': name
316
- }
317
- },
318
- model: {
319
- key: 'alignment',
320
- value: name
321
- }
322
- });
323
- }
324
- return definitions;
275
+ * Prepare upcast definitions for inline alignment styles.
276
+ */
277
+ function buildUpcastInlineDefinitions(options) {
278
+ const definitions = [];
279
+ for (const { name } of options) definitions.push({
280
+ view: {
281
+ key: "style",
282
+ value: { "text-align": name }
283
+ },
284
+ model: {
285
+ key: "alignment",
286
+ value: name
287
+ }
288
+ });
289
+ return definitions;
325
290
  }
326
291
  /**
327
- * Prepare upcast definitions for deprecated `align` attribute.
328
- */ function buildUpcastCompatibilityDefinitions(options) {
329
- const definitions = [];
330
- for (const { name } of options){
331
- definitions.push({
332
- view: {
333
- key: 'align',
334
- value: name
335
- },
336
- model: {
337
- key: 'alignment',
338
- value: name
339
- }
340
- });
341
- }
342
- return definitions;
292
+ * Prepare upcast definitions for deprecated `align` attribute.
293
+ */
294
+ function buildUpcastCompatibilityDefinitions(options) {
295
+ const definitions = [];
296
+ for (const { name } of options) definitions.push({
297
+ view: {
298
+ key: "align",
299
+ value: name
300
+ },
301
+ model: {
302
+ key: "alignment",
303
+ value: name
304
+ }
305
+ });
306
+ return definitions;
343
307
  }
344
308
  /**
345
- * Prepare conversion definitions for upcast and downcast alignment with classes.
346
- */ function buildClassDefinition(options) {
347
- const view = {};
348
- for (const option of options){
349
- view[option.name] = {
350
- key: 'class',
351
- value: option.className
352
- };
353
- }
354
- const definition = {
355
- model: {
356
- key: 'alignment',
357
- values: options.map((option)=>option.name)
358
- },
359
- view
360
- };
361
- return definition;
309
+ * Prepare conversion definitions for upcast and downcast alignment with classes.
310
+ */
311
+ function buildClassDefinition(options) {
312
+ const view = {};
313
+ for (const option of options) view[option.name] = {
314
+ key: "class",
315
+ value: option.className
316
+ };
317
+ return {
318
+ model: {
319
+ key: "alignment",
320
+ values: options.map((option) => option.name)
321
+ },
322
+ view
323
+ };
362
324
  }
363
325
 
364
- const iconsMap = /* #__PURE__ */ (()=>new Map([
365
- [
366
- 'left',
367
- IconAlignLeft
368
- ],
369
- [
370
- 'right',
371
- IconAlignRight
372
- ],
373
- [
374
- 'center',
375
- IconAlignCenter
376
- ],
377
- [
378
- 'justify',
379
- IconAlignJustify
380
- ]
381
- ]))();
382
326
  /**
383
- * The default alignment UI plugin.
384
- *
385
- * It introduces the `'alignment:left'`, `'alignment:right'`, `'alignment:center'` and `'alignment:justify'` buttons
386
- * and the `'alignment'` dropdown.
387
- */ class AlignmentUI extends Plugin {
388
- /**
389
- * Returns the localized option titles provided by the plugin.
390
- *
391
- * The following localized titles corresponding with
392
- * {@link module:alignment/alignmentconfig~AlignmentConfig#options} are available:
393
- *
394
- * * `'left'`,
395
- * * `'right'`,
396
- * * `'center'`,
397
- * * `'justify'`.
398
- *
399
- * @readonly
400
- */ get localizedOptionTitles() {
401
- const t = this.editor.t;
402
- return {
403
- 'left': t('Align left'),
404
- 'right': t('Align right'),
405
- 'center': t('Align center'),
406
- 'justify': t('Justify')
407
- };
408
- }
409
- /**
410
- * @inheritDoc
411
- */ static get pluginName() {
412
- return 'AlignmentUI';
413
- }
414
- /**
415
- * @inheritDoc
416
- */ static get isOfficialPlugin() {
417
- return true;
418
- }
419
- /**
420
- * @inheritDoc
421
- */ init() {
422
- const editor = this.editor;
423
- const options = normalizeAlignmentOptions(editor.config.get('alignment.options'));
424
- options.map((option)=>option.name).filter(isSupported).forEach((option)=>this._addButton(option));
425
- this._addToolbarDropdown(options);
426
- this._addMenuBarMenu(options);
427
- }
428
- /**
429
- * Helper method for initializing the button and linking it with an appropriate command.
430
- *
431
- * @param option The name of the alignment option for which the button is added.
432
- */ _addButton(option) {
433
- const editor = this.editor;
434
- editor.ui.componentFactory.add(`alignment:${option}`, (locale)=>this._createButton(locale, option));
435
- }
436
- /**
437
- * Helper method for creating the button view element.
438
- *
439
- * @param locale Editor locale.
440
- * @param option The name of the alignment option for which the button is added.
441
- * @param buttonAttrs Optional parameters passed to button view instance.
442
- */ _createButton(locale, option, buttonAttrs = {}) {
443
- const editor = this.editor;
444
- const command = editor.commands.get('alignment');
445
- const buttonView = new ButtonView(locale);
446
- buttonView.set({
447
- label: this.localizedOptionTitles[option],
448
- icon: iconsMap.get(option),
449
- tooltip: true,
450
- isToggleable: true,
451
- ...buttonAttrs
452
- });
453
- // Bind button model to command.
454
- buttonView.bind('isEnabled').to(command);
455
- buttonView.bind('isOn').to(command, 'value', (value)=>value === option);
456
- // Execute command.
457
- this.listenTo(buttonView, 'execute', ()=>{
458
- editor.execute('alignment', {
459
- value: option
460
- });
461
- editor.editing.view.focus();
462
- });
463
- return buttonView;
464
- }
465
- /**
466
- * Helper method for initializing the toolnar dropdown and linking it with an appropriate command.
467
- *
468
- * @param options The name of the alignment option for which the button is added.
469
- */ _addToolbarDropdown(options) {
470
- const editor = this.editor;
471
- const factory = editor.ui.componentFactory;
472
- factory.add('alignment', (locale)=>{
473
- const dropdownView = createDropdown(locale);
474
- const tooltipPosition = locale.uiLanguageDirection === 'rtl' ? 'w' : 'e';
475
- const t = locale.t;
476
- // Add existing alignment buttons to dropdown's toolbar.
477
- addToolbarToDropdown(dropdownView, ()=>options.map((option)=>this._createButton(locale, option.name, {
478
- tooltipPosition
479
- })), {
480
- enableActiveItemFocusOnDropdownOpen: true,
481
- isVertical: true,
482
- ariaLabel: t('Text alignment toolbar')
483
- });
484
- // Configure dropdown properties an behavior.
485
- dropdownView.buttonView.set({
486
- label: t('Text alignment'),
487
- tooltip: true
488
- });
489
- dropdownView.extendTemplate({
490
- attributes: {
491
- class: 'ck-alignment-dropdown'
492
- }
493
- });
494
- // The default icon depends on the direction of the content.
495
- const defaultIcon = locale.contentLanguageDirection === 'rtl' ? iconsMap.get('right') : iconsMap.get('left');
496
- const command = editor.commands.get('alignment');
497
- // Change icon to reflect current selection's alignment.
498
- dropdownView.buttonView.bind('icon').to(command, 'value', (value)=>iconsMap.get(value) || defaultIcon);
499
- // Enable button if any of the buttons is enabled.
500
- dropdownView.bind('isEnabled').to(command, 'isEnabled');
501
- // Focus the editable after executing the command.
502
- // Overrides a default behaviour where the focus is moved to the dropdown button.
503
- // See https://github.com/ckeditor/ckeditor5/issues/12125.
504
- this.listenTo(dropdownView, 'execute', ()=>{
505
- editor.editing.view.focus();
506
- });
507
- return dropdownView;
508
- });
509
- }
510
- /**
511
- * Creates a menu for all alignment options to use either in menu bar.
512
- *
513
- * @param options Normalized alignment options from config.
514
- */ _addMenuBarMenu(options) {
515
- const editor = this.editor;
516
- editor.ui.componentFactory.add('menuBar:alignment', (locale)=>{
517
- const command = editor.commands.get('alignment');
518
- const t = locale.t;
519
- const menuView = new MenuBarMenuView(locale);
520
- const listView = new MenuBarMenuListView(locale);
521
- menuView.bind('isEnabled').to(command);
522
- listView.set({
523
- ariaLabel: t('Text alignment'),
524
- role: 'menu'
525
- });
526
- menuView.buttonView.set({
527
- label: t('Text alignment')
528
- });
529
- for (const option of options){
530
- const listItemView = new MenuBarMenuListItemView(locale, menuView);
531
- const buttonView = new MenuBarMenuListItemButtonView(locale);
532
- buttonView.delegate('execute').to(menuView);
533
- buttonView.set({
534
- label: this.localizedOptionTitles[option.name],
535
- icon: iconsMap.get(option.name),
536
- role: 'menuitemcheckbox',
537
- isToggleable: true
538
- });
539
- buttonView.on('execute', ()=>{
540
- editor.execute('alignment', {
541
- value: option.name
542
- });
543
- editor.editing.view.focus();
544
- });
545
- buttonView.bind('isOn').to(command, 'value', (value)=>value === option.name);
546
- buttonView.bind('isEnabled').to(command, 'isEnabled');
547
- listItemView.children.add(buttonView);
548
- listView.items.add(listItemView);
549
- }
550
- menuView.panelView.children.add(listView);
551
- return menuView;
552
- });
553
- }
554
- }
327
+ * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
328
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
329
+ */
330
+ /**
331
+ * @module alignment/alignmentui
332
+ */
333
+ const iconsMap = /* #__PURE__ */ (() => new Map([
334
+ ["left", IconAlignLeft],
335
+ ["right", IconAlignRight],
336
+ ["center", IconAlignCenter],
337
+ ["justify", IconAlignJustify]
338
+ ]))();
339
+ /**
340
+ * The default alignment UI plugin.
341
+ *
342
+ * It introduces the `'alignment:left'`, `'alignment:right'`, `'alignment:center'` and `'alignment:justify'` buttons
343
+ * and the `'alignment'` dropdown.
344
+ */
345
+ var AlignmentUI = class extends Plugin {
346
+ /**
347
+ * Returns the localized option titles provided by the plugin.
348
+ *
349
+ * The following localized titles corresponding with
350
+ * {@link module:alignment/alignmentconfig~AlignmentConfig#options} are available:
351
+ *
352
+ * * `'left'`,
353
+ * * `'right'`,
354
+ * * `'center'`,
355
+ * * `'justify'`.
356
+ *
357
+ * @readonly
358
+ */
359
+ get localizedOptionTitles() {
360
+ const t = this.editor.t;
361
+ return {
362
+ "left": t("Align left"),
363
+ "right": t("Align right"),
364
+ "center": t("Align center"),
365
+ "justify": t("Justify")
366
+ };
367
+ }
368
+ /**
369
+ * @inheritDoc
370
+ */
371
+ static get pluginName() {
372
+ return "AlignmentUI";
373
+ }
374
+ /**
375
+ * @inheritDoc
376
+ */
377
+ static get isOfficialPlugin() {
378
+ return true;
379
+ }
380
+ /**
381
+ * @inheritDoc
382
+ */
383
+ init() {
384
+ const editor = this.editor;
385
+ const options = normalizeAlignmentOptions(editor.config.get("alignment.options"));
386
+ options.map((option) => option.name).filter(isSupported).forEach((option) => this._addButton(option));
387
+ this._addToolbarDropdown(options);
388
+ this._addMenuBarMenu(options);
389
+ }
390
+ /**
391
+ * Helper method for initializing the button and linking it with an appropriate command.
392
+ *
393
+ * @param option The name of the alignment option for which the button is added.
394
+ */
395
+ _addButton(option) {
396
+ this.editor.ui.componentFactory.add(`alignment:${option}`, (locale) => this._createButton(locale, option));
397
+ }
398
+ /**
399
+ * Helper method for creating the button view element.
400
+ *
401
+ * @param locale Editor locale.
402
+ * @param option The name of the alignment option for which the button is added.
403
+ * @param buttonAttrs Optional parameters passed to button view instance.
404
+ */
405
+ _createButton(locale, option, buttonAttrs = {}) {
406
+ const editor = this.editor;
407
+ const command = editor.commands.get("alignment");
408
+ const buttonView = new ButtonView(locale);
409
+ buttonView.set({
410
+ label: this.localizedOptionTitles[option],
411
+ icon: iconsMap.get(option),
412
+ tooltip: true,
413
+ isToggleable: true,
414
+ ...buttonAttrs
415
+ });
416
+ buttonView.bind("isEnabled").to(command);
417
+ buttonView.bind("isOn").to(command, "value", (value) => value === option);
418
+ this.listenTo(buttonView, "execute", () => {
419
+ editor.execute("alignment", { value: option });
420
+ editor.editing.view.focus();
421
+ });
422
+ return buttonView;
423
+ }
424
+ /**
425
+ * Helper method for initializing the toolnar dropdown and linking it with an appropriate command.
426
+ *
427
+ * @param options The name of the alignment option for which the button is added.
428
+ */
429
+ _addToolbarDropdown(options) {
430
+ const editor = this.editor;
431
+ editor.ui.componentFactory.add("alignment", (locale) => {
432
+ const dropdownView = createDropdown(locale);
433
+ const tooltipPosition = locale.uiLanguageDirection === "rtl" ? "w" : "e";
434
+ const t = locale.t;
435
+ addToolbarToDropdown(dropdownView, () => options.map((option) => this._createButton(locale, option.name, { tooltipPosition })), {
436
+ enableActiveItemFocusOnDropdownOpen: true,
437
+ isVertical: true,
438
+ ariaLabel: t("Text alignment toolbar")
439
+ });
440
+ dropdownView.buttonView.set({
441
+ label: t("Text alignment"),
442
+ tooltip: true
443
+ });
444
+ dropdownView.extendTemplate({ attributes: { class: "ck-alignment-dropdown" } });
445
+ const defaultIcon = locale.contentLanguageDirection === "rtl" ? iconsMap.get("right") : iconsMap.get("left");
446
+ const command = editor.commands.get("alignment");
447
+ dropdownView.buttonView.bind("icon").to(command, "value", (value) => iconsMap.get(value) || defaultIcon);
448
+ dropdownView.bind("isEnabled").to(command, "isEnabled");
449
+ this.listenTo(dropdownView, "execute", () => {
450
+ editor.editing.view.focus();
451
+ });
452
+ return dropdownView;
453
+ });
454
+ }
455
+ /**
456
+ * Creates a menu for all alignment options to use either in menu bar.
457
+ *
458
+ * @param options Normalized alignment options from config.
459
+ */
460
+ _addMenuBarMenu(options) {
461
+ const editor = this.editor;
462
+ editor.ui.componentFactory.add("menuBar:alignment", (locale) => {
463
+ const command = editor.commands.get("alignment");
464
+ const t = locale.t;
465
+ const menuView = new MenuBarMenuView(locale);
466
+ const listView = new MenuBarMenuListView(locale);
467
+ menuView.bind("isEnabled").to(command);
468
+ listView.set({
469
+ ariaLabel: t("Text alignment"),
470
+ role: "menu"
471
+ });
472
+ menuView.buttonView.set({ label: t("Text alignment") });
473
+ for (const option of options) {
474
+ const listItemView = new MenuBarMenuListItemView(locale, menuView);
475
+ const buttonView = new MenuBarMenuListItemButtonView(locale);
476
+ buttonView.delegate("execute").to(menuView);
477
+ buttonView.set({
478
+ label: this.localizedOptionTitles[option.name],
479
+ icon: iconsMap.get(option.name),
480
+ role: "menuitemcheckbox",
481
+ isToggleable: true
482
+ });
483
+ buttonView.on("execute", () => {
484
+ editor.execute("alignment", { value: option.name });
485
+ editor.editing.view.focus();
486
+ });
487
+ buttonView.bind("isOn").to(command, "value", (value) => value === option.name);
488
+ buttonView.bind("isEnabled").to(command, "isEnabled");
489
+ listItemView.children.add(buttonView);
490
+ listView.items.add(listItemView);
491
+ }
492
+ menuView.panelView.children.add(listView);
493
+ return menuView;
494
+ });
495
+ }
496
+ };
555
497
 
556
498
  /**
557
- * The text alignment plugin.
558
- *
559
- * For a detailed overview, check the {@glink features/text-alignment Text alignment} feature guide
560
- * and the {@glink api/alignment package page}.
561
- *
562
- * This is a "glue" plugin which loads the {@link module:alignment/alignmentediting~AlignmentEditing} and
563
- * {@link module:alignment/alignmentui~AlignmentUI} plugins.
564
- */ class Alignment extends Plugin {
565
- /**
566
- * @inheritDoc
567
- */ static get requires() {
568
- return [
569
- AlignmentEditing,
570
- AlignmentUI
571
- ];
572
- }
573
- /**
574
- * @inheritDoc
575
- */ static get pluginName() {
576
- return 'Alignment';
577
- }
578
- /**
579
- * @inheritDoc
580
- */ static get isOfficialPlugin() {
581
- return true;
582
- }
583
- }
499
+ * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
500
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
501
+ */
502
+ /**
503
+ * @module alignment/alignment
504
+ */
505
+ /**
506
+ * The text alignment plugin.
507
+ *
508
+ * For a detailed overview, check the {@glink features/text-alignment Text alignment} feature guide
509
+ * and the {@glink api/alignment package page}.
510
+ *
511
+ * This is a "glue" plugin which loads the {@link module:alignment/alignmentediting~AlignmentEditing} and
512
+ * {@link module:alignment/alignmentui~AlignmentUI} plugins.
513
+ */
514
+ var Alignment = class extends Plugin {
515
+ /**
516
+ * @inheritDoc
517
+ */
518
+ static get requires() {
519
+ return [AlignmentEditing, AlignmentUI];
520
+ }
521
+ /**
522
+ * @inheritDoc
523
+ */
524
+ static get pluginName() {
525
+ return "Alignment";
526
+ }
527
+ /**
528
+ * @inheritDoc
529
+ */
530
+ static get isOfficialPlugin() {
531
+ return true;
532
+ }
533
+ };
534
+
535
+ /**
536
+ * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
537
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
538
+ */
584
539
 
585
540
  export { Alignment, AlignmentCommand, AlignmentEditing, AlignmentUI, supportedOptions as _ALIGNMENT_SUPPORTED_OPTIONS, isSupported as _isAlignmentSupported, isDefault as _isDefaultAlignment, normalizeAlignmentOptions as _normalizeAlignmentOptions };
586
- //# sourceMappingURL=index.js.map
541
+ //# sourceMappingURL=index.js.map