@ckeditor/ckeditor5-indent 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 (183) hide show
  1. package/ckeditor5-metadata.json +9 -21
  2. package/{src → dist}/indent.d.ts +1 -1
  3. package/{src → dist}/indentblock.d.ts +1 -1
  4. package/{src → dist}/indentblockcommand.d.ts +1 -1
  5. package/dist/indentcommandbehavior/resetindentusingclasses.d.ts +24 -0
  6. package/dist/indentcommandbehavior/resetindentusingoffset.d.ts +24 -0
  7. package/{src → dist}/indentediting.d.ts +1 -1
  8. package/{src → dist}/indentui.d.ts +1 -1
  9. package/dist/index.css +3 -0
  10. package/dist/index.css.map +1 -0
  11. package/dist/index.js +82 -114
  12. package/dist/index.js.map +1 -1
  13. package/{src → dist}/integrations/indentblocklistcommand.d.ts +1 -1
  14. package/{src → dist}/integrations/indentblocklistintegration.d.ts +4 -12
  15. package/{src → dist}/integrations/indentblocklistitemcommand.d.ts +1 -8
  16. package/package.json +25 -48
  17. package/build/indent.js +0 -5
  18. package/build/translations/af.js +0 -1
  19. package/build/translations/ar.js +0 -1
  20. package/build/translations/ast.js +0 -1
  21. package/build/translations/az.js +0 -1
  22. package/build/translations/be.js +0 -1
  23. package/build/translations/bg.js +0 -1
  24. package/build/translations/bn.js +0 -1
  25. package/build/translations/bs.js +0 -1
  26. package/build/translations/ca.js +0 -1
  27. package/build/translations/cs.js +0 -1
  28. package/build/translations/da.js +0 -1
  29. package/build/translations/de-ch.js +0 -1
  30. package/build/translations/de.js +0 -1
  31. package/build/translations/el.js +0 -1
  32. package/build/translations/en-au.js +0 -1
  33. package/build/translations/en-gb.js +0 -1
  34. package/build/translations/eo.js +0 -1
  35. package/build/translations/es-co.js +0 -1
  36. package/build/translations/es.js +0 -1
  37. package/build/translations/et.js +0 -1
  38. package/build/translations/eu.js +0 -1
  39. package/build/translations/fa.js +0 -1
  40. package/build/translations/fi.js +0 -1
  41. package/build/translations/fr.js +0 -1
  42. package/build/translations/gl.js +0 -1
  43. package/build/translations/gu.js +0 -1
  44. package/build/translations/he.js +0 -1
  45. package/build/translations/hi.js +0 -1
  46. package/build/translations/hr.js +0 -1
  47. package/build/translations/hu.js +0 -1
  48. package/build/translations/hy.js +0 -1
  49. package/build/translations/id.js +0 -1
  50. package/build/translations/it.js +0 -1
  51. package/build/translations/ja.js +0 -1
  52. package/build/translations/jv.js +0 -1
  53. package/build/translations/kk.js +0 -1
  54. package/build/translations/km.js +0 -1
  55. package/build/translations/kn.js +0 -1
  56. package/build/translations/ko.js +0 -1
  57. package/build/translations/ku.js +0 -1
  58. package/build/translations/lt.js +0 -1
  59. package/build/translations/lv.js +0 -1
  60. package/build/translations/ms.js +0 -1
  61. package/build/translations/nb.js +0 -1
  62. package/build/translations/ne.js +0 -1
  63. package/build/translations/nl.js +0 -1
  64. package/build/translations/no.js +0 -1
  65. package/build/translations/oc.js +0 -1
  66. package/build/translations/pl.js +0 -1
  67. package/build/translations/pt-br.js +0 -1
  68. package/build/translations/pt.js +0 -1
  69. package/build/translations/ro.js +0 -1
  70. package/build/translations/ru.js +0 -1
  71. package/build/translations/si.js +0 -1
  72. package/build/translations/sk.js +0 -1
  73. package/build/translations/sl.js +0 -1
  74. package/build/translations/sq.js +0 -1
  75. package/build/translations/sr-latn.js +0 -1
  76. package/build/translations/sr.js +0 -1
  77. package/build/translations/sv.js +0 -1
  78. package/build/translations/th.js +0 -1
  79. package/build/translations/ti.js +0 -1
  80. package/build/translations/tk.js +0 -1
  81. package/build/translations/tr.js +0 -1
  82. package/build/translations/tt.js +0 -1
  83. package/build/translations/ug.js +0 -1
  84. package/build/translations/uk.js +0 -1
  85. package/build/translations/ur.js +0 -1
  86. package/build/translations/uz.js +0 -1
  87. package/build/translations/vi.js +0 -1
  88. package/build/translations/zh-cn.js +0 -1
  89. package/build/translations/zh.js +0 -1
  90. package/lang/contexts.json +0 -4
  91. package/lang/translations/af.po +0 -20
  92. package/lang/translations/ar.po +0 -20
  93. package/lang/translations/ast.po +0 -20
  94. package/lang/translations/az.po +0 -20
  95. package/lang/translations/be.po +0 -20
  96. package/lang/translations/bg.po +0 -20
  97. package/lang/translations/bn.po +0 -20
  98. package/lang/translations/bs.po +0 -20
  99. package/lang/translations/ca.po +0 -20
  100. package/lang/translations/cs.po +0 -20
  101. package/lang/translations/da.po +0 -20
  102. package/lang/translations/de-ch.po +0 -20
  103. package/lang/translations/de.po +0 -20
  104. package/lang/translations/el.po +0 -20
  105. package/lang/translations/en-au.po +0 -20
  106. package/lang/translations/en-gb.po +0 -20
  107. package/lang/translations/en.po +0 -20
  108. package/lang/translations/eo.po +0 -20
  109. package/lang/translations/es-co.po +0 -20
  110. package/lang/translations/es.po +0 -20
  111. package/lang/translations/et.po +0 -20
  112. package/lang/translations/eu.po +0 -20
  113. package/lang/translations/fa.po +0 -20
  114. package/lang/translations/fi.po +0 -20
  115. package/lang/translations/fr.po +0 -20
  116. package/lang/translations/gl.po +0 -20
  117. package/lang/translations/gu.po +0 -20
  118. package/lang/translations/he.po +0 -20
  119. package/lang/translations/hi.po +0 -20
  120. package/lang/translations/hr.po +0 -20
  121. package/lang/translations/hu.po +0 -20
  122. package/lang/translations/hy.po +0 -20
  123. package/lang/translations/id.po +0 -20
  124. package/lang/translations/it.po +0 -20
  125. package/lang/translations/ja.po +0 -20
  126. package/lang/translations/jv.po +0 -20
  127. package/lang/translations/kk.po +0 -20
  128. package/lang/translations/km.po +0 -20
  129. package/lang/translations/kn.po +0 -20
  130. package/lang/translations/ko.po +0 -20
  131. package/lang/translations/ku.po +0 -20
  132. package/lang/translations/lt.po +0 -20
  133. package/lang/translations/lv.po +0 -20
  134. package/lang/translations/ms.po +0 -20
  135. package/lang/translations/nb.po +0 -20
  136. package/lang/translations/ne.po +0 -20
  137. package/lang/translations/nl.po +0 -20
  138. package/lang/translations/no.po +0 -20
  139. package/lang/translations/oc.po +0 -20
  140. package/lang/translations/pl.po +0 -20
  141. package/lang/translations/pt-br.po +0 -20
  142. package/lang/translations/pt.po +0 -20
  143. package/lang/translations/ro.po +0 -20
  144. package/lang/translations/ru.po +0 -20
  145. package/lang/translations/si.po +0 -20
  146. package/lang/translations/sk.po +0 -20
  147. package/lang/translations/sl.po +0 -20
  148. package/lang/translations/sq.po +0 -20
  149. package/lang/translations/sr-latn.po +0 -20
  150. package/lang/translations/sr.po +0 -20
  151. package/lang/translations/sv.po +0 -20
  152. package/lang/translations/th.po +0 -20
  153. package/lang/translations/ti.po +0 -20
  154. package/lang/translations/tk.po +0 -20
  155. package/lang/translations/tr.po +0 -20
  156. package/lang/translations/tt.po +0 -20
  157. package/lang/translations/ug.po +0 -20
  158. package/lang/translations/uk.po +0 -20
  159. package/lang/translations/ur.po +0 -20
  160. package/lang/translations/uz.po +0 -20
  161. package/lang/translations/vi.po +0 -20
  162. package/lang/translations/zh-cn.po +0 -20
  163. package/lang/translations/zh.po +0 -20
  164. package/src/augmentation.js +0 -5
  165. package/src/indent.js +0 -50
  166. package/src/indentblock.js +0 -160
  167. package/src/indentblockcommand.js +0 -102
  168. package/src/indentcommandbehavior/indentbehavior.js +0 -5
  169. package/src/indentcommandbehavior/indentusingclasses.js +0 -51
  170. package/src/indentcommandbehavior/indentusingoffset.js +0 -59
  171. package/src/indentconfig.js +0 -5
  172. package/src/indentediting.js +0 -38
  173. package/src/indentui.js +0 -79
  174. package/src/index.js +0 -18
  175. package/src/integrations/indentblocklistcommand.js +0 -108
  176. package/src/integrations/indentblocklistintegration.js +0 -328
  177. package/src/integrations/indentblocklistitemcommand.js +0 -96
  178. /package/{src → dist}/augmentation.d.ts +0 -0
  179. /package/{src → dist}/indentcommandbehavior/indentbehavior.d.ts +0 -0
  180. /package/{src → dist}/indentcommandbehavior/indentusingclasses.d.ts +0 -0
  181. /package/{src → dist}/indentcommandbehavior/indentusingoffset.d.ts +0 -0
  182. /package/{src → dist}/indentconfig.d.ts +0 -0
  183. /package/{src → dist}/index.d.ts +0 -0
