@ckeditor/ckeditor5-list 47.6.1 → 48.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
@@ -1,88 +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/listformatting/listitemitalicintegration
|
|
7
|
-
*/
|
|
8
|
-
import { Plugin } from 'ckeditor5/src/core.js';
|
|
9
|
-
import { env } from 'ckeditor5/src/utils.js';
|
|
10
|
-
import { ListEditing } from '../list/listediting.js';
|
|
11
|
-
/**
|
|
12
|
-
* The list item italic integration plugin.
|
|
13
|
-
*/
|
|
14
|
-
export class ListItemItalicIntegration extends Plugin {
|
|
15
|
-
/**
|
|
16
|
-
* @inheritDoc
|
|
17
|
-
*/
|
|
18
|
-
static get pluginName() {
|
|
19
|
-
return 'ListItemItalicIntegration';
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* @inheritDoc
|
|
23
|
-
*/
|
|
24
|
-
static get isOfficialPlugin() {
|
|
25
|
-
return true;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* @inheritDoc
|
|
29
|
-
*/
|
|
30
|
-
static get requires() {
|
|
31
|
-
return [ListEditing];
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* @inheritDoc
|
|
35
|
-
*/
|
|
36
|
-
init() {
|
|
37
|
-
const editor = this.editor;
|
|
38
|
-
const ListFormatting = editor.plugins.get('ListFormatting');
|
|
39
|
-
const listEditing = editor.plugins.get(ListEditing);
|
|
40
|
-
if (!editor.plugins.has('ItalicEditing') || !this.editor.config.get('list.enableListItemMarkerFormatting')) {
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
ListFormatting.registerFormatAttribute('italic', 'listItemItalic');
|
|
44
|
-
// Register the downcast strategy in init() so that the attribute name is registered before the list editing
|
|
45
|
-
// registers its converters.
|
|
46
|
-
// This ensures that the attribute is recognized by downcast strategies and bogus paragraphs are handled correctly.
|
|
47
|
-
listEditing.registerDowncastStrategy({
|
|
48
|
-
scope: 'item',
|
|
49
|
-
attributeName: 'listItemItalic',
|
|
50
|
-
setAttributeOnDowncast(writer, value, viewElement, options) {
|
|
51
|
-
if (value) {
|
|
52
|
-
writer.addClass('ck-list-marker-italic', viewElement);
|
|
53
|
-
// See: https://github.com/ckeditor/ckeditor5/issues/18790.
|
|
54
|
-
if (env.isSafari && !(options && options.dataPipeline)) {
|
|
55
|
-
writer.setStyle('--ck-content-list-marker-dummy-italic', '0', viewElement);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* @inheritDoc
|
|
63
|
-
*/
|
|
64
|
-
afterInit() {
|
|
65
|
-
const editor = this.editor;
|
|
66
|
-
const model = editor.model;
|
|
67
|
-
if (!editor.plugins.has('ItalicEditing') || !this.editor.config.get('list.enableListItemMarkerFormatting')) {
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
model.schema.extend('$listItem', { allowAttributes: 'listItemItalic' });
|
|
71
|
-
model.schema.setAttributeProperties('listItemItalic', {
|
|
72
|
-
isFormatting: true
|
|
73
|
-
});
|
|
74
|
-
model.schema.addAttributeCheck(context => {
|
|
75
|
-
const item = context.last;
|
|
76
|
-
if (!item.getAttribute('listItemId')) {
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
}, 'listItemItalic');
|
|
80
|
-
editor.conversion.for('upcast').attributeToAttribute({
|
|
81
|
-
model: 'listItemItalic',
|
|
82
|
-
view: {
|
|
83
|
-
name: 'li',
|
|
84
|
-
classes: 'ck-list-marker-italic'
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
}
|
package/src/listformatting.js
DELETED
|
@@ -1,248 +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/listformatting
|
|
7
|
-
*/
|
|
8
|
-
import { Plugin } from 'ckeditor5/src/core.js';
|
|
9
|
-
import { ListItemBoldIntegration } from './listformatting/listitemboldintegration.js';
|
|
10
|
-
import { ListItemItalicIntegration } from './listformatting/listitemitalicintegration.js';
|
|
11
|
-
import { ListItemFontSizeIntegration } from './listformatting/listitemfontsizeintegration.js';
|
|
12
|
-
import { ListItemFontColorIntegration } from './listformatting/listitemfontcolorintegration.js';
|
|
13
|
-
import { ListItemFontFamilyIntegration } from './listformatting/listitemfontfamilyintegration.js';
|
|
14
|
-
import { isListItemBlock, getAllListItemBlocks, isFirstBlockOfListItem } from './list/utils/model.js';
|
|
15
|
-
import '../theme/listformatting.css';
|
|
16
|
-
/**
|
|
17
|
-
* The list formatting plugin.
|
|
18
|
-
*
|
|
19
|
-
* It enables integration with formatting plugins to style the list marker.
|
|
20
|
-
* The list marker is styled based on the consistent formatting applied to the content of the list item.
|
|
21
|
-
*
|
|
22
|
-
* The list of supported formatting plugins includes:
|
|
23
|
-
* * Font color.
|
|
24
|
-
* * Font size.
|
|
25
|
-
* * Font family.
|
|
26
|
-
* * Bold.
|
|
27
|
-
* * Italic.
|
|
28
|
-
*/
|
|
29
|
-
export class ListFormatting extends Plugin {
|
|
30
|
-
/**
|
|
31
|
-
* The list of loaded formatting.
|
|
32
|
-
*/
|
|
33
|
-
_loadedFormatting = {};
|
|
34
|
-
/**
|
|
35
|
-
* @inheritDoc
|
|
36
|
-
*/
|
|
37
|
-
static get pluginName() {
|
|
38
|
-
return 'ListFormatting';
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* @inheritDoc
|
|
42
|
-
*/
|
|
43
|
-
static get isOfficialPlugin() {
|
|
44
|
-
return true;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* @inheritDoc
|
|
48
|
-
*/
|
|
49
|
-
static get requires() {
|
|
50
|
-
return [
|
|
51
|
-
ListItemBoldIntegration,
|
|
52
|
-
ListItemItalicIntegration,
|
|
53
|
-
ListItemFontSizeIntegration,
|
|
54
|
-
ListItemFontColorIntegration,
|
|
55
|
-
ListItemFontFamilyIntegration
|
|
56
|
-
];
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* @inheritDoc
|
|
60
|
-
*/
|
|
61
|
-
constructor(editor) {
|
|
62
|
-
super(editor);
|
|
63
|
-
editor.config.define('list.enableListItemMarkerFormatting', true);
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* @inheritDoc
|
|
67
|
-
*/
|
|
68
|
-
afterInit() {
|
|
69
|
-
if (!this.editor.config.get('list.enableListItemMarkerFormatting')) {
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
this._registerPostfixerForListItemFormatting();
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Registers a postfixer that ensures that the list item formatting attribute is consistent with the formatting
|
|
76
|
-
* applied to the content of the list item.
|
|
77
|
-
*/
|
|
78
|
-
_registerPostfixerForListItemFormatting() {
|
|
79
|
-
const model = this.editor.model;
|
|
80
|
-
model.document.registerPostFixer(writer => {
|
|
81
|
-
const changes = model.document.differ.getChanges();
|
|
82
|
-
const modifiedListItems = new Set();
|
|
83
|
-
let returnValue = false;
|
|
84
|
-
for (const entry of changes) {
|
|
85
|
-
if (entry.type === 'attribute') {
|
|
86
|
-
if (entry.attributeKey == 'listItemId' ||
|
|
87
|
-
entry.attributeKey == 'listType' ||
|
|
88
|
-
this._isInlineOrSelectionFormatting(entry.attributeKey) ||
|
|
89
|
-
Object.values(this._loadedFormatting).includes(entry.attributeKey)) {
|
|
90
|
-
if (isListItemBlock(entry.range.start.nodeAfter)) {
|
|
91
|
-
modifiedListItems.add(entry.range.start.nodeAfter);
|
|
92
|
-
}
|
|
93
|
-
else if (isListItemBlock(entry.range.start.parent)) {
|
|
94
|
-
modifiedListItems.add(entry.range.start.parent);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
if (isListItemBlock(entry.position.nodeAfter)) {
|
|
100
|
-
modifiedListItems.add(entry.position.nodeAfter);
|
|
101
|
-
}
|
|
102
|
-
if (isListItemBlock(entry.position.nodeBefore)) {
|
|
103
|
-
modifiedListItems.add(entry.position.nodeBefore);
|
|
104
|
-
}
|
|
105
|
-
if (isListItemBlock(entry.position.parent)) {
|
|
106
|
-
modifiedListItems.add(entry.position.parent);
|
|
107
|
-
}
|
|
108
|
-
if (entry.type == 'insert' && entry.name != '$text') {
|
|
109
|
-
const range = writer.createRangeIn(entry.position.nodeAfter);
|
|
110
|
-
for (const item of range.getItems()) {
|
|
111
|
-
if (isListItemBlock(item)) {
|
|
112
|
-
modifiedListItems.add(item);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
for (const listItem of modifiedListItems) {
|
|
119
|
-
const formats = getListItemConsistentFormat(model, listItem, Object.keys(this._loadedFormatting));
|
|
120
|
-
for (const [formatAttributeName, formatValue] of Object.entries(formats)) {
|
|
121
|
-
const listItemFormatAttributeName = this._loadedFormatting[formatAttributeName];
|
|
122
|
-
if (formatValue && setFormattingToListItem(writer, listItem, listItemFormatAttributeName, formatValue)) {
|
|
123
|
-
returnValue = true;
|
|
124
|
-
}
|
|
125
|
-
else if (!formatValue && removeFormattingFromListItem(writer, listItem, listItemFormatAttributeName)) {
|
|
126
|
-
returnValue = true;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
return returnValue;
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Registers an integration between a default attribute (e.g., `fontFamily`) and a new attribute
|
|
135
|
-
* intended specifically for list item elements (e.g., `listItemFontFamily`).
|
|
136
|
-
*
|
|
137
|
-
* These attributes are later used by the postfixer logic to determine whether to add the new attribute
|
|
138
|
-
* to the list item element, based on whether there is a consistent default formatting attribute
|
|
139
|
-
* applied within its content.
|
|
140
|
-
*/
|
|
141
|
-
registerFormatAttribute(formatAttribute, listItemFormatAttribute) {
|
|
142
|
-
this._loadedFormatting[formatAttribute] = listItemFormatAttribute;
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Returns true if the given model attribute name is a supported inline formatting attribute.
|
|
146
|
-
*/
|
|
147
|
-
_isInlineOrSelectionFormatting(attributeKey) {
|
|
148
|
-
return attributeKey.replace(/^selection:/, '') in this._loadedFormatting;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Returns the consistent format of the list item element.
|
|
153
|
-
* If the list item contains multiple blocks, it checks only the first block.
|
|
154
|
-
*/
|
|
155
|
-
function getListItemConsistentFormat(model, listItem, attributeKeys) {
|
|
156
|
-
if (isFirstBlockOfListItem(listItem)) {
|
|
157
|
-
return getSingleListItemConsistentFormat(model, listItem, attributeKeys);
|
|
158
|
-
}
|
|
159
|
-
// Always the first block of the list item should be checked for consistent formatting.
|
|
160
|
-
const listItemBlocks = getAllListItemBlocks(listItem);
|
|
161
|
-
return getSingleListItemConsistentFormat(model, listItemBlocks[0], attributeKeys);
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Returns the consistent format of a single list item element.
|
|
165
|
-
*/
|
|
166
|
-
function getSingleListItemConsistentFormat(model, listItem, attributeKeys) {
|
|
167
|
-
// Only bulleted and numbered lists can have formatting (to-do lists are not supported).
|
|
168
|
-
// Do not check internals of limit elements (for example, do not check table cells).
|
|
169
|
-
if (!isNumberedOrBulletedList(listItem) || model.schema.isLimit(listItem)) {
|
|
170
|
-
return Object.fromEntries(attributeKeys.map(attributeKey => [attributeKey]));
|
|
171
|
-
}
|
|
172
|
-
if (listItem.isEmpty) {
|
|
173
|
-
return Object.fromEntries(attributeKeys.map(attributeKey => ([attributeKey, listItem.getAttribute(`selection:${attributeKey}`)])));
|
|
174
|
-
}
|
|
175
|
-
const attributesToCheck = new Set(attributeKeys);
|
|
176
|
-
const valuesMap = {};
|
|
177
|
-
const range = model.createRangeIn(listItem);
|
|
178
|
-
const walker = range.getWalker({ ignoreElementEnd: true });
|
|
179
|
-
for (const { item } of walker) {
|
|
180
|
-
for (const attributeKey of attributesToCheck) {
|
|
181
|
-
if (model.schema.checkAttribute(item, attributeKey)) {
|
|
182
|
-
const formatAttribute = item.getAttribute(attributeKey);
|
|
183
|
-
if (formatAttribute === undefined) {
|
|
184
|
-
attributesToCheck.delete(attributeKey);
|
|
185
|
-
valuesMap[attributeKey] = undefined;
|
|
186
|
-
}
|
|
187
|
-
else if (valuesMap[attributeKey] === undefined) {
|
|
188
|
-
// First item inside a list item block.
|
|
189
|
-
valuesMap[attributeKey] = formatAttribute;
|
|
190
|
-
}
|
|
191
|
-
else if (valuesMap[attributeKey] !== formatAttribute) {
|
|
192
|
-
// Following items in the same block of a list item.
|
|
193
|
-
attributesToCheck.delete(attributeKey);
|
|
194
|
-
valuesMap[attributeKey] = undefined;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
else if (!(attributeKey in valuesMap)) {
|
|
198
|
-
// Store it so a format would be removed when all items in the given list item does not allow that formatting.
|
|
199
|
-
valuesMap[attributeKey] = undefined;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
// End early if all attributes have been checked and are inconsistent.
|
|
203
|
-
if (!attributesToCheck.size) {
|
|
204
|
-
break;
|
|
205
|
-
}
|
|
206
|
-
// Jump over inline limit elements as we expect only outside them to be the same formatting.
|
|
207
|
-
if (model.schema.isLimit(item)) {
|
|
208
|
-
walker.jumpTo(model.createPositionAfter(item));
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
return valuesMap;
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Adds the specified formatting attribute to the list item element.
|
|
215
|
-
*/
|
|
216
|
-
function setFormattingToListItem(writer, listItem, attributeKey, attributeValue) {
|
|
217
|
-
// Multi-block items should have consistent formatting.
|
|
218
|
-
const listItemBlocks = getAllListItemBlocks(listItem);
|
|
219
|
-
let wasChanged = false;
|
|
220
|
-
for (const listItem of listItemBlocks) {
|
|
221
|
-
if (!listItem.hasAttribute(attributeKey) || listItem.getAttribute(attributeKey) !== attributeValue) {
|
|
222
|
-
writer.setAttribute(attributeKey, attributeValue, listItem);
|
|
223
|
-
wasChanged = true;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
return wasChanged;
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Removes the specified formatting attribute from the list item element.
|
|
230
|
-
*/
|
|
231
|
-
function removeFormattingFromListItem(writer, listItem, attributeKey) {
|
|
232
|
-
// Multi-block items should have consistent formatting.
|
|
233
|
-
const listItemBlocks = getAllListItemBlocks(listItem);
|
|
234
|
-
let wasChanged = false;
|
|
235
|
-
for (const listItem of listItemBlocks) {
|
|
236
|
-
if (listItem.hasAttribute(attributeKey)) {
|
|
237
|
-
writer.removeAttribute(attributeKey, listItem);
|
|
238
|
-
wasChanged = true;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
return wasChanged;
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* Checks if the given list type is a numbered or bulleted list.
|
|
245
|
-
*/
|
|
246
|
-
function isNumberedOrBulletedList(listItem) {
|
|
247
|
-
return ['numbered', 'bulleted', 'customNumbered', 'customBulleted'].includes(listItem.getAttribute('listType'));
|
|
248
|
-
}
|
|
@@ -1,43 +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
|
-
* Returns a converter that consumes the `style`, `reversed`, and `start` attributes.
|
|
7
|
-
* In `style`, it searches for the `list-style-type` definition.
|
|
8
|
-
* If not found, the `"default"` value will be used.
|
|
9
|
-
*
|
|
10
|
-
* @internal
|
|
11
|
-
* @param strategy
|
|
12
|
-
*/
|
|
13
|
-
export function listPropertiesUpcastConverter(strategy) {
|
|
14
|
-
return (evt, data, conversionApi) => {
|
|
15
|
-
const { writer, schema, consumable } = conversionApi;
|
|
16
|
-
// If there is no view consumable to consume, set the default attribute value to be able to reconvert nested lists on parent change.
|
|
17
|
-
// So abort converting if attribute was directly consumed.
|
|
18
|
-
if (consumable.test(data.viewItem, strategy.viewConsumables) === false) {
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
if (!data.modelRange) {
|
|
22
|
-
Object.assign(data, conversionApi.convertChildren(data.viewItem, data.modelCursor));
|
|
23
|
-
}
|
|
24
|
-
let applied = false;
|
|
25
|
-
for (const item of data.modelRange.getItems({ shallow: true })) {
|
|
26
|
-
if (!schema.checkAttribute(item, strategy.attributeName)) {
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
if (!strategy.appliesToListItem(item)) {
|
|
30
|
-
continue;
|
|
31
|
-
}
|
|
32
|
-
// Set list attributes only on same level items, those nested deeper are already handled by the recursive conversion.
|
|
33
|
-
if (item.hasAttribute(strategy.attributeName)) {
|
|
34
|
-
continue;
|
|
35
|
-
}
|
|
36
|
-
writer.setAttribute(strategy.attributeName, strategy.getAttributeOnUpcast(data.viewItem), item);
|
|
37
|
-
applied = true;
|
|
38
|
-
}
|
|
39
|
-
if (applied) {
|
|
40
|
-
consumable.consume(data.viewItem, strategy.viewConsumables);
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
}
|
|
@@ -1,291 +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/listproperties/listpropertiesediting
|
|
7
|
-
*/
|
|
8
|
-
import { Plugin } from 'ckeditor5/src/core.js';
|
|
9
|
-
import { ListEditing } from '../list/listediting.js';
|
|
10
|
-
import { ListStartCommand } from './liststartcommand.js';
|
|
11
|
-
import { ListStyleCommand } from './liststylecommand.js';
|
|
12
|
-
import { ListReversedCommand } from './listreversedcommand.js';
|
|
13
|
-
import { listPropertiesUpcastConverter } from './converters.js';
|
|
14
|
-
import { getAllSupportedStyleTypes, getListTypeFromListStyleType, getListStyleTypeFromTypeAttribute, getTypeAttributeFromListStyleType, normalizeListStyle } from './utils/style.js';
|
|
15
|
-
import { ListPropertiesUtils } from './listpropertiesutils.js';
|
|
16
|
-
import { isNumberedListType } from '../list/utils/model.js';
|
|
17
|
-
import { getNormalizedConfig } from './utils/config.js';
|
|
18
|
-
const DEFAULT_LIST_TYPE = 'default';
|
|
19
|
-
/**
|
|
20
|
-
* The document list properties engine feature.
|
|
21
|
-
*
|
|
22
|
-
* It registers the `'listStyle'`, `'listReversed'` and `'listStart'` commands if they are enabled in the configuration.
|
|
23
|
-
* Read more in {@link module:list/listconfig~ListPropertiesConfig}.
|
|
24
|
-
*/
|
|
25
|
-
export class ListPropertiesEditing extends Plugin {
|
|
26
|
-
/**
|
|
27
|
-
* @inheritDoc
|
|
28
|
-
*/
|
|
29
|
-
static get requires() {
|
|
30
|
-
return [ListEditing, ListPropertiesUtils];
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* @inheritDoc
|
|
34
|
-
*/
|
|
35
|
-
static get pluginName() {
|
|
36
|
-
return 'ListPropertiesEditing';
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* @inheritDoc
|
|
40
|
-
* @internal
|
|
41
|
-
*/
|
|
42
|
-
static get licenseFeatureCode() {
|
|
43
|
-
return 'LP';
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* @inheritDoc
|
|
47
|
-
*/
|
|
48
|
-
static get isOfficialPlugin() {
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* @inheritDoc
|
|
53
|
-
*/
|
|
54
|
-
static get isPremiumPlugin() {
|
|
55
|
-
return true;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* @inheritDoc
|
|
59
|
-
*/
|
|
60
|
-
constructor(editor) {
|
|
61
|
-
super(editor);
|
|
62
|
-
editor.config.define('list.properties', {
|
|
63
|
-
styles: true,
|
|
64
|
-
startIndex: false,
|
|
65
|
-
reversed: false
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* @inheritDoc
|
|
70
|
-
*/
|
|
71
|
-
init() {
|
|
72
|
-
const editor = this.editor;
|
|
73
|
-
const model = editor.model;
|
|
74
|
-
const listEditing = editor.plugins.get(ListEditing);
|
|
75
|
-
const enabledProperties = editor.config.get('list.properties');
|
|
76
|
-
const strategies = createAttributeStrategies(enabledProperties);
|
|
77
|
-
for (const strategy of strategies) {
|
|
78
|
-
strategy.addCommand(editor);
|
|
79
|
-
model.schema.extend('$listItem', { allowAttributes: strategy.attributeName });
|
|
80
|
-
// Register downcast strategy.
|
|
81
|
-
listEditing.registerDowncastStrategy({
|
|
82
|
-
scope: 'list',
|
|
83
|
-
attributeName: strategy.attributeName,
|
|
84
|
-
setAttributeOnDowncast(writer, attributeValue, viewElement) {
|
|
85
|
-
strategy.setAttributeOnDowncast(writer, attributeValue, viewElement);
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
// Set up conversion.
|
|
90
|
-
editor.conversion.for('upcast').add(dispatcher => {
|
|
91
|
-
for (const strategy of strategies) {
|
|
92
|
-
dispatcher.on('element:ol', listPropertiesUpcastConverter(strategy));
|
|
93
|
-
dispatcher.on('element:ul', listPropertiesUpcastConverter(strategy));
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
// Verify if the list view element (ul or ol) requires refreshing.
|
|
97
|
-
listEditing.on('checkAttributes:list', (evt, { viewElement, modelAttributes, modelReferenceElement }) => {
|
|
98
|
-
for (const strategy of strategies) {
|
|
99
|
-
if (!strategy.appliesToListItem(modelReferenceElement)) {
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
if (strategy.getAttributeOnUpcast(viewElement) != modelAttributes[strategy.attributeName]) {
|
|
103
|
-
evt.return = true;
|
|
104
|
-
evt.stop();
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
// Reset list properties after indenting list items.
|
|
109
|
-
this.listenTo(editor.commands.get('indentList'), 'afterExecute', (evt, changedBlocks) => {
|
|
110
|
-
model.change(writer => {
|
|
111
|
-
for (const node of changedBlocks) {
|
|
112
|
-
for (const strategy of strategies) {
|
|
113
|
-
if (strategy.appliesToListItem(node)) {
|
|
114
|
-
// Just reset the attribute.
|
|
115
|
-
// If there is a previous indented list that this node should be merged into,
|
|
116
|
-
// the postfixer will unify all the attributes of both sub-lists.
|
|
117
|
-
writer.setAttribute(strategy.attributeName, strategy.defaultValue, node);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
// Add or remove list properties attributes depending on the list type.
|
|
124
|
-
listEditing.on('postFixer', (evt, { listNodes, writer }) => {
|
|
125
|
-
for (const { node } of listNodes) {
|
|
126
|
-
for (const strategy of strategies) {
|
|
127
|
-
// Check if attribute is valid.
|
|
128
|
-
if (strategy.hasValidAttribute(node)) {
|
|
129
|
-
continue;
|
|
130
|
-
}
|
|
131
|
-
// Add missing default property attributes...
|
|
132
|
-
if (strategy.appliesToListItem(node)) {
|
|
133
|
-
writer.setAttribute(strategy.attributeName, strategy.defaultValue, node);
|
|
134
|
-
}
|
|
135
|
-
// ...or remove invalid property attributes.
|
|
136
|
-
else {
|
|
137
|
-
writer.removeAttribute(strategy.attributeName, node);
|
|
138
|
-
}
|
|
139
|
-
evt.return = true;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
// Make sure that all items in a single list (items at the same level & listType) have the same properties.
|
|
144
|
-
listEditing.on('postFixer', (evt, { listNodes, writer }) => {
|
|
145
|
-
for (const { node, previousNodeInList } of listNodes) {
|
|
146
|
-
// This is a first item of a nested list.
|
|
147
|
-
if (!previousNodeInList) {
|
|
148
|
-
continue;
|
|
149
|
-
}
|
|
150
|
-
// This is a first block of a list of a different type.
|
|
151
|
-
if (previousNodeInList.getAttribute('listType') != node.getAttribute('listType')) {
|
|
152
|
-
continue;
|
|
153
|
-
}
|
|
154
|
-
// Copy properties from the previous one.
|
|
155
|
-
for (const strategy of strategies) {
|
|
156
|
-
const { attributeName } = strategy;
|
|
157
|
-
if (!strategy.appliesToListItem(node)) {
|
|
158
|
-
continue;
|
|
159
|
-
}
|
|
160
|
-
const value = previousNodeInList.getAttribute(attributeName);
|
|
161
|
-
if (node.getAttribute(attributeName) != value) {
|
|
162
|
-
writer.setAttribute(attributeName, value, node);
|
|
163
|
-
evt.return = true;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Creates an array of strategies for dealing with enabled listItem attributes.
|
|
172
|
-
*/
|
|
173
|
-
function createAttributeStrategies(enabledProperties) {
|
|
174
|
-
const strategies = [];
|
|
175
|
-
const normalizedConfig = getNormalizedConfig(enabledProperties);
|
|
176
|
-
if (enabledProperties.styles) {
|
|
177
|
-
const useAttribute = normalizedConfig.styles.useAttribute;
|
|
178
|
-
strategies.push({
|
|
179
|
-
attributeName: 'listStyle',
|
|
180
|
-
defaultValue: DEFAULT_LIST_TYPE,
|
|
181
|
-
viewConsumables: { styles: 'list-style-type' },
|
|
182
|
-
addCommand(editor) {
|
|
183
|
-
let supportedTypes = getAllSupportedStyleTypes();
|
|
184
|
-
if (useAttribute) {
|
|
185
|
-
supportedTypes = supportedTypes.filter(styleType => !!getTypeAttributeFromListStyleType(styleType));
|
|
186
|
-
}
|
|
187
|
-
editor.commands.add('listStyle', new ListStyleCommand(editor, DEFAULT_LIST_TYPE, supportedTypes));
|
|
188
|
-
},
|
|
189
|
-
appliesToListItem(item) {
|
|
190
|
-
return item.getAttribute('listType') == 'numbered' || item.getAttribute('listType') == 'bulleted';
|
|
191
|
-
},
|
|
192
|
-
hasValidAttribute(item) {
|
|
193
|
-
if (!this.appliesToListItem(item)) {
|
|
194
|
-
return !item.hasAttribute('listStyle');
|
|
195
|
-
}
|
|
196
|
-
if (!item.hasAttribute('listStyle')) {
|
|
197
|
-
return false;
|
|
198
|
-
}
|
|
199
|
-
const value = item.getAttribute('listStyle');
|
|
200
|
-
if (value == DEFAULT_LIST_TYPE) {
|
|
201
|
-
return true;
|
|
202
|
-
}
|
|
203
|
-
return getListTypeFromListStyleType(value) == item.getAttribute('listType');
|
|
204
|
-
},
|
|
205
|
-
setAttributeOnDowncast(writer, listStyle, element) {
|
|
206
|
-
if (listStyle && listStyle !== DEFAULT_LIST_TYPE) {
|
|
207
|
-
if (useAttribute) {
|
|
208
|
-
const value = getTypeAttributeFromListStyleType(listStyle);
|
|
209
|
-
if (value) {
|
|
210
|
-
writer.setAttribute('type', value, element);
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
else {
|
|
215
|
-
writer.setStyle('list-style-type', listStyle, element);
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
writer.removeStyle('list-style-type', element);
|
|
220
|
-
writer.removeAttribute('type', element);
|
|
221
|
-
},
|
|
222
|
-
getAttributeOnUpcast(listParent) {
|
|
223
|
-
const style = listParent.getStyle('list-style-type');
|
|
224
|
-
if (style) {
|
|
225
|
-
return normalizeListStyle(style);
|
|
226
|
-
}
|
|
227
|
-
const attribute = listParent.getAttribute('type');
|
|
228
|
-
if (attribute) {
|
|
229
|
-
return getListStyleTypeFromTypeAttribute(attribute);
|
|
230
|
-
}
|
|
231
|
-
return DEFAULT_LIST_TYPE;
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
if (enabledProperties.reversed) {
|
|
236
|
-
strategies.push({
|
|
237
|
-
attributeName: 'listReversed',
|
|
238
|
-
defaultValue: false,
|
|
239
|
-
viewConsumables: { attributes: 'reversed' },
|
|
240
|
-
addCommand(editor) {
|
|
241
|
-
editor.commands.add('listReversed', new ListReversedCommand(editor));
|
|
242
|
-
},
|
|
243
|
-
appliesToListItem(item) {
|
|
244
|
-
return item.getAttribute('listType') == 'numbered';
|
|
245
|
-
},
|
|
246
|
-
hasValidAttribute(item) {
|
|
247
|
-
return this.appliesToListItem(item) == item.hasAttribute('listReversed');
|
|
248
|
-
},
|
|
249
|
-
setAttributeOnDowncast(writer, listReversed, element) {
|
|
250
|
-
if (listReversed) {
|
|
251
|
-
writer.setAttribute('reversed', 'reversed', element);
|
|
252
|
-
}
|
|
253
|
-
else {
|
|
254
|
-
writer.removeAttribute('reversed', element);
|
|
255
|
-
}
|
|
256
|
-
},
|
|
257
|
-
getAttributeOnUpcast(listParent) {
|
|
258
|
-
return listParent.hasAttribute('reversed');
|
|
259
|
-
}
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
|
-
if (enabledProperties.startIndex) {
|
|
263
|
-
strategies.push({
|
|
264
|
-
attributeName: 'listStart',
|
|
265
|
-
defaultValue: 1,
|
|
266
|
-
viewConsumables: { attributes: 'start' },
|
|
267
|
-
addCommand(editor) {
|
|
268
|
-
editor.commands.add('listStart', new ListStartCommand(editor));
|
|
269
|
-
},
|
|
270
|
-
appliesToListItem(item) {
|
|
271
|
-
return isNumberedListType(item.getAttribute('listType'));
|
|
272
|
-
},
|
|
273
|
-
hasValidAttribute(item) {
|
|
274
|
-
return this.appliesToListItem(item) == item.hasAttribute('listStart');
|
|
275
|
-
},
|
|
276
|
-
setAttributeOnDowncast(writer, listStart, element) {
|
|
277
|
-
if (listStart == 0 || listStart > 1) {
|
|
278
|
-
writer.setAttribute('start', listStart, element);
|
|
279
|
-
}
|
|
280
|
-
else {
|
|
281
|
-
writer.removeAttribute('start', element);
|
|
282
|
-
}
|
|
283
|
-
},
|
|
284
|
-
getAttributeOnUpcast(listParent) {
|
|
285
|
-
const startAttributeValue = listParent.getAttribute('start');
|
|
286
|
-
return startAttributeValue >= 0 ? startAttributeValue : 1;
|
|
287
|
-
}
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
return strategies;
|
|
291
|
-
}
|