@ckeditor/ckeditor5-list 29.2.0 → 32.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +2 -2
- package/build/list.js +3 -3
- package/build/translations/ar.js +1 -1
- package/build/translations/ast.js +1 -1
- package/build/translations/az.js +1 -1
- package/build/translations/bg.js +1 -1
- package/build/translations/cs.js +1 -1
- package/build/translations/da.js +1 -1
- package/build/translations/de-ch.js +1 -1
- package/build/translations/de.js +1 -1
- package/build/translations/el.js +1 -1
- package/build/translations/en-au.js +1 -1
- package/build/translations/en-gb.js +1 -1
- package/build/translations/eo.js +1 -1
- package/build/translations/es.js +1 -1
- package/build/translations/et.js +1 -1
- package/build/translations/eu.js +1 -1
- package/build/translations/fa.js +1 -1
- package/build/translations/fi.js +1 -1
- package/build/translations/fr.js +1 -1
- package/build/translations/gl.js +1 -1
- package/build/translations/he.js +1 -1
- package/build/translations/hi.js +1 -1
- package/build/translations/hr.js +1 -1
- package/build/translations/hu.js +1 -1
- package/build/translations/id.js +1 -1
- package/build/translations/it.js +1 -1
- package/build/translations/ja.js +1 -1
- package/build/translations/km.js +1 -1
- package/build/translations/kn.js +1 -1
- package/build/translations/ko.js +1 -1
- package/build/translations/ku.js +1 -1
- package/build/translations/lt.js +1 -1
- package/build/translations/lv.js +1 -1
- package/build/translations/nb.js +1 -1
- package/build/translations/ne.js +1 -1
- package/build/translations/nl.js +1 -1
- package/build/translations/no.js +1 -1
- package/build/translations/pl.js +1 -1
- package/build/translations/pt-br.js +1 -1
- package/build/translations/pt.js +1 -1
- package/build/translations/ro.js +1 -1
- package/build/translations/ru.js +1 -1
- package/build/translations/si.js +1 -1
- package/build/translations/sk.js +1 -1
- package/build/translations/sq.js +1 -1
- package/build/translations/sr-latn.js +1 -1
- package/build/translations/sr.js +1 -1
- package/build/translations/sv.js +1 -1
- package/build/translations/tk.js +1 -1
- package/build/translations/tr.js +1 -1
- package/build/translations/ug.js +1 -1
- package/build/translations/uk.js +1 -1
- package/build/translations/uz.js +1 -0
- package/build/translations/vi.js +1 -1
- package/build/translations/zh-cn.js +1 -1
- package/build/translations/zh.js +1 -1
- package/ckeditor5-metadata.json +8 -4
- package/lang/contexts.json +5 -1
- package/lang/translations/ar.po +17 -1
- package/lang/translations/ast.po +17 -1
- package/lang/translations/az.po +17 -1
- package/lang/translations/bg.po +17 -1
- package/lang/translations/cs.po +17 -1
- package/lang/translations/da.po +17 -1
- package/lang/translations/de-ch.po +17 -1
- package/lang/translations/de.po +17 -1
- package/lang/translations/el.po +17 -1
- package/lang/translations/en-au.po +17 -1
- package/lang/translations/en-gb.po +17 -1
- package/lang/translations/en.po +17 -1
- package/lang/translations/eo.po +17 -1
- package/lang/translations/es.po +20 -4
- package/lang/translations/et.po +17 -1
- package/lang/translations/eu.po +17 -1
- package/lang/translations/fa.po +17 -1
- package/lang/translations/fi.po +17 -1
- package/lang/translations/fr.po +17 -1
- package/lang/translations/gl.po +17 -1
- package/lang/translations/he.po +17 -1
- package/lang/translations/hi.po +17 -1
- package/lang/translations/hr.po +17 -1
- package/lang/translations/hu.po +17 -1
- package/lang/translations/id.po +17 -1
- package/lang/translations/it.po +17 -1
- package/lang/translations/ja.po +17 -1
- package/lang/translations/km.po +17 -1
- package/lang/translations/kn.po +17 -1
- package/lang/translations/ko.po +17 -1
- package/lang/translations/ku.po +17 -1
- package/lang/translations/lt.po +17 -1
- package/lang/translations/lv.po +17 -1
- package/lang/translations/nb.po +17 -1
- package/lang/translations/ne.po +17 -1
- package/lang/translations/nl.po +21 -5
- package/lang/translations/no.po +17 -1
- package/lang/translations/pl.po +17 -1
- package/lang/translations/pt-br.po +17 -1
- package/lang/translations/pt.po +17 -1
- package/lang/translations/ro.po +17 -1
- package/lang/translations/ru.po +17 -1
- package/lang/translations/si.po +17 -1
- package/lang/translations/sk.po +17 -1
- package/lang/translations/sq.po +17 -1
- package/lang/translations/sr-latn.po +17 -1
- package/lang/translations/sr.po +17 -1
- package/lang/translations/sv.po +17 -1
- package/lang/translations/tk.po +17 -1
- package/lang/translations/tr.po +17 -1
- package/lang/translations/ug.po +17 -1
- package/lang/translations/uk.po +17 -1
- package/lang/translations/uz.po +125 -0
- package/lang/translations/vi.po +17 -1
- package/lang/translations/zh-cn.po +17 -1
- package/lang/translations/zh.po +36 -20
- package/package.json +27 -27
- package/src/checktodolistcommand.js +1 -1
- package/src/converters.js +14 -15
- package/src/indentcommand.js +1 -1
- package/src/index.js +4 -4
- package/src/list.js +24 -1
- package/src/listcommand.js +2 -2
- package/src/listediting.js +1 -1
- package/src/listproperties.js +96 -0
- package/src/{liststyleediting.js → listpropertiesediting.js} +299 -122
- package/src/listpropertiesui.js +314 -0
- package/src/listreversedcommand.js +64 -0
- package/src/liststartcommand.js +63 -0
- package/src/liststyle.js +12 -6
- package/src/liststylecommand.js +5 -22
- package/src/listui.js +1 -1
- package/src/todolist.js +1 -1
- package/src/todolistconverters.js +1 -1
- package/src/todolistediting.js +1 -1
- package/src/todolistui.js +1 -1
- package/src/ui/collapsibleview.js +152 -0
- package/src/ui/listpropertiesview.js +405 -0
- package/src/utils.js +49 -4
- package/theme/collapsible.css +10 -0
- package/theme/listproperties.css +10 -0
- package/theme/liststyles.css +2 -6
- package/theme/todolist.css +1 -1
- package/CHANGELOG.md +0 -272
- package/src/liststyleui.js +0 -225
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module list/ui/collapsibleview
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { View, ButtonView } from 'ckeditor5/src/ui';
|
|
11
|
+
|
|
12
|
+
// eslint-disable-next-line ckeditor5-rules/ckeditor-imports
|
|
13
|
+
import dropdownArrowIcon from '@ckeditor/ckeditor5-ui/theme/icons/dropdown-arrow.svg';
|
|
14
|
+
|
|
15
|
+
import '../../theme/collapsible.css';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A collapsible UI component. Consists of a labeled button and a container which can be collapsed
|
|
19
|
+
* by clicking the button. The collapsible container can be a host to other UI views.
|
|
20
|
+
*
|
|
21
|
+
* @protected
|
|
22
|
+
* @extends module:ui/view~View
|
|
23
|
+
*/
|
|
24
|
+
export default class CollapsibleView extends View {
|
|
25
|
+
/**
|
|
26
|
+
* Creates an instance of the collapsible view.
|
|
27
|
+
*
|
|
28
|
+
* @param {module:utils/locale~Locale} locale The {@link module:core/editor/editor~Editor#locale} instance.
|
|
29
|
+
* @param {Array.<module:ui/view~View>} [childViews] An optional array of initial child views to be inserted
|
|
30
|
+
* into the collapsible.
|
|
31
|
+
*/
|
|
32
|
+
constructor( locale, childViews ) {
|
|
33
|
+
super( locale );
|
|
34
|
+
|
|
35
|
+
const bind = this.bindTemplate;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* `true` when the container with {@link #children} is collapsed. `false` otherwise.
|
|
39
|
+
*
|
|
40
|
+
* @observable
|
|
41
|
+
* @member {Boolean} #isCollapsed
|
|
42
|
+
*/
|
|
43
|
+
this.set( 'isCollapsed', false );
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The text label of the {@link #buttonView}.
|
|
47
|
+
*
|
|
48
|
+
* @observable
|
|
49
|
+
* @member {String} #label
|
|
50
|
+
* @default 'Show more'
|
|
51
|
+
*/
|
|
52
|
+
this.set( 'label', '' );
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The main button that, when clicked, collapses or expands the container with {@link #children}.
|
|
56
|
+
*
|
|
57
|
+
* @readonly
|
|
58
|
+
* @member {module:ui/button/buttonview~ButtonView} #buttonView
|
|
59
|
+
*/
|
|
60
|
+
this.buttonView = this._createButtonView();
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* A collection of the child views that can be collapsed by clicking the {@link #buttonView}.
|
|
64
|
+
*
|
|
65
|
+
* @readonly
|
|
66
|
+
* @member {module:ui/viewcollection~ViewCollection} #children
|
|
67
|
+
*/
|
|
68
|
+
this.children = this.createCollection();
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The ID of the label inside the {@link #buttonView} that describes the collapsible
|
|
72
|
+
* container for assistive technologies. Set after the button was {@link #render rendered}.
|
|
73
|
+
*
|
|
74
|
+
* @private
|
|
75
|
+
* @readonly
|
|
76
|
+
* @observable
|
|
77
|
+
* @member {String} #_collapsibleAriaLabelUid
|
|
78
|
+
*/
|
|
79
|
+
this.set( '_collapsibleAriaLabelUid' );
|
|
80
|
+
|
|
81
|
+
if ( childViews ) {
|
|
82
|
+
this.children.addMany( childViews );
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
this.setTemplate( {
|
|
86
|
+
tag: 'div',
|
|
87
|
+
attributes: {
|
|
88
|
+
class: [
|
|
89
|
+
'ck',
|
|
90
|
+
'ck-collapsible',
|
|
91
|
+
bind.if( 'isCollapsed', 'ck-collapsible_collapsed' )
|
|
92
|
+
]
|
|
93
|
+
},
|
|
94
|
+
children: [
|
|
95
|
+
this.buttonView,
|
|
96
|
+
{
|
|
97
|
+
tag: 'div',
|
|
98
|
+
attributes: {
|
|
99
|
+
class: [
|
|
100
|
+
'ck',
|
|
101
|
+
'ck-collapsible__children'
|
|
102
|
+
],
|
|
103
|
+
role: 'region',
|
|
104
|
+
hidden: bind.if( 'isCollapsed', 'hidden' ),
|
|
105
|
+
'aria-labelledby': bind.to( '_collapsibleAriaLabelUid' )
|
|
106
|
+
},
|
|
107
|
+
children: this.children
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
} );
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @inheritDoc
|
|
115
|
+
*/
|
|
116
|
+
render() {
|
|
117
|
+
super.render();
|
|
118
|
+
|
|
119
|
+
this._collapsibleAriaLabelUid = this.buttonView.labelView.element.id;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Creates the main {@link #buttonView} of the collapsible.
|
|
124
|
+
*
|
|
125
|
+
* @private
|
|
126
|
+
* @returns {module:ui/button/buttonview~ButtonView}
|
|
127
|
+
*/
|
|
128
|
+
_createButtonView() {
|
|
129
|
+
const buttonView = new ButtonView( this.locale );
|
|
130
|
+
const bind = buttonView.bindTemplate;
|
|
131
|
+
|
|
132
|
+
buttonView.set( {
|
|
133
|
+
withText: true,
|
|
134
|
+
icon: dropdownArrowIcon
|
|
135
|
+
} );
|
|
136
|
+
|
|
137
|
+
buttonView.extendTemplate( {
|
|
138
|
+
attributes: {
|
|
139
|
+
'aria-expanded': bind.to( 'isOn', value => String( value ) )
|
|
140
|
+
}
|
|
141
|
+
} );
|
|
142
|
+
|
|
143
|
+
buttonView.bind( 'label' ).to( this );
|
|
144
|
+
buttonView.bind( 'isOn' ).to( this, 'isCollapsed', isCollapsed => !isCollapsed );
|
|
145
|
+
|
|
146
|
+
buttonView.on( 'execute', () => {
|
|
147
|
+
this.isCollapsed = !this.isCollapsed;
|
|
148
|
+
} );
|
|
149
|
+
|
|
150
|
+
return buttonView;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module list/ui/listpropertiesview
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
View,
|
|
12
|
+
ViewCollection,
|
|
13
|
+
FocusCycler,
|
|
14
|
+
SwitchButtonView,
|
|
15
|
+
LabeledFieldView,
|
|
16
|
+
createLabeledInputNumber
|
|
17
|
+
} from 'ckeditor5/src/ui';
|
|
18
|
+
import {
|
|
19
|
+
FocusTracker,
|
|
20
|
+
KeystrokeHandler
|
|
21
|
+
} from 'ckeditor5/src/utils';
|
|
22
|
+
|
|
23
|
+
import CollapsibleView from './collapsibleview';
|
|
24
|
+
|
|
25
|
+
import '../../theme/listproperties.css';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The list properties view to be displayed in the list dropdown.
|
|
29
|
+
*
|
|
30
|
+
* Contains a grid of available list styles and, for numbered list, also the list start index and reversed fields.
|
|
31
|
+
*
|
|
32
|
+
* @extends module:ui/view~View
|
|
33
|
+
*/
|
|
34
|
+
export default class ListPropertiesView extends View {
|
|
35
|
+
/**
|
|
36
|
+
* Creates an instance of the list properties view.
|
|
37
|
+
*
|
|
38
|
+
* @param {module:utils/locale~Locale} locale The {@link module:core/editor/editor~Editor#locale} instance.
|
|
39
|
+
* @param {Object} options Options of the view.
|
|
40
|
+
* @param {Object.<String,Boolean>} options.enabledProperties An object containing the configuration of enabled list property names.
|
|
41
|
+
* Allows conditional rendering the sub-components of the properties view.
|
|
42
|
+
* @param {Array.<module:ui/button/buttonview~ButtonView>|null} options.styleButtonViews A list of style buttons to be rendered
|
|
43
|
+
* inside the styles grid. The grid will not be rendered when `enabledProperties` does not include the `'styles'` key.
|
|
44
|
+
* @param {String} options.styleGridAriaLabel An assistive technologies label set on the grid of styles (if the grid is rendered).
|
|
45
|
+
*/
|
|
46
|
+
constructor( locale, { enabledProperties, styleButtonViews, styleGridAriaLabel } ) {
|
|
47
|
+
super( locale );
|
|
48
|
+
|
|
49
|
+
const elementCssClasses = [
|
|
50
|
+
'ck',
|
|
51
|
+
'ck-list-properties'
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* A collection of the child views.
|
|
56
|
+
*
|
|
57
|
+
* @readonly
|
|
58
|
+
* @member {module:ui/viewcollection~ViewCollection}
|
|
59
|
+
*/
|
|
60
|
+
this.children = this.createCollection();
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* A view that renders the grid of list styles.
|
|
64
|
+
*
|
|
65
|
+
* @readonly
|
|
66
|
+
* @member {module:ui/view~View|null}
|
|
67
|
+
*/
|
|
68
|
+
this.stylesView = null;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* A collapsible view that hosts additional list property fields ({@link #startIndexFieldView} and
|
|
72
|
+
* {@link #reversedSwitchButtonView}) to visually separate them from the {@link #stylesView grid of styles}.
|
|
73
|
+
*
|
|
74
|
+
* **Note**: Only present when:
|
|
75
|
+
* * the view represents **numbered** list properties,
|
|
76
|
+
* * and the {@link #stylesView} is rendered,
|
|
77
|
+
* * and either {@link #startIndexFieldView} or {@link #reversedSwitchButtonView} is rendered.
|
|
78
|
+
*
|
|
79
|
+
* @readonly
|
|
80
|
+
* @member {module:list/ui/collapsibleview~CollapsibleView|null}
|
|
81
|
+
*/
|
|
82
|
+
this.additionalPropertiesCollapsibleView = null;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* A labeled number field allowing the user to set the start index of the list.
|
|
86
|
+
*
|
|
87
|
+
* **Note**: Only present when the view represents **numbered** list properties.
|
|
88
|
+
*
|
|
89
|
+
* @readonly
|
|
90
|
+
* @member {module:ui/labeledfield/labeledfieldview~LabeledFieldView|null}
|
|
91
|
+
*/
|
|
92
|
+
this.startIndexFieldView = null;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* A switch button allowing the user to make the edited list reversed.
|
|
96
|
+
*
|
|
97
|
+
* **Note**: Only present when the view represents **numbered** list properties.
|
|
98
|
+
*
|
|
99
|
+
* @readonly
|
|
100
|
+
* @member {module:ui/button/switchbuttonview~SwitchButtonView|null}
|
|
101
|
+
*/
|
|
102
|
+
this.reversedSwitchButtonView = null;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Tracks information about the DOM focus in the view.
|
|
106
|
+
*
|
|
107
|
+
* @readonly
|
|
108
|
+
* @member {module:utils/focustracker~FocusTracker}
|
|
109
|
+
*/
|
|
110
|
+
this.focusTracker = new FocusTracker();
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
|
|
114
|
+
*
|
|
115
|
+
* @readonly
|
|
116
|
+
* @member {module:utils/keystrokehandler~KeystrokeHandler}
|
|
117
|
+
*/
|
|
118
|
+
this.keystrokes = new KeystrokeHandler();
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* A collection of views that can be focused in the properties view.
|
|
122
|
+
*
|
|
123
|
+
* @readonly
|
|
124
|
+
* @member {module:ui/viewcollection~ViewCollection}
|
|
125
|
+
*/
|
|
126
|
+
this.focusables = new ViewCollection();
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Helps cycling over {@link #focusables} in the view.
|
|
130
|
+
*
|
|
131
|
+
* @readonly
|
|
132
|
+
* @protected
|
|
133
|
+
* @member {module:ui/focuscycler~FocusCycler}
|
|
134
|
+
*/
|
|
135
|
+
this.focusCycler = new FocusCycler( {
|
|
136
|
+
focusables: this.focusables,
|
|
137
|
+
focusTracker: this.focusTracker,
|
|
138
|
+
keystrokeHandler: this.keystrokes,
|
|
139
|
+
actions: {
|
|
140
|
+
// Navigate #children backwards using the <kbd>Shift</kbd> + <kbd>Tab</kbd> keystroke.
|
|
141
|
+
focusPrevious: 'shift + tab',
|
|
142
|
+
|
|
143
|
+
// Navigate #children forwards using the <kbd>Tab</kbd> key.
|
|
144
|
+
focusNext: 'tab'
|
|
145
|
+
}
|
|
146
|
+
} );
|
|
147
|
+
|
|
148
|
+
// The rendering of the styles grid is conditional. When there is no styles grid, the view will render without collapsible
|
|
149
|
+
// for numbered list properties, hence simplifying the layout.
|
|
150
|
+
if ( enabledProperties.styles ) {
|
|
151
|
+
this.stylesView = this._createStylesView( styleButtonViews, styleGridAriaLabel );
|
|
152
|
+
this.children.add( this.stylesView );
|
|
153
|
+
} else {
|
|
154
|
+
elementCssClasses.push( 'ck-list-properties_without-styles' );
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// The rendering of the numbered list property views is also conditional. It only makes sense for the numbered list
|
|
158
|
+
// dropdown. The unordered list does not have such properties.
|
|
159
|
+
if ( enabledProperties.startIndex || enabledProperties.reversed ) {
|
|
160
|
+
this._addNumberedListPropertyViews( enabledProperties, styleButtonViews );
|
|
161
|
+
|
|
162
|
+
elementCssClasses.push( 'ck-list-properties_with-numbered-properties' );
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
this.setTemplate( {
|
|
166
|
+
tag: 'div',
|
|
167
|
+
attributes: {
|
|
168
|
+
class: elementCssClasses
|
|
169
|
+
},
|
|
170
|
+
children: this.children
|
|
171
|
+
} );
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* @inheritDoc
|
|
176
|
+
*/
|
|
177
|
+
render() {
|
|
178
|
+
super.render();
|
|
179
|
+
|
|
180
|
+
if ( this.stylesView ) {
|
|
181
|
+
for ( const styleButtonView of this.stylesView.children ) {
|
|
182
|
+
// Register the view as focusable.
|
|
183
|
+
this.focusables.add( styleButtonView );
|
|
184
|
+
|
|
185
|
+
// Register the view in the focus tracker.
|
|
186
|
+
this.focusTracker.add( styleButtonView.element );
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Register the collapsible toggle button to the focus system.
|
|
190
|
+
if ( this.startIndexFieldView || this.reversedSwitchButtonView ) {
|
|
191
|
+
this.focusables.add( this.children.last.buttonView );
|
|
192
|
+
this.focusTracker.add( this.children.last.buttonView.element );
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if ( this.startIndexFieldView ) {
|
|
197
|
+
this.focusables.add( this.startIndexFieldView );
|
|
198
|
+
this.focusTracker.add( this.startIndexFieldView.element );
|
|
199
|
+
|
|
200
|
+
// Intercept the `selectstart` event, which is blocked by default because of the default behavior
|
|
201
|
+
// of the DropdownView#panelView.
|
|
202
|
+
// TODO: blocking `selectstart` in the #panelView should be configurable per–drop–down instance.
|
|
203
|
+
this.listenTo( this.startIndexFieldView.element, 'selectstart', ( evt, domEvt ) => {
|
|
204
|
+
domEvt.stopPropagation();
|
|
205
|
+
}, { priority: 'high' } );
|
|
206
|
+
|
|
207
|
+
const stopPropagation = data => data.stopPropagation();
|
|
208
|
+
|
|
209
|
+
// Since the form is in the dropdown panel which is a child of the toolbar, the toolbar's
|
|
210
|
+
// keystroke handler would take over the key management in the input. We need to prevent
|
|
211
|
+
// this ASAP. Otherwise, the basic caret movement using the arrow keys will be impossible.
|
|
212
|
+
this.keystrokes.set( 'arrowright', stopPropagation );
|
|
213
|
+
this.keystrokes.set( 'arrowleft', stopPropagation );
|
|
214
|
+
this.keystrokes.set( 'arrowup', stopPropagation );
|
|
215
|
+
this.keystrokes.set( 'arrowdown', stopPropagation );
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if ( this.reversedSwitchButtonView ) {
|
|
219
|
+
this.focusables.add( this.reversedSwitchButtonView );
|
|
220
|
+
this.focusTracker.add( this.reversedSwitchButtonView.element );
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Start listening for the keystrokes coming from #element.
|
|
224
|
+
this.keystrokes.listenTo( this.element );
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* @inheritDoc
|
|
229
|
+
*/
|
|
230
|
+
focus() {
|
|
231
|
+
this.focusCycler.focusFirst();
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* @inheritDoc
|
|
236
|
+
*/
|
|
237
|
+
focusLast() {
|
|
238
|
+
this.focusCycler.focusLast();
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* @inheritDoc
|
|
243
|
+
*/
|
|
244
|
+
destroy() {
|
|
245
|
+
super.destroy();
|
|
246
|
+
|
|
247
|
+
this.focusTracker.destroy();
|
|
248
|
+
this.keystrokes.destroy();
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Creates the list styles grid.
|
|
253
|
+
*
|
|
254
|
+
* @protected
|
|
255
|
+
* @param {Array.<module:ui/button/buttonview~ButtonView>} styleButtons Buttons to be placed in the grid.
|
|
256
|
+
* @param {String} styleGridAriaLabel The assistive technology label of the grid.
|
|
257
|
+
* @returns {module:ui/view~View}
|
|
258
|
+
*/
|
|
259
|
+
_createStylesView( styleButtons, styleGridAriaLabel ) {
|
|
260
|
+
const stylesView = new View( this.locale );
|
|
261
|
+
|
|
262
|
+
stylesView.children = stylesView.createCollection( this.locale );
|
|
263
|
+
stylesView.children.addMany( styleButtons );
|
|
264
|
+
|
|
265
|
+
stylesView.setTemplate( {
|
|
266
|
+
tag: 'div',
|
|
267
|
+
attributes: {
|
|
268
|
+
'aria-label': styleGridAriaLabel,
|
|
269
|
+
class: [
|
|
270
|
+
'ck',
|
|
271
|
+
'ck-list-styles-list'
|
|
272
|
+
]
|
|
273
|
+
},
|
|
274
|
+
children: stylesView.children
|
|
275
|
+
} );
|
|
276
|
+
|
|
277
|
+
stylesView.children.delegate( 'execute' ).to( this );
|
|
278
|
+
|
|
279
|
+
return stylesView;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Renders {@link #startIndexFieldView} and/or {@link #reversedSwitchButtonView} depending on the configuration of the properties view.
|
|
284
|
+
*
|
|
285
|
+
* @private
|
|
286
|
+
* @param {Object.<String,Boolean>} options.enabledProperties An object containing the configuration of enabled list property names
|
|
287
|
+
* (see {@link #constructor}).
|
|
288
|
+
*/
|
|
289
|
+
_addNumberedListPropertyViews( enabledProperties ) {
|
|
290
|
+
const t = this.locale.t;
|
|
291
|
+
const numberedPropertyViews = [];
|
|
292
|
+
|
|
293
|
+
if ( enabledProperties.startIndex ) {
|
|
294
|
+
this.startIndexFieldView = this._createStartIndexField();
|
|
295
|
+
numberedPropertyViews.push( this.startIndexFieldView );
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if ( enabledProperties.reversed ) {
|
|
299
|
+
this.reversedSwitchButtonView = this._createReversedSwitchButton();
|
|
300
|
+
numberedPropertyViews.push( this.reversedSwitchButtonView );
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// When there are some style buttons, pack the numbered list properties into a collapsible to separate them.
|
|
304
|
+
if ( enabledProperties.styles ) {
|
|
305
|
+
this.additionalPropertiesCollapsibleView = new CollapsibleView( this.locale, numberedPropertyViews );
|
|
306
|
+
|
|
307
|
+
this.additionalPropertiesCollapsibleView.set( {
|
|
308
|
+
label: t( 'List properties' ),
|
|
309
|
+
isCollapsed: true
|
|
310
|
+
} );
|
|
311
|
+
|
|
312
|
+
// Don't enable the collapsible view unless either start index or reversed field is enabled (e.g. when no list is selected).
|
|
313
|
+
this.additionalPropertiesCollapsibleView.buttonView.bind( 'isEnabled' ).toMany(
|
|
314
|
+
numberedPropertyViews, 'isEnabled', ( ...areEnabled ) => areEnabled.some( isEnabled => isEnabled ) );
|
|
315
|
+
|
|
316
|
+
// Automatically collapse the additional properties collapsible when either start index or reversed field gets disabled.
|
|
317
|
+
this.additionalPropertiesCollapsibleView.buttonView.on( 'change:isEnabled', ( evt, data, isEnabled ) => {
|
|
318
|
+
if ( !isEnabled ) {
|
|
319
|
+
this.additionalPropertiesCollapsibleView.isCollapsed = true;
|
|
320
|
+
}
|
|
321
|
+
} );
|
|
322
|
+
|
|
323
|
+
this.children.add( this.additionalPropertiesCollapsibleView );
|
|
324
|
+
} else {
|
|
325
|
+
this.children.addMany( numberedPropertyViews );
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Creates the list start index labeled field.
|
|
331
|
+
*
|
|
332
|
+
* @private
|
|
333
|
+
* @protected
|
|
334
|
+
* @returns {module:ui/labeledfield/labeledfieldview~LabeledFieldView}
|
|
335
|
+
*/
|
|
336
|
+
_createStartIndexField() {
|
|
337
|
+
const t = this.locale.t;
|
|
338
|
+
const startIndexFieldView = new LabeledFieldView( this.locale, createLabeledInputNumber );
|
|
339
|
+
|
|
340
|
+
startIndexFieldView.set( {
|
|
341
|
+
label: t( 'Start at' ),
|
|
342
|
+
class: 'ck-numbered-list-properties__start-index'
|
|
343
|
+
} );
|
|
344
|
+
|
|
345
|
+
startIndexFieldView.fieldView.set( {
|
|
346
|
+
min: 1,
|
|
347
|
+
step: 1,
|
|
348
|
+
value: 1,
|
|
349
|
+
inputMode: 'numeric'
|
|
350
|
+
} );
|
|
351
|
+
|
|
352
|
+
startIndexFieldView.fieldView.on( 'input', () => {
|
|
353
|
+
const inputElement = startIndexFieldView.fieldView.element;
|
|
354
|
+
const startIndex = inputElement.valueAsNumber;
|
|
355
|
+
|
|
356
|
+
if ( Number.isNaN( startIndex ) ) {
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if ( !inputElement.checkValidity() ) {
|
|
361
|
+
startIndexFieldView.errorText = t( 'Start index must be greater than 0.' );
|
|
362
|
+
} else {
|
|
363
|
+
this.fire( 'listStart', { startIndex } );
|
|
364
|
+
}
|
|
365
|
+
} );
|
|
366
|
+
|
|
367
|
+
return startIndexFieldView;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Creates the reversed list switch button.
|
|
372
|
+
*
|
|
373
|
+
* @private
|
|
374
|
+
* @protected
|
|
375
|
+
* @returns {module:ui/button/switchbuttonview~SwitchButtonView}
|
|
376
|
+
*/
|
|
377
|
+
_createReversedSwitchButton() {
|
|
378
|
+
const t = this.locale.t;
|
|
379
|
+
const reversedButtonView = new SwitchButtonView( this.locale );
|
|
380
|
+
|
|
381
|
+
reversedButtonView.set( {
|
|
382
|
+
withText: true,
|
|
383
|
+
label: t( 'Reversed order' ),
|
|
384
|
+
class: 'ck-numbered-list-properties__reversed-order'
|
|
385
|
+
} );
|
|
386
|
+
|
|
387
|
+
reversedButtonView.delegate( 'execute' ).to( this, 'listReversed' );
|
|
388
|
+
|
|
389
|
+
return reversedButtonView;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Fired when the list start index value has changed via {@link #startIndexFieldView}.
|
|
394
|
+
*
|
|
395
|
+
* @event listStart
|
|
396
|
+
* @param {Object} data
|
|
397
|
+
* @param {Number} data.startIndex The new start index of the list.
|
|
398
|
+
*/
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Fired when the list order has changed (reversed) via {@link #reversedSwitchButtonView}.
|
|
402
|
+
*
|
|
403
|
+
* @event listReversed
|
|
404
|
+
*/
|
|
405
|
+
}
|
package/src/utils.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Copyright (c) 2003-
|
|
2
|
+
* @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -285,9 +285,9 @@ export function findNestedList( viewElement ) {
|
|
|
285
285
|
}
|
|
286
286
|
|
|
287
287
|
/**
|
|
288
|
-
* Returns an array with all `listItem` elements that
|
|
288
|
+
* Returns an array with all `listItem` elements that represent the same list.
|
|
289
289
|
*
|
|
290
|
-
* It means that values
|
|
290
|
+
* It means that values of `listIndent`, `listType`, `listStyle`, `listReversed` and `listStart` for all items are equal.
|
|
291
291
|
*
|
|
292
292
|
* @param {module:engine/model/position~Position} position Starting position.
|
|
293
293
|
* @param {'forward'|'backward'} direction Walking direction.
|
|
@@ -350,11 +350,21 @@ export function getSiblingNodes( position, direction ) {
|
|
|
350
350
|
// ○ List item 3. [listType=bulleted]
|
|
351
351
|
// ○ List item 4. [listType=bulleted]
|
|
352
352
|
//
|
|
353
|
-
// Abort searching when found a different list style
|
|
353
|
+
// Abort searching when found a different list style,
|
|
354
354
|
if ( element.getAttribute( 'listStyle' ) !== listItem.getAttribute( 'listStyle' ) ) {
|
|
355
355
|
break;
|
|
356
356
|
}
|
|
357
357
|
|
|
358
|
+
// ... different direction
|
|
359
|
+
if ( element.getAttribute( 'listReversed' ) !== listItem.getAttribute( 'listReversed' ) ) {
|
|
360
|
+
break;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// ... and different start index
|
|
364
|
+
if ( element.getAttribute( 'listStart' ) !== listItem.getAttribute( 'listStart' ) ) {
|
|
365
|
+
break;
|
|
366
|
+
}
|
|
367
|
+
|
|
358
368
|
if ( direction === 'backward' ) {
|
|
359
369
|
items.unshift( element );
|
|
360
370
|
} else {
|
|
@@ -365,6 +375,41 @@ export function getSiblingNodes( position, direction ) {
|
|
|
365
375
|
return items;
|
|
366
376
|
}
|
|
367
377
|
|
|
378
|
+
/**
|
|
379
|
+
* Returns an array with all `listItem` elements in the model selection.
|
|
380
|
+
*
|
|
381
|
+
* It returns all the items even if only part of the list is selected, including items that belong to nested lists.
|
|
382
|
+
* If no list is selected, returns an empty array.
|
|
383
|
+
* The order of elements is not specified.
|
|
384
|
+
*
|
|
385
|
+
* @protected
|
|
386
|
+
* @param {module:engine/model/model~Model} model
|
|
387
|
+
* @returns {Array.<module:engine/model/element~Element>}
|
|
388
|
+
*/
|
|
389
|
+
export function getSelectedListItems( model ) {
|
|
390
|
+
const document = model.document;
|
|
391
|
+
|
|
392
|
+
// For all selected blocks find all list items that are being selected
|
|
393
|
+
// and update the `listStyle` attribute in those lists.
|
|
394
|
+
let listItems = [ ...document.selection.getSelectedBlocks() ]
|
|
395
|
+
.filter( element => element.is( 'element', 'listItem' ) )
|
|
396
|
+
.map( element => {
|
|
397
|
+
const position = model.change( writer => writer.createPositionAt( element, 0 ) );
|
|
398
|
+
|
|
399
|
+
return [
|
|
400
|
+
...getSiblingNodes( position, 'backward' ),
|
|
401
|
+
...getSiblingNodes( position, 'forward' )
|
|
402
|
+
];
|
|
403
|
+
} )
|
|
404
|
+
.flat();
|
|
405
|
+
|
|
406
|
+
// Since `getSelectedBlocks()` can return items that belong to the same list, and
|
|
407
|
+
// `getSiblingNodes()` returns the entire list, we need to remove duplicated items.
|
|
408
|
+
listItems = [ ...new Set( listItems ) ];
|
|
409
|
+
|
|
410
|
+
return listItems;
|
|
411
|
+
}
|
|
412
|
+
|
|
368
413
|
// Implementation of getFillerOffset for view list item element.
|
|
369
414
|
//
|
|
370
415
|
// @returns {Number|null} Block filler offset or `null` if block filler is not needed.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
.ck.ck-collapsible.ck-collapsible_collapsed {
|
|
7
|
+
& > .ck-collapsible__children {
|
|
8
|
+
display: none;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/*
|
|
7
|
+
* Note: This file should contain the wireframe styles only. But since there are no such styles,
|
|
8
|
+
* it acts as a message to the builder telling that it should look for the corresponding styles
|
|
9
|
+
* **in the theme** when compiling the editor.
|
|
10
|
+
*/
|
package/theme/liststyles.css
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c) 2003-
|
|
2
|
+
* Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
.ck.ck-list-styles-
|
|
7
|
-
/*
|
|
8
|
-
* Use the benefits of the toolbar (e.g. out-of-the-box keyboard navigation) but make it look
|
|
9
|
-
* like a panel with thumbnails (previews).
|
|
10
|
-
*/
|
|
6
|
+
.ck.ck-list-styles-list {
|
|
11
7
|
display: grid;
|
|
12
8
|
}
|
package/theme/todolist.css
CHANGED