@@ -5,17 +5,17 @@
5
5
  "className": "Indent",
6
6
  "description": "Implements the core of the indent feature. It requires compatible plugins, such as indent block or list, to work.",
7
7
  "docs": "features/indent.html",
8
- "path": "src/indent.js",
8
+ "path": "src/indent.ts",
9
9
  "uiComponents": [
10
10
  {
11
11
  "type": "Button",
12
12
  "name": "indent",
13
- "iconPath": "@ckeditor/ckeditor5-icons/theme/icons/indent.svg"
13
+ "iconName": "IconIndent"
14
14
  },
15
15
  {
16
16
  "type": "Button",
17
17
  "name": "outdent",
18
- "iconPath": "@ckeditor/ckeditor5-icons/theme/icons/outdent.svg"
18
+ "iconName": "IconOutdent"
19
19
  }
20
20
  ]
21
21
  },
@@ -24,7 +24,7 @@
24
24
  "className": "IndentBlock",
25
25
  "description": "The indent block feature, together with the indent feature, controls the indentation of elements such as paragraphs and headings.",
26
26
  "docs": "features/indent.html",
27
- "path": "src/indentblock.js",
27
+ "path": "src/indentblock.ts",
28
28
  "requires": [
29
29
  "Indent"
30
30
  ],
