@ckeditor/ckeditor5-ui 35.2.0 → 35.3.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.
Files changed (59) hide show
  1. package/package.json +31 -23
  2. package/src/bindings/addkeyboardhandlingforgrid.js +45 -57
  3. package/src/bindings/clickoutsidehandler.js +15 -21
  4. package/src/bindings/injectcsstransitiondisabler.js +16 -20
  5. package/src/bindings/preventdefault.js +6 -8
  6. package/src/bindings/submithandler.js +5 -7
  7. package/src/button/button.js +5 -0
  8. package/src/button/buttonview.js +220 -259
  9. package/src/button/switchbuttonview.js +56 -71
  10. package/src/colorgrid/colorgridview.js +135 -197
  11. package/src/colorgrid/colortileview.js +37 -47
  12. package/src/colorgrid/utils.js +57 -66
  13. package/src/componentfactory.js +79 -93
  14. package/src/dropdown/button/dropdownbutton.js +5 -0
  15. package/src/dropdown/button/dropdownbuttonview.js +44 -57
  16. package/src/dropdown/button/splitbuttonview.js +159 -207
  17. package/src/dropdown/dropdownpanelfocusable.js +5 -0
  18. package/src/dropdown/dropdownpanelview.js +101 -112
  19. package/src/dropdown/dropdownview.js +396 -438
  20. package/src/dropdown/utils.js +164 -213
  21. package/src/editableui/editableuiview.js +125 -141
  22. package/src/editableui/inline/inlineeditableuiview.js +44 -54
  23. package/src/editorui/bodycollection.js +61 -75
  24. package/src/editorui/boxed/boxededitoruiview.js +91 -104
  25. package/src/editorui/editoruiview.js +30 -39
  26. package/src/focuscycler.js +214 -245
  27. package/src/formheader/formheaderview.js +58 -70
  28. package/src/icon/iconview.js +145 -111
  29. package/src/iframe/iframeview.js +37 -49
  30. package/src/index.js +0 -17
  31. package/src/input/inputview.js +170 -198
  32. package/src/inputnumber/inputnumberview.js +48 -56
  33. package/src/inputtext/inputtextview.js +14 -18
  34. package/src/label/labelview.js +44 -53
  35. package/src/labeledfield/labeledfieldview.js +212 -235
  36. package/src/labeledfield/utils.js +39 -57
  37. package/src/labeledinput/labeledinputview.js +190 -221
  38. package/src/list/listitemview.js +40 -50
  39. package/src/list/listseparatorview.js +15 -19
  40. package/src/list/listview.js +94 -115
  41. package/src/model.js +19 -25
  42. package/src/notification/notification.js +151 -202
  43. package/src/panel/balloon/balloonpanelview.js +535 -628
  44. package/src/panel/balloon/contextualballoon.js +611 -732
  45. package/src/panel/sticky/stickypanelview.js +238 -270
  46. package/src/template.js +1049 -1479
  47. package/src/toolbar/balloon/balloontoolbar.js +337 -424
  48. package/src/toolbar/block/blockbuttonview.js +32 -42
  49. package/src/toolbar/block/blocktoolbar.js +375 -477
  50. package/src/toolbar/normalizetoolbarconfig.js +17 -21
  51. package/src/toolbar/toolbarlinebreakview.js +15 -19
  52. package/src/toolbar/toolbarseparatorview.js +15 -19
  53. package/src/toolbar/toolbarview.js +866 -1053
  54. package/src/tooltipmanager.js +324 -353
  55. package/src/view.js +389 -430
  56. package/src/viewcollection.js +147 -178
  57. package/src/button/button.jsdoc +0 -165
  58. package/src/dropdown/button/dropdownbutton.jsdoc +0 -22
  59. package/src/dropdown/dropdownpanelfocusable.jsdoc +0 -27
@@ -2,286 +2,254 @@
2
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
-
6
5
  /**
7
6
  * @module ui/panel/sticky/stickypanelview
8
7
  */
