@ckeditor/ckeditor5-list 47.6.1 → 48.0.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/LICENSE.md +1 -1
- package/ckeditor5-metadata.json +21 -18
- package/dist/index-content.css +135 -111
- package/dist/index-editor.css +152 -73
- package/dist/index.css +204 -238
- package/dist/index.css.map +1 -1
- package/dist/index.js.map +1 -1
- package/{src → dist}/legacylist/legacyconverters.d.ts +2 -2
- package/{src → dist}/legacylist/legacyindentcommand.d.ts +1 -1
- package/{src → dist}/legacylist/legacylistcommand.d.ts +1 -1
- package/{src → dist}/legacylist/legacylistediting.d.ts +3 -3
- package/{src → dist}/legacylist/legacylistutils.d.ts +2 -2
- package/{src → dist}/legacylist/legacyutils.d.ts +1 -1
- package/{src → dist}/legacylist.d.ts +1 -1
- package/{src → dist}/legacylistproperties/legacylistpropertiesediting.d.ts +1 -1
- package/{src → dist}/legacylistproperties/legacylistreversedcommand.d.ts +1 -1
- package/{src → dist}/legacylistproperties/legacyliststartcommand.d.ts +1 -1
- package/{src → dist}/legacylistproperties/legacyliststylecommand.d.ts +1 -1
- package/{src → dist}/legacylistproperties.d.ts +1 -1
- package/{src → dist}/legacytodolist/legacychecktodolistcommand.d.ts +2 -2
- package/{src → dist}/legacytodolist/legacytodolistconverters.d.ts +2 -2
- package/{src → dist}/legacytodolist/legacytodolistediting.d.ts +1 -1
- package/{src → dist}/legacytodolist.d.ts +1 -1
- package/{src → dist}/list/adjacentlistssupport.d.ts +1 -1
- package/{src → dist}/list/converters.d.ts +2 -2
- package/{src → dist}/list/listcommand.d.ts +2 -2
- package/{src → dist}/list/listediting.d.ts +5 -5
- package/{src → dist}/list/listindentcommand.d.ts +2 -2
- package/{src → dist}/list/listmergecommand.d.ts +2 -2
- package/{src → dist}/list/listsplitcommand.d.ts +2 -2
- package/{src → dist}/list/listui.d.ts +1 -1
- package/{src → dist}/list/listutils.d.ts +3 -3
- package/{src → dist}/list/utils/listwalker.d.ts +2 -2
- package/{src → dist}/list/utils/model.d.ts +2 -2
- package/{src → dist}/list/utils/postfixers.d.ts +1 -1
- package/{src → dist}/list/utils/view.d.ts +1 -1
- package/{src → dist}/list/utils.d.ts +1 -1
- package/{src → dist}/list.d.ts +1 -1
- package/{src → dist}/listconfig.d.ts +1 -1
- package/{src → dist}/listformatting/listitemboldintegration.d.ts +1 -1
- package/{src → dist}/listformatting/listitemfontcolorintegration.d.ts +1 -1
- package/{src → dist}/listformatting/listitemfontfamilyintegration.d.ts +1 -1
- package/{src → dist}/listformatting/listitemfontsizeintegration.d.ts +1 -1
- package/{src → dist}/listformatting/listitemitalicintegration.d.ts +1 -1
- package/{src → dist}/listformatting.d.ts +1 -1
- package/{src → dist}/listproperties/converters.d.ts +2 -2
- package/{src → dist}/listproperties/listpropertiesediting.d.ts +2 -2
- package/{src → dist}/listproperties/listpropertiesui.d.ts +1 -1
- package/{src → dist}/listproperties/listpropertiesutils.d.ts +1 -1
- package/{src → dist}/listproperties/listreversedcommand.d.ts +1 -1
- package/{src → dist}/listproperties/liststartcommand.d.ts +1 -1
- package/{src → dist}/listproperties/liststylecommand.d.ts +1 -1
- package/{src → dist}/listproperties/ui/listpropertiesview.d.ts +2 -2
- package/{src → dist}/listproperties.d.ts +1 -1
- package/{src → dist}/todolist/checktodolistcommand.d.ts +1 -1
- package/{src → dist}/todolist/todocheckboxchangeobserver.d.ts +1 -1
- package/{src → dist}/todolist/todolistediting.d.ts +1 -1
- package/{src → dist}/todolist/todolistui.d.ts +1 -1
- package/{src → dist}/todolist.d.ts +1 -1
- package/package.json +28 -52
- package/build/list.js +0 -5
- package/build/translations/af.js +0 -1
- package/build/translations/ar.js +0 -1
- package/build/translations/ast.js +0 -1
- package/build/translations/az.js +0 -1
- package/build/translations/be.js +0 -1
- package/build/translations/bg.js +0 -1
- package/build/translations/bn.js +0 -1
- package/build/translations/bs.js +0 -1
- package/build/translations/ca.js +0 -1
- package/build/translations/cs.js +0 -1
- package/build/translations/da.js +0 -1
- package/build/translations/de-ch.js +0 -1
- package/build/translations/de.js +0 -1
- package/build/translations/el.js +0 -1
- package/build/translations/en-au.js +0 -1
- package/build/translations/en-gb.js +0 -1
- package/build/translations/eo.js +0 -1
- package/build/translations/es-co.js +0 -1
- package/build/translations/es.js +0 -1
- package/build/translations/et.js +0 -1
- package/build/translations/eu.js +0 -1
- package/build/translations/fa.js +0 -1
- package/build/translations/fi.js +0 -1
- package/build/translations/fr.js +0 -1
- package/build/translations/gl.js +0 -1
- package/build/translations/gu.js +0 -1
- package/build/translations/he.js +0 -1
- package/build/translations/hi.js +0 -1
- package/build/translations/hr.js +0 -1
- package/build/translations/hu.js +0 -1
- package/build/translations/hy.js +0 -1
- package/build/translations/id.js +0 -1
- package/build/translations/it.js +0 -1
- package/build/translations/ja.js +0 -1
- package/build/translations/jv.js +0 -1
- package/build/translations/kk.js +0 -1
- package/build/translations/km.js +0 -1
- package/build/translations/kn.js +0 -1
- package/build/translations/ko.js +0 -1
- package/build/translations/ku.js +0 -1
- package/build/translations/lt.js +0 -1
- package/build/translations/lv.js +0 -1
- package/build/translations/ms.js +0 -1
- package/build/translations/nb.js +0 -1
- package/build/translations/ne.js +0 -1
- package/build/translations/nl.js +0 -1
- package/build/translations/no.js +0 -1
- package/build/translations/oc.js +0 -1
- package/build/translations/pl.js +0 -1
- package/build/translations/pt-br.js +0 -1
- package/build/translations/pt.js +0 -1
- package/build/translations/ro.js +0 -1
- package/build/translations/ru.js +0 -1
- package/build/translations/si.js +0 -1
- package/build/translations/sk.js +0 -1
- package/build/translations/sl.js +0 -1
- package/build/translations/sq.js +0 -1
- package/build/translations/sr-latn.js +0 -1
- package/build/translations/sr.js +0 -1
- package/build/translations/sv.js +0 -1
- package/build/translations/th.js +0 -1
- package/build/translations/ti.js +0 -1
- package/build/translations/tk.js +0 -1
- package/build/translations/tr.js +0 -1
- package/build/translations/tt.js +0 -1
- package/build/translations/ug.js +0 -1
- package/build/translations/uk.js +0 -1
- package/build/translations/ur.js +0 -1
- package/build/translations/uz.js +0 -1
- package/build/translations/vi.js +0 -1
- package/build/translations/zh-cn.js +0 -1
- package/build/translations/zh.js +0 -1
- package/lang/contexts.json +0 -37
- package/lang/translations/af.po +0 -152
- package/lang/translations/ar.po +0 -152
- package/lang/translations/ast.po +0 -152
- package/lang/translations/az.po +0 -152
- package/lang/translations/be.po +0 -152
- package/lang/translations/bg.po +0 -152
- package/lang/translations/bn.po +0 -152
- package/lang/translations/bs.po +0 -152
- package/lang/translations/ca.po +0 -152
- package/lang/translations/cs.po +0 -152
- package/lang/translations/da.po +0 -152
- package/lang/translations/de-ch.po +0 -152
- package/lang/translations/de.po +0 -152
- package/lang/translations/el.po +0 -152
- package/lang/translations/en-au.po +0 -152
- package/lang/translations/en-gb.po +0 -152
- package/lang/translations/en.po +0 -152
- package/lang/translations/eo.po +0 -152
- package/lang/translations/es-co.po +0 -152
- package/lang/translations/es.po +0 -152
- package/lang/translations/et.po +0 -152
- package/lang/translations/eu.po +0 -152
- package/lang/translations/fa.po +0 -152
- package/lang/translations/fi.po +0 -152
- package/lang/translations/fr.po +0 -152
- package/lang/translations/gl.po +0 -152
- package/lang/translations/gu.po +0 -152
- package/lang/translations/he.po +0 -152
- package/lang/translations/hi.po +0 -152
- package/lang/translations/hr.po +0 -152
- package/lang/translations/hu.po +0 -152
- package/lang/translations/hy.po +0 -152
- package/lang/translations/id.po +0 -152
- package/lang/translations/it.po +0 -152
- package/lang/translations/ja.po +0 -152
- package/lang/translations/jv.po +0 -152
- package/lang/translations/kk.po +0 -152
- package/lang/translations/km.po +0 -152
- package/lang/translations/kn.po +0 -152
- package/lang/translations/ko.po +0 -152
- package/lang/translations/ku.po +0 -152
- package/lang/translations/lt.po +0 -152
- package/lang/translations/lv.po +0 -152
- package/lang/translations/ms.po +0 -152
- package/lang/translations/nb.po +0 -152
- package/lang/translations/ne.po +0 -152
- package/lang/translations/nl.po +0 -152
- package/lang/translations/no.po +0 -152
- package/lang/translations/oc.po +0 -152
- package/lang/translations/pl.po +0 -152
- package/lang/translations/pt-br.po +0 -152
- package/lang/translations/pt.po +0 -152
- package/lang/translations/ro.po +0 -152
- package/lang/translations/ru.po +0 -152
- package/lang/translations/si.po +0 -152
- package/lang/translations/sk.po +0 -152
- package/lang/translations/sl.po +0 -152
- package/lang/translations/sq.po +0 -152
- package/lang/translations/sr-latn.po +0 -152
- package/lang/translations/sr.po +0 -152
- package/lang/translations/sv.po +0 -152
- package/lang/translations/th.po +0 -152
- package/lang/translations/ti.po +0 -152
- package/lang/translations/tk.po +0 -152
- package/lang/translations/tr.po +0 -152
- package/lang/translations/tt.po +0 -152
- package/lang/translations/ug.po +0 -152
- package/lang/translations/uk.po +0 -152
- package/lang/translations/ur.po +0 -152
- package/lang/translations/uz.po +0 -152
- package/lang/translations/vi.po +0 -152
- package/lang/translations/zh-cn.po +0 -152
- package/lang/translations/zh.po +0 -152
- package/src/augmentation.js +0 -5
- package/src/index.js +0 -67
- package/src/legacyerrors.js +0 -28
- package/src/legacylist/legacyconverters.js +0 -921
- package/src/legacylist/legacyindentcommand.js +0 -111
- package/src/legacylist/legacylistcommand.js +0 -278
- package/src/legacylist/legacylistediting.js +0 -167
- package/src/legacylist/legacylistutils.js +0 -52
- package/src/legacylist/legacyutils.js +0 -357
- package/src/legacylist.js +0 -36
- package/src/legacylistproperties/legacylistpropertiesediting.js +0 -703
- package/src/legacylistproperties/legacylistreversedcommand.js +0 -52
- package/src/legacylistproperties/legacyliststartcommand.js +0 -52
- package/src/legacylistproperties/legacyliststylecommand.js +0 -105
- package/src/legacylistproperties.js +0 -37
- package/src/legacytodolist/legacychecktodolistcommand.js +0 -82
- package/src/legacytodolist/legacytodolistconverters.js +0 -268
- package/src/legacytodolist/legacytodolistediting.js +0 -199
- package/src/legacytodolist.js +0 -37
- package/src/list/adjacentlistssupport.js +0 -87
- package/src/list/converters.js +0 -533
- package/src/list/listcommand.js +0 -176
- package/src/list/listediting.js +0 -696
- package/src/list/listindentcommand.js +0 -136
- package/src/list/listmergecommand.js +0 -182
- package/src/list/listsplitcommand.js +0 -74
- package/src/list/listui.js +0 -42
- package/src/list/listutils.js +0 -68
- package/src/list/utils/listwalker.js +0 -236
- package/src/list/utils/model.js +0 -487
- package/src/list/utils/postfixers.js +0 -131
- package/src/list/utils/view.js +0 -117
- package/src/list/utils.js +0 -51
- package/src/list.js +0 -36
- package/src/listconfig.js +0 -5
- package/src/listformatting/listitemboldintegration.js +0 -88
- package/src/listformatting/listitemfontcolorintegration.js +0 -92
- package/src/listformatting/listitemfontfamilyintegration.js +0 -93
- package/src/listformatting/listitemfontsizeintegration.js +0 -124
- package/src/listformatting/listitemitalicintegration.js +0 -88
- package/src/listformatting.js +0 -248
- package/src/listproperties/converters.js +0 -43
- package/src/listproperties/listpropertiesediting.js +0 -291
- package/src/listproperties/listpropertiesui.js +0 -385
- package/src/listproperties/listpropertiesutils.js +0 -50
- package/src/listproperties/listreversedcommand.js +0 -55
- package/src/listproperties/liststartcommand.js +0 -61
- package/src/listproperties/liststylecommand.js +0 -121
- package/src/listproperties/ui/listpropertiesview.js +0 -318
- package/src/listproperties/utils/config.js +0 -84
- package/src/listproperties/utils/style.js +0 -85
- package/src/listproperties.js +0 -37
- package/src/todolist/checktodolistcommand.js +0 -82
- package/src/todolist/todocheckboxchangeobserver.js +0 -36
- package/src/todolist/todolistediting.js +0 -470
- package/src/todolist/todolistui.js +0 -35
- package/src/todolist.js +0 -37
- package/theme/documentlist.css +0 -8
- package/theme/list.css +0 -40
- package/theme/listformatting.css +0 -66
- package/theme/listproperties.css +0 -10
- package/theme/liststyles.css +0 -8
- package/theme/todolist.css +0 -140
- /package/{src → dist}/augmentation.d.ts +0 -0
- /package/{src → dist}/index.d.ts +0 -0
- /package/{src → dist}/legacyerrors.d.ts +0 -0
- /package/{src → dist}/listproperties/utils/config.d.ts +0 -0
- /package/{src → dist}/listproperties/utils/style.d.ts +0 -0
package/src/list/utils/model.js
DELETED
|
@@ -1,487 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
-
*/
|
|
5
|
-
import { uid, toArray } from 'ckeditor5/src/utils.js';
|
|
6
|
-
import { ListWalker, SiblingListBlocksIterator } from './listwalker.js';
|
|
7
|
-
/**
|
|
8
|
-
* The list item ID generator.
|
|
9
|
-
*
|
|
10
|
-
* @internal
|
|
11
|
-
*/
|
|
12
|
-
export class ListItemUid {
|
|
13
|
-
/**
|
|
14
|
-
* Returns the next ID.
|
|
15
|
-
*
|
|
16
|
-
* @internal
|
|
17
|
-
*/
|
|
18
|
-
/* istanbul ignore next: static function definition -- @preserve */
|
|
19
|
-
static next() {
|
|
20
|
-
return uid();
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Returns true if the given model node is a list item block.
|
|
25
|
-
*
|
|
26
|
-
* @internal
|
|
27
|
-
*/
|
|
28
|
-
export function isListItemBlock(node) {
|
|
29
|
-
return !!node && node.is('element') && node.hasAttribute('listItemId');
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Returns an array with all elements that represents the same list item.
|
|
33
|
-
*
|
|
34
|
-
* It means that values for `listIndent`, and `listItemId` for all items are equal.
|
|
35
|
-
*
|
|
36
|
-
* @internal
|
|
37
|
-
* @param listItem Starting list item element.
|
|
38
|
-
* @param options.higherIndent Whether blocks with a higher indent level than the start block should be included
|
|
39
|
-
* in the result.
|
|
40
|
-
*/
|
|
41
|
-
export function getAllListItemBlocks(listItem, options = {}) {
|
|
42
|
-
return [
|
|
43
|
-
...getListItemBlocks(listItem, { ...options, direction: 'backward' }),
|
|
44
|
-
...getListItemBlocks(listItem, { ...options, direction: 'forward' })
|
|
45
|
-
];
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Returns an array with elements that represents the same list item in the specified direction.
|
|
49
|
-
*
|
|
50
|
-
* It means that values for `listIndent` and `listItemId` for all items are equal.
|
|
51
|
-
*
|
|
52
|
-
* **Note**: For backward search the provided item is not included, but for forward search it is included in the result.
|
|
53
|
-
*
|
|
54
|
-
* @internal
|
|
55
|
-
* @param listItem Starting list item element.
|
|
56
|
-
* @param options.direction Walking direction.
|
|
57
|
-
* @param options.higherIndent Whether blocks with a higher indent level than the start block should be included in the result.
|
|
58
|
-
*/
|
|
59
|
-
export function getListItemBlocks(listItem, options = {}) {
|
|
60
|
-
const isForward = options.direction == 'forward';
|
|
61
|
-
const items = Array.from(new ListWalker(listItem, {
|
|
62
|
-
...options,
|
|
63
|
-
includeSelf: isForward,
|
|
64
|
-
sameIndent: true,
|
|
65
|
-
sameAttributes: 'listItemId'
|
|
66
|
-
}));
|
|
67
|
-
return isForward ? items : items.reverse();
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Returns a list items nested inside the given list item.
|
|
71
|
-
*
|
|
72
|
-
* @internal
|
|
73
|
-
*/
|
|
74
|
-
export function getNestedListBlocks(listItem) {
|
|
75
|
-
return Array.from(new ListWalker(listItem, {
|
|
76
|
-
direction: 'forward',
|
|
77
|
-
higherIndent: true
|
|
78
|
-
}));
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Returns array of all blocks/items of the same list as given block (same indent, same type and properties).
|
|
82
|
-
*
|
|
83
|
-
* @internal
|
|
84
|
-
* @param listItem Starting list item element.
|
|
85
|
-
* @param options Additional list walker options to modify the range of returned list items.
|
|
86
|
-
*/
|
|
87
|
-
export function getListItems(listItem, options) {
|
|
88
|
-
const backwardBlocks = new ListWalker(listItem, {
|
|
89
|
-
sameIndent: true,
|
|
90
|
-
sameAttributes: 'listType',
|
|
91
|
-
...options
|
|
92
|
-
});
|
|
93
|
-
const forwardBlocks = new ListWalker(listItem, {
|
|
94
|
-
sameIndent: true,
|
|
95
|
-
sameAttributes: 'listType',
|
|
96
|
-
includeSelf: true,
|
|
97
|
-
direction: 'forward',
|
|
98
|
-
...options
|
|
99
|
-
});
|
|
100
|
-
return [
|
|
101
|
-
...Array.from(backwardBlocks).reverse(),
|
|
102
|
-
...forwardBlocks
|
|
103
|
-
];
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Check if the given block is the first in the list item.
|
|
107
|
-
*
|
|
108
|
-
* @internal
|
|
109
|
-
* @param listBlock The list block element.
|
|
110
|
-
*/
|
|
111
|
-
export function isFirstBlockOfListItem(listBlock) {
|
|
112
|
-
const previousSibling = ListWalker.first(listBlock, {
|
|
113
|
-
sameIndent: true,
|
|
114
|
-
sameAttributes: 'listItemId'
|
|
115
|
-
});
|
|
116
|
-
if (!previousSibling) {
|
|
117
|
-
return true;
|
|
118
|
-
}
|
|
119
|
-
return false;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Check if the given block is the last in the list item.
|
|
123
|
-
*
|
|
124
|
-
* @internal
|
|
125
|
-
*/
|
|
126
|
-
export function isLastBlockOfListItem(listBlock) {
|
|
127
|
-
const nextSibling = ListWalker.first(listBlock, {
|
|
128
|
-
direction: 'forward',
|
|
129
|
-
sameIndent: true,
|
|
130
|
-
sameAttributes: 'listItemId'
|
|
131
|
-
});
|
|
132
|
-
if (!nextSibling) {
|
|
133
|
-
return true;
|
|
134
|
-
}
|
|
135
|
-
return false;
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Expands the given list of selected blocks to include the leading and tailing blocks of partially selected list items.
|
|
139
|
-
*
|
|
140
|
-
* @internal
|
|
141
|
-
* @param blocks The list of selected blocks.
|
|
142
|
-
* @param options.withNested Whether should include nested list items.
|
|
143
|
-
*/
|
|
144
|
-
export function expandListBlocksToCompleteItems(blocks, options = {}) {
|
|
145
|
-
blocks = toArray(blocks);
|
|
146
|
-
const higherIndent = options.withNested !== false;
|
|
147
|
-
const allBlocks = new Set();
|
|
148
|
-
for (const block of blocks) {
|
|
149
|
-
for (const itemBlock of getAllListItemBlocks(block, { higherIndent })) {
|
|
150
|
-
allBlocks.add(itemBlock);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
return sortBlocks(allBlocks);
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* Expands the given list of selected blocks to include all the items of the lists they're in.
|
|
157
|
-
*
|
|
158
|
-
* @internal
|
|
159
|
-
* @param blocks The list of selected blocks.
|
|
160
|
-
*/
|
|
161
|
-
export function expandListBlocksToCompleteList(blocks) {
|
|
162
|
-
blocks = toArray(blocks);
|
|
163
|
-
const allBlocks = new Set();
|
|
164
|
-
for (const block of blocks) {
|
|
165
|
-
for (const itemBlock of getListItems(block)) {
|
|
166
|
-
allBlocks.add(itemBlock);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
return sortBlocks(allBlocks);
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Splits the list item just before the provided list block.
|
|
173
|
-
*
|
|
174
|
-
* @internal
|
|
175
|
-
* @param listBlock The list block element.
|
|
176
|
-
* @param writer The model writer.
|
|
177
|
-
* @returns The array of updated blocks.
|
|
178
|
-
*/
|
|
179
|
-
export function splitListItemBefore(listBlock, writer) {
|
|
180
|
-
const blocks = getListItemBlocks(listBlock, { direction: 'forward' });
|
|
181
|
-
const id = ListItemUid.next();
|
|
182
|
-
for (const block of blocks) {
|
|
183
|
-
writer.setAttribute('listItemId', id, block);
|
|
184
|
-
}
|
|
185
|
-
return blocks;
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* Merges the list item with the parent list item.
|
|
189
|
-
*
|
|
190
|
-
* @internal
|
|
191
|
-
* @param listBlock The list block element.
|
|
192
|
-
* @param parentBlock The list block element to merge with.
|
|
193
|
-
* @param writer The model writer.
|
|
194
|
-
* @returns The array of updated blocks.
|
|
195
|
-
*/
|
|
196
|
-
export function mergeListItemBefore(listBlock, parentBlock, writer) {
|
|
197
|
-
const attributes = {};
|
|
198
|
-
for (const [key, value] of parentBlock.getAttributes()) {
|
|
199
|
-
if (key.startsWith('list')) {
|
|
200
|
-
attributes[key] = value;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
const blocks = getListItemBlocks(listBlock, { direction: 'forward' });
|
|
204
|
-
for (const block of blocks) {
|
|
205
|
-
writer.setAttributes(attributes, block);
|
|
206
|
-
}
|
|
207
|
-
return blocks;
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* Increases indentation of given list blocks.
|
|
211
|
-
*
|
|
212
|
-
* @internal
|
|
213
|
-
* @param blocks The block or iterable of blocks.
|
|
214
|
-
* @param writer The model writer.
|
|
215
|
-
* @param options Additional options.
|
|
216
|
-
* @param options.expand Whether should expand the list of blocks to include complete list items.
|
|
217
|
-
* @param options.indentBy The number of levels the indentation should change (could be negative).
|
|
218
|
-
* @param options.attributeNames List of attribute names to remove when a block leaves the list (when blockIndent < 0).
|
|
219
|
-
*/
|
|
220
|
-
export function indentBlocks(blocks, writer, { expand, indentBy = 1, attributeNames }) {
|
|
221
|
-
blocks = toArray(blocks);
|
|
222
|
-
// Expand the selected blocks to contain the whole list items.
|
|
223
|
-
const allBlocks = expand ? expandListBlocksToCompleteItems(blocks) : blocks;
|
|
224
|
-
for (const block of allBlocks) {
|
|
225
|
-
const blockIndent = block.getAttribute('listIndent') + indentBy;
|
|
226
|
-
if (blockIndent < 0) {
|
|
227
|
-
removeListAttributes(block, writer, attributeNames);
|
|
228
|
-
}
|
|
229
|
-
else {
|
|
230
|
-
writer.setAttribute('listIndent', blockIndent, block);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
return allBlocks;
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Decreases indentation of given list of blocks. If the indentation of some blocks matches the indentation
|
|
237
|
-
* of surrounding blocks, they get merged together.
|
|
238
|
-
*
|
|
239
|
-
* @internal
|
|
240
|
-
* @param blocks The block or iterable of blocks.
|
|
241
|
-
* @param writer The model writer.
|
|
242
|
-
* @param options Additional options.
|
|
243
|
-
* @param options.attributeNames List of attribute names to remove when a block leaves the list (when blockIndent < 0).
|
|
244
|
-
*/
|
|
245
|
-
export function outdentBlocksWithMerge(blocks, writer, { attributeNames }) {
|
|
246
|
-
blocks = toArray(blocks);
|
|
247
|
-
// Expand the selected blocks to contain the whole list items.
|
|
248
|
-
const allBlocks = expandListBlocksToCompleteItems(blocks);
|
|
249
|
-
const visited = new Set();
|
|
250
|
-
const referenceIndent = Math.min(...allBlocks.map(block => block.getAttribute('listIndent')));
|
|
251
|
-
const parentBlocks = new Map();
|
|
252
|
-
// Collect parent blocks before the list structure gets altered.
|
|
253
|
-
for (const block of allBlocks) {
|
|
254
|
-
parentBlocks.set(block, ListWalker.first(block, { lowerIndent: true }));
|
|
255
|
-
}
|
|
256
|
-
for (const block of allBlocks) {
|
|
257
|
-
if (visited.has(block)) {
|
|
258
|
-
continue;
|
|
259
|
-
}
|
|
260
|
-
visited.add(block);
|
|
261
|
-
const blockIndent = block.getAttribute('listIndent') - 1;
|
|
262
|
-
if (blockIndent < 0) {
|
|
263
|
-
removeListAttributes(block, writer, attributeNames);
|
|
264
|
-
continue;
|
|
265
|
-
}
|
|
266
|
-
// Merge with parent list item while outdenting and indent matches reference indent.
|
|
267
|
-
if (block.getAttribute('listIndent') == referenceIndent) {
|
|
268
|
-
const mergedBlocks = mergeListItemIfNotLast(block, parentBlocks.get(block), writer);
|
|
269
|
-
// All list item blocks are updated while merging so add those to visited set.
|
|
270
|
-
for (const mergedBlock of mergedBlocks) {
|
|
271
|
-
visited.add(mergedBlock);
|
|
272
|
-
}
|
|
273
|
-
// The indent level was updated while merging so continue to next block.
|
|
274
|
-
if (mergedBlocks.length) {
|
|
275
|
-
continue;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
writer.setAttribute('listIndent', blockIndent, block);
|
|
279
|
-
}
|
|
280
|
-
return sortBlocks(visited);
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* Removes all list attributes from the given blocks.
|
|
284
|
-
*
|
|
285
|
-
* @internal
|
|
286
|
-
* @param blocks The block or iterable of blocks.
|
|
287
|
-
* @param writer The model writer.
|
|
288
|
-
* @param attributeNames List of attribute names to remove.
|
|
289
|
-
* @returns Array of altered blocks.
|
|
290
|
-
*/
|
|
291
|
-
export function removeListAttributes(blocks, writer, attributeNames) {
|
|
292
|
-
blocks = toArray(blocks);
|
|
293
|
-
// Convert simple list items to plain paragraphs.
|
|
294
|
-
for (const block of blocks) {
|
|
295
|
-
if (block.is('element', 'listItem')) {
|
|
296
|
-
writer.rename(block, 'paragraph');
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
// Remove list attributes.
|
|
300
|
-
for (const block of blocks) {
|
|
301
|
-
for (const attributeKey of block.getAttributeKeys()) {
|
|
302
|
-
if (attributeNames.includes(attributeKey)) {
|
|
303
|
-
writer.removeAttribute(attributeKey, block);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
return blocks;
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* Checks whether the given blocks are related to a single list item.
|
|
311
|
-
*
|
|
312
|
-
* @internal
|
|
313
|
-
* @param blocks The list block elements.
|
|
314
|
-
*/
|
|
315
|
-
export function isSingleListItem(blocks) {
|
|
316
|
-
if (!blocks.length) {
|
|
317
|
-
return false;
|
|
318
|
-
}
|
|
319
|
-
const firstItemId = blocks[0].getAttribute('listItemId');
|
|
320
|
-
if (!firstItemId) {
|
|
321
|
-
return false;
|
|
322
|
-
}
|
|
323
|
-
return !blocks.some(item => item.getAttribute('listItemId') != firstItemId);
|
|
324
|
-
}
|
|
325
|
-
/**
|
|
326
|
-
* Modifies the indents of list blocks following the given list block so the indentation is valid after
|
|
327
|
-
* the given block is no longer a list item.
|
|
328
|
-
*
|
|
329
|
-
* @internal
|
|
330
|
-
* @param lastBlock The last list block that has become a non-list element.
|
|
331
|
-
* @param writer The model writer.
|
|
332
|
-
* @returns Array of altered blocks.
|
|
333
|
-
*/
|
|
334
|
-
export function outdentFollowingItems(lastBlock, writer) {
|
|
335
|
-
const changedBlocks = [];
|
|
336
|
-
// Start from the model item that is just after the last turned-off item.
|
|
337
|
-
let currentIndent = Number.POSITIVE_INFINITY;
|
|
338
|
-
// Correct indent of all items after the last turned off item.
|
|
339
|
-
// Rules that should be followed:
|
|
340
|
-
// 1. All direct sub-items of turned-off item should become indent 0, because the first item after it
|
|
341
|
-
// will be the first item of a new list. Other items are at the same level, so should have same 0 index.
|
|
342
|
-
// 2. All items with indent lower than indent of turned-off item should become indent 0, because they
|
|
343
|
-
// should not end up as a child of any of list items that they were not children of before.
|
|
344
|
-
// 3. All other items should have their indent changed relatively to it's parent.
|
|
345
|
-
//
|
|
346
|
-
// For example:
|
|
347
|
-
// 1 * --------
|
|
348
|
-
// 2 * --------
|
|
349
|
-
// 3 * -------- <-- this is turned off.
|
|
350
|
-
// 4 * -------- <-- this has to become indent = 0, because it will be first item on a new list.
|
|
351
|
-
// 5 * -------- <-- this should be still be a child of item above, so indent = 1.
|
|
352
|
-
// 6 * -------- <-- this has to become indent = 0, because it should not be a child of any of items above.
|
|
353
|
-
// 7 * -------- <-- this should be still be a child of item above, so indent = 1.
|
|
354
|
-
// 8 * -------- <-- this has to become indent = 0.
|
|
355
|
-
// 9 * -------- <-- this should still be a child of item above, so indent = 1.
|
|
356
|
-
// 10 * -------- <-- this should still be a child of item above, so indent = 2.
|
|
357
|
-
// 11 * -------- <-- this should still be at the same level as item above, so indent = 2.
|
|
358
|
-
// 12 * -------- <-- this and all below are left unchanged.
|
|
359
|
-
// 13 * --------
|
|
360
|
-
// 14 * --------
|
|
361
|
-
//
|
|
362
|
-
// After turning off 3 the list becomes:
|
|
363
|
-
//
|
|
364
|
-
// 1 * --------
|
|
365
|
-
// 2 * --------
|
|
366
|
-
//
|
|
367
|
-
// 3 --------
|
|
368
|
-
//
|
|
369
|
-
// 4 * --------
|
|
370
|
-
// 5 * --------
|
|
371
|
-
// 6 * --------
|
|
372
|
-
// 7 * --------
|
|
373
|
-
// 8 * --------
|
|
374
|
-
// 9 * --------
|
|
375
|
-
// 10 * --------
|
|
376
|
-
// 11 * --------
|
|
377
|
-
// 12 * --------
|
|
378
|
-
// 13 * --------
|
|
379
|
-
// 14 * --------
|
|
380
|
-
//
|
|
381
|
-
// Thanks to this algorithm no lists are mismatched and no items get unexpected children/parent, while
|
|
382
|
-
// those parent-child connection which are possible to maintain are still maintained. It's worth noting
|
|
383
|
-
// that this is the same effect that we would be get by multiple use of outdent command. However doing
|
|
384
|
-
// it like this is much more efficient because it's less operation (less memory usage, easier OT) and
|
|
385
|
-
// less conversion (faster).
|
|
386
|
-
for (const { node } of new SiblingListBlocksIterator(lastBlock.nextSibling)) {
|
|
387
|
-
// Check each next list item, as long as its indent is higher than 0.
|
|
388
|
-
const indent = node.getAttribute('listIndent');
|
|
389
|
-
// If the indent is 0 we are not going to change anything anyway.
|
|
390
|
-
if (indent == 0) {
|
|
391
|
-
break;
|
|
392
|
-
}
|
|
393
|
-
// We check if that's item indent is lower than current relative indent.
|
|
394
|
-
if (indent < currentIndent) {
|
|
395
|
-
// If it is, current relative indent becomes that indent.
|
|
396
|
-
currentIndent = indent;
|
|
397
|
-
}
|
|
398
|
-
// Fix indent relatively to current relative indent.
|
|
399
|
-
// Note, that if we just changed the current relative indent, the newIndent will be equal to 0.
|
|
400
|
-
const newIndent = indent - currentIndent;
|
|
401
|
-
writer.setAttribute('listIndent', newIndent, node);
|
|
402
|
-
changedBlocks.push(node);
|
|
403
|
-
}
|
|
404
|
-
return changedBlocks;
|
|
405
|
-
}
|
|
406
|
-
/**
|
|
407
|
-
* Returns the array of given blocks sorted by model indexes (document order).
|
|
408
|
-
*
|
|
409
|
-
* @internal
|
|
410
|
-
*/
|
|
411
|
-
export function sortBlocks(blocks) {
|
|
412
|
-
return Array.from(blocks)
|
|
413
|
-
.filter(block => block.root.rootName !== '$graveyard')
|
|
414
|
-
.sort((a, b) => a.index - b.index);
|
|
415
|
-
}
|
|
416
|
-
/**
|
|
417
|
-
* Returns a selected block object. If a selected object is inline or when there is no selected
|
|
418
|
-
* object, `null` is returned.
|
|
419
|
-
*
|
|
420
|
-
* @internal
|
|
421
|
-
* @param model The instance of editor model.
|
|
422
|
-
* @returns Selected block object or `null`.
|
|
423
|
-
*/
|
|
424
|
-
export function getSelectedBlockObject(model) {
|
|
425
|
-
const selectedElement = model.document.selection.getSelectedElement();
|
|
426
|
-
if (!selectedElement) {
|
|
427
|
-
return null;
|
|
428
|
-
}
|
|
429
|
-
if (model.schema.isObject(selectedElement) && model.schema.isBlock(selectedElement)) {
|
|
430
|
-
return selectedElement;
|
|
431
|
-
}
|
|
432
|
-
return null;
|
|
433
|
-
}
|
|
434
|
-
/**
|
|
435
|
-
* Checks whether the given block can be replaced by a listItem.
|
|
436
|
-
*
|
|
437
|
-
* Note that this is possible only when multiBlock = false option is set in feature config.
|
|
438
|
-
*
|
|
439
|
-
* @param block A block to be tested.
|
|
440
|
-
* @param schema The schema of the document.
|
|
441
|
-
* @internal
|
|
442
|
-
*/
|
|
443
|
-
export function canBecomeSimpleListItem(block, schema) {
|
|
444
|
-
return schema.checkChild(block.parent, 'listItem') &&
|
|
445
|
-
schema.checkChild(block, '$text') &&
|
|
446
|
-
!schema.isObject(block);
|
|
447
|
-
}
|
|
448
|
-
/**
|
|
449
|
-
* Returns true if listType is of type `numbered` or `customNumbered`.
|
|
450
|
-
*
|
|
451
|
-
* @internal
|
|
452
|
-
*/
|
|
453
|
-
export function isNumberedListType(listType) {
|
|
454
|
-
return listType == 'numbered' || listType == 'customNumbered';
|
|
455
|
-
}
|
|
456
|
-
/**
|
|
457
|
-
* Checks if the given list item is the first item in the list.
|
|
458
|
-
*
|
|
459
|
-
* This function checks if there's any other list item before the given list item
|
|
460
|
-
* at the same indent level with the same list type.
|
|
461
|
-
*/
|
|
462
|
-
export function isFirstListItemInList(listItem) {
|
|
463
|
-
const previousItem = ListWalker.first(listItem, {
|
|
464
|
-
sameIndent: true,
|
|
465
|
-
sameAttributes: 'listType'
|
|
466
|
-
});
|
|
467
|
-
return !previousItem;
|
|
468
|
-
}
|
|
469
|
-
/**
|
|
470
|
-
* Merges a given block to the given parent block if parent is a list item and there is no more blocks in the same item.
|
|
471
|
-
*/
|
|
472
|
-
function mergeListItemIfNotLast(block, parentBlock, writer) {
|
|
473
|
-
const parentItemBlocks = getListItemBlocks(parentBlock, { direction: 'forward' });
|
|
474
|
-
// Merge with parent only if outdented item wasn't the last one in its parent.
|
|
475
|
-
// Merge:
|
|
476
|
-
// * a -> * a
|
|
477
|
-
// * [b] -> b
|
|
478
|
-
// c -> c
|
|
479
|
-
// Don't merge:
|
|
480
|
-
// * a -> * a
|
|
481
|
-
// * [b] -> * b
|
|
482
|
-
// * c -> * c
|
|
483
|
-
if (parentItemBlocks.pop().index > block.index) {
|
|
484
|
-
return mergeListItemBefore(block, parentBlock, writer);
|
|
485
|
-
}
|
|
486
|
-
return [];
|
|
487
|
-
}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
-
*/
|
|
5
|
-
import { SiblingListBlocksIterator } from './listwalker.js';
|
|
6
|
-
import { getListItemBlocks, isListItemBlock, ListItemUid } from './model.js';
|
|
7
|
-
/**
|
|
8
|
-
* Based on the provided positions looks for the list head and stores it in the provided map.
|
|
9
|
-
*
|
|
10
|
-
* @internal
|
|
11
|
-
* @param position The search starting position.
|
|
12
|
-
* @param itemToListHead The map from list item element to the list head element.
|
|
13
|
-
* @param visited A set of elements that were already visited.
|
|
14
|
-
*/
|
|
15
|
-
export function findAndAddListHeadToMap(position, itemToListHead, visited) {
|
|
16
|
-
const previousNode = position.nodeBefore;
|
|
17
|
-
if (!isListItemBlock(previousNode)) {
|
|
18
|
-
const item = position.nodeAfter;
|
|
19
|
-
if (isListItemBlock(item)) {
|
|
20
|
-
itemToListHead.add(item);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
let listHead = previousNode;
|
|
25
|
-
// Previously, the loop below was defined like this:
|
|
26
|
-
//
|
|
27
|
-
// for ( { node: listHead } of new SiblingListBlocksIterator( listHead, 'backward' ) )
|
|
28
|
-
//
|
|
29
|
-
// Unfortunately, such a destructuring is incorrectly transpiled by Babel and the loop never ends.
|
|
30
|
-
// See: https://github.com/ckeditor/ckeditor5-react/issues/345.
|
|
31
|
-
for (const { node } of new SiblingListBlocksIterator(listHead, 'backward')) {
|
|
32
|
-
listHead = node;
|
|
33
|
-
if (visited.has(listHead)) {
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
visited.add(listHead);
|
|
37
|
-
if (itemToListHead.has(previousNode)) {
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
itemToListHead.add(listHead);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Scans the list starting from the given list head element and fixes items' indentation.
|
|
46
|
-
*
|
|
47
|
-
* @internal
|
|
48
|
-
* @param listNodes The iterable of list nodes.
|
|
49
|
-
* @param writer The model writer.
|
|
50
|
-
* @returns Whether the model was modified.
|
|
51
|
-
*/
|
|
52
|
-
export function fixListIndents(listNodes, writer) {
|
|
53
|
-
let maxIndent = 0; // Guards local sublist max indents that need fixing.
|
|
54
|
-
let prevIndent = -1; // Previous item indent.
|
|
55
|
-
let fixBy = null;
|
|
56
|
-
let applied = false;
|
|
57
|
-
for (const { node } of listNodes) {
|
|
58
|
-
const itemIndent = node.getAttribute('listIndent');
|
|
59
|
-
if (itemIndent > maxIndent) {
|
|
60
|
-
let newIndent;
|
|
61
|
-
if (fixBy === null) {
|
|
62
|
-
fixBy = itemIndent - maxIndent;
|
|
63
|
-
newIndent = maxIndent;
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
if (fixBy > itemIndent) {
|
|
67
|
-
fixBy = itemIndent;
|
|
68
|
-
}
|
|
69
|
-
newIndent = itemIndent - fixBy;
|
|
70
|
-
}
|
|
71
|
-
if (newIndent > prevIndent + 1) {
|
|
72
|
-
newIndent = prevIndent + 1;
|
|
73
|
-
}
|
|
74
|
-
writer.setAttribute('listIndent', newIndent, node);
|
|
75
|
-
applied = true;
|
|
76
|
-
prevIndent = newIndent;
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
fixBy = null;
|
|
80
|
-
maxIndent = itemIndent + 1;
|
|
81
|
-
prevIndent = itemIndent;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return applied;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Scans the list starting from the given list head element and fixes items' types.
|
|
88
|
-
*
|
|
89
|
-
* @internal
|
|
90
|
-
* @param listNodes The iterable of list nodes.
|
|
91
|
-
* @param seenIds The set of already known IDs.
|
|
92
|
-
* @param writer The model writer.
|
|
93
|
-
* @returns Whether the model was modified.
|
|
94
|
-
*/
|
|
95
|
-
export function fixListItemIds(listNodes, seenIds, writer) {
|
|
96
|
-
const visited = new Set();
|
|
97
|
-
let applied = false;
|
|
98
|
-
for (const { node } of listNodes) {
|
|
99
|
-
if (visited.has(node)) {
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
let listType = node.getAttribute('listType');
|
|
103
|
-
let listItemId = node.getAttribute('listItemId');
|
|
104
|
-
// Use a new ID if this one was spot earlier (even in other list).
|
|
105
|
-
if (seenIds.has(listItemId)) {
|
|
106
|
-
listItemId = ListItemUid.next();
|
|
107
|
-
}
|
|
108
|
-
seenIds.add(listItemId);
|
|
109
|
-
// Make sure that all items in a simple list have unique IDs.
|
|
110
|
-
if (node.is('element', 'listItem')) {
|
|
111
|
-
if (node.getAttribute('listItemId') != listItemId) {
|
|
112
|
-
writer.setAttribute('listItemId', listItemId, node);
|
|
113
|
-
applied = true;
|
|
114
|
-
}
|
|
115
|
-
continue;
|
|
116
|
-
}
|
|
117
|
-
for (const block of getListItemBlocks(node, { direction: 'forward' })) {
|
|
118
|
-
visited.add(block);
|
|
119
|
-
// Use a new ID if a block of a bigger list item has different type.
|
|
120
|
-
if (block.getAttribute('listType') != listType) {
|
|
121
|
-
listItemId = ListItemUid.next();
|
|
122
|
-
listType = block.getAttribute('listType');
|
|
123
|
-
}
|
|
124
|
-
if (block.getAttribute('listItemId') != listItemId) {
|
|
125
|
-
writer.setAttribute('listItemId', listItemId, block);
|
|
126
|
-
applied = true;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
return applied;
|
|
131
|
-
}
|