/
documentliststylecommand.js
140 lines (118 loc) · 3.53 KB
/
documentliststylecommand.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/**
* @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
/**
* @module list/documentlistproperties/documentliststylecommand
*/
import { Command } from 'ckeditor5/src/core';
import { first } from 'ckeditor5/src/utils';
import {
expandListBlocksToCompleteList,
isListItemBlock
} from '../documentlist/utils/model';
import { getListTypeFromListStyleType } from './utils/style';
/**
* The list style command. It changes `listStyle` attribute of the selected list items,
* letting the user choose styles for the list item markers.
* It is used by the {@link module:list/documentlistproperties~DocumentListProperties list properties feature}.
*
* @extends module:core/command~Command
*/
export default class DocumentListStyleCommand extends Command {
/**
* Creates an instance of the command.
*
* @param {module:core/editor/editor~Editor} editor The editor instance.
* @param {String} defaultType The list type that will be used by default if the value was not specified during
* the command execution.
*/
constructor( editor, defaultType ) {
super( editor );
/**
* The default type of the list style.
*
* @protected
* @member {String}
*/
this._defaultType = defaultType;
}
/**
* @inheritDoc
*/
refresh() {
this.value = this._getValue();
this.isEnabled = this._checkEnabled();
}
/**
* Executes the command.
*
* @fires execute
* @param {Object} options
* @param {String|null} [options.type] The type of the list style, e.g. `'disc'` or `'square'`. If `null` is specified, the default
* style will be applied.
*/
execute( options = {} ) {
const model = this.editor.model;
const document = model.document;
model.change( writer => {
this._tryToConvertItemsToList( options );
let blocks = Array.from( document.selection.getSelectedBlocks() )
.filter( block => block.hasAttribute( 'listType' ) );
if ( !blocks.length ) {
return;
}
blocks = expandListBlocksToCompleteList( blocks );
for ( const block of blocks ) {
writer.setAttribute( 'listStyle', options.type || this._defaultType, block );
}
} );
}
/**
* Checks the command's {@link #value}.
*
* @private
* @returns {String|null} The current value.
*/
_getValue() {
const listItem = first( this.editor.model.document.selection.getSelectedBlocks() );
if ( isListItemBlock( listItem ) ) {
return listItem.getAttribute( 'listStyle' );
}
return null;
}
/**
* Checks whether the command can be enabled in the current context.
*
* @private
* @returns {Boolean} Whether the command should be enabled.
*/
_checkEnabled() {
const editor = this.editor;
const numberedList = editor.commands.get( 'numberedList' );
const bulletedList = editor.commands.get( 'bulletedList' );
return numberedList.isEnabled || bulletedList.isEnabled;
}
/**
* Check if the provided list style is valid. Also change the selection to a list if it's not set yet.
*
* @private
* @param {Object} options
* @param {String|null} [options.type] The type of the list style. If `null` is specified, the function does nothing.
*/
_tryToConvertItemsToList( options ) {
if ( !options.type ) {
return;
}
const listType = getListTypeFromListStyleType( options.type );
if ( !listType ) {
return;
}
const editor = this.editor;
const commandName = listType + 'List';
const command = editor.commands.get( commandName );
if ( !command.value ) {
editor.execute( commandName );
}
}
}