@@ -50,7 +50,7 @@
50
50
  "className": "IndentBlockListIntegration",
51
51
  "description": "Provides block indentation integration for lists, enabling indent and outdent of lists and list items.",
52
52
  "docs": "features/indent.html",
53
- "path": "src/integrations/indentblocklistintegration.js",
53
+ "path": "src/integrations/indentblocklistintegration.ts",
54
54
  "requires": [
55
55
  "IndentBlock"
56
56
  ],
@@ -58,7 +58,8 @@
58
58
  {
59
59
  "elements": [
60
60
  "ol",
61
- "ul"
61
+ "ul",
62
+ "li"
62
63
  ],
63
64
  "styles": [
64
65
  "margin-left",
@@ -66,28 +67,15 @@
66
67
  ],
67
68
  "_comment": "By default, the plugin uses inline styles for indentation."
68
69
  },
69
- {
70
- "elements": "li",
71
- "styles": [
72
- "margin-left",
73
- "margin-right"
74
- ],
75
- "_comment": "By default, the plugin uses inline styles for indentation."
76
- },
77
70
  {
78
71
  "elements": [
79
72
  "ol",
80
- "ul"
73
+ "ul",
74
+ "li"
81
75
  ],
82
76
  "classes": "*",
83
77
  "isAlternative": true,
84
78
  "_comment": "If classes are defined in `config.indentBlock.classes`, they are used instead of inline styles."
85
- },
86
- {
87
- "elements": "li",
88
- "classes": "*",
89
- "isAlternative": true,
90
- "_comment": "If classes are defined in `config.indentBlock.classes`, they are used instead of inline styles."
91
79
  }