9
-
10
8
  import global from '@ckeditor/ckeditor5-utils/src/dom/global';
11
9
  import View from '../../view';
12
10
  import Template from '../../template';
13
11
  import toUnit from '@ckeditor/ckeditor5-utils/src/dom/tounit';
14
-
15
12
  import '../../../theme/components/panel/stickypanel.css';
16
-
17
- const toPx = toUnit( 'px' );
18
-
13
+ const toPx = toUnit('px');
19
14
  /**
20
15
  * The sticky panel view class.
21
16
  */
22
17
  export default class StickyPanelView extends View {
23
- /**
24
- * @inheritDoc
25
- */
26
- constructor( locale ) {
27
- super( locale );
28
-
29
- const bind = this.bindTemplate;
30
-
31
- /**
32
- * Controls whether the sticky panel should be active.
33
- *
34
- * @readonly
35
- * @observable
36
- * @member {Boolean} #isActive
37
- */
38
- this.set( 'isActive', false );
39
-
40
- /**
41
- * Controls whether the sticky panel is in the "sticky" state.
42
- *
43
- * @readonly
44
- * @observable
45
- * @member {Boolean} #isSticky
46
- */
47
- this.set( 'isSticky', false );
48
-
49
- /**
50
- * The limiter element for the sticky panel instance. Its bounding rect limits
51
- * the "stickyness" of the panel, i.e. when the panel reaches the bottom
52
- * edge of the limiter, it becomes sticky to that edge and does not float
53
- * off the limiter. It is mandatory for the panel to work properly and once
54
- * set, it cannot be changed.
55
- *
56
- * @readonly
57
- * @observable
58
- * @member {HTMLElement} #limiterElement
59
- */
60
- this.set( 'limiterElement', null );
61
-
62
- /**
63
- * The offset from the bottom edge of {@link #limiterElement}
64
- * which stops the panel from stickying any further to prevent limiter's content
65
- * from being completely covered.
66
- *
67
- * @readonly
68
- * @observable
69
- * @default 50
70
- * @member {Number} #limiterBottomOffset
71
- */
72
- this.set( 'limiterBottomOffset', 50 );
73
-
74
- /**
75
- * The offset from the top edge of the web browser's viewport which makes the
76
- * panel become sticky. The default value is `0`, which means the panel becomes
77
- * sticky when it's upper edge touches the top of the page viewport.
78
- *
79
- * This attribute is useful when the web page has UI elements positioned to the top
80
- * either using `position: fixed` or `position: sticky`, which would cover the
81
- * sticky panel or vice–versa (depending on the `z-index` hierarchy).
82
- *
83
- * Bound to {@link module:core/editor/editorui~EditorUI#viewportOffset `EditorUI#viewportOffset`}.
84
- *
85
- * If {@link module:core/editor/editorconfig~EditorConfig#ui `EditorConfig#ui.viewportOffset.top`} is defined, then
86
- * it will override the default value.
87
- *
88
- * @observable
89
- * @default 0
90
- * @member {Number} #viewportTopOffset
91
- */
92
- this.set( 'viewportTopOffset', 0 );
93
-
94
- /**
95
- * Controls the `margin-left` CSS style of the panel.
96
- *
97
- * @protected
98
- * @readonly
99
- * @observable
100
- * @member {String} #_marginLeft
101
- */
102
- this.set( '_marginLeft', null );
103
-
104
- /**
105
- * Set `true` if the sticky panel reached the bottom edge of the
106
- * {@link #limiterElement}.
107
- *
108
- * @protected
109
- * @readonly
110
- * @observable
111
- * @member {Boolean} #_isStickyToTheLimiter
112
- */
113
- this.set( '_isStickyToTheLimiter', false );
114
-
115
- /**
116
- * Set `true` if the sticky panel uses the {@link #viewportTopOffset},
117
- * i.e. not {@link #_isStickyToTheLimiter} and the {@link #viewportTopOffset}
118
- * is not `0`.
119
- *
120
- * @protected
121
- * @readonly
122
- * @observable
123
- * @member {Boolean} #_hasViewportTopOffset
124
- */
125
- this.set( '_hasViewportTopOffset', false );
126
-
127
- /**
128
- * Collection of the child views which creates balloon panel contents.
129
- *
130
- * @readonly
131
- * @member {module:ui/viewcollection~ViewCollection}
132
- */
133
- this.content = this.createCollection();
134
-
135
- /**
136
- * The DOM bounding client rect of the {@link module:ui/view~View#element} of the panel.
137
- *
138
- * @protected
139
- * @member {Object} #_panelRect
140
- */
141
-
142
- /**
143
- * The DOM bounding client rect of the {@link #limiterElement}
144
- * of the panel.
145
- *
146
- * @protected
147
- * @member {Object} #_limiterRect
148
- */
149
-
150
- /**
151
- * A dummy element which visually fills the space as long as the
152
- * actual panel is sticky. It prevents flickering of the UI.
153
- *
154
- * @protected
155
- * @property {HTMLElement}
156
- */
157
- this._contentPanelPlaceholder = new Template( {
158
- tag: 'div',
159
- attributes: {
160
- class: [
161
- 'ck',
162
- 'ck-sticky-panel__placeholder'
163
- ],
164
- style: {
165
- display: bind.to( 'isSticky', isSticky => isSticky ? 'block' : 'none' ),
166
- height: bind.to( 'isSticky', isSticky => {
167
- return isSticky ? toPx( this._panelRect.height ) : null;
168
- } )
169
- }
170
- }
171
- } ).render();
172
-
173
- /**
174
- * The panel which accepts children into {@link #content} collection.
175
- * Also an element which is positioned when {@link #isSticky}.
176
- *
177
- * @protected
178
- * @property {HTMLElement}
179
- */
180
- this._contentPanel = new Template( {
181
- tag: 'div',
182
-
183
- attributes: {
184
- class: [
185
- 'ck',
186
- 'ck-sticky-panel__content',
187
- // Toggle class of the panel when "sticky" state changes in the view.
188
- bind.if( 'isSticky', 'ck-sticky-panel__content_sticky' ),
189
- bind.if( '_isStickyToTheLimiter', 'ck-sticky-panel__content_sticky_bottom-limit' )
190
- ],
191
- style: {
192
- width: bind.to( 'isSticky', isSticky => {
193
- return isSticky ? toPx( this._contentPanelPlaceholder.getBoundingClientRect().width ) : null;
194
- } ),
195
-
196
- top: bind.to( '_hasViewportTopOffset', _hasViewportTopOffset => {
197
- return _hasViewportTopOffset ? toPx( this.viewportTopOffset ) : null;
198
- } ),
199
-
200
- bottom: bind.to( '_isStickyToTheLimiter', _isStickyToTheLimiter => {
201
- return _isStickyToTheLimiter ? toPx( this.limiterBottomOffset ) : null;
202
- } ),
203
-
204
- marginLeft: bind.to( '_marginLeft' )
205
- }
206
- },
207
-
208
- children: this.content
209
- } ).render();
210
-
211
- this.setTemplate( {
212
- tag: 'div',
213
- attributes: {
214
- class: [
215
- 'ck',
216
- 'ck-sticky-panel'
217
- ]
218
- },
219
- children: [
220
- this._contentPanelPlaceholder,
221
- this._contentPanel
222
- ]
223
- } );
224
- }
225
-
226
- /**
227
- * @inheritDoc
228
- */
229
- render() {
230
- super.render();
231
-
232
- // Check if the panel should go into the sticky state immediately.
233
- this._checkIfShouldBeSticky();
234
-
235
- // Update sticky state of the panel as the window is being scrolled.
236
- this.listenTo( global.window, 'scroll', () => {
237
- this._checkIfShouldBeSticky();
238
- } );
239
-
240
- // Synchronize with `model.isActive` because sticking an inactive panel is pointless.
241
- this.listenTo( this, 'change:isActive', () => {
242
- this._checkIfShouldBeSticky();
243
- } );
244
- }
245
-
246
- /**
247
- * Analyzes the environment to decide whether the panel should
248
- * be sticky or not.
249
- *
250
- * @protected
251
- */
252
- _checkIfShouldBeSticky() {
253
- const panelRect = this._panelRect = this._contentPanel.getBoundingClientRect();
254
- let limiterRect;
255
-
256
- if ( !this.limiterElement ) {
257
- this.isSticky = false;
258
- } else {
259
- limiterRect = this._limiterRect = this.limiterElement.getBoundingClientRect();
260
-
261
- // The panel must be active to become sticky.
262
- this.isSticky = this.isActive &&
263
- // The limiter's top edge must be beyond the upper edge of the visible viewport (+the viewportTopOffset).
264
- limiterRect.top < this.viewportTopOffset &&
265
- // The model#limiterElement's height mustn't be smaller than the panel's height and model#limiterBottomOffset.
266
- // There's no point in entering the sticky mode if the model#limiterElement is very, very small, because
267
- // it would immediately set model#_isStickyToTheLimiter true and, given model#limiterBottomOffset, the panel
268
- // would be positioned before the model#limiterElement.
269
- this._panelRect.height + this.limiterBottomOffset < limiterRect.height;
270
- }
271
-
272
- // Stick the panel to the top edge of the viewport simulating CSS position:sticky.
273
- // TODO: Possibly replaced by CSS in the future http://caniuse.com/#feat=css-sticky
274
- if ( this.isSticky ) {
275
- this._isStickyToTheLimiter =
276
- limiterRect.bottom < panelRect.height + this.limiterBottomOffset + this.viewportTopOffset;
277
- this._hasViewportTopOffset = !this._isStickyToTheLimiter && !!this.viewportTopOffset;
278
- this._marginLeft = this._isStickyToTheLimiter ? null : toPx( -global.window.scrollX );
279
- }
280
- // Detach the panel from the top edge of the viewport.
281
- else {
282
- this._isStickyToTheLimiter = false;
283
- this._hasViewportTopOffset = false;
284
- this._marginLeft = null;
285
- }
286
- }
18
+ /**
19
+ * @inheritDoc
20
+ */
21
+ constructor(locale) {
22
+ super(locale);
23
+ const bind = this.bindTemplate;
24
+ /**
25
+ * Controls whether the sticky panel should be active.
26
+ *
27
+ * @readonly
28
+ * @observable
29
+ * @member {Boolean} #isActive
30
+ */
31
+ this.set('isActive', false);
32
+ /**
33
+ * Controls whether the sticky panel is in the "sticky" state.
34
+ *
35
+ * @readonly
36
+ * @observable
37
+ * @member {Boolean} #isSticky
38
+ */
39
+ this.set('isSticky', false);
40
+ /**
41
+ * The limiter element for the sticky panel instance. Its bounding rect limits
42
+ * the "stickyness" of the panel, i.e. when the panel reaches the bottom
43
+ * edge of the limiter, it becomes sticky to that edge and does not float
44
+ * off the limiter. It is mandatory for the panel to work properly and once
45
+ * set, it cannot be changed.
46
+ *
47
+ * @readonly
48
+ * @observable
49
+ * @member {HTMLElement} #limiterElement
50
+ */
51
+ this.set('limiterElement', null);
52
+ /**
53
+ * The offset from the bottom edge of {@link #limiterElement}
54
+ * which stops the panel from stickying any further to prevent limiter's content
55
+ * from being completely covered.
56
+ *
57
+ * @readonly
58
+ * @observable
59
+ * @default 50
60
+ * @member {Number} #limiterBottomOffset
61
+ */
62
+ this.set('limiterBottomOffset', 50);
63
+ /**
64
+ * The offset from the top edge of the web browser's viewport which makes the
65
+ * panel become sticky. The default value is `0`, which means the panel becomes
66
+ * sticky when it's upper edge touches the top of the page viewport.
67
+ *
68
+ * This attribute is useful when the web page has UI elements positioned to the top
69
+ * either using `position: fixed` or `position: sticky`, which would cover the
70
+ * sticky panel or vice–versa (depending on the `z-index` hierarchy).
71
+ *
72
+ * Bound to {@link module:core/editor/editorui~EditorUI#viewportOffset `EditorUI#viewportOffset`}.
73
+ *
74
+ * If {@link module:core/editor/editorconfig~EditorConfig#ui `EditorConfig#ui.viewportOffset.top`} is defined, then
75
+ * it will override the default value.
76
+ *
77
+ * @observable
78
+ * @default 0
79
+ * @member {Number} #viewportTopOffset
80
+ */
81
+ this.set('viewportTopOffset', 0);
82
+ /**
83
+ * Controls the `margin-left` CSS style of the panel.
84
+ *
85
+ * @protected
86
+ * @readonly
87
+ * @observable
88
+ * @member {String} #_marginLeft
89
+ */
90
+ this.set('_marginLeft', null);
91
+ /**
92
+ * Set `true` if the sticky panel reached the bottom edge of the
93
+ * {@link #limiterElement}.
94
+ *
95
+ * @protected
96
+ * @readonly
97
+ * @observable
98
+ * @member {Boolean} #_isStickyToTheLimiter
99
+ */
100
+ this.set('_isStickyToTheLimiter', false);
101
+ /**
102
+ * Set `true` if the sticky panel uses the {@link #viewportTopOffset},
103
+ * i.e. not {@link #_isStickyToTheLimiter} and the {@link #viewportTopOffset}
104
+ * is not `0`.
105
+ *
106
+ * @protected
107
+ * @readonly
108
+ * @observable
109
+ * @member {Boolean} #_hasViewportTopOffset
110
+ */
111
+ this.set('_hasViewportTopOffset', false);
112
+ /**
113
+ * Collection of the child views which creates balloon panel contents.
114
+ *
115
+ * @readonly
116
+ * @member {module:ui/viewcollection~ViewCollection}
117
+ */
118
+ this.content = this.createCollection();
119
+ /**
120
+ * The DOM bounding client rect of the {@link module:ui/view~View#element} of the panel.
121
+ *
122
+ * @protected
123
+ * @member {Object} #_panelRect
124
+ */
125
+ /**
126
+ * The DOM bounding client rect of the {@link #limiterElement}
127
+ * of the panel.
128
+ *
129
+ * @protected
130
+ * @member {Object} #_limiterRect
131
+ */
132
+ /**
133
+ * A dummy element which visually fills the space as long as the
134
+ * actual panel is sticky. It prevents flickering of the UI.
135
+ *
136
+ * @protected
137
+ * @property {HTMLElement}
138
+ */
139
+ this._contentPanelPlaceholder = new Template({
140
+ tag: 'div',
141
+ attributes: {
142
+ class: [
143
+ 'ck',
144
+ 'ck-sticky-panel__placeholder'
145
+ ],
146
+ style: {
147
+ display: bind.to('isSticky', isSticky => isSticky ? 'block' : 'none'),
148
+ height: bind.to('isSticky', isSticky => {
149
+ return isSticky ? toPx(this._panelRect.height) : null;
150
+ })
151
+ }
152
+ }
153
+ }).render();
154
+ /**
155
+ * The panel which accepts children into {@link #content} collection.
156
+ * Also an element which is positioned when {@link #isSticky}.
157
+ *
158
+ * @protected
159
+ * @property {HTMLElement}
160
+ */
161
+ this._contentPanel = new Template({
162
+ tag: 'div',
163
+ attributes: {
164
+ class: [
165
+ 'ck',
166
+ 'ck-sticky-panel__content',
167
+ // Toggle class of the panel when "sticky" state changes in the view.
168
+ bind.if('isSticky', 'ck-sticky-panel__content_sticky'),
169
+ bind.if('_isStickyToTheLimiter', 'ck-sticky-panel__content_sticky_bottom-limit')
170
+ ],
171
+ style: {
172
+ width: bind.to('isSticky', isSticky => {
173
+ return isSticky ? toPx(this._contentPanelPlaceholder.getBoundingClientRect().width) : null;
174
+ }),
175
+ top: bind.to('_hasViewportTopOffset', _hasViewportTopOffset => {
176
+ return _hasViewportTopOffset ? toPx(this.viewportTopOffset) : null;
177
+ }),
178
+ bottom: bind.to('_isStickyToTheLimiter', _isStickyToTheLimiter => {
179
+ return _isStickyToTheLimiter ? toPx(this.limiterBottomOffset) : null;
180
+ }),
181
+ marginLeft: bind.to('_marginLeft')
182
+ }
183
+ },
184
+ children: this.content
185
+ }).render();
186
+ this.setTemplate({
187
+ tag: 'div',
188
+ attributes: {
189
+ class: [
190
+ 'ck',
191
+ 'ck-sticky-panel'
192
+ ]
193
+ },
194
+ children: [
195
+ this._contentPanelPlaceholder,
196
+ this._contentPanel
197
+ ]
198
+ });
199
+ }
200
+ /**
201
+ * @inheritDoc
202
+ */
203
+ render() {
204
+ super.render();
205
+ // Check if the panel should go into the sticky state immediately.
206
+ this._checkIfShouldBeSticky();
207
+ // Update sticky state of the panel as the window is being scrolled.
208
+ this.listenTo(global.window, 'scroll', () => {
209
+ this._checkIfShouldBeSticky();
210
+ });
211
+ // Synchronize with `model.isActive` because sticking an inactive panel is pointless.
212
+ this.listenTo(this, 'change:isActive', () => {
213
+ this._checkIfShouldBeSticky();
214
+ });
215
+ }
216
+ /**
217
+ * Analyzes the environment to decide whether the panel should
218
+ * be sticky or not.
219
+ *
220
+ * @protected
221
+ */
222
+ _checkIfShouldBeSticky() {
223
+ const panelRect = this._panelRect = this._contentPanel.getBoundingClientRect();
224
+ let limiterRect;
225
+ if (!this.limiterElement) {
226
+ this.isSticky = false;
227
+ }
228
+ else {
229
+ limiterRect = this._limiterRect = this.limiterElement.getBoundingClientRect();
230
+ // The panel must be active to become sticky.
231
+ this.isSticky = this.isActive &&
232
+ // The limiter's top edge must be beyond the upper edge of the visible viewport (+the viewportTopOffset).
233
+ limiterRect.top < this.viewportTopOffset &&
234
+ // The model#limiterElement's height mustn't be smaller than the panel's height and model#limiterBottomOffset.
235
+ // There's no point in entering the sticky mode if the model#limiterElement is very, very small, because
236
+ // it would immediately set model#_isStickyToTheLimiter true and, given model#limiterBottomOffset, the panel
237
+ // would be positioned before the model#limiterElement.
238
+ this._panelRect.height + this.limiterBottomOffset < limiterRect.height;
239
+ }
240
+ // Stick the panel to the top edge of the viewport simulating CSS position:sticky.
241
+ // TODO: Possibly replaced by CSS in the future http://caniuse.com/#feat=css-sticky
242
+ if (this.isSticky) {
243
+ this._isStickyToTheLimiter =
244
+ limiterRect.bottom < panelRect.height + this.limiterBottomOffset + this.viewportTopOffset;
245
+ this._hasViewportTopOffset = !this._isStickyToTheLimiter && !!this.viewportTopOffset;
246
+ this._marginLeft = this._isStickyToTheLimiter ? null : toPx(-global.window.scrollX);
247
+ }
248
+ // Detach the panel from the top edge of the viewport.
249
+ else {
250
+ this._isStickyToTheLimiter = false;
251
+ this._hasViewportTopOffset = false;
252
+ this._marginLeft = null;
253
+ }
254
+ }
287
255
  }