@ckeditor/ckeditor5-ui 34.2.0 → 35.1.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/CHANGELOG.md +542 -0
- package/LICENSE.md +4 -0
- package/lang/contexts.json +4 -2
- package/lang/translations/ar.po +31 -23
- package/lang/translations/ast.po +12 -4
- package/lang/translations/az.po +12 -4
- package/lang/translations/bg.po +113 -0
- package/lang/translations/bn.po +113 -0
- package/lang/translations/ca.po +113 -0
- package/lang/translations/cs.po +12 -4
- package/lang/translations/da.po +12 -4
- package/lang/translations/de-ch.po +12 -4
- package/lang/translations/de.po +12 -4
- package/lang/translations/el.po +12 -4
- package/lang/translations/en-au.po +12 -4
- package/lang/translations/en-gb.po +12 -4
- package/lang/translations/en.po +12 -4
- package/lang/translations/eo.po +12 -4
- package/lang/translations/es.po +12 -4
- package/lang/translations/et.po +12 -4
- package/lang/translations/eu.po +12 -4
- package/lang/translations/fa.po +12 -4
- package/lang/translations/fi.po +14 -6
- package/lang/translations/fr.po +12 -4
- package/lang/translations/gl.po +12 -4
- package/lang/translations/he.po +26 -18
- package/lang/translations/hi.po +12 -4
- package/lang/translations/hr.po +12 -4
- package/lang/translations/hu.po +12 -4
- package/lang/translations/id.po +12 -4
- package/lang/translations/it.po +12 -4
- package/lang/translations/ja.po +17 -9
- package/lang/translations/km.po +12 -4
- package/lang/translations/kn.po +12 -4
- package/lang/translations/ko.po +12 -4
- package/lang/translations/ku.po +12 -4
- package/lang/translations/lt.po +16 -8
- package/lang/translations/lv.po +12 -4
- package/lang/translations/ms.po +113 -0
- package/lang/translations/nb.po +12 -4
- package/lang/translations/ne.po +12 -4
- package/lang/translations/nl.po +12 -4
- package/lang/translations/no.po +12 -4
- package/lang/translations/pl.po +12 -4
- package/lang/translations/pt-br.po +12 -4
- package/lang/translations/pt.po +29 -21
- package/lang/translations/ro.po +12 -4
- package/lang/translations/ru.po +12 -4
- package/lang/translations/sk.po +12 -4
- package/lang/translations/sl.po +11 -3
- package/lang/translations/sq.po +12 -4
- package/lang/translations/sr-latn.po +12 -4
- package/lang/translations/sr.po +12 -4
- package/lang/translations/sv.po +31 -23
- package/lang/translations/th.po +18 -10
- package/lang/translations/tk.po +12 -4
- package/lang/translations/tr.po +12 -4
- package/lang/translations/tt.po +113 -0
- package/lang/translations/ug.po +12 -4
- package/lang/translations/uk.po +12 -4
- package/lang/translations/ur.po +29 -21
- package/lang/translations/uz.po +12 -4
- package/lang/translations/vi.po +12 -4
- package/lang/translations/zh-cn.po +12 -4
- package/lang/translations/zh.po +12 -4
- package/package.json +23 -20
- package/src/bindings/addkeyboardhandlingforgrid.js +76 -0
- package/src/button/button.jsdoc +2 -2
- package/src/button/buttonview.js +19 -35
- package/src/colorgrid/colorgridview.js +19 -25
- package/src/dropdown/button/dropdownbuttonview.js +2 -1
- package/src/dropdown/button/splitbuttonview.js +4 -1
- package/src/dropdown/dropdownpanelview.js +22 -2
- package/src/dropdown/dropdownview.js +12 -2
- package/src/dropdown/utils.js +71 -1
- package/src/editableui/inline/inlineeditableuiview.js +18 -3
- package/src/icon/iconview.js +3 -1
- package/src/index.js +2 -2
- package/src/list/listitemview.js +14 -1
- package/src/panel/balloon/balloonpanelview.js +132 -78
- package/src/toolbar/balloon/balloontoolbar.js +17 -5
- package/src/toolbar/block/blocktoolbar.js +17 -0
- package/src/tooltipmanager.js +430 -0
- package/theme/components/button/button.css +0 -8
- package/theme/components/dropdown/dropdown.css +0 -12
- package/theme/components/dropdown/splitbutton.css +0 -7
- package/theme/components/responsive-form/responsiveform.css +28 -16
- package/theme/components/tooltip/tooltip.css +3 -26
- package/src/toolbar/enabletoolbarkeyboardfocus.js +0 -64
- package/src/tooltip/tooltipview.js +0 -107
- package/theme/components/tooltip/mixins/_tooltip.css +0 -54
package/src/button/buttonview.js
CHANGED
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
|
|
10
10
|
import View from '../view';
|
|
11
11
|
import IconView from '../icon/iconview';
|
|
12
|
-
import TooltipView from '../tooltip/tooltipview';
|
|
13
12
|
|
|
14
13
|
import uid from '@ckeditor/ckeditor5-utils/src/uid';
|
|
15
14
|
import { getEnvKeystrokeText } from '@ckeditor/ckeditor5-utils/src/keyboard';
|
|
15
|
+
import env from '@ckeditor/ckeditor5-utils/src/env';
|
|
16
16
|
|
|
17
17
|
import '../../theme/components/button/button.css';
|
|
18
18
|
|
|
@@ -70,14 +70,6 @@ export default class ButtonView extends View {
|
|
|
70
70
|
*/
|
|
71
71
|
this.children = this.createCollection();
|
|
72
72
|
|
|
73
|
-
/**
|
|
74
|
-
* Tooltip of the button view. It is configurable using the {@link #tooltip tooltip attribute}.
|
|
75
|
-
*
|
|
76
|
-
* @readonly
|
|
77
|
-
* @member {module:ui/tooltip/tooltipview~TooltipView} #tooltipView
|
|
78
|
-
*/
|
|
79
|
-
this.tooltipView = this._createTooltipView();
|
|
80
|
-
|
|
81
73
|
/**
|
|
82
74
|
* Label of the button view. It is configurable using the {@link #label label attribute}.
|
|
83
75
|
*
|
|
@@ -118,7 +110,7 @@ export default class ButtonView extends View {
|
|
|
118
110
|
* @see #_getTooltipString
|
|
119
111
|
* @private
|
|
120
112
|
* @observable
|
|
121
|
-
* @member {
|
|
113
|
+
* @member {String|undefined} #_tooltipString
|
|
122
114
|
*/
|
|
123
115
|
this.bind( '_tooltipString' ).to(
|
|
124
116
|
this, 'tooltip',
|
|
@@ -127,7 +119,7 @@ export default class ButtonView extends View {
|
|
|
127
119
|
this._getTooltipString.bind( this )
|
|
128
120
|
);
|
|
129
121
|
|
|
130
|
-
|
|
122
|
+
const template = {
|
|
131
123
|
tag: 'button',
|
|
132
124
|
|
|
133
125
|
attributes: {
|
|
@@ -145,16 +137,14 @@ export default class ButtonView extends View {
|
|
|
145
137
|
tabindex: bind.to( 'tabindex' ),
|
|
146
138
|
'aria-labelledby': `ck-editor__aria-label_${ ariaLabelUid }`,
|
|
147
139
|
'aria-disabled': bind.if( 'isEnabled', true, value => !value ),
|
|
148
|
-
'aria-pressed': bind.to( 'isOn', value => this.isToggleable ? String( value ) : false )
|
|
140
|
+
'aria-pressed': bind.to( 'isOn', value => this.isToggleable ? String( !!value ) : false ),
|
|
141
|
+
'data-cke-tooltip-text': bind.to( '_tooltipString' ),
|
|
142
|
+
'data-cke-tooltip-position': bind.to( 'tooltipPosition' )
|
|
149
143
|
},
|
|
150
144
|
|
|
151
145
|
children: this.children,
|
|
152
146
|
|
|
153
147
|
on: {
|
|
154
|
-
mousedown: bind.to( evt => {
|
|
155
|
-
evt.preventDefault();
|
|
156
|
-
} ),
|
|
157
|
-
|
|
158
148
|
click: bind.to( evt => {
|
|
159
149
|
// We can't make the button disabled using the disabled attribute, because it won't be focusable.
|
|
160
150
|
// Though, shouldn't this condition be moved to the button controller?
|
|
@@ -167,7 +157,18 @@ export default class ButtonView extends View {
|
|
|
167
157
|
}
|
|
168
158
|
} )
|
|
169
159
|
}
|
|
170
|
-
}
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
// On Safari we have to force the focus on a button on click as it's the only browser
|
|
163
|
+
// that doesn't do that automatically. See #12115.
|
|
164
|
+
if ( env.isSafari ) {
|
|
165
|
+
template.on.mousedown = bind.to( evt => {
|
|
166
|
+
this.focus();
|
|
167
|
+
evt.preventDefault();
|
|
168
|
+
} );
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
this.setTemplate( template );
|
|
171
172
|
}
|
|
172
173
|
|
|
173
174
|
/**
|
|
@@ -181,7 +182,6 @@ export default class ButtonView extends View {
|
|
|
181
182
|
this.children.add( this.iconView );
|
|
182
183
|
}
|
|
183
184
|
|
|
184
|
-
this.children.add( this.tooltipView );
|
|
185
185
|
this.children.add( this.labelView );
|
|
186
186
|
|
|
187
187
|
if ( this.withKeystroke && this.keystroke ) {
|
|
@@ -196,22 +196,6 @@ export default class ButtonView extends View {
|
|
|
196
196
|
this.element.focus();
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
/**
|
|
200
|
-
* Creates a {@link module:ui/tooltip/tooltipview~TooltipView} instance and binds it with button
|
|
201
|
-
* attributes.
|
|
202
|
-
*
|
|
203
|
-
* @private
|
|
204
|
-
* @returns {module:ui/tooltip/tooltipview~TooltipView}
|
|
205
|
-
*/
|
|
206
|
-
_createTooltipView() {
|
|
207
|
-
const tooltipView = new TooltipView();
|
|
208
|
-
|
|
209
|
-
tooltipView.bind( 'text' ).to( this, '_tooltipString' );
|
|
210
|
-
tooltipView.bind( 'position' ).to( this, 'tooltipPosition' );
|
|
211
|
-
|
|
212
|
-
return tooltipView;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
199
|
/**
|
|
216
200
|
* Creates a label view instance and binds it with button attributes.
|
|
217
201
|
*
|
|
@@ -276,7 +260,7 @@ export default class ButtonView extends View {
|
|
|
276
260
|
}
|
|
277
261
|
|
|
278
262
|
/**
|
|
279
|
-
* Gets the text for the
|
|
263
|
+
* Gets the text for the tooltip from the combination of
|
|
280
264
|
* {@link #tooltip}, {@link #label} and {@link #keystroke} attributes.
|
|
281
265
|
*
|
|
282
266
|
* @private
|
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
import View from '../view';
|
|
11
11
|
import ColorTileView from './colortileview';
|
|
12
12
|
import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
|
|
13
|
-
import FocusCycler from '../focuscycler';
|
|
14
13
|
import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';
|
|
14
|
+
import addKeyboardHandlingForGrid from '../bindings/addkeyboardhandlingforgrid';
|
|
15
|
+
|
|
15
16
|
import '../../theme/components/colorgrid/colorgrid.css';
|
|
16
17
|
|
|
17
18
|
/**
|
|
@@ -27,7 +28,7 @@ export default class ColorGridView extends View {
|
|
|
27
28
|
* @param {Object} options Component configuration
|
|
28
29
|
* @param {Array.<module:ui/colorgrid/colorgrid~ColorDefinition>} [options.colorDefinitions] Array with definitions
|
|
29
30
|
* required to create the {@link module:ui/colorgrid/colortile~ColorTileView tiles}.
|
|
30
|
-
* @param {Number} options.columns A number of columns to display the tiles.
|
|
31
|
+
* @param {Number} [options.columns=5] A number of columns to display the tiles.
|
|
31
32
|
*/
|
|
32
33
|
constructor( locale, options ) {
|
|
33
34
|
super( locale );
|
|
@@ -35,9 +36,15 @@ export default class ColorGridView extends View {
|
|
|
35
36
|
const colorDefinitions = options && options.colorDefinitions || [];
|
|
36
37
|
const viewStyleAttribute = {};
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
/**
|
|
40
|
+
* A number of columns for the tiles grid.
|
|
41
|
+
*
|
|
42
|
+
* @readonly
|
|
43
|
+
* @member {Number}
|
|
44
|
+
*/
|
|
45
|
+
this.columns = options && options.columns ? options.columns : 5;
|
|
46
|
+
|
|
47
|
+
viewStyleAttribute.gridTemplateColumns = `repeat( ${ this.columns }, 1fr)`;
|
|
41
48
|
|
|
42
49
|
/**
|
|
43
50
|
* The color of the currently selected color tile in {@link #items}.
|
|
@@ -71,26 +78,6 @@ export default class ColorGridView extends View {
|
|
|
71
78
|
*/
|
|
72
79
|
this.keystrokes = new KeystrokeHandler();
|
|
73
80
|
|
|
74
|
-
/**
|
|
75
|
-
* Helps cycling over focusable {@link #items} in the grid.
|
|
76
|
-
*
|
|
77
|
-
* @readonly
|
|
78
|
-
* @protected
|
|
79
|
-
* @member {module:ui/focuscycler~FocusCycler}
|
|
80
|
-
*/
|
|
81
|
-
this._focusCycler = new FocusCycler( {
|
|
82
|
-
focusables: this.items,
|
|
83
|
-
focusTracker: this.focusTracker,
|
|
84
|
-
keystrokeHandler: this.keystrokes,
|
|
85
|
-
actions: {
|
|
86
|
-
// Navigate grid items backwards using the arrowup key.
|
|
87
|
-
focusPrevious: 'arrowleft',
|
|
88
|
-
|
|
89
|
-
// Navigate grid items forwards using the arrowdown key.
|
|
90
|
-
focusNext: 'arrowright'
|
|
91
|
-
}
|
|
92
|
-
} );
|
|
93
|
-
|
|
94
81
|
this.items.on( 'add', ( evt, colorTile ) => {
|
|
95
82
|
colorTile.isOn = colorTile.color === this.selectedColor;
|
|
96
83
|
} );
|
|
@@ -174,6 +161,13 @@ export default class ColorGridView extends View {
|
|
|
174
161
|
|
|
175
162
|
// Start listening for the keystrokes coming from #element.
|
|
176
163
|
this.keystrokes.listenTo( this.element );
|
|
164
|
+
|
|
165
|
+
addKeyboardHandlingForGrid( {
|
|
166
|
+
keystrokeHandler: this.keystrokes,
|
|
167
|
+
focusTracker: this.focusTracker,
|
|
168
|
+
gridItems: this.items,
|
|
169
|
+
numberOfColumns: this.columns
|
|
170
|
+
} );
|
|
177
171
|
}
|
|
178
172
|
|
|
179
173
|
/**
|
|
@@ -222,7 +222,10 @@ export default class SplitButtonView extends View {
|
|
|
222
222
|
|
|
223
223
|
arrowView.extendTemplate( {
|
|
224
224
|
attributes: {
|
|
225
|
-
class:
|
|
225
|
+
class: [
|
|
226
|
+
'ck-splitbutton__arrow'
|
|
227
|
+
],
|
|
228
|
+
'data-cke-tooltip-disabled': bind.to( 'isOn' ),
|
|
226
229
|
'aria-haspopup': true,
|
|
227
230
|
'aria-expanded': bind.to( 'isOn', value => String( value ) )
|
|
228
231
|
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import View from '../view';
|
|
11
|
+
import { logWarning } from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* The dropdown panel view class.
|
|
@@ -81,13 +82,32 @@ export default class DropdownPanelView extends View {
|
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
/**
|
|
84
|
-
* Focuses the
|
|
85
|
+
* Focuses the first view in the {@link #children} collection.
|
|
85
86
|
*
|
|
86
87
|
* See also {@link module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable}.
|
|
87
88
|
*/
|
|
88
89
|
focus() {
|
|
89
90
|
if ( this.children.length ) {
|
|
90
|
-
this.children.first.focus
|
|
91
|
+
if ( typeof this.children.first.focus === 'function' ) {
|
|
92
|
+
this.children.first.focus();
|
|
93
|
+
} else {
|
|
94
|
+
/**
|
|
95
|
+
* The child view of a dropdown could not be focused because it is missing the `focus()` method.
|
|
96
|
+
*
|
|
97
|
+
* This warning appears when a dropdown {@link module:ui/dropdown/dropdownview~DropdownView#isOpen gets open} and it
|
|
98
|
+
* attempts to focus the {@link module:ui/dropdown/dropdownpanelview~DropdownPanelView#children first child} of its panel
|
|
99
|
+
* but the child does not implement the
|
|
100
|
+
* {@link module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable focusable interface}.
|
|
101
|
+
*
|
|
102
|
+
* Focusing the content of a dropdown on open greatly improves the accessibility. Please make sure the view instance
|
|
103
|
+
* provides the `focus()` method for the best user experience.
|
|
104
|
+
*
|
|
105
|
+
* @error ui-dropdown-panel-focus-child-missing-focus
|
|
106
|
+
* @param {module:ui/view~View} childView
|
|
107
|
+
* @param {module:ui/dropdown/dropdownpanelview~DropdownPanelView} dropdownPanel
|
|
108
|
+
*/
|
|
109
|
+
logWarning( 'ui-dropdown-panel-focus-child-missing-focus', { childView: this.children.first, dropdownPanel: this } );
|
|
110
|
+
}
|
|
91
111
|
}
|
|
92
112
|
}
|
|
93
113
|
|
|
@@ -106,6 +106,10 @@ export default class DropdownView extends View {
|
|
|
106
106
|
/**
|
|
107
107
|
* Controls whether the dropdown view is open, i.e. shows or hides the {@link #panelView panel}.
|
|
108
108
|
*
|
|
109
|
+
* **Note**: When the dropdown gets open, it will attempt to call `focus()` on the first child of its {@link #panelView}.
|
|
110
|
+
* See {@link module:ui/dropdown/utils~addToolbarToDropdown}, {@link module:ui/dropdown/utils~addListToDropdown}, and
|
|
111
|
+
* {@link module:ui/dropdown/utils~focusChildOnDropdownOpen} to learn more about focus management in dropdowns.
|
|
112
|
+
*
|
|
109
113
|
* @observable
|
|
110
114
|
* @member {Boolean} #isOpen
|
|
111
115
|
*/
|
|
@@ -190,7 +194,8 @@ export default class DropdownView extends View {
|
|
|
190
194
|
attributes: {
|
|
191
195
|
class: [
|
|
192
196
|
'ck-dropdown__button'
|
|
193
|
-
]
|
|
197
|
+
],
|
|
198
|
+
'data-cke-tooltip-disabled': bind.to( 'isOpen' )
|
|
194
199
|
}
|
|
195
200
|
} );
|
|
196
201
|
|
|
@@ -248,6 +253,9 @@ export default class DropdownView extends View {
|
|
|
248
253
|
// be updated every time the dropdown is open.
|
|
249
254
|
this.on( 'change:isOpen', () => {
|
|
250
255
|
if ( !this.isOpen ) {
|
|
256
|
+
// If the dropdown was closed, move the focus back to the button (#12125).
|
|
257
|
+
this.focus();
|
|
258
|
+
|
|
251
259
|
return;
|
|
252
260
|
}
|
|
253
261
|
|
|
@@ -263,6 +271,9 @@ export default class DropdownView extends View {
|
|
|
263
271
|
} else {
|
|
264
272
|
this.panelView.position = this.panelPosition;
|
|
265
273
|
}
|
|
274
|
+
|
|
275
|
+
// Focus the first item in the dropdown when the dropdown opened
|
|
276
|
+
this.panelView.focus();
|
|
266
277
|
} );
|
|
267
278
|
|
|
268
279
|
// Listen for keystrokes coming from within #element.
|
|
@@ -270,7 +281,6 @@ export default class DropdownView extends View {
|
|
|
270
281
|
|
|
271
282
|
const closeDropdown = ( data, cancel ) => {
|
|
272
283
|
if ( this.isOpen ) {
|
|
273
|
-
this.buttonView.focus();
|
|
274
284
|
this.isOpen = false;
|
|
275
285
|
cancel();
|
|
276
286
|
}
|
package/src/dropdown/utils.js
CHANGED
|
@@ -19,6 +19,8 @@ import SwitchButtonView from '../button/switchbuttonview';
|
|
|
19
19
|
|
|
20
20
|
import clickOutsideHandler from '../bindings/clickoutsidehandler';
|
|
21
21
|
|
|
22
|
+
import { logWarning } from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
|
|
23
|
+
|
|
22
24
|
import '../../theme/components/dropdown/toolbardropdown.css';
|
|
23
25
|
import '../../theme/components/dropdown/listdropdown.css';
|
|
24
26
|
|
|
@@ -123,12 +125,22 @@ export function createDropdown( locale, ButtonClass = DropdownButtonView ) {
|
|
|
123
125
|
* dropdown.render()
|
|
124
126
|
* document.body.appendChild( dropdown.element );
|
|
125
127
|
*
|
|
128
|
+
* **Note:** To improve the accessibility, you can tell the dropdown to focus the first active button of the toolbar when the dropdown
|
|
129
|
+
* {@link module:ui/dropdown/dropdownview~DropdownView#isOpen gets open}. See the documentation of `options` to learn more.
|
|
130
|
+
*
|
|
126
131
|
* See {@link module:ui/dropdown/utils~createDropdown} and {@link module:ui/toolbar/toolbarview~ToolbarView}.
|
|
127
132
|
*
|
|
128
133
|
* @param {module:ui/dropdown/dropdownview~DropdownView} dropdownView A dropdown instance to which `ToolbarView` will be added.
|
|
129
134
|
* @param {Iterable.<module:ui/button/buttonview~ButtonView>} buttons
|
|
135
|
+
* @param {Object} [options]
|
|
136
|
+
* @param {Boolean} [options.enableActiveItemFocusOnDropdownOpen=false] When set `true`, the focus will automatically move to the first
|
|
137
|
+
* active {@link module:ui/toolbar/toolbarview~ToolbarView#items item} of the toolbar upon
|
|
138
|
+
* {@link module:ui/dropdown/dropdownview~DropdownView#isOpen opening} the dropdown. Active items are those with the `isOn` property set
|
|
139
|
+
* `true` (for instance {@link module:ui/button/buttonview~ButtonView buttons}). If no active items is found, the toolbar will be focused
|
|
140
|
+
* as a whole resulting in the focus moving to its first focusable item (default behavior of
|
|
141
|
+
* {@link module:ui/dropdown/dropdownview~DropdownView}).
|
|
130
142
|
*/
|
|
131
|
-
export function addToolbarToDropdown( dropdownView, buttons ) {
|
|
143
|
+
export function addToolbarToDropdown( dropdownView, buttons, options = {} ) {
|
|
132
144
|
const locale = dropdownView.locale;
|
|
133
145
|
const t = locale.t;
|
|
134
146
|
const toolbarView = dropdownView.toolbarView = new ToolbarView( locale );
|
|
@@ -143,6 +155,11 @@ export function addToolbarToDropdown( dropdownView, buttons ) {
|
|
|
143
155
|
|
|
144
156
|
buttons.map( view => toolbarView.items.add( view ) );
|
|
145
157
|
|
|
158
|
+
if ( options.enableActiveItemFocusOnDropdownOpen ) {
|
|
159
|
+
// Accessibility: Focus the first active button in the toolbar when the dropdown gets open.
|
|
160
|
+
focusChildOnDropdownOpen( dropdownView, () => toolbarView.items.find( item => item.isOn ) );
|
|
161
|
+
}
|
|
162
|
+
|
|
146
163
|
dropdownView.panelView.children.add( toolbarView );
|
|
147
164
|
toolbarView.items.delegate( 'execute' ).to( dropdownView );
|
|
148
165
|
}
|
|
@@ -182,6 +199,9 @@ export function addToolbarToDropdown( dropdownView, buttons ) {
|
|
|
182
199
|
* The `items` collection passed to this methods controls the presence and attributes of respective
|
|
183
200
|
* {@link module:ui/list/listitemview~ListItemView list items}.
|
|
184
201
|
*
|
|
202
|
+
* **Note:** To improve the accessibility, when a list is added to the dropdown using this helper the dropdown will automatically attempt
|
|
203
|
+
* to focus the first active item (a host to a {@link module:ui/button/buttonview~ButtonView} with
|
|
204
|
+
* {@link module:ui/button/buttonview~ButtonView#isOn} set `true`) or the very first item when none are active.
|
|
185
205
|
*
|
|
186
206
|
* See {@link module:ui/dropdown/utils~createDropdown} and {@link module:list/list~List}.
|
|
187
207
|
*
|
|
@@ -219,6 +239,56 @@ export function addListToDropdown( dropdownView, items ) {
|
|
|
219
239
|
dropdownView.panelView.children.add( listView );
|
|
220
240
|
|
|
221
241
|
listView.items.delegate( 'execute' ).to( dropdownView );
|
|
242
|
+
|
|
243
|
+
// Accessibility: Focus the first active button in the list when the dropdown gets open.
|
|
244
|
+
focusChildOnDropdownOpen( dropdownView, () => listView.items.find( item => {
|
|
245
|
+
if ( item instanceof ListItemView ) {
|
|
246
|
+
return item.children.first.isOn;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return false;
|
|
250
|
+
} ) );
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* A helper to be used on an existing {@link module:ui/dropdown/dropdownview~DropdownView} that focuses
|
|
255
|
+
* a specific child in DOM when the dropdown {@link module:ui/dropdown/dropdownview~DropdownView#isOpen gets open}.
|
|
256
|
+
*
|
|
257
|
+
* @param {module:ui/dropdown/dropdownview~DropdownView} dropdownView A dropdown instance to which the focus behavior will be added.
|
|
258
|
+
* @param {Function} childSelectorCallback A callback executed when the dropdown gets open. It should return a {@link module:ui/view~View}
|
|
259
|
+
* instance (child of {@link module:ui/dropdown/dropdownview~DropdownView#panelView}) that will get focused or a falsy value.
|
|
260
|
+
* If falsy value is returned, a default behavior of the dropdown will engage focusing the first focusable child in
|
|
261
|
+
* the {@link module:ui/dropdown/dropdownview~DropdownView#panelView}.
|
|
262
|
+
*/
|
|
263
|
+
export function focusChildOnDropdownOpen( dropdownView, childSelectorCallback ) {
|
|
264
|
+
dropdownView.on( 'change:isOpen', () => {
|
|
265
|
+
if ( !dropdownView.isOpen ) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const childToFocus = childSelectorCallback();
|
|
270
|
+
|
|
271
|
+
if ( !childToFocus ) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if ( typeof childToFocus.focus === 'function' ) {
|
|
276
|
+
childToFocus.focus();
|
|
277
|
+
} else {
|
|
278
|
+
/**
|
|
279
|
+
* The child view of a {@link module:ui/dropdown/dropdownview~DropdownView dropdown} is missing the `focus()` method
|
|
280
|
+
* and could not be focused when the dropdown got {@link module:ui/dropdown/dropdownview~DropdownView#isOpen open}.
|
|
281
|
+
*
|
|
282
|
+
* Making the content of a dropdown focusable in this case greatly improves the accessibility. Please make the view instance
|
|
283
|
+
* implements the {@link module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable focusable interface} for the best user
|
|
284
|
+
* experience.
|
|
285
|
+
*
|
|
286
|
+
* @error ui-dropdown-focus-child-on-open-child-missing-focus
|
|
287
|
+
* @param {module:ui/view~View} view
|
|
288
|
+
*/
|
|
289
|
+
logWarning( 'ui-dropdown-focus-child-on-open-child-missing-focus', { view: childToFocus } );
|
|
290
|
+
}
|
|
291
|
+
}, { priority: 'low' } );
|
|
222
292
|
}
|
|
223
293
|
|
|
224
294
|
// Add a set of default behaviors to dropdown view.
|
|
@@ -23,16 +23,32 @@ export default class InlineEditableUIView extends EditableUIView {
|
|
|
23
23
|
* @param {HTMLElement} [editableElement] The editable element. If not specified, the
|
|
24
24
|
* {@link module:ui/editableui/editableuiview~EditableUIView}
|
|
25
25
|
* will create it. Otherwise, the existing element will be used.
|
|
26
|
+
* @param {Object} [options] Additional configuration of the view.
|
|
27
|
+
* @param {Function} [options.label] A function that gets called with the instance of this view as an argument
|
|
28
|
+
* and should return a string that represents the label of the editable for assistive technologies. If not provided,
|
|
29
|
+
* a default label generator is used.
|
|
26
30
|
*/
|
|
27
|
-
constructor( locale, editingView, editableElement ) {
|
|
31
|
+
constructor( locale, editingView, editableElement, options = {} ) {
|
|
28
32
|
super( locale, editingView, editableElement );
|
|
29
33
|
|
|
34
|
+
const t = locale.t;
|
|
35
|
+
|
|
30
36
|
this.extendTemplate( {
|
|
31
37
|
attributes: {
|
|
32
38
|
role: 'textbox',
|
|
33
39
|
class: 'ck-editor__editable_inline'
|
|
34
40
|
}
|
|
35
41
|
} );
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* A function that gets called with the instance of this view as an argument and should return a string that
|
|
45
|
+
* represents the label of the editable for assistive technologies.
|
|
46
|
+
*
|
|
47
|
+
* @private
|
|
48
|
+
* @readonly
|
|
49
|
+
* @param {Function}
|
|
50
|
+
*/
|
|
51
|
+
this._generateLabel = options.label || ( () => t( 'Editor editing area: %0', this.name ) );
|
|
36
52
|
}
|
|
37
53
|
|
|
38
54
|
/**
|
|
@@ -42,12 +58,11 @@ export default class InlineEditableUIView extends EditableUIView {
|
|
|
42
58
|
super.render();
|
|
43
59
|
|
|
44
60
|
const editingView = this._editingView;
|
|
45
|
-
const t = this.t;
|
|
46
61
|
|
|
47
62
|
editingView.change( writer => {
|
|
48
63
|
const viewRoot = editingView.document.getRoot( this.name );
|
|
49
64
|
|
|
50
|
-
writer.setAttribute( 'aria-label',
|
|
65
|
+
writer.setAttribute( 'aria-label', this._generateLabel( this ), viewRoot );
|
|
51
66
|
} );
|
|
52
67
|
}
|
|
53
68
|
}
|
package/src/icon/iconview.js
CHANGED
|
@@ -103,7 +103,9 @@ export default class IconView extends View {
|
|
|
103
103
|
this.viewBox = viewBox;
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
this.element.
|
|
106
|
+
while ( this.element.firstChild ) {
|
|
107
|
+
this.element.removeChild( this.element.firstChild );
|
|
108
|
+
}
|
|
107
109
|
|
|
108
110
|
while ( svg.childNodes.length > 0 ) {
|
|
109
111
|
this.element.appendChild( svg.childNodes[ 0 ] );
|
package/src/index.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
export { default as clickOutsideHandler } from './bindings/clickoutsidehandler';
|
|
11
11
|
export { default as injectCssTransitionDisabler } from './bindings/injectcsstransitiondisabler';
|
|
12
12
|
export { default as submitHandler } from './bindings/submithandler';
|
|
13
|
+
export { default as addKeyboardHandlingForGrid } from './bindings/addkeyboardhandlingforgrid';
|
|
13
14
|
|
|
14
15
|
export { default as BodyCollection } from './editorui/bodycollection';
|
|
15
16
|
|
|
@@ -52,12 +53,11 @@ export { default as BalloonPanelView } from './panel/balloon/balloonpanelview';
|
|
|
52
53
|
export { default as ContextualBalloon } from './panel/balloon/contextualballoon';
|
|
53
54
|
export { default as StickyPanelView } from './panel/sticky/stickypanelview';
|
|
54
55
|
|
|
55
|
-
export { default as
|
|
56
|
+
export { default as TooltipManager } from './tooltipmanager';
|
|
56
57
|
export { default as Template } from './template';
|
|
57
58
|
|
|
58
59
|
export { default as ToolbarView } from './toolbar/toolbarview';
|
|
59
60
|
export { default as ToolbarSeparatorView } from './toolbar/toolbarseparatorview';
|
|
60
|
-
export { default as enableToolbarKeyboardFocus } from './toolbar/enabletoolbarkeyboardfocus';
|
|
61
61
|
export { default as normalizeToolbarConfig } from './toolbar/normalizetoolbarconfig';
|
|
62
62
|
export { default as BalloonToolbar } from './toolbar/balloon/balloontoolbar';
|
|
63
63
|
export { default as BlockToolbar } from './toolbar/block/blocktoolbar';
|
package/src/list/listitemview.js
CHANGED
|
@@ -21,6 +21,18 @@ export default class ListItemView extends View {
|
|
|
21
21
|
constructor( locale ) {
|
|
22
22
|
super( locale );
|
|
23
23
|
|
|
24
|
+
const bind = this.bindTemplate;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Controls whether the item view is visible. Visible by default, list items are hidden
|
|
28
|
+
* using a CSS class.
|
|
29
|
+
*
|
|
30
|
+
* @observable
|
|
31
|
+
* @default true
|
|
32
|
+
* @member {Boolean} #isVisible
|
|
33
|
+
*/
|
|
34
|
+
this.set( 'isVisible', true );
|
|
35
|
+
|
|
24
36
|
/**
|
|
25
37
|
* Collection of the child views inside of the list item {@link #element}.
|
|
26
38
|
*
|
|
@@ -35,7 +47,8 @@ export default class ListItemView extends View {
|
|
|
35
47
|
attributes: {
|
|
36
48
|
class: [
|
|
37
49
|
'ck',
|
|
38
|
-
'ck-list__item'
|
|
50
|
+
'ck-list__item',
|
|
51
|
+
bind.if( 'isVisible', 'ck-hidden', value => !value )
|
|
39
52
|
]
|
|
40
53
|
},
|
|
41
54
|
|