1 | /**
|
2 | * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
3 | * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
4 | */
|
5 | /**
|
6 | * @module list/listproperties/liststylecommand
|
7 | */
|
8 | import { Command } from 'ckeditor5/src/core';
|
9 | import { getListTypeFromListStyleType, getSelectedListItems } from '../list/utils';
|
10 | /**
|
11 | * The list style command. It changes the `listStyle` attribute of the selected list items.
|
12 | *
|
13 | * If the list type (numbered or bulleted) can be inferred from the passed style type,
|
14 | * the command tries to convert selected items to a list of that type.
|
15 | * It is used by the {@link module:list/listproperties~ListProperties list properties feature}.
|
16 | */
|
17 | export default class ListStyleCommand extends Command {
|
18 | /**
|
19 | * Creates an instance of the command.
|
20 | *
|
21 | * @param editor The editor instance.
|
22 | * @param defaultType The list type that will be used by default if the value was not specified during
|
23 | * the command execution.
|
24 | */
|
25 | constructor(editor, defaultType) {
|
26 | super(editor);
|
27 | this.defaultType = defaultType;
|
28 | }
|
29 | /**
|
30 | * @inheritDoc
|
31 | */
|
32 | refresh() {
|
33 | this.value = this._getValue();
|
34 | this.isEnabled = this._checkEnabled();
|
35 | }
|
36 | /**
|
37 | * Executes the command.
|
38 | *
|
39 | * @fires execute
|
40 | * @param options.type The type of the list style, e.g. `'disc'` or `'square'`. If `null` is specified, the default
|
41 | * style will be applied.
|
42 | */
|
43 | execute(options = {}) {
|
44 | this._tryToConvertItemsToList(options);
|
45 | const model = this.editor.model;
|
46 | const listItems = getSelectedListItems(model);
|
47 | if (!listItems.length) {
|
48 | return;
|
49 | }
|
50 | model.change(writer => {
|
51 | for (const item of listItems) {
|
52 | writer.setAttribute('listStyle', options.type || this.defaultType, item);
|
53 | }
|
54 | });
|
55 | }
|
56 | /**
|
57 | * Checks the command's {@link #value}.
|
58 | *
|
59 | * @returns The current value.
|
60 | */
|
61 | _getValue() {
|
62 | const listItem = this.editor.model.document.selection.getFirstPosition().parent;
|
63 | if (listItem && listItem.is('element', 'listItem')) {
|
64 | return listItem.getAttribute('listStyle');
|
65 | }
|
66 | return null;
|
67 | }
|
68 | /**
|
69 | * Checks whether the command can be enabled in the current context.
|
70 | *
|
71 | * @returns Whether the command should be enabled.
|
72 | */
|
73 | _checkEnabled() {
|
74 | const editor = this.editor;
|
75 | const numberedList = editor.commands.get('numberedList');
|
76 | const bulletedList = editor.commands.get('bulletedList');
|
77 | return numberedList.isEnabled || bulletedList.isEnabled;
|
78 | }
|
79 | /**
|
80 | * Checks if the provided list style is valid. Also changes the selection to a list if it's not set yet.
|
81 | *
|
82 | * @param The type of the list style. If `null` is specified, the function does nothing.
|
83 | */
|
84 | _tryToConvertItemsToList(options) {
|
85 | if (!options.type) {
|
86 | return;
|
87 | }
|
88 | const listType = getListTypeFromListStyleType(options.type);
|
89 | if (!listType) {
|
90 | return;
|
91 | }
|
92 | const editor = this.editor;
|
93 | const commandName = `${listType}List`;
|
94 | const command = editor.commands.get(commandName);
|
95 | if (!command.value) {
|
96 | editor.execute(commandName);
|
97 | }
|
98 | }
|
99 | }
|