@ckeditor/ckeditor5-list 35.4.0 → 36.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.
Files changed (54) hide show
  1. package/LICENSE.md +1 -1
  2. package/build/list.js +2 -2
  3. package/package.json +43 -39
  4. package/src/documentlist/converters.js +303 -419
  5. package/src/documentlist/documentlistcommand.js +136 -207
  6. package/src/documentlist/documentlistediting.js +538 -698
  7. package/src/documentlist/documentlistindentcommand.js +115 -168
  8. package/src/documentlist/documentlistmergecommand.js +161 -222
  9. package/src/documentlist/documentlistsplitcommand.js +59 -103
  10. package/src/documentlist/documentlistutils.js +31 -45
  11. package/src/documentlist/utils/listwalker.js +138 -236
  12. package/src/documentlist/utils/model.js +322 -421
  13. package/src/documentlist/utils/postfixers.js +98 -126
  14. package/src/documentlist/utils/view.js +74 -105
  15. package/src/documentlist.js +13 -19
  16. package/src/documentlistproperties/converters.js +33 -47
  17. package/src/documentlistproperties/documentlistpropertiesediting.js +265 -356
  18. package/src/documentlistproperties/documentlistpropertiesutils.js +32 -57
  19. package/src/documentlistproperties/documentlistreversedcommand.js +40 -61
  20. package/src/documentlistproperties/documentliststartcommand.js +42 -61
  21. package/src/documentlistproperties/documentliststylecommand.js +97 -147
  22. package/src/documentlistproperties/utils/style.js +27 -47
  23. package/src/documentlistproperties.js +13 -19
  24. package/src/index.js +1 -3
  25. package/src/list/converters.js +772 -929
  26. package/src/list/indentcommand.js +105 -140
  27. package/src/list/listcommand.js +262 -315
  28. package/src/list/listediting.js +141 -200
  29. package/src/list/listui.js +16 -25
  30. package/src/list/listutils.js +37 -59
  31. package/src/list/utils.js +295 -378
  32. package/src/list.js +13 -44
  33. package/src/listcommands.js +5 -0
  34. package/src/listconfig.js +5 -0
  35. package/src/listproperties/listpropertiesediting.js +656 -803
  36. package/src/listproperties/listpropertiesui.js +244 -296
  37. package/src/listproperties/listreversedcommand.js +37 -49
  38. package/src/listproperties/liststartcommand.js +37 -49
  39. package/src/listproperties/liststylecommand.js +82 -115
  40. package/src/listproperties/ui/collapsibleview.js +75 -138
  41. package/src/listproperties/ui/listpropertiesview.js +289 -415
  42. package/src/listproperties.js +13 -118
  43. package/src/liststyle.js +18 -24
  44. package/src/todolist/checktodolistcommand.js +60 -102
  45. package/src/todolist/todolistconverters.js +189 -271
  46. package/src/todolist/todolistediting.js +141 -206
  47. package/src/todolist/todolistui.js +14 -21
  48. package/src/todolist.js +13 -19
  49. package/theme/collapsible.css +1 -1
  50. package/theme/documentlist.css +1 -1
  51. package/theme/list.css +40 -0
  52. package/theme/listproperties.css +1 -1
  53. package/theme/liststyles.css +1 -37
  54. package/theme/todolist.css +1 -1
@@ -1,216 +1,145 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
-
6
- /**
7
- * @module list/documentlist/documentlistcommand
8
- */
9
-
10
5
  import { Command } from 'ckeditor5/src/core';
11
- import {
12
- splitListItemBefore,
13
- expandListBlocksToCompleteItems,
14
- getListItemBlocks,
15
- getListItems,
16
- removeListAttributes,
17
- outdentFollowingItems,
18
- ListItemUid,
19
- sortBlocks,
20
- getSelectedBlockObject,
21
- isListItemBlock
22
- } from './utils/model';
23
-
6
+ import { splitListItemBefore, expandListBlocksToCompleteItems, getListItemBlocks, getListItems, removeListAttributes, outdentFollowingItems, ListItemUid, sortBlocks, getSelectedBlockObject, isListItemBlock } from './utils/model';
24
7
  /**
25
8
  * The list command. It is used by the {@link module:list/documentlist~DocumentList document list feature}.
26
- *
27
- * @extends module:core/command~Command
28
9
  */