92
80
  ]
93
81
  }
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * @module indent/indent
7
7
  */
8
- import { Plugin } from 'ckeditor5/src/core.js';
8
+ import { Plugin } from '@ckeditor/ckeditor5-core';
9
9
  import { IndentEditing } from './indentediting.js';
10
10
  import { IndentUI } from './indentui.js';
11
11
  /**
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * @module indent/indentblock
7
7
  */
8
- import { Plugin, type Editor } from 'ckeditor5/src/core.js';
8
+ import { Plugin, type Editor } from '@ckeditor/ckeditor5-core';
9
9
  import { IndentBlockListIntegration } from './integrations/indentblocklistintegration.js';
10
10
  /**
11
11
  * The block indentation feature.
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * @module indent/indentblockcommand
7
7
  */
8
- import { Command, type Editor } from 'ckeditor5/src/core.js';
8
+ import { Command, type Editor } from '@ckeditor/ckeditor5-core';
9
9
  import type { IndentBehavior } from './indentcommandbehavior/indentbehavior.js';
10
10
  /**
11
11
  * The indent block command.
@@ -0,0 +1,24 @@
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 indent/indentcommandbehavior/resetindentusingclasses
7
+ */
8
+ import { IndentUsingClasses } from './indentusingclasses.js';
9
+ /**
10
+ * The list item block indentation behavior that resets class-based indentation toward zero.
11
+ *
12
+ * Unlike {@link module:indent/indentcommandbehavior/indentusingclasses~IndentUsingClasses}, this behavior
13
+ * is enabled only in the backward (outdent) direction when a class-based indentation is set.
14
+ * This is because class-based indentation values cannot be negative, so the only way to reset
15
+ * them to zero is to remove the class by outdenting.
16
+ *
17
+ * @internal
18
+ */
19
+ export declare class ResetIndentUsingClasses extends IndentUsingClasses {
20
+ /**
21
+ * @inheritDoc
22
+ */
23
+ checkEnabled(indentAttributeValue: string): boolean;
24
+ }
@@ -0,0 +1,24 @@
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 indent/indentcommandbehavior/resetindentusingoffset
7
+ */
8
+ import { IndentUsingOffset } from './indentusingoffset.js';
9
+ /**
10
+ * The list item block indentation behavior that resets offset-based indentation toward zero.
11
+ *
12
+ * Unlike {@link module:indent/indentcommandbehavior/indentusingoffset~IndentUsingOffset}, this behavior
13
+ * is enabled only when the current indentation value can be moved toward zero:
14
+ * - for forward direction only when the current offset is negative,
15
+ * - for backward direction only when the current offset is positive.
16
+ *
17
+ * @internal
18
+ */
19
+ export declare class ResetIndentUsingOffset extends IndentUsingOffset {
20
+ /**
21
+ * @inheritDoc
22
+ */
23
+ checkEnabled(indentAttributeValue: string): boolean;
24
+ }
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * @module indent/indentediting
7
7
  */
8
- import { Plugin } from 'ckeditor5/src/core.js';
8
+ import { Plugin } from '@ckeditor/ckeditor5-core';
9
9
  /**
10
10
  * The indent editing feature.
11
11
  *
@@ -2,7 +2,7 @@
2
2
  * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
4
  */
5
- import { Plugin } from 'ckeditor5/src/core.js';
5
+ import { Plugin } from '@ckeditor/ckeditor5-core';
6
6
  /**
7
7
  * The indent UI feature.
8
8
  *
package/dist/index.css CHANGED
@@ -2,3 +2,6 @@
2
2
  * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
4
  */
5
+
6
+
7
+ /*# sourceMappingURL=index.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["index.css"],"names":[],"mappings":";;;;;;AAEA,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC","file":"index.css.map","sourcesContent":["\n\n/*# sourceMappingURL=index.css.map */"]}
package/dist/index.js CHANGED
@@ -373,6 +373,7 @@ import { _isListItemBlock } from '@ckeditor/ckeditor5-list/dist/index.js';
373
373
  const editor = this.editor;
