@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.
Files changed (275) hide show
  1. package/LICENSE.md +1 -1
  2. package/ckeditor5-metadata.json +21 -18
  3. package/dist/index-content.css +135 -111
  4. package/dist/index-editor.css +152 -73
  5. package/dist/index.css +204 -238
  6. package/dist/index.css.map +1 -1
  7. package/dist/index.js.map +1 -1
  8. package/{src → dist}/legacylist/legacyconverters.d.ts +2 -2
  9. package/{src → dist}/legacylist/legacyindentcommand.d.ts +1 -1
  10. package/{src → dist}/legacylist/legacylistcommand.d.ts +1 -1
  11. package/{src → dist}/legacylist/legacylistediting.d.ts +3 -3
  12. package/{src → dist}/legacylist/legacylistutils.d.ts +2 -2
  13. package/{src → dist}/legacylist/legacyutils.d.ts +1 -1
  14. package/{src → dist}/legacylist.d.ts +1 -1
  15. package/{src → dist}/legacylistproperties/legacylistpropertiesediting.d.ts +1 -1
  16. package/{src → dist}/legacylistproperties/legacylistreversedcommand.d.ts +1 -1
  17. package/{src → dist}/legacylistproperties/legacyliststartcommand.d.ts +1 -1
  18. package/{src → dist}/legacylistproperties/legacyliststylecommand.d.ts +1 -1
  19. package/{src → dist}/legacylistproperties.d.ts +1 -1
  20. package/{src → dist}/legacytodolist/legacychecktodolistcommand.d.ts +2 -2
  21. package/{src → dist}/legacytodolist/legacytodolistconverters.d.ts +2 -2
  22. package/{src → dist}/legacytodolist/legacytodolistediting.d.ts +1 -1
  23. package/{src → dist}/legacytodolist.d.ts +1 -1
  24. package/{src → dist}/list/adjacentlistssupport.d.ts +1 -1
  25. package/{src → dist}/list/converters.d.ts +2 -2
  26. package/{src → dist}/list/listcommand.d.ts +2 -2
  27. package/{src → dist}/list/listediting.d.ts +5 -5
  28. package/{src → dist}/list/listindentcommand.d.ts +2 -2
  29. package/{src → dist}/list/listmergecommand.d.ts +2 -2
  30. package/{src → dist}/list/listsplitcommand.d.ts +2 -2
  31. package/{src → dist}/list/listui.d.ts +1 -1
  32. package/{src → dist}/list/listutils.d.ts +3 -3
  33. package/{src → dist}/list/utils/listwalker.d.ts +2 -2
  34. package/{src → dist}/list/utils/model.d.ts +2 -2
  35. package/{src → dist}/list/utils/postfixers.d.ts +1 -1
  36. package/{src → dist}/list/utils/view.d.ts +1 -1
  37. package/{src → dist}/list/utils.d.ts +1 -1
  38. package/{src → dist}/list.d.ts +1 -1
  39. package/{src → dist}/listconfig.d.ts +1 -1
  40. package/{src → dist}/listformatting/listitemboldintegration.d.ts +1 -1
  41. package/{src → dist}/listformatting/listitemfontcolorintegration.d.ts +1 -1
  42. package/{src → dist}/listformatting/listitemfontfamilyintegration.d.ts +1 -1
  43. package/{src → dist}/listformatting/listitemfontsizeintegration.d.ts +1 -1
  44. package/{src → dist}/listformatting/listitemitalicintegration.d.ts +1 -1
  45. package/{src → dist}/listformatting.d.ts +1 -1
  46. package/{src → dist}/listproperties/converters.d.ts +2 -2
  47. package/{src → dist}/listproperties/listpropertiesediting.d.ts +2 -2
  48. package/{src → dist}/listproperties/listpropertiesui.d.ts +1 -1
  49. package/{src → dist}/listproperties/listpropertiesutils.d.ts +1 -1
  50. package/{src → dist}/listproperties/listreversedcommand.d.ts +1 -1
  51. package/{src → dist}/listproperties/liststartcommand.d.ts +1 -1
  52. package/{src → dist}/listproperties/liststylecommand.d.ts +1 -1
  53. package/{src → dist}/listproperties/ui/listpropertiesview.d.ts +2 -2
  54. package/{src → dist}/listproperties.d.ts +1 -1
  55. package/{src → dist}/todolist/checktodolistcommand.d.ts +1 -1
  56. package/{src → dist}/todolist/todocheckboxchangeobserver.d.ts +1 -1
  57. package/{src → dist}/todolist/todolistediting.d.ts +1 -1
  58. package/{src → dist}/todolist/todolistui.d.ts +1 -1
  59. package/{src → dist}/todolist.d.ts +1 -1
  60. package/package.json +28 -52
  61. package/build/list.js +0 -5
  62. package/build/translations/af.js +0 -1
  63. package/build/translations/ar.js +0 -1
  64. package/build/translations/ast.js +0 -1
  65. package/build/translations/az.js +0 -1
  66. package/build/translations/be.js +0 -1
  67. package/build/translations/bg.js +0 -1
  68. package/build/translations/bn.js +0 -1
  69. package/build/translations/bs.js +0 -1
  70. package/build/translations/ca.js +0 -1
  71. package/build/translations/cs.js +0 -1
  72. package/build/translations/da.js +0 -1
  73. package/build/translations/de-ch.js +0 -1
  74. package/build/translations/de.js +0 -1
  75. package/build/translations/el.js +0 -1
  76. package/build/translations/en-au.js +0 -1
  77. package/build/translations/en-gb.js +0 -1
  78. package/build/translations/eo.js +0 -1
  79. package/build/translations/es-co.js +0 -1
  80. package/build/translations/es.js +0 -1
  81. package/build/translations/et.js +0 -1
  82. package/build/translations/eu.js +0 -1
  83. package/build/translations/fa.js +0 -1
  84. package/build/translations/fi.js +0 -1
  85. package/build/translations/fr.js +0 -1
  86. package/build/translations/gl.js +0 -1
  87. package/build/translations/gu.js +0 -1
  88. package/build/translations/he.js +0 -1
  89. package/build/translations/hi.js +0 -1
  90. package/build/translations/hr.js +0 -1
  91. package/build/translations/hu.js +0 -1
  92. package/build/translations/hy.js +0 -1
  93. package/build/translations/id.js +0 -1
  94. package/build/translations/it.js +0 -1
  95. package/build/translations/ja.js +0 -1
  96. package/build/translations/jv.js +0 -1
  97. package/build/translations/kk.js +0 -1
  98. package/build/translations/km.js +0 -1
  99. package/build/translations/kn.js +0 -1
  100. package/build/translations/ko.js +0 -1
  101. package/build/translations/ku.js +0 -1
  102. package/build/translations/lt.js +0 -1
  103. package/build/translations/lv.js +0 -1
  104. package/build/translations/ms.js +0 -1
  105. package/build/translations/nb.js +0 -1
  106. package/build/translations/ne.js +0 -1
  107. package/build/translations/nl.js +0 -1
  108. package/build/translations/no.js +0 -1
  109. package/build/translations/oc.js +0 -1
  110. package/build/translations/pl.js +0 -1
  111. package/build/translations/pt-br.js +0 -1
  112. package/build/translations/pt.js +0 -1
  113. package/build/translations/ro.js +0 -1
  114. package/build/translations/ru.js +0 -1
  115. package/build/translations/si.js +0 -1
  116. package/build/translations/sk.js +0 -1
  117. package/build/translations/sl.js +0 -1
  118. package/build/translations/sq.js +0 -1
  119. package/build/translations/sr-latn.js +0 -1
  120. package/build/translations/sr.js +0 -1
  121. package/build/translations/sv.js +0 -1
  122. package/build/translations/th.js +0 -1
  123. package/build/translations/ti.js +0 -1
  124. package/build/translations/tk.js +0 -1
  125. package/build/translations/tr.js +0 -1
  126. package/build/translations/tt.js +0 -1
  127. package/build/translations/ug.js +0 -1
  128. package/build/translations/uk.js +0 -1
  129. package/build/translations/ur.js +0 -1
  130. package/build/translations/uz.js +0 -1
  131. package/build/translations/vi.js +0 -1
  132. package/build/translations/zh-cn.js +0 -1
  133. package/build/translations/zh.js +0 -1
  134. package/lang/contexts.json +0 -37
  135. package/lang/translations/af.po +0 -152
  136. package/lang/translations/ar.po +0 -152
  137. package/lang/translations/ast.po +0 -152
  138. package/lang/translations/az.po +0 -152
  139. package/lang/translations/be.po +0 -152
  140. package/lang/translations/bg.po +0 -152
  141. package/lang/translations/bn.po +0 -152
  142. package/lang/translations/bs.po +0 -152
  143. package/lang/translations/ca.po +0 -152
  144. package/lang/translations/cs.po +0 -152
  145. package/lang/translations/da.po +0 -152
  146. package/lang/translations/de-ch.po +0 -152
  147. package/lang/translations/de.po +0 -152
  148. package/lang/translations/el.po +0 -152
  149. package/lang/translations/en-au.po +0 -152
  150. package/lang/translations/en-gb.po +0 -152
  151. package/lang/translations/en.po +0 -152
  152. package/lang/translations/eo.po +0 -152
  153. package/lang/translations/es-co.po +0 -152
  154. package/lang/translations/es.po +0 -152
  155. package/lang/translations/et.po +0 -152
  156. package/lang/translations/eu.po +0 -152
  157. package/lang/translations/fa.po +0 -152
  158. package/lang/translations/fi.po +0 -152
  159. package/lang/translations/fr.po +0 -152
  160. package/lang/translations/gl.po +0 -152
  161. package/lang/translations/gu.po +0 -152
  162. package/lang/translations/he.po +0 -152
  163. package/lang/translations/hi.po +0 -152
  164. package/lang/translations/hr.po +0 -152
  165. package/lang/translations/hu.po +0 -152
  166. package/lang/translations/hy.po +0 -152
  167. package/lang/translations/id.po +0 -152
  168. package/lang/translations/it.po +0 -152
  169. package/lang/translations/ja.po +0 -152
  170. package/lang/translations/jv.po +0 -152
  171. package/lang/translations/kk.po +0 -152
  172. package/lang/translations/km.po +0 -152
  173. package/lang/translations/kn.po +0 -152
  174. package/lang/translations/ko.po +0 -152
  175. package/lang/translations/ku.po +0 -152
  176. package/lang/translations/lt.po +0 -152
  177. package/lang/translations/lv.po +0 -152
  178. package/lang/translations/ms.po +0 -152
  179. package/lang/translations/nb.po +0 -152
  180. package/lang/translations/ne.po +0 -152
  181. package/lang/translations/nl.po +0 -152
  182. package/lang/translations/no.po +0 -152
  183. package/lang/translations/oc.po +0 -152
  184. package/lang/translations/pl.po +0 -152
  185. package/lang/translations/pt-br.po +0 -152
  186. package/lang/translations/pt.po +0 -152
  187. package/lang/translations/ro.po +0 -152
  188. package/lang/translations/ru.po +0 -152
  189. package/lang/translations/si.po +0 -152
  190. package/lang/translations/sk.po +0 -152
  191. package/lang/translations/sl.po +0 -152
  192. package/lang/translations/sq.po +0 -152
  193. package/lang/translations/sr-latn.po +0 -152
  194. package/lang/translations/sr.po +0 -152
  195. package/lang/translations/sv.po +0 -152
  196. package/lang/translations/th.po +0 -152
  197. package/lang/translations/ti.po +0 -152
  198. package/lang/translations/tk.po +0 -152
  199. package/lang/translations/tr.po +0 -152
  200. package/lang/translations/tt.po +0 -152
  201. package/lang/translations/ug.po +0 -152
  202. package/lang/translations/uk.po +0 -152
  203. package/lang/translations/ur.po +0 -152
  204. package/lang/translations/uz.po +0 -152
  205. package/lang/translations/vi.po +0 -152
  206. package/lang/translations/zh-cn.po +0 -152
  207. package/lang/translations/zh.po +0 -152
  208. package/src/augmentation.js +0 -5
  209. package/src/index.js +0 -67
  210. package/src/legacyerrors.js +0 -28
  211. package/src/legacylist/legacyconverters.js +0 -921
  212. package/src/legacylist/legacyindentcommand.js +0 -111
  213. package/src/legacylist/legacylistcommand.js +0 -278
  214. package/src/legacylist/legacylistediting.js +0 -167
  215. package/src/legacylist/legacylistutils.js +0 -52
  216. package/src/legacylist/legacyutils.js +0 -357
  217. package/src/legacylist.js +0 -36
  218. package/src/legacylistproperties/legacylistpropertiesediting.js +0 -703
  219. package/src/legacylistproperties/legacylistreversedcommand.js +0 -52
  220. package/src/legacylistproperties/legacyliststartcommand.js +0 -52
  221. package/src/legacylistproperties/legacyliststylecommand.js +0 -105
  222. package/src/legacylistproperties.js +0 -37
  223. package/src/legacytodolist/legacychecktodolistcommand.js +0 -82
  224. package/src/legacytodolist/legacytodolistconverters.js +0 -268
  225. package/src/legacytodolist/legacytodolistediting.js +0 -199
  226. package/src/legacytodolist.js +0 -37
  227. package/src/list/adjacentlistssupport.js +0 -87
  228. package/src/list/converters.js +0 -533
  229. package/src/list/listcommand.js +0 -176
  230. package/src/list/listediting.js +0 -696
  231. package/src/list/listindentcommand.js +0 -136
  232. package/src/list/listmergecommand.js +0 -182
  233. package/src/list/listsplitcommand.js +0 -74
  234. package/src/list/listui.js +0 -42
  235. package/src/list/listutils.js +0 -68
  236. package/src/list/utils/listwalker.js +0 -236
  237. package/src/list/utils/model.js +0 -487
  238. package/src/list/utils/postfixers.js +0 -131
  239. package/src/list/utils/view.js +0 -117
  240. package/src/list/utils.js +0 -51
  241. package/src/list.js +0 -36
  242. package/src/listconfig.js +0 -5
  243. package/src/listformatting/listitemboldintegration.js +0 -88
  244. package/src/listformatting/listitemfontcolorintegration.js +0 -92
  245. package/src/listformatting/listitemfontfamilyintegration.js +0 -93
  246. package/src/listformatting/listitemfontsizeintegration.js +0 -124
  247. package/src/listformatting/listitemitalicintegration.js +0 -88
  248. package/src/listformatting.js +0 -248
  249. package/src/listproperties/converters.js +0 -43
  250. package/src/listproperties/listpropertiesediting.js +0 -291
  251. package/src/listproperties/listpropertiesui.js +0 -385
  252. package/src/listproperties/listpropertiesutils.js +0 -50
  253. package/src/listproperties/listreversedcommand.js +0 -55
  254. package/src/listproperties/liststartcommand.js +0 -61
  255. package/src/listproperties/liststylecommand.js +0 -121
  256. package/src/listproperties/ui/listpropertiesview.js +0 -318
  257. package/src/listproperties/utils/config.js +0 -84
  258. package/src/listproperties/utils/style.js +0 -85
  259. package/src/listproperties.js +0 -37
  260. package/src/todolist/checktodolistcommand.js +0 -82
  261. package/src/todolist/todocheckboxchangeobserver.js +0 -36
  262. package/src/todolist/todolistediting.js +0 -470
  263. package/src/todolist/todolistui.js +0 -35
  264. package/src/todolist.js +0 -37
  265. package/theme/documentlist.css +0 -8
  266. package/theme/list.css +0 -40
  267. package/theme/listformatting.css +0 -66
  268. package/theme/listproperties.css +0 -10
  269. package/theme/liststyles.css +0 -8
  270. package/theme/todolist.css +0 -140
  271. /package/{src → dist}/augmentation.d.ts +0 -0
  272. /package/{src → dist}/index.d.ts +0 -0
  273. /package/{src → dist}/legacyerrors.d.ts +0 -0
  274. /package/{src → dist}/listproperties/utils/config.d.ts +0 -0
  275. /package/{src → dist}/listproperties/utils/style.d.ts +0 -0