29
10
  export default class DocumentListCommand extends Command {
30
- /**
31
- * Creates an instance of the command.
32
- *
33
- * @param {module:core/editor/editor~Editor} editor The editor instance.
34
- * @param {'numbered'|'bulleted'} type List type that will be handled by this command.
35
- */
36
- constructor( editor, type ) {
37
- super( editor );
38
-
39
- /**
40
- * The type of the list created by the command.
41
- *
42
- * @readonly
43
- * @member {'numbered'|'bulleted'}
44
- */
45
- this.type = type;
46
-
47
- /**
48
- * A flag indicating whether the command is active, which means that the selection starts in a list of the same type.
49
- *
50
- * @observable
51
- * @readonly
52
- * @member {Boolean} #value
53
- */
54
- }
55
-
56
- /**
57
- * @inheritDoc
58
- */
59
- refresh() {
60
- this.value = this._getValue();
61
- this.isEnabled = this._checkEnabled();
62
- }
63
-
64
- /**
65
- * Executes the list command.
66
- *
67
- * @fires execute
68
- * @fires afterExecute
69
- * @param {Object} [options] Command options.
70
- * @param {Boolean} [options.forceValue] If set, it will force the command behavior. If `true`, the command will try to convert the
71
- * selected items and potentially the neighbor elements to the proper list items. If set to `false` it will convert selected elements
72
- * to paragraphs. If not set, the command will toggle selected elements to list items or paragraphs, depending on the selection.
73
- */
74
- execute( options = {} ) {
75
- const model = this.editor.model;
76
- const document = model.document;
77
- const selectedBlockObject = getSelectedBlockObject( model );
78
-
79
- const blocks = Array.from( document.selection.getSelectedBlocks() )
80
- .filter( block => model.schema.checkAttribute( block, 'listType' ) );
81
-
82
- // Whether we are turning off some items.
83
- const turnOff = options.forceValue !== undefined ? !options.forceValue : this.value;
84
-
85
- model.change( writer => {
86
- if ( turnOff ) {
87
- const lastBlock = blocks[ blocks.length - 1 ];
88
-
89
- // Split the first block from the list item.
90
- const itemBlocks = getListItemBlocks( lastBlock, { direction: 'forward' } );
91
- const changedBlocks = [];
92
-
93
- if ( itemBlocks.length > 1 ) {
94
- changedBlocks.push( ...splitListItemBefore( itemBlocks[ 1 ], writer ) );
95
- }
96
-
97
- // Convert list blocks to plain blocks.
98
- changedBlocks.push( ...removeListAttributes( blocks, writer ) );
99
-
100
- // Outdent items following the selected list item.
101
- changedBlocks.push( ...outdentFollowingItems( lastBlock, writer ) );
102
-
103
- this._fireAfterExecute( changedBlocks );
104
- }
105
- // Turning on the list items for a collapsed selection inside a list item.
106
- else if ( ( selectedBlockObject || document.selection.isCollapsed ) && isListItemBlock( blocks[ 0 ] ) ) {
107
- const changedBlocks = getListItems( selectedBlockObject || blocks[ 0 ] );
108
-
109
- for ( const block of changedBlocks ) {
110
- writer.setAttribute( 'listType', this.type, block );
111
- }
112
-
113
- this._fireAfterExecute( changedBlocks );
114
- }
115
- // Turning on the list items for a non-collapsed selection.
116
- else {
117
- const changedBlocks = [];
118
-
119
- for ( const block of blocks ) {
120
- // Promote the given block to the list item.
121
- if ( !block.hasAttribute( 'listType' ) ) {
122
- writer.setAttributes( {
123
- listIndent: 0,
124
- listItemId: ListItemUid.next(),
125
- listType: this.type
126
- }, block );
127
-
128
- changedBlocks.push( block );
129
- }
130
- // Change the type of list item.
131
- else {
132
- for ( const node of expandListBlocksToCompleteItems( block, { withNested: false } ) ) {
133
- if ( node.getAttribute( 'listType' ) != this.type ) {
134
- writer.setAttribute( 'listType', this.type, node );
135
- changedBlocks.push( node );
136
- }
137
- }
138
- }
139
- }
140
-
141
- this._fireAfterExecute( changedBlocks );
142
- }
143
- } );
144
- }
145
-
146
- /**
147
- * Fires the `afterExecute` event.
148
- *
149
- * @private
150
- * @param {Array.<module:engine/model/element~Element>} changedBlocks The changed list elements.
151
- */
152
- _fireAfterExecute( changedBlocks ) {
153
- /**
154
- * Event fired by the {@link #execute} method.
155
- *
156
- * It allows to execute an action after executing the {@link ~DocumentListCommand#execute} method,
157
- * for example adjusting attributes of changed list items.
158
- *
159
- * @protected
160
- * @event afterExecute
161
- */
162
- this.fire( 'afterExecute', sortBlocks( new Set( changedBlocks ) ) );
163
- }
164
-
165
- /**
166
- * Checks the command's {@link #value}.
167
- *
168
- * @private
169
- * @returns {Boolean} The current value.
170
- */
171
- _getValue() {
172
- const selection = this.editor.model.document.selection;
173
- const blocks = Array.from( selection.getSelectedBlocks() );
174
-
175
- if ( !blocks.length ) {
176
- return false;
177
- }
178
-
179
- for ( const block of blocks ) {
180
- if ( block.getAttribute( 'listType' ) != this.type ) {
181
- return false;
182
- }
183
- }
184
-
185
- return true;
186
- }
187
-
188
- /**
189
- * Checks whether the command can be enabled in the current context.
190
- *
191
- * @private
192
- * @returns {Boolean} Whether the command should be enabled.
193
- */
194
- _checkEnabled() {
195
- const selection = this.editor.model.document.selection;
196
- const schema = this.editor.model.schema;
197
- const blocks = Array.from( selection.getSelectedBlocks() );
198
-
199
- if ( !blocks.length ) {
200
- return false;
201
- }
202
-
203
- // If command value is true it means that we are in list item, so the command should be enabled.
204
- if ( this.value ) {
205
- return true;
206
- }
207
-
208
- for ( const block of blocks ) {
209
- if ( schema.checkAttribute( block, 'listType' ) ) {
210
- return true;
211
- }
212
- }
213
-
214
- return false;
215
- }
11
+ /**
12
+ * Creates an instance of the command.
13
+ *
14
+ * @param editor The editor instance.
15
+ * @param type List type that will be handled by this command.
16
+ */
17
+ constructor(editor, type) {
18
+ super(editor);
19
+ this.type = type;
20
+ }
21
+ /**
22
+ * @inheritDoc
23
+ */
24
+ refresh() {
25
+ this.value = this._getValue();
26
+ this.isEnabled = this._checkEnabled();
27
+ }
28
+ /**
29
+ * Executes the list command.
30
+ *
31
+ * @fires execute
32
+ * @fires afterExecute
33
+ * @param options Command options.
34
+ * @param options.forceValue If set, it will force the command behavior. If `true`, the command will try to convert the
35
+ * selected items and potentially the neighbor elements to the proper list items. If set to `false` it will convert selected elements
36
+ * to paragraphs. If not set, the command will toggle selected elements to list items or paragraphs, depending on the selection.
37
+ */
38
+ execute(options = {}) {
39
+ const model = this.editor.model;
40
+ const document = model.document;
41
+ const selectedBlockObject = getSelectedBlockObject(model);
42
+ const blocks = Array.from(document.selection.getSelectedBlocks())
43
+ .filter(block => model.schema.checkAttribute(block, 'listType'));
44
+ // Whether we are turning off some items.
45
+ const turnOff = options.forceValue !== undefined ? !options.forceValue : this.value;
46
+ model.change(writer => {
47
+ if (turnOff) {
48
+ const lastBlock = blocks[blocks.length - 1];
49
+ // Split the first block from the list item.
50
+ const itemBlocks = getListItemBlocks(lastBlock, { direction: 'forward' });
51
+ const changedBlocks = [];
52
+ if (itemBlocks.length > 1) {
53
+ changedBlocks.push(...splitListItemBefore(itemBlocks[1], writer));
54
+ }
55
+ // Convert list blocks to plain blocks.
56
+ changedBlocks.push(...removeListAttributes(blocks, writer));
57
+ // Outdent items following the selected list item.
58
+ changedBlocks.push(...outdentFollowingItems(lastBlock, writer));
59
+ this._fireAfterExecute(changedBlocks);
60
+ }
61
+ // Turning on the list items for a collapsed selection inside a list item.
62
+ else if ((selectedBlockObject || document.selection.isCollapsed) && isListItemBlock(blocks[0])) {
63
+ const changedBlocks = getListItems(selectedBlockObject || blocks[0]);
64
+ for (const block of changedBlocks) {
65
+ writer.setAttribute('listType', this.type, block);
66
+ }
67
+ this._fireAfterExecute(changedBlocks);
68
+ }
69
+ // Turning on the list items for a non-collapsed selection.
70
+ else {
71
+ const changedBlocks = [];
72
+ for (const block of blocks) {
73
+ // Promote the given block to the list item.
74
+ if (!block.hasAttribute('listType')) {
75
+ writer.setAttributes({
76
+ listIndent: 0,
77
+ listItemId: ListItemUid.next(),
78
+ listType: this.type
79
+ }, block);
80
+ changedBlocks.push(block);
81
+ }
82
+ // Change the type of list item.
83
+ else {
84
+ for (const node of expandListBlocksToCompleteItems(block, { withNested: false })) {
85
+ if (node.getAttribute('listType') != this.type) {
86
+ writer.setAttribute('listType', this.type, node);
87
+ changedBlocks.push(node);
88
+ }
89
+ }
90
+ }
91
+ }
92
+ this._fireAfterExecute(changedBlocks);
93
+ }
94
+ });
95
+ }
96
+ /**
97
+ * Fires the `afterExecute` event.
98
+ *
99
+ * @param changedBlocks The changed list elements.
100
+ */
101
+ _fireAfterExecute(changedBlocks) {
102
+ this.fire('afterExecute', sortBlocks(new Set(changedBlocks)));
103
+ }
104
+ /**
105
+ * Checks the command's {@link #value}.
106
+ *
107
+ * @returns The current value.
108
+ */
109
+ _getValue() {
110
+ const selection = this.editor.model.document.selection;
111
+ const blocks = Array.from(selection.getSelectedBlocks());
112
+ if (!blocks.length) {
113
+ return false;
114
+ }
115
+ for (const block of blocks) {
116
+ if (block.getAttribute('listType') != this.type) {
117
+ return false;
118
+ }
119
+ }
120
+ return true;
121
+ }
122
+ /**
123
+ * Checks whether the command can be enabled in the current context.
124
+ *
125
+ * @returns Whether the command should be enabled.
126
+ */
127
+ _checkEnabled() {
128
+ const selection = this.editor.model.document.selection;
129
+ const schema = this.editor.model.schema;
130
+ const blocks = Array.from(selection.getSelectedBlocks());
131
+ if (!blocks.length) {
132
+ return false;
133
+ }
134
+ // If command value is true it means that we are in list item, so the command should be enabled.
135
+ if (this.value) {
136
+ return true;
137
+ }
138
+ for (const block of blocks) {
139
+ if (schema.checkAttribute(block, 'listType')) {
140
+ return true;
141
+ }
142
+ }
143
+ return false;
144
+ }
216
145
  }