374
374
  const model = editor.model;
375
375
  const selection = model.document.selection;
376
+ const listUtils = editor.plugins.get('ListUtils');
376
377
  model.change((writer)=>{
377
378
  const listItem = this._getFirstListItemIfSelectionIsAtListStart(selection);
378
379
  const listItems = [];
@@ -386,7 +387,9 @@ import { _isListItemBlock } from '@ckeditor/ckeditor5-list/dist/index.js';
386
387
  } else {
387
388
  listItems.push(listItem);
388
389
  }
389
- for (const item of listItems){
390
+ // Expand to all list items in the selected lists to process them together and reduce postfixer usage.
391
+ const expandedListItems = listUtils.expandListBlocksToCompleteList(listItems);
392
+ for (const item of expandedListItems){
390
393
  const currentIndent = item.getAttribute('blockIndentList');
391
394
  const nextIndent = this._indentBehavior.getNextIndent(currentIndent);
392
395
  if (nextIndent) {
@@ -472,24 +475,46 @@ import { _isListItemBlock } from '@ckeditor/ckeditor5-list/dist/index.js';
472
475
  }
473
476
  /**
474
477
  * Returns `true` if changing the block indentation is allowed for the given list item.
475
- *
476
- * Indentation of a list item is only allowed if it moves toward zero. This means that:
477
- * - when currentIndent = 0, the command should be disabled
478
- * - when currentIndent < 0, only forward indentation should be allowed
479
- * - when currentIndent > 0, only backward indentation should be allowed
480
- *
481
- * For classes-based indentation, the command should be enabled if there is a class to be removed.
482
478
  */ _isIndentationChangeAllowed(element) {
483
479
  if (!element.hasAttribute('blockIndentListItem')) {
484
480
  return false;
485
481
  }
486
- const currentIndent = parseFloat(element.getAttribute('blockIndentListItem'));
487
- // Class based indent, allow only outdent.
488
- // TODO find a better way, probably use behavior to find out.
489
- if (isNaN(currentIndent)) {
490
- return !this._indentBehavior.isForward;
491
- }
492
- return this._indentBehavior.isForward && currentIndent < 0 || !this._indentBehavior.isForward && currentIndent > 0;
482
+ return this._indentBehavior.checkEnabled(element.getAttribute('blockIndentListItem'));
483
+ }
484
+ }
485
+
486
+ /**
487
+ * The list item block indentation behavior that resets offset-based indentation toward zero.
488
+ *
489
+ * Unlike {@link module:indent/indentcommandbehavior/indentusingoffset~IndentUsingOffset}, this behavior
490
+ * is enabled only when the current indentation value can be moved toward zero:
491
+ * - for forward direction only when the current offset is negative,
492
+ * - for backward direction only when the current offset is positive.
493
+ *
494
+ * @internal
495
+ */ class ResetIndentUsingOffset extends IndentUsingOffset {
496
+ /**
497
+ * @inheritDoc
498
+ */ checkEnabled(indentAttributeValue) {
499
+ const currentOffset = parseFloat(indentAttributeValue);
500
+ return this.isForward && currentOffset < 0 || !this.isForward && currentOffset > 0;
501
+ }
502
+ }
503
+
504
+ /**
505
+ * The list item block indentation behavior that resets class-based indentation toward zero.
506
+ *
507
+ * Unlike {@link module:indent/indentcommandbehavior/indentusingclasses~IndentUsingClasses}, this behavior
508
+ * is enabled only in the backward (outdent) direction when a class-based indentation is set.
509
+ * This is because class-based indentation values cannot be negative, so the only way to reset
510
+ * them to zero is to remove the class by outdenting.
511
+ *
512
+ * @internal
513
+ */ class ResetIndentUsingClasses extends IndentUsingClasses {
514
+ /**
515
+ * @inheritDoc
516
+ */ checkEnabled(indentAttributeValue) {
517
+ return !this.isForward && !!indentAttributeValue;
493
518
  }
494
519
  }
495
520
 
@@ -515,8 +540,9 @@ import { _isListItemBlock } from '@ckeditor/ckeditor5-list/dist/index.js';
515
540
  }
516
541
  const config = editor.config.get('indentBlock');
517
542
  if (config.classes && config.classes.length) {
518
- this._setupConversionUsingClassesForListBlock(config.classes);
519
- this._setupConversionUsingClassesForListItemBlock(config.classes);
543
+ this._setupConversionUsingClasses(config.classes, 'ol', 'blockIndentList', 'list');
544
+ this._setupConversionUsingClasses(config.classes, 'ul', 'blockIndentList', 'list');
545
+ this._setupConversionUsingClasses(config.classes, 'li', 'blockIndentListItem', 'item');
520
546
  editor.commands.add('indentBlockList', new IndentBlockListCommand(editor, new IndentUsingClasses({
521
547
  direction: 'forward',
522
548
  classes: config.classes
@@ -525,18 +551,19 @@ import { _isListItemBlock } from '@ckeditor/ckeditor5-list/dist/index.js';
525
551
  direction: 'backward',
526
552
  classes: config.classes
527
553
  })));
528
- editor.commands.add('indentBlockListItem', new IndentBlockListItemCommand(editor, new IndentUsingClasses({
554
+ editor.commands.add('indentBlockListItem', new IndentBlockListItemCommand(editor, new ResetIndentUsingClasses({
529
555
  direction: 'forward',
530
556
  classes: config.classes
531
557
  })));
532
- editor.commands.add('outdentBlockListItem', new IndentBlockListItemCommand(editor, new IndentUsingClasses({
558
+ editor.commands.add('outdentBlockListItem', new IndentBlockListItemCommand(editor, new ResetIndentUsingClasses({
533
559
  direction: 'backward',
534
560
  classes: config.classes
535
561
  })));
536
562
  } else {
537
563
  editor.data.addStyleProcessorRules(addMarginStylesRules);
538
- this._setupConversionUsingOffsetForListBlock();
539
- this._setupConversionUsingOffsetForListItemBlock();
564
+ this._setupConversionUsingOffset('ol', 'blockIndentList', 'list');
565
+ this._setupConversionUsingOffset('ul', 'blockIndentList', 'list');
566
+ this._setupConversionUsingOffset('li', 'blockIndentListItem', 'item');
540
567
  editor.commands.add('indentBlockList', new IndentBlockListCommand(editor, new IndentUsingOffset({
541
568
  direction: 'forward',
542
569
  offset: config.offset,
@@ -547,12 +574,12 @@ import { _isListItemBlock } from '@ckeditor/ckeditor5-list/dist/index.js';
547
574
  offset: config.offset,
548
575
  unit: config.unit
549
576
  })));
550
- editor.commands.add('indentBlockListItem', new IndentBlockListItemCommand(editor, new IndentUsingOffset({
577
+ editor.commands.add('indentBlockListItem', new IndentBlockListItemCommand(editor, new ResetIndentUsingOffset({
551
578
  direction: 'forward',
552
579
  offset: config.offset,
553
580
  unit: config.unit
554
581
  })));
555
- editor.commands.add('outdentBlockListItem', new IndentBlockListItemCommand(editor, new IndentUsingOffset({
582
+ editor.commands.add('outdentBlockListItem', new IndentBlockListItemCommand(editor, new ResetIndentUsingOffset({
556
583
  direction: 'backward',
557
584
  offset: config.offset,
558
585
  unit: config.unit
@@ -560,6 +587,8 @@ import { _isListItemBlock } from '@ckeditor/ckeditor5-list/dist/index.js';
560
587
  }
561
588
  const listEditing = editor.plugins.get('ListEditing');
562
589
  // Make sure that all items in a single list (items at the same level & listType) have the same blockIndentList attribute value.
590
+ // Also make sure that all block in a single list item (blocks with the same listItemId) have the same
591
+ // blockIndentListItem attribute value.
563
592
  listEditing.on('postFixer', (evt, { listNodes, writer })=>{
564
593
  for (const { node, previousNodeInList } of listNodes){
565
594
  // This is a first item of a nested list.
@@ -662,43 +691,23 @@ import { _isListItemBlock } from '@ckeditor/ckeditor5-list/dist/index.js';
662
691
  outdentCommand.registerChildCommand(editor.commands.get('outdentBlockListItem'));
663
692
  }
664
693
  /**
665
- * Setups conversion for list block indent using offset indents.
666
- */ _setupConversionUsingOffsetForListBlock() {
667
- const editor = this.editor;
668
- const conversion = editor.conversion;
669
- const locale = editor.locale;
670
- const marginProperty = locale.contentLanguageDirection === 'rtl' ? 'margin-right' : 'margin-left';
671
- const listEditing = editor.plugins.get('ListEditing');
672
- conversion.for('upcast').add((dispatcher)=>{
673
- dispatcher.on('element:ol', listBlockIndentUpcastConverter('blockIndentList', marginProperty));
674
- dispatcher.on('element:ul', listBlockIndentUpcastConverter('blockIndentList', marginProperty));
675
- });
676
- listEditing.registerDowncastStrategy({
677
- scope: 'list',
678
- attributeName: 'blockIndentList',
679
- setAttributeOnDowncast (writer, value, element) {
680
- if (value) {
681
- writer.setStyle(marginProperty, value, element);
682
- }
683
- }
684
- });
685
- }
686
- /**
687
- * Setups conversion for list item block indent using offset indents.
688
- */ _setupConversionUsingOffsetForListItemBlock() {
694
+ * Setups conversion for list block indent using offset.
695
+ */ _setupConversionUsingOffset(element, attributeName, scope) {
689
696
  const editor = this.editor;
690
697
  const locale = editor.locale;
691
698
  const conversion = editor.conversion;
692
699
  const marginProperty = locale.contentLanguageDirection === 'rtl' ? 'margin-right' : 'margin-left';
693
700
  const listEditing = editor.plugins.get('ListEditing');
694
701
  conversion.for('upcast').add((dispatcher)=>{
695
- dispatcher.on('element:li', listBlockIndentUpcastConverter('blockIndentListItem', marginProperty), {
702
+ dispatcher.on(`element:${element}`, listBlockIndentUpcastConverter(attributeName, (item)=>item.getStyle(marginProperty), (consumable, item)=>consumable.consume(item, {
703
+ styles: marginProperty
704
+ })), {
696
705
  priority: 'low'
697
706
  });
698
707
  });
699
708
  listEditing.registerDowncastStrategy({
700
- scope: 'item',
701
- attributeName: 'blockIndentListItem',
709
+ scope,
710
+ attributeName,
702
711
  setAttributeOnDowncast (writer, value, element) {
703
712
  if (value) {
704
713
  writer.setStyle(marginProperty, value, element);
@@ -708,38 +717,20 @@ import { _isListItemBlock } from '@ckeditor/ckeditor5-list/dist/index.js';
708
717
  }
709
718
  /**
710
719
  * Setups conversion for list block indent using classes.
711
- */ _setupConversionUsingClassesForListBlock(classes) {
712
- const editor = this.editor;
713
- const conversion = editor.conversion;
714
- const listEditing = editor.plugins.get('ListEditing');
715
- conversion.for('upcast').add((dispatcher)=>{
716
- dispatcher.on('element:ol', listBlockIndentUpcastConverterUsingClasses('blockIndentList', classes));
717
- dispatcher.on('element:ul', listBlockIndentUpcastConverterUsingClasses('blockIndentList', classes));
718
- });
719
- listEditing.registerDowncastStrategy({
720
- scope: 'list',
721
- attributeName: 'blockIndentList',
722
- setAttributeOnDowncast (writer, value, element) {
723
- if (value) {
724
- writer.addClass(value, element);
725
- }
726
- }
727
- });
728
- }
729
- /**
730
- * Setups conversion for list item block indent using classes.
731
- */ _setupConversionUsingClassesForListItemBlock(classes) {
720
+ */ _setupConversionUsingClasses(classes, element, attributeName, scope) {
732
721
  const editor = this.editor;
733
722
  const conversion = editor.conversion;
734
723
  const listEditing = editor.plugins.get('ListEditing');
735
724
  conversion.for('upcast').add((dispatcher)=>{
736
- dispatcher.on('element:li', listBlockIndentUpcastConverterUsingClasses('blockIndentListItem', classes), {
725
+ dispatcher.on(`element:${element}`, listBlockIndentUpcastConverter(attributeName, (item)=>classes.find((cls)=>item.hasClass(cls)), (consumable, item, value)=>consumable.consume(item, {
726
+ classes: value
727
+ })), {
737
728
  priority: 'low'
738
729
  });
739
730
  });
740
731
  listEditing.registerDowncastStrategy({
741
- scope: 'item',
742
- attributeName: 'blockIndentListItem',
732
+ scope,
733
+ attributeName,
743
734
  setAttributeOnDowncast (writer, value, element) {
744
735
  if (value) {
745
736
  writer.addClass(value, element);
@@ -748,15 +739,21 @@ import { _isListItemBlock } from '@ckeditor/ckeditor5-list/dist/index.js';
748
739
  });
749
740
  }
750
741
  }
751
- function listBlockIndentUpcastConverterUsingClasses(attributeName, classes) {
742
+ /**
743
+ * Returns an upcast converter for block list indentation.
744
+ *
745
+ * @param attributeName The name of the model attribute.
746
+ * @param getValue A function to get the value from the view element.
747
+ * @param consume A function to consume the view element.
748
+ * @returns A callback for the upcast conversion.
749
+ */ function listBlockIndentUpcastConverter(attributeName, getValue, consume) {
752
750
  return (evt, data, conversionApi)=>{
753
751
  const { writer, consumable } = conversionApi;
754
752
  if (!data.modelRange) {
755
753
  Object.assign(data, conversionApi.convertChildren(data.viewItem, data.modelCursor));
756
754
  }
757
- const viewClasses = Array.from(data.viewItem.getClassNames());
758
- const matchedClass = classes.find((cls)=>viewClasses.includes(cls));
759
- if (matchedClass === undefined) {
755
+ const value = getValue(data.viewItem);
756
+ if (value === undefined) {
760
757
  return;
761
758
  }
762
759
  let applied = false;
@@ -773,48 +770,19 @@ function listBlockIndentUpcastConverterUsingClasses(attributeName, classes) {
773
770
  if (item.getAttribute('listIndent') !== indentLevel) {
774
771
  continue;
775
772
  }
776
- writer.setAttribute(attributeName, matchedClass, item);
777
- applied = true;
778
- }
779
- if (applied) {
780
- consumable.consume(data.viewItem, {
781
- classes: matchedClass
782
- });
783
- }
784
- };
785
- }
786
- function listBlockIndentUpcastConverter(attributeName, marginProperty) {
787
- return (evt, data, conversionApi)=>{
788
- const { writer, consumable } = conversionApi;
789
- if (!data.modelRange) {
790
- Object.assign(data, conversionApi.convertChildren(data.viewItem, data.modelCursor));
791
- }
792
- const marginValue = data.viewItem.getStyle(marginProperty);
793
- let applied = false;
794
- let indentLevel;
795
- for (const item of data.modelRange.getItems({
796
- shallow: true
797
- })){
798
- if (indentLevel === undefined) {
799
- indentLevel = item.getAttribute('listIndent');
800
- }
801
- if (item.hasAttribute(attributeName)) {
802
- continue;
803
- }
804
- if (item.getAttribute('listIndent') !== indentLevel) {
805
- continue;
806
- }
807
- writer.setAttribute(attributeName, marginValue, item);
773
+ writer.setAttribute(attributeName, value, item);
808
774
  applied = true;
809
775
  }
810
776
  if (applied) {
811
- consumable.consume(data.viewItem, {
812
- styles: marginProperty
813
- });
777
+ consume(consumable, data.viewItem, value);
814
778
  }
815
779
  };
816
780
  }
817
- function ensureIndentValuesConsistency(attributeName, node, previousNodeInList, writer) {
781
+ /**
782
+ * Ensures that two nodes have the same value of the given attribute.
783
+ * If the values are different, the attribute value from the previous node is applied to the given node.
784
+ * Returns true if the attribute value was changed, false otherwise.
785
+ */ function ensureIndentValuesConsistency(attributeName, node, previousNodeInList, writer) {
818
786
  const prevNodeIndentListValue = previousNodeInList.getAttribute(attributeName);
819
787
  if (node.getAttribute(attributeName) === prevNodeIndentListValue) {
820
788
  return false;