@@ -1,111 +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 { Command } from 'ckeditor5/src/core.js';
6
- import { first } from 'ckeditor5/src/utils.js';
7
- /**
8
- * The list indent command. It is used by the {@link module:list/legacylist~LegacyList legacy list feature}.
9
- */
10
- export class LegacyIndentCommand extends Command {
11
- /**
12
- * Determines by how much the command will change the list item's indent attribute.
13
- */
14
- _indentBy;
15
- /**
16
- * Creates an instance of the command.
17
- *
18
- * @param editor The editor instance.
19
- * @param indentDirection The direction of indent. If it is equal to `backward`, the command will outdent a list item.
20
- */
21
- constructor(editor, indentDirection) {
22
- super(editor);
23
- this._indentBy = indentDirection == 'forward' ? 1 : -1;
24
- }
25
- /**
26
- * @inheritDoc
27
- */
28
- refresh() {
29
- this.isEnabled = this._checkEnabled();
30
- }
31
- /**
32
- * Indents or outdents (depending on the {@link #constructor}'s `indentDirection` parameter) selected list items.
33
- *
34
- * @fires execute
35
- */
36
- execute() {
37
- const model = this.editor.model;
38
- const doc = model.document;
39
- let itemsToChange = Array.from(doc.selection.getSelectedBlocks());
40
- model.change(writer => {
41
- const lastItem = itemsToChange[itemsToChange.length - 1];
42
- // Indenting a list item should also indent all the items that are already sub-items of indented item.
43
- let next = lastItem.nextSibling;
44
- // Check all items after last indented item, as long as their indent is bigger than indent of that item.
45
- while (next && next.name == 'listItem' &&
46
- next.getAttribute('listIndent') > lastItem.getAttribute('listIndent')) {
47
- itemsToChange.push(next);
48
- next = next.nextSibling;
49
- }
50
- // We need to be sure to keep model in correct state after each small change, because converters
51
- // bases on that state and assumes that model is correct.
52
- // Because of that, if the command outdents items, we will outdent them starting from the last item, as
53
- // it is safer.
54
- if (this._indentBy < 0) {
55
- itemsToChange = itemsToChange.reverse();
56
- }
57
- for (const item of itemsToChange) {
58
- const indent = item.getAttribute('listIndent') + this._indentBy;
59
- // If indent is lower than 0, it means that the item got outdented when it was not indented.
60
- // This means that we need to convert that list item to paragraph.
61
- if (indent < 0) {
62
- // To keep the model as correct as possible, first rename listItem, then remove attributes,
63
- // as listItem without attributes is very incorrect and will cause problems in converters.
64
- // No need to remove attributes, will be removed by post fixer.
65
- writer.rename(item, 'paragraph');
66
- }
67
- // If indent is >= 0, change the attribute value.
68
- else {
69
- writer.setAttribute('listIndent', indent, item);
70
- }
71
- }
72
- // It allows to execute an action after executing the `~IndentCommand#execute` method, for example adjusting
73
- // attributes of changed list items.
74
- this.fire('_executeCleanup', itemsToChange);
75
- });
76
- }
77
- /**
78
- * Checks whether the command can be enabled in the current context.
79
- *
80
- * @returns Whether the command should be enabled.
81
- */
82
- _checkEnabled() {
83
- // Check whether any of position's ancestor is a list item.
84
- const listItem = first(this.editor.model.document.selection.getSelectedBlocks());
85
- // If selection is not in a list item, the command is disabled.
86
- if (!listItem || !listItem.is('element', 'listItem')) {
87
- return false;
88
- }
89
- if (this._indentBy > 0) {
90
- // Cannot indent first item in it's list. Check if before `listItem` is a list item that is in same list.
91
- // To be in the same list, the item has to have same attributes and cannot be "split" by an item with lower indent.
92
- const indent = listItem.getAttribute('listIndent');
93
- const type = listItem.getAttribute('listType');
94
- let prev = listItem.previousSibling;
95
- while (prev && prev.is('element', 'listItem') && prev.getAttribute('listIndent') >= indent) {
96
- if (prev.getAttribute('listIndent') == indent) {
97
- // The item is on the same level.
98
- // If it has same type, it means that we found a preceding sibling from the same list.
99
- // If it does not have same type, it means that `listItem` is on different list (this can happen only
100
- // on top level lists, though).
101
- return prev.getAttribute('listType') == type;
102
- }
103
- prev = prev.previousSibling;
104
- }
105
- // Could not find similar list item, this means that `listItem` is first in its list.
106
- return false;
107
- }
108
- // If we are outdenting it is enough to be in list item. Every list item can always be outdented.
109
- return true;
110
- }
111
- }
@@ -1,278 +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 { Command } from 'ckeditor5/src/core.js';
6
- import { first } from 'ckeditor5/src/utils.js';
7
- /**
8
- * The list command. It is used by the {@link module:list/legacylist~LegacyList legacy list feature}.
9
- */
10
- export class LegacyListCommand extends Command {
11
- /**
12
- * The type of the list created by the command.
13
- */
14
- type;
15
- /**
16
- * Creates an instance of the command.
17
- *
18
- * @param editor The editor instance.
19
- * @param type List type that will be handled by this command.
20
- */
21
- constructor(editor, type) {
22
- super(editor);
23
- this.type = type;
24
- }
25
- /**
26
- * @inheritDoc
27
- */
28
- refresh() {
29
- this.value = this._getValue();
30
- this.isEnabled = this._checkEnabled();
31
- }
32
- /**
33
- * Executes the list command.
34
- *
35
- * @fires execute
36
- * @param options Command options.
37
- * @param options.forceValue If set, it will force the command behavior. If `true`, the command will try to convert the
38
- * selected items and potentially the neighbor elements to the proper list items. If set to `false`, it will convert selected elements
39
- * to paragraphs. If not set, the command will toggle selected elements to list items or paragraphs, depending on the selection.
40
- */
41
- execute(options = {}) {
42
- const model = this.editor.model;
43
- const document = model.document;
44
- const blocks = Array.from(document.selection.getSelectedBlocks())
45
- .filter(block => checkCanBecomeListItem(block, model.schema));
46
- // Whether we are turning off some items.
47
- const turnOff = options.forceValue !== undefined ? !options.forceValue : this.value;
48
- // If we are turning off items, we are going to rename them to paragraphs.
49
- model.change(writer => {
50
- // If part of a list got turned off, we need to handle (outdent) all of sub-items of the last turned-off item.
51
- // To be sure that model is all the time in a good state, we first fix items below turned-off item.
52
- if (turnOff) {
53
- // Start from the model item that is just after the last turned-off item.
54
- let next = blocks[blocks.length - 1].nextSibling;
55
- let currentIndent = Number.POSITIVE_INFINITY;
56
- let changes = [];
57
- // Correct indent of all items after the last turned off item.
58
- // Rules that should be followed:
59
- // 1. All direct sub-items of turned-off item should become indent 0, because the first item after it
60
- // will be the first item of a new list. Other items are at the same level, so should have same 0 index.
61
- // 2. All items with indent lower than indent of turned-off item should become indent 0, because they
62
- // should not end up as a child of any of list items that they were not children of before.
63
- // 3. All other items should have their indent changed relatively to it's parent.
64
- //
65
- // For example:
66
- // 1 * --------
67
- // 2 * --------
68
- // 3 * -------- <-- this is turned off.
69
- // 4 * -------- <-- this has to become indent = 0, because it will be first item on a new list.
70
- // 5 * -------- <-- this should be still be a child of item above, so indent = 1.
71
- // 6 * -------- <-- this has to become indent = 0, because it should not be a child of any of items above.
72
- // 7 * -------- <-- this should be still be a child of item above, so indent = 1.
73
- // 8 * -------- <-- this has to become indent = 0.
74
- // 9 * -------- <-- this should still be a child of item above, so indent = 1.
75
- // 10 * -------- <-- this should still be a child of item above, so indent = 2.
76
- // 11 * -------- <-- this should still be at the same level as item above, so indent = 2.
77
- // 12 * -------- <-- this and all below are left unchanged.
78
- // 13 * --------
79
- // 14 * --------
80
- //
81
- // After turning off 3 the list becomes:
82
- //
83
- // 1 * --------
84
- // 2 * --------
85
- //
86
- // 3 --------
87
- //
88
- // 4 * --------
89
- // 5 * --------
90
- // 6 * --------
91
- // 7 * --------
92
- // 8 * --------
93
- // 9 * --------
94
- // 10 * --------
95
- // 11 * --------
96
- // 12 * --------
97
- // 13 * --------
98
- // 14 * --------
99
- //
100
- // Thanks to this algorithm no lists are mismatched and no items get unexpected children/parent, while
101
- // those parent-child connection which are possible to maintain are still maintained. It's worth noting
102
- // that this is the same effect that we would be get by multiple use of outdent command. However doing
103
- // it like this is much more efficient because it's less operation (less memory usage, easier OT) and
104
- // less conversion (faster).
105
- while (next && next.name == 'listItem' && next.getAttribute('listIndent') !== 0) {
106
- // Check each next list item, as long as its indent is bigger than 0.
107
- // If the indent is 0 we are not going to change anything anyway.
108
- const indent = next.getAttribute('listIndent');
109
- // We check if that's item indent is lower as current relative indent.
110
- if (indent < currentIndent) {
111
- // If it is, current relative indent becomes that indent.
112
- currentIndent = indent;
113
- }
114
- // Fix indent relatively to current relative indent.
115
- // Note, that if we just changed the current relative indent, the newIndent will be equal to 0.
116
- const newIndent = indent - currentIndent;
117
- // Save the entry in changes array. We do not apply it at the moment, because we will need to
118
- // reverse the changes so the last item is changed first.
119
- // This is to keep model in correct state all the time.
120
- changes.push({ element: next, listIndent: newIndent });
121
- // Find next item.
122
- next = next.nextSibling;
123
- }
124
- changes = changes.reverse();
125
- for (const item of changes) {
126
- writer.setAttribute('listIndent', item.listIndent, item.element);
127
- }
128
- }
129
- // If we are turning on, we might change some items that are already `listItem`s but with different type.
130
- // Changing one nested list item to other type should also trigger changing all its siblings so the
131
- // whole nested list is of the same type.
132
- // Example (assume changing to numbered list):
133
- // * ------ <-- do not fix, top level item
134
- // * ------ <-- fix, because latter list item of this item's list is changed
135
- // * ------ <-- do not fix, item is not affected (different list)
136
- // * ------ <-- fix, because latter list item of this item's list is changed
137
- // * ------ <-- fix, because latter list item of this item's list is changed
138
- // * ---[-- <-- already in selection
139
- // * ------ <-- already in selection
140
- // * ------ <-- already in selection
141
- // * ------ <-- already in selection, but does not cause other list items to change because is top-level
142
- // * ---]-- <-- already in selection
143
- // * ------ <-- fix, because preceding list item of this item's list is changed
144
- // * ------ <-- do not fix, item is not affected (different list)
145
- // * ------ <-- do not fix, top level item
146
- if (!turnOff) {
147
- // Find lowest indent among selected items. This will be indicator what is the indent of
148
- // top-most list affected by the command.
149
- let lowestIndent = Number.POSITIVE_INFINITY;
150
- for (const item of blocks) {
151
- if (item.is('element', 'listItem') && item.getAttribute('listIndent') < lowestIndent) {
152
- lowestIndent = item.getAttribute('listIndent');
153
- }
154
- }
155
- // Do not execute the fix for top-level lists.
156
- lowestIndent = lowestIndent === 0 ? 1 : lowestIndent;
157
- // Fix types of list items that are "before" the selected blocks.
158
- _fixType(blocks, true, lowestIndent);
159
- // Fix types of list items that are "after" the selected blocks.
160
- _fixType(blocks, false, lowestIndent);
161
- }
162
- // Phew! Now it will be easier :).
163
- // For each block element that was in the selection, we will either: turn it to list item,
164
- // turn it to paragraph, or change it's type. Or leave it as it is.
165
- // Do it in reverse as there might be multiple blocks (same as with changing indents).
166
- for (const element of blocks.reverse()) {
167
- if (turnOff && element.name == 'listItem') {
168
- // We are turning off and the element is a `listItem` - it should be converted to `paragraph`.
169
- // List item specific attributes are removed by post fixer.
170
- writer.rename(element, 'paragraph');
171
- }
172
- else if (!turnOff && element.name != 'listItem') {
173
- // We are turning on and the element is not a `listItem` - it should be converted to `listItem`.
174
- // The order of operations is important to keep model in correct state.
175
- writer.setAttributes({ listType: this.type, listIndent: 0 }, element);
176
- writer.rename(element, 'listItem');
177
- }
178
- else if (!turnOff && element.name == 'listItem' && element.getAttribute('listType') != this.type) {
179
- // We are turning on and the element is a `listItem` but has different type - change it's type and
180
- // type of it's all siblings that have same indent.
181
- writer.setAttribute('listType', this.type, element);
182
- }
183
- }
184
- /**
185
- * Event fired by the {@link #execute} method.
186
- *
187
- * It allows to execute an action after executing the {@link ~ListCommand#execute} method, for example adjusting
188
- * attributes of changed blocks.
189
- *
190
- * @protected
191
- * @event _executeCleanup
192
- */
193
- this.fire('_executeCleanup', blocks);
194
- });
195
- }
196
- /**
197
- * Checks the command's {@link #value}.
198
- *
199
- * @returns The current value.
200
- */
201
- _getValue() {
202
- // Check whether closest `listItem` ancestor of the position has a correct type.
203
- const listItem = first(this.editor.model.document.selection.getSelectedBlocks());
204
- return !!listItem && listItem.is('element', 'listItem') && listItem.getAttribute('listType') == this.type;
205
- }
206
- /**
207
- * Checks whether the command can be enabled in the current context.
208
- *
209
- * @returns Whether the command should be enabled.
210
- */
211
- _checkEnabled() {
212
- // If command value is true it means that we are in list item, so the command should be enabled.
213
- if (this.value) {
214
- return true;
215
- }
216
- const selection = this.editor.model.document.selection;
217
- const schema = this.editor.model.schema;
218
- const firstBlock = first(selection.getSelectedBlocks());
219
- if (!firstBlock) {
220
- return false;
221
- }
222
- // Otherwise, check if list item can be inserted at the position start.
223
- return checkCanBecomeListItem(firstBlock, schema);
224
- }
225
- }
226
- /**
227
- * Helper function used when one or more list item have their type changed. Fixes type of other list items
228
- * that are affected by the change (are in same lists) but are not directly in selection. The function got extracted
229
- * not to duplicated code, as same fix has to be performed before and after selection.
230
- *
231
- * @param blocks Blocks that are in selection.
232
- * @param isBackward Specified whether fix will be applied for blocks before first selected block (`true`)
233
- * or blocks after last selected block (`false`).
234
- * @param lowestIndent Lowest indent among selected blocks.
235
- */
236
- function _fixType(blocks, isBackward, lowestIndent) {
237
- // We need to check previous sibling of first changed item and next siblings of last changed item.
238
- const startingItem = isBackward ? blocks[0] : blocks[blocks.length - 1];
239
- if (startingItem.is('element', 'listItem')) {
240
- let item = startingItem[isBackward ? 'previousSibling' : 'nextSibling'];
241
- // During processing items, keeps the lowest indent of already processed items.
242
- // This saves us from changing too many items.
243
- // Following example is for going forward as it is easier to read, however same applies to going backward.
244
- // * ------
245
- // * ------
246
- // * --[---
247
- // * ------ <-- `lowestIndent` should be 1
248
- // * --]--- <-- `startingItem`, `currentIndent` = 2, `lowestIndent` == 1
249
- // * ------ <-- should be fixed, `indent` == 2 == `currentIndent`
250
- // * ------ <-- should be fixed, set `currentIndent` to 1, `indent` == 1 == `currentIndent`
251
- // * ------ <-- should not be fixed, item is in different list, `indent` = 2, `indent` != `currentIndent`
252
- // * ------ <-- should be fixed, `indent` == 1 == `currentIndent`
253
- // * ------ <-- break loop (`indent` < `lowestIndent`)
254
- let currentIndent = startingItem.getAttribute('listIndent');
255
- // Look back until a list item with indent lower than reference `lowestIndent`.
256
- // That would be the parent of nested sublist which contains item having `lowestIndent`.
257
- while (item && item.is('element', 'listItem') && item.getAttribute('listIndent') >= lowestIndent) {
258
- if (currentIndent > item.getAttribute('listIndent')) {
259
- currentIndent = item.getAttribute('listIndent');
260
- }
261
- // Found an item that is in the same nested sublist.
262
- if (item.getAttribute('listIndent') == currentIndent) {
263
- // Just add the item to selected blocks like it was selected by the user.
264
- blocks[isBackward ? 'unshift' : 'push'](item);
265
- }
266
- item = item[isBackward ? 'previousSibling' : 'nextSibling'];
267
- }
268
- }
269
- }
270
- /**
271
- * Checks whether the given block can be replaced by a listItem.
272
- *
273
- * @param block A block to be tested.
274
- * @param schema The schema of the document.
275
- */
276
- function checkCanBecomeListItem(block, schema) {
277
- return schema.checkChild(block.parent, 'listItem') && !schema.isObject(block);
278
- }
@@ -1,167 +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
- /**
6
- * @module list/legacylist/legacylistediting
7
- */
8
- import { LegacyListCommand } from './legacylistcommand.js';
9
- import { LegacyIndentCommand } from './legacyindentcommand.js';
10
- import { LegacyListUtils } from './legacylistutils.js';
11
- import { Plugin } from 'ckeditor5/src/core.js';
12
- import { Enter } from 'ckeditor5/src/enter.js';
13
- import { Delete } from 'ckeditor5/src/typing.js';
14
- import { cleanList, cleanListItem, modelViewInsertion, modelViewChangeType, modelViewMergeAfterChangeType, modelViewMergeAfter, modelViewRemove, modelViewSplitOnInsert, modelViewChangeIndent, modelChangePostFixer, modelIndentPasteFixer, viewModelConverter, modelToViewPosition, viewToModelPosition } from './legacyconverters.js';
15
- import '../../theme/list.css';
16
- /**
17
- * The engine of the list feature. It handles creating, editing and removing lists and list items.
18
- *
19
- * It registers the `'numberedList'`, `'bulletedList'`, `'indentList'` and `'outdentList'` commands.
20
- */
21
- export class LegacyListEditing extends Plugin {
22
- /**
23
- * @inheritDoc
24
- */
25
- static get pluginName() {
26
- return 'LegacyListEditing';
27
- }
28
- /**
29
- * @inheritDoc
30
- */
31
- static get isOfficialPlugin() {
32
- return true;
33
- }
34
- /**
35
- * @inheritDoc
36
- */
37
- static get requires() {
38
- return [Enter, Delete, LegacyListUtils];
39
- }
40
- /**
41
- * @inheritDoc
42
- */
43
- init() {
44
- const editor = this.editor;
45
- // Schema.
46
- // Note: in case `$block` will ever be allowed in `listItem`, keep in mind that this feature
47
- // uses `Selection#getSelectedBlocks()` without any additional processing to obtain all selected list items.
48
- // If there are blocks allowed inside list item, algorithms using `getSelectedBlocks()` will have to be modified.
49
- editor.model.schema.register('listItem', {
50
- inheritAllFrom: '$block',
51
- allowAttributes: ['listType', 'listIndent']
52
- });
53
- // Converters.
54
- const data = editor.data;
55
- const editing = editor.editing;
56
- editor.model.document.registerPostFixer(writer => modelChangePostFixer(editor.model, writer));
57
- editing.mapper.registerViewToModelLength('li', getViewListItemLength);
58
- data.mapper.registerViewToModelLength('li', getViewListItemLength);
59
- editing.mapper.on('modelToViewPosition', modelToViewPosition(editing.view));
60
- editing.mapper.on('viewToModelPosition', viewToModelPosition(editor.model));
61
- data.mapper.on('modelToViewPosition', modelToViewPosition(editing.view));
62
- editor.conversion.for('editingDowncast')
63
- .add(dispatcher => {
64
- dispatcher.on('insert', modelViewSplitOnInsert, { priority: 'high' });
65
- dispatcher.on('insert:listItem', modelViewInsertion(editor.model));
66
- dispatcher.on('attribute:listType:listItem', modelViewChangeType, { priority: 'high' });
67
- dispatcher.on('attribute:listType:listItem', modelViewMergeAfterChangeType, { priority: 'low' });
68
- dispatcher.on('attribute:listIndent:listItem', modelViewChangeIndent(editor.model));
69
- dispatcher.on('remove:listItem', modelViewRemove(editor.model));
70
- dispatcher.on('remove', modelViewMergeAfter, { priority: 'low' });
71
- });
72
- editor.conversion.for('dataDowncast')
73
- .add(dispatcher => {
74
- dispatcher.on('insert', modelViewSplitOnInsert, { priority: 'high' });
75
- dispatcher.on('insert:listItem', modelViewInsertion(editor.model));
76
- });
77
- editor.conversion.for('upcast')
78
- .add(dispatcher => {
79
- dispatcher.on('element:ul', cleanList, { priority: 'high' });
80
- dispatcher.on('element:ol', cleanList, { priority: 'high' });
81
- dispatcher.on('element:li', cleanListItem, { priority: 'high' });
82
- dispatcher.on('element:li', viewModelConverter);
83
- });
84
- // Fix indentation of pasted items.
85
- editor.model.on('insertContent', modelIndentPasteFixer, { priority: 'high' });
86
- // Register commands for numbered and bulleted list.
87
- editor.commands.add('numberedList', new LegacyListCommand(editor, 'numbered'));
88
- editor.commands.add('bulletedList', new LegacyListCommand(editor, 'bulleted'));
89
- // Register commands for indenting.
90
- editor.commands.add('indentList', new LegacyIndentCommand(editor, 'forward'));
91
- editor.commands.add('outdentList', new LegacyIndentCommand(editor, 'backward'));
92
- const viewDocument = editing.view.document;
93
- // Overwrite default Enter key behavior.
94
- // If Enter key is pressed with selection collapsed in empty list item, outdent it instead of breaking it.
95
- this.listenTo(viewDocument, 'enter', (evt, data) => {
96
- const doc = this.editor.model.document;
97
- const positionParent = doc.selection.getLastPosition().parent;
98
- if (doc.selection.isCollapsed && positionParent.name == 'listItem' && positionParent.isEmpty) {
99
- this.editor.execute('outdentList');
100
- data.preventDefault();
101
- evt.stop();
102
- }
103
- }, { context: 'li' });
104
- // Overwrite default Backspace key behavior.
105
- // If Backspace key is pressed with selection collapsed on first position in first list item, outdent it. #83
106
- this.listenTo(viewDocument, 'delete', (evt, data) => {
107
- // Check conditions from those that require less computations like those immediately available.
108
- if (data.direction !== 'backward') {
109
- return;
110
- }
111
- const selection = this.editor.model.document.selection;
112
- if (!selection.isCollapsed) {
113
- return;
114
- }
115
- const firstPosition = selection.getFirstPosition();
116
- if (!firstPosition.isAtStart) {
117
- return;
118
- }
119
- const positionParent = firstPosition.parent;
120
- if (positionParent.name !== 'listItem') {
121
- return;
122
- }
123
- const previousIsAListItem = positionParent.previousSibling && positionParent.previousSibling.name === 'listItem';
124
- if (previousIsAListItem) {
125
- return;
126
- }
127
- this.editor.execute('outdentList');
128
- data.preventDefault();
129
- evt.stop();
130
- }, { context: 'li' });
131
- this.listenTo(editor.editing.view.document, 'tab', (evt, data) => {
132
- const commandName = data.shiftKey ? 'outdentList' : 'indentList';
133
- const command = this.editor.commands.get(commandName);
134
- if (command.isEnabled) {
135
- editor.execute(commandName);
136
- data.stopPropagation();
137
- data.preventDefault();
138
- evt.stop();
139
- }
140
- }, { context: 'li' });
141
- }
142
- /**
143
- * @inheritDoc
144
- */
145
- afterInit() {
146
- const commands = this.editor.commands;
147
- const indent = commands.get('indent');
148
- const outdent = commands.get('outdent');
149
- if (indent) {
150
- indent.registerChildCommand(commands.get('indentList'));
151
- }
152
- if (outdent) {
153
- outdent.registerChildCommand(commands.get('outdentList'));
154
- }
155
- }
156
- }
157
- function getViewListItemLength(element) {
158
- let length = 1;
159
- for (const child of element.getChildren()) {
160
- if (child.name == 'ul' || child.name == 'ol') {
161
- for (const item of child.getChildren()) {
162
- length += getViewListItemLength(item);
163
- }
164
- }
165
- }
166
- return length;
167
- }
@@ -1,52 +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 { Plugin } from 'ckeditor5/src/core.js';
6
- import { getListTypeFromListStyleType, getSelectedListItems, getSiblingNodes } from './legacyutils.js';
7
- /**
8
- * A set of helpers related to legacy lists.
9
- */
10
- export class LegacyListUtils extends Plugin {
11
- /**
12
- * @inheritDoc
13
- */
14
- static get pluginName() {
15
- return 'LegacyListUtils';
16
- }
17
- /**
18
- * @inheritDoc
19
- */
20
- static get isOfficialPlugin() {
21
- return true;
22
- }
23
- /**
24
- * Checks whether the given list-style-type is supported by numbered or bulleted list.
25
- */
26
- getListTypeFromListStyleType(listStyleType) {
27
- return getListTypeFromListStyleType(listStyleType);
28
- }
29
- /**
30
- * Returns an array with all `listItem` elements in the model selection.
31
- *
32
- * It returns all the items even if only a part of the list is selected, including items that belong to nested lists.
33
- * If no list is selected, it returns an empty array.
34
- * The order of the elements is not specified.
35
- */
36
- getSelectedListItems(model) {
37
- return getSelectedListItems(model);
38
- }
39
- /**
40
- * Returns an array with all `listItem` elements that represent the same list.
41
- *
42
- * It means that values of `listIndent`, `listType`, `listStyle`, `listReversed` and `listStart` for all items are equal.
43
- *
44
- * Additionally, if the `position` is inside a list item, that list item will be returned as well.
45
- *
46
- * @param position Starting position.
47
- * @param direction Walking direction.
48
- */
49
- getSiblingNodes(position, direction) {
50
- return getSiblingNodes(position, direction);
51
- }
52
- }