@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.
- package/package.json +31 -23
- package/src/bindings/addkeyboardhandlingforgrid.js +45 -57
- package/src/bindings/clickoutsidehandler.js +15 -21
- package/src/bindings/injectcsstransitiondisabler.js +16 -20
- package/src/bindings/preventdefault.js +6 -8
- package/src/bindings/submithandler.js +5 -7
- package/src/button/button.js +5 -0
- package/src/button/buttonview.js +220 -259
- package/src/button/switchbuttonview.js +56 -71
- package/src/colorgrid/colorgridview.js +135 -197
- package/src/colorgrid/colortileview.js +37 -47
- package/src/colorgrid/utils.js +57 -66
- package/src/componentfactory.js +79 -93
- package/src/dropdown/button/dropdownbutton.js +5 -0
- package/src/dropdown/button/dropdownbuttonview.js +44 -57
- package/src/dropdown/button/splitbuttonview.js +159 -207
- package/src/dropdown/dropdownpanelfocusable.js +5 -0
- package/src/dropdown/dropdownpanelview.js +101 -112
- package/src/dropdown/dropdownview.js +396 -438
- package/src/dropdown/utils.js +164 -213
- package/src/editableui/editableuiview.js +125 -141
- package/src/editableui/inline/inlineeditableuiview.js +44 -54
- package/src/editorui/bodycollection.js +61 -75
- package/src/editorui/boxed/boxededitoruiview.js +91 -104
- package/src/editorui/editoruiview.js +30 -39
- package/src/focuscycler.js +214 -245
- package/src/formheader/formheaderview.js +58 -70
- package/src/icon/iconview.js +145 -111
- package/src/iframe/iframeview.js +37 -49
- package/src/index.js +0 -17
- package/src/input/inputview.js +170 -198
- package/src/inputnumber/inputnumberview.js +48 -56
- package/src/inputtext/inputtextview.js +14 -18
- package/src/label/labelview.js +44 -53
- package/src/labeledfield/labeledfieldview.js +212 -235
- package/src/labeledfield/utils.js +39 -57
- package/src/labeledinput/labeledinputview.js +190 -221
- package/src/list/listitemview.js +40 -50
- package/src/list/listseparatorview.js +15 -19
- package/src/list/listview.js +94 -115
- package/src/model.js +19 -25
- package/src/notification/notification.js +151 -202
- package/src/panel/balloon/balloonpanelview.js +535 -628
- package/src/panel/balloon/contextualballoon.js +611 -732
- package/src/panel/sticky/stickypanelview.js +238 -270
- package/src/template.js +1049 -1479
- package/src/toolbar/balloon/balloontoolbar.js +337 -424
- package/src/toolbar/block/blockbuttonview.js +32 -42
- package/src/toolbar/block/blocktoolbar.js +375 -477
- package/src/toolbar/normalizetoolbarconfig.js +17 -21
- package/src/toolbar/toolbarlinebreakview.js +15 -19
- package/src/toolbar/toolbarseparatorview.js +15 -19
- package/src/toolbar/toolbarview.js +866 -1053
- package/src/tooltipmanager.js +324 -353
- package/src/view.js +389 -430
- package/src/viewcollection.js +147 -178
- package/src/button/button.jsdoc +0 -165
- package/src/dropdown/button/dropdownbutton.jsdoc +0 -22
- package/src/dropdown/dropdownpanelfocusable.jsdoc +0 -27
|
@@ -2,23 +2,18 @@
|
|
|
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/balloon/balloonpanelview
|
|
8
7
|
*/
|
|
9
|
-
|
|
10
8
|
import View from '../../view';
|
|
11
9
|
import { getOptimalPosition } from '@ckeditor/ckeditor5-utils/src/dom/position';
|
|
12
10
|
import isRange from '@ckeditor/ckeditor5-utils/src/dom/isrange';
|
|
13
11
|
import toUnit from '@ckeditor/ckeditor5-utils/src/dom/tounit';
|
|
14
12
|
import global from '@ckeditor/ckeditor5-utils/src/dom/global';
|
|
15
13
|
import { isElement } from 'lodash-es';
|
|
16
|
-
|
|
17
14
|
import '../../../theme/components/panel/balloonpanel.css';
|
|
18
|
-
|
|
19
|
-
const toPx = toUnit( 'px' );
|
|
15
|
+
const toPx = toUnit('px');
|
|
20
16
|
const defaultLimiterElement = global.document.body;
|
|
21
|
-
|
|
22
17
|
/**
|
|
23
18
|
* The balloon panel view class.
|
|
24
19
|
*
|
|
@@ -59,338 +54,285 @@ const defaultLimiterElement = global.document.body;
|
|
|
59
54
|
* @extends module:ui/view~View
|
|
60
55
|
*/
|
|
61
56
|
export default class BalloonPanelView extends View {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
const scrollTarget = domEvt.target;
|
|
341
|
-
|
|
342
|
-
// The position needs to be updated if the positioning target is within the scrolled element.
|
|
343
|
-
const isWithinScrollTarget = targetElement && scrollTarget.contains( targetElement );
|
|
344
|
-
|
|
345
|
-
// The position needs to be updated if the positioning limiter is within the scrolled element.
|
|
346
|
-
const isLimiterWithinScrollTarget = limiterElement && scrollTarget.contains( limiterElement );
|
|
347
|
-
|
|
348
|
-
// The positioning target and/or limiter can be a Rect, object etc..
|
|
349
|
-
// There's no way to optimize the listener then.
|
|
350
|
-
if ( isWithinScrollTarget || isLimiterWithinScrollTarget || !targetElement || !limiterElement ) {
|
|
351
|
-
this.attachTo( options );
|
|
352
|
-
}
|
|
353
|
-
}, { useCapture: true } );
|
|
354
|
-
|
|
355
|
-
// We need to listen on window resize event and update position.
|
|
356
|
-
this.listenTo( global.window, 'resize', () => {
|
|
357
|
-
this.attachTo( options );
|
|
358
|
-
} );
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* Stops managing the pinned state of the panel. See {@link #pin}.
|
|
363
|
-
*
|
|
364
|
-
* @private
|
|
365
|
-
*/
|
|
366
|
-
_stopPinning() {
|
|
367
|
-
this.stopListening( global.document, 'scroll' );
|
|
368
|
-
this.stopListening( global.window, 'resize' );
|
|
369
|
-
}
|
|
57
|
+
/**
|
|
58
|
+
* @inheritDoc
|
|
59
|
+
*/
|
|
60
|
+
constructor(locale) {
|
|
61
|
+
super(locale);
|
|
62
|
+
const bind = this.bindTemplate;
|
|
63
|
+
/**
|
|
64
|
+
* The absolute top position of the balloon panel in pixels.
|
|
65
|
+
*
|
|
66
|
+
* @observable
|
|
67
|
+
* @default 0
|
|
68
|
+
* @member {Number} #top
|
|
69
|
+
*/
|
|
70
|
+
this.set('top', 0);
|
|
71
|
+
/**
|
|
72
|
+
* The absolute left position of the balloon panel in pixels.
|
|
73
|
+
*
|
|
74
|
+
* @observable
|
|
75
|
+
* @default 0
|
|
76
|
+
* @member {Number} #left
|
|
77
|
+
*/
|
|
78
|
+
this.set('left', 0);
|
|
79
|
+
/**
|
|
80
|
+
* The balloon panel's current position. The position name is reflected in the CSS class set
|
|
81
|
+
* to the balloon, i.e. `.ck-balloon-panel_arrow_nw` for the "arrow_nw" position. The class
|
|
82
|
+
* controls the minor aspects of the balloon's visual appearance like the placement
|
|
83
|
+
* of an {@link #withArrow arrow}. To support a new position, an additional CSS must be created.
|
|
84
|
+
*
|
|
85
|
+
* Default position names correspond with
|
|
86
|
+
* {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}.
|
|
87
|
+
*
|
|
88
|
+
* See the {@link #attachTo} and {@link #pin} methods to learn about custom balloon positions.
|
|
89
|
+
*
|
|
90
|
+
* @observable
|
|
91
|
+
* @default 'arrow_nw'
|
|
92
|
+
* @member {'arrow_nw'|'arrow_ne'|'arrow_sw'|'arrow_se'} #position
|
|
93
|
+
*/
|
|
94
|
+
this.set('position', 'arrow_nw');
|
|
95
|
+
/**
|
|
96
|
+
* Controls whether the balloon panel is visible or not.
|
|
97
|
+
*
|
|
98
|
+
* @observable
|
|
99
|
+
* @default false
|
|
100
|
+
* @member {Boolean} #isVisible
|
|
101
|
+
*/
|
|
102
|
+
this.set('isVisible', false);
|
|
103
|
+
/**
|
|
104
|
+
* Controls whether the balloon panel has an arrow. The presence of the arrow
|
|
105
|
+
* is reflected in the `ck-balloon-panel_with-arrow` CSS class.
|
|
106
|
+
*
|
|
107
|
+
* @observable
|
|
108
|
+
* @default true
|
|
109
|
+
* @member {Boolean} #withArrow
|
|
110
|
+
*/
|
|
111
|
+
this.set('withArrow', true);
|
|
112
|
+
/**
|
|
113
|
+
* An additional CSS class added to the {@link #element}.
|
|
114
|
+
*
|
|
115
|
+
* @observable
|
|
116
|
+
* @member {String} #class
|
|
117
|
+
*/
|
|
118
|
+
this.set('class', undefined);
|
|
119
|
+
/**
|
|
120
|
+
* A callback that starts pinning the panel when {@link #isVisible} gets
|
|
121
|
+
* `true`. Used by {@link #pin}.
|
|
122
|
+
*
|
|
123
|
+
* @private
|
|
124
|
+
* @member {Function} #_pinWhenIsVisibleCallback
|
|
125
|
+
*/
|
|
126
|
+
this._pinWhenIsVisibleCallback = null;
|
|
127
|
+
/**
|
|
128
|
+
* A collection of the child views that creates the balloon panel contents.
|
|
129
|
+
*
|
|
130
|
+
* @readonly
|
|
131
|
+
* @member {module:ui/viewcollection~ViewCollection}
|
|
132
|
+
*/
|
|
133
|
+
this.content = this.createCollection();
|
|
134
|
+
this.setTemplate({
|
|
135
|
+
tag: 'div',
|
|
136
|
+
attributes: {
|
|
137
|
+
class: [
|
|
138
|
+
'ck',
|
|
139
|
+
'ck-balloon-panel',
|
|
140
|
+
bind.to('position', value => `ck-balloon-panel_${value}`),
|
|
141
|
+
bind.if('isVisible', 'ck-balloon-panel_visible'),
|
|
142
|
+
bind.if('withArrow', 'ck-balloon-panel_with-arrow'),
|
|
143
|
+
bind.to('class')
|
|
144
|
+
],
|
|
145
|
+
style: {
|
|
146
|
+
top: bind.to('top', toPx),
|
|
147
|
+
left: bind.to('left', toPx)
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
children: this.content
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Shows the panel.
|
|
155
|
+
*
|
|
156
|
+
* See {@link #isVisible}.
|
|
157
|
+
*/
|
|
158
|
+
show() {
|
|
159
|
+
this.isVisible = true;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Hides the panel.
|
|
163
|
+
*
|
|
164
|
+
* See {@link #isVisible}.
|
|
165
|
+
*/
|
|
166
|
+
hide() {
|
|
167
|
+
this.isVisible = false;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Attaches the panel to a specified {@link module:utils/dom/position~Options#target} with a
|
|
171
|
+
* smart positioning heuristics that chooses from available positions to make sure the panel
|
|
172
|
+
* is visible to the user i.e. within the limits of the viewport.
|
|
173
|
+
*
|
|
174
|
+
* This method accepts configuration {@link module:utils/dom/position~Options options}
|
|
175
|
+
* to set the `target`, optional `limiter` and `positions` the balloon should choose from.
|
|
176
|
+
*
|
|
177
|
+
* const panel = new BalloonPanelView( locale );
|
|
178
|
+
* const positions = BalloonPanelView.defaultPositions;
|
|
179
|
+
*
|
|
180
|
+
* panel.render();
|
|
181
|
+
*
|
|
182
|
+
* // Attach the panel to an element with the "target" id DOM.
|
|
183
|
+
* panel.attachTo( {
|
|
184
|
+
* target: document.querySelector( '#target' ),
|
|
185
|
+
* positions: [
|
|
186
|
+
* positions.northArrowSouth,
|
|
187
|
+
* positions.southArrowNorth
|
|
188
|
+
* ]
|
|
189
|
+
* } );
|
|
190
|
+
*
|
|
191
|
+
* **Note**: Attaching the panel will also automatically {@link #show} it.
|
|
192
|
+
*
|
|
193
|
+
* **Note**: An attached panel will not follow its target when the window is scrolled or resized.
|
|
194
|
+
* See the {@link #pin} method for a more permanent positioning strategy.
|
|
195
|
+
*
|
|
196
|
+
* @param {module:utils/dom/position~Options} options Positioning options compatible with
|
|
197
|
+
* {@link module:utils/dom/position~getOptimalPosition}. Default `positions` array is
|
|
198
|
+
* {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}.
|
|
199
|
+
*/
|
|
200
|
+
attachTo(options) {
|
|
201
|
+
this.show();
|
|
202
|
+
const defaultPositions = BalloonPanelView.defaultPositions;
|
|
203
|
+
const positionOptions = Object.assign({}, {
|
|
204
|
+
element: this.element,
|
|
205
|
+
positions: [
|
|
206
|
+
defaultPositions.southArrowNorth,
|
|
207
|
+
defaultPositions.southArrowNorthMiddleWest,
|
|
208
|
+
defaultPositions.southArrowNorthMiddleEast,
|
|
209
|
+
defaultPositions.southArrowNorthWest,
|
|
210
|
+
defaultPositions.southArrowNorthEast,
|
|
211
|
+
defaultPositions.northArrowSouth,
|
|
212
|
+
defaultPositions.northArrowSouthMiddleWest,
|
|
213
|
+
defaultPositions.northArrowSouthMiddleEast,
|
|
214
|
+
defaultPositions.northArrowSouthWest,
|
|
215
|
+
defaultPositions.northArrowSouthEast,
|
|
216
|
+
defaultPositions.viewportStickyNorth
|
|
217
|
+
],
|
|
218
|
+
limiter: defaultLimiterElement,
|
|
219
|
+
fitInViewport: true
|
|
220
|
+
}, options);
|
|
221
|
+
const optimalPosition = BalloonPanelView._getOptimalPosition(positionOptions);
|
|
222
|
+
// Usually browsers make some problems with super accurate values like 104.345px
|
|
223
|
+
// so it is better to use int values.
|
|
224
|
+
const left = parseInt(optimalPosition.left);
|
|
225
|
+
const top = parseInt(optimalPosition.top);
|
|
226
|
+
const position = optimalPosition.name;
|
|
227
|
+
const config = optimalPosition.config || {};
|
|
228
|
+
const { withArrow = true } = config;
|
|
229
|
+
this.top = top;
|
|
230
|
+
this.left = left;
|
|
231
|
+
this.position = position;
|
|
232
|
+
this.withArrow = withArrow;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Works the same way as the {@link #attachTo} method except that the position of the panel is
|
|
236
|
+
* continuously updated when:
|
|
237
|
+
*
|
|
238
|
+
* * any ancestor of the {@link module:utils/dom/position~Options#target}
|
|
239
|
+
* or {@link module:utils/dom/position~Options#limiter} is scrolled,
|
|
240
|
+
* * the browser window gets resized or scrolled.
|
|
241
|
+
*
|
|
242
|
+
* Thanks to that, the panel always sticks to the {@link module:utils/dom/position~Options#target}
|
|
243
|
+
* and is immune to the changing environment.
|
|
244
|
+
*
|
|
245
|
+
* const panel = new BalloonPanelView( locale );
|
|
246
|
+
* const positions = BalloonPanelView.defaultPositions;
|
|
247
|
+
*
|
|
248
|
+
* panel.render();
|
|
249
|
+
*
|
|
250
|
+
* // Pin the panel to an element with the "target" id DOM.
|
|
251
|
+
* panel.pin( {
|
|
252
|
+
* target: document.querySelector( '#target' ),
|
|
253
|
+
* positions: [
|
|
254
|
+
* positions.northArrowSouth,
|
|
255
|
+
* positions.southArrowNorth
|
|
256
|
+
* ]
|
|
257
|
+
* } );
|
|
258
|
+
*
|
|
259
|
+
* To leave the pinned state, use the {@link #unpin} method.
|
|
260
|
+
*
|
|
261
|
+
* **Note**: Pinning the panel will also automatically {@link #show} it.
|
|
262
|
+
*
|
|
263
|
+
* @param {module:utils/dom/position~Options} options Positioning options compatible with
|
|
264
|
+
* {@link module:utils/dom/position~getOptimalPosition}. Default `positions` array is
|
|
265
|
+
* {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}.
|
|
266
|
+
*/
|
|
267
|
+
pin(options) {
|
|
268
|
+
this.unpin();
|
|
269
|
+
this._pinWhenIsVisibleCallback = () => {
|
|
270
|
+
if (this.isVisible) {
|
|
271
|
+
this._startPinning(options);
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
this._stopPinning();
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
this._startPinning(options);
|
|
278
|
+
// Control the state of the listeners depending on whether the panel is visible
|
|
279
|
+
// or not.
|
|
280
|
+
// TODO: Use on() (https://github.com/ckeditor/ckeditor5-utils/issues/144).
|
|
281
|
+
this.listenTo(this, 'change:isVisible', this._pinWhenIsVisibleCallback);
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Stops pinning the panel, as set up by {@link #pin}.
|
|
285
|
+
*/
|
|
286
|
+
unpin() {
|
|
287
|
+
if (this._pinWhenIsVisibleCallback) {
|
|
288
|
+
// Deactivate listeners attached by pin().
|
|
289
|
+
this._stopPinning();
|
|
290
|
+
// Deactivate the panel pin() control logic.
|
|
291
|
+
// TODO: Use off() (https://github.com/ckeditor/ckeditor5-utils/issues/144).
|
|
292
|
+
this.stopListening(this, 'change:isVisible', this._pinWhenIsVisibleCallback);
|
|
293
|
+
this._pinWhenIsVisibleCallback = null;
|
|
294
|
+
this.hide();
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Starts managing the pinned state of the panel. See {@link #pin}.
|
|
299
|
+
*
|
|
300
|
+
* @private
|
|
301
|
+
* @param {module:utils/dom/position~Options} options Positioning options compatible with
|
|
302
|
+
* {@link module:utils/dom/position~getOptimalPosition}.
|
|
303
|
+
*/
|
|
304
|
+
_startPinning(options) {
|
|
305
|
+
this.attachTo(options);
|
|
306
|
+
const targetElement = getDomElement(options.target);
|
|
307
|
+
const limiterElement = options.limiter ? getDomElement(options.limiter) : defaultLimiterElement;
|
|
308
|
+
// Then we need to listen on scroll event of eny element in the document.
|
|
309
|
+
this.listenTo(global.document, 'scroll', (evt, domEvt) => {
|
|
310
|
+
const scrollTarget = domEvt.target;
|
|
311
|
+
// The position needs to be updated if the positioning target is within the scrolled element.
|
|
312
|
+
const isWithinScrollTarget = targetElement && scrollTarget.contains(targetElement);
|
|
313
|
+
// The position needs to be updated if the positioning limiter is within the scrolled element.
|
|
314
|
+
const isLimiterWithinScrollTarget = limiterElement && scrollTarget.contains(limiterElement);
|
|
315
|
+
// The positioning target and/or limiter can be a Rect, object etc..
|
|
316
|
+
// There's no way to optimize the listener then.
|
|
317
|
+
if (isWithinScrollTarget || isLimiterWithinScrollTarget || !targetElement || !limiterElement) {
|
|
318
|
+
this.attachTo(options);
|
|
319
|
+
}
|
|
320
|
+
}, { useCapture: true });
|
|
321
|
+
// We need to listen on window resize event and update position.
|
|
322
|
+
this.listenTo(global.window, 'resize', () => {
|
|
323
|
+
this.attachTo(options);
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Stops managing the pinned state of the panel. See {@link #pin}.
|
|
328
|
+
*
|
|
329
|
+
* @private
|
|
330
|
+
*/
|
|
331
|
+
_stopPinning() {
|
|
332
|
+
this.stopListening(global.document, 'scroll');
|
|
333
|
+
this.stopListening(global.window, 'resize');
|
|
334
|
+
}
|
|
370
335
|
}
|
|
371
|
-
|
|
372
|
-
// Returns the DOM element for given object or null, if there is none,
|
|
373
|
-
// e.g. when the passed object is a Rect instance or so.
|
|
374
|
-
//
|
|
375
|
-
// @private
|
|
376
|
-
// @param {*} object
|
|
377
|
-
// @returns {HTMLElement|null}
|
|
378
|
-
function getDomElement( object ) {
|
|
379
|
-
if ( isElement( object ) ) {
|
|
380
|
-
return object;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
if ( isRange( object ) ) {
|
|
384
|
-
return object.commonAncestorContainer;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
if ( typeof object == 'function' ) {
|
|
388
|
-
return getDomElement( object() );
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
return null;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
336
|
/**
|
|
395
337
|
* A side offset of the arrow tip from the edge of the balloon. Controlled by CSS.
|
|
396
338
|
*
|
|
@@ -409,7 +351,6 @@ function getDomElement( object ) {
|
|
|
409
351
|
* @member {Number} module:ui/panel/balloon/balloonpanelview~BalloonPanelView.arrowSideOffset
|
|
410
352
|
*/
|
|
411
353
|
BalloonPanelView.arrowSideOffset = 25;
|
|
412
|
-
|
|
413
354
|
/**
|
|
414
355
|
* A height offset of the arrow from the edge of the balloon. Controlled by CSS.
|
|
415
356
|
*
|
|
@@ -439,9 +380,8 @@ BalloonPanelView.arrowSideOffset = 25;
|
|
|
439
380
|
*
|
|
440
381
|
* @default 10
|
|
441
382
|
* @member {Number} module:ui/panel/balloon/balloonpanelview~BalloonPanelView.arrowHeightOffset
|
|
442
|
-
|
|
383
|
+
*/
|
|
443
384
|
BalloonPanelView.arrowHeightOffset = 10;
|
|
444
|
-
|
|
445
385
|
/**
|
|
446
386
|
* A vertical offset of the balloon panel from the edge of the viewport if sticky.
|
|
447
387
|
* It helps in accessing toolbar buttons underneath the balloon panel.
|
|
@@ -465,7 +405,6 @@ BalloonPanelView.arrowHeightOffset = 10;
|
|
|
465
405
|
* @member {Number} module:ui/panel/balloon/balloonpanelview~BalloonPanelView.stickyVerticalOffset
|
|
466
406
|
*/
|
|
467
407
|
BalloonPanelView.stickyVerticalOffset = 20;
|
|
468
|
-
|
|
469
408
|
/**
|
|
470
409
|
* Function used to calculate the optimal position for the balloon.
|
|
471
410
|
*
|
|
@@ -473,7 +412,6 @@ BalloonPanelView.stickyVerticalOffset = 20;
|
|
|
473
412
|
* @member {Function} module:ui/panel/balloon/balloonpanelview~BalloonPanelView._getOptimalPosition
|
|
474
413
|
*/
|
|
475
414
|
BalloonPanelView._getOptimalPosition = getOptimalPosition;
|
|
476
|
-
|
|
477
415
|
/**
|
|
478
416
|
* A default set of positioning functions used by the balloon panel view
|
|
479
417
|
* when attaching using the {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView#attachTo} method.
|
|
@@ -796,7 +734,24 @@ BalloonPanelView._getOptimalPosition = getOptimalPosition;
|
|
|
796
734
|
* module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions
|
|
797
735
|
*/
|
|
798
736
|
BalloonPanelView.defaultPositions = generatePositions();
|
|
799
|
-
|
|
737
|
+
// Returns the DOM element for given object or null, if there is none,
|
|
738
|
+
// e.g. when the passed object is a Rect instance or so.
|
|
739
|
+
//
|
|
740
|
+
// @private
|
|
741
|
+
// @param {*} object
|
|
742
|
+
// @returns {HTMLElement|null}
|
|
743
|
+
function getDomElement(object) {
|
|
744
|
+
if (isElement(object)) {
|
|
745
|
+
return object;
|
|
746
|
+
}
|
|
747
|
+
if (isRange(object)) {
|
|
748
|
+
return object.commonAncestorContainer;
|
|
749
|
+
}
|
|
750
|
+
if (typeof object == 'function') {
|
|
751
|
+
return getDomElement(object());
|
|
752
|
+
}
|
|
753
|
+
return null;
|
|
754
|
+
}
|
|
800
755
|
/**
|
|
801
756
|
* Returns available {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView}
|
|
802
757
|
* {@link module:utils/dom/position~PositioningFunction positioning functions} adjusted by the specific offsets.
|
|
@@ -818,289 +773,241 @@ BalloonPanelView.defaultPositions = generatePositions();
|
|
|
818
773
|
* about {@link module:utils/dom/position~PositioningFunction positioning functions}.
|
|
819
774
|
* @returns {Object.<String,module:utils/dom/position~PositioningFunction>}
|
|
820
775
|
*/
|
|
821
|
-
export function generatePositions( {
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
// ------- East
|
|
1060
|
-
|
|
1061
|
-
eastArrowWest: ( targetRect, balloonRect ) => ( {
|
|
1062
|
-
top: targetRect.top + targetRect.height / 2 - balloonRect.height / 2,
|
|
1063
|
-
left: targetRect.right + heightOffset,
|
|
1064
|
-
name: 'arrow_w',
|
|
1065
|
-
...( config && { config } )
|
|
1066
|
-
} ),
|
|
1067
|
-
|
|
1068
|
-
// ------- Sticky
|
|
1069
|
-
|
|
1070
|
-
viewportStickyNorth: ( targetRect, balloonRect, viewportRect ) => {
|
|
1071
|
-
if ( !targetRect.getIntersection( viewportRect ) ) {
|
|
1072
|
-
return null;
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
|
-
return {
|
|
1076
|
-
top: viewportRect.top + stickyVerticalOffset,
|
|
1077
|
-
left: targetRect.left + targetRect.width / 2 - balloonRect.width / 2,
|
|
1078
|
-
name: 'arrowless',
|
|
1079
|
-
config: {
|
|
1080
|
-
withArrow: false,
|
|
1081
|
-
...config
|
|
1082
|
-
}
|
|
1083
|
-
};
|
|
1084
|
-
}
|
|
1085
|
-
};
|
|
1086
|
-
|
|
1087
|
-
// Returns the top coordinate for positions starting with `north*`.
|
|
1088
|
-
//
|
|
1089
|
-
// @private
|
|
1090
|
-
// @param {utils/dom/rect~Rect} targetRect A rect of the target.
|
|
1091
|
-
// @param {utils/dom/rect~Rect} elementRect A rect of the balloon.
|
|
1092
|
-
// @returns {Number}
|
|
1093
|
-
function getNorthTop( targetRect, balloonRect ) {
|
|
1094
|
-
return targetRect.top - balloonRect.height - heightOffset;
|
|
1095
|
-
}
|
|
1096
|
-
|
|
1097
|
-
// Returns the top coordinate for positions starting with `south*`.
|
|
1098
|
-
//
|
|
1099
|
-
// @private
|
|
1100
|
-
// @param {utils/dom/rect~Rect} targetRect A rect of the target.
|
|
1101
|
-
// @param {utils/dom/rect~Rect} elementRect A rect of the balloon.
|
|
1102
|
-
// @returns {Number}
|
|
1103
|
-
function getSouthTop( targetRect ) {
|
|
1104
|
-
return targetRect.bottom + heightOffset;
|
|
1105
|
-
}
|
|
776
|
+
export function generatePositions(options = {}) {
|
|
777
|
+
const { sideOffset = BalloonPanelView.arrowSideOffset, heightOffset = BalloonPanelView.arrowHeightOffset, stickyVerticalOffset = BalloonPanelView.stickyVerticalOffset, config } = options;
|
|
778
|
+
return {
|
|
779
|
+
// ------- North west
|
|
780
|
+
northWestArrowSouthWest: (targetRect, balloonRect) => ({
|
|
781
|
+
top: getNorthTop(targetRect, balloonRect),
|
|
782
|
+
left: targetRect.left - sideOffset,
|
|
783
|
+
name: 'arrow_sw',
|
|
784
|
+
...(config && { config })
|
|
785
|
+
}),
|
|
786
|
+
northWestArrowSouthMiddleWest: (targetRect, balloonRect) => ({
|
|
787
|
+
top: getNorthTop(targetRect, balloonRect),
|
|
788
|
+
left: targetRect.left - (balloonRect.width * .25) - sideOffset,
|
|
789
|
+
name: 'arrow_smw',
|
|
790
|
+
...(config && { config })
|
|
791
|
+
}),
|
|
792
|
+
northWestArrowSouth: (targetRect, balloonRect) => ({
|
|
793
|
+
top: getNorthTop(targetRect, balloonRect),
|
|
794
|
+
left: targetRect.left - balloonRect.width / 2,
|
|
795
|
+
name: 'arrow_s',
|
|
796
|
+
...(config && { config })
|
|
797
|
+
}),
|
|
798
|
+
northWestArrowSouthMiddleEast: (targetRect, balloonRect) => ({
|
|
799
|
+
top: getNorthTop(targetRect, balloonRect),
|
|
800
|
+
left: targetRect.left - (balloonRect.width * .75) + sideOffset,
|
|
801
|
+
name: 'arrow_sme',
|
|
802
|
+
...(config && { config })
|
|
803
|
+
}),
|
|
804
|
+
northWestArrowSouthEast: (targetRect, balloonRect) => ({
|
|
805
|
+
top: getNorthTop(targetRect, balloonRect),
|
|
806
|
+
left: targetRect.left - balloonRect.width + sideOffset,
|
|
807
|
+
name: 'arrow_se',
|
|
808
|
+
...(config && { config })
|
|
809
|
+
}),
|
|
810
|
+
// ------- North
|
|
811
|
+
northArrowSouthWest: (targetRect, balloonRect) => ({
|
|
812
|
+
top: getNorthTop(targetRect, balloonRect),
|
|
813
|
+
left: targetRect.left + targetRect.width / 2 - sideOffset,
|
|
814
|
+
name: 'arrow_sw',
|
|
815
|
+
...(config && { config })
|
|
816
|
+
}),
|
|
817
|
+
northArrowSouthMiddleWest: (targetRect, balloonRect) => ({
|
|
818
|
+
top: getNorthTop(targetRect, balloonRect),
|
|
819
|
+
left: targetRect.left + targetRect.width / 2 - (balloonRect.width * .25) - sideOffset,
|
|
820
|
+
name: 'arrow_smw',
|
|
821
|
+
...(config && { config })
|
|
822
|
+
}),
|
|
823
|
+
northArrowSouth: (targetRect, balloonRect) => ({
|
|
824
|
+
top: getNorthTop(targetRect, balloonRect),
|
|
825
|
+
left: targetRect.left + targetRect.width / 2 - balloonRect.width / 2,
|
|
826
|
+
name: 'arrow_s',
|
|
827
|
+
...(config && { config })
|
|
828
|
+
}),
|
|
829
|
+
northArrowSouthMiddleEast: (targetRect, balloonRect) => ({
|
|
830
|
+
top: getNorthTop(targetRect, balloonRect),
|
|
831
|
+
left: targetRect.left + targetRect.width / 2 - (balloonRect.width * .75) + sideOffset,
|
|
832
|
+
name: 'arrow_sme',
|
|
833
|
+
...(config && { config })
|
|
834
|
+
}),
|
|
835
|
+
northArrowSouthEast: (targetRect, balloonRect) => ({
|
|
836
|
+
top: getNorthTop(targetRect, balloonRect),
|
|
837
|
+
left: targetRect.left + targetRect.width / 2 - balloonRect.width + sideOffset,
|
|
838
|
+
name: 'arrow_se',
|
|
839
|
+
...(config && { config })
|
|
840
|
+
}),
|
|
841
|
+
// ------- North east
|
|
842
|
+
northEastArrowSouthWest: (targetRect, balloonRect) => ({
|
|
843
|
+
top: getNorthTop(targetRect, balloonRect),
|
|
844
|
+
left: targetRect.right - sideOffset,
|
|
845
|
+
name: 'arrow_sw',
|
|
846
|
+
...(config && { config })
|
|
847
|
+
}),
|
|
848
|
+
northEastArrowSouthMiddleWest: (targetRect, balloonRect) => ({
|
|
849
|
+
top: getNorthTop(targetRect, balloonRect),
|
|
850
|
+
left: targetRect.right - (balloonRect.width * .25) - sideOffset,
|
|
851
|
+
name: 'arrow_smw',
|
|
852
|
+
...(config && { config })
|
|
853
|
+
}),
|
|
854
|
+
northEastArrowSouth: (targetRect, balloonRect) => ({
|
|
855
|
+
top: getNorthTop(targetRect, balloonRect),
|
|
856
|
+
left: targetRect.right - balloonRect.width / 2,
|
|
857
|
+
name: 'arrow_s',
|
|
858
|
+
...(config && { config })
|
|
859
|
+
}),
|
|
860
|
+
northEastArrowSouthMiddleEast: (targetRect, balloonRect) => ({
|
|
861
|
+
top: getNorthTop(targetRect, balloonRect),
|
|
862
|
+
left: targetRect.right - (balloonRect.width * .75) + sideOffset,
|
|
863
|
+
name: 'arrow_sme',
|
|
864
|
+
...(config && { config })
|
|
865
|
+
}),
|
|
866
|
+
northEastArrowSouthEast: (targetRect, balloonRect) => ({
|
|
867
|
+
top: getNorthTop(targetRect, balloonRect),
|
|
868
|
+
left: targetRect.right - balloonRect.width + sideOffset,
|
|
869
|
+
name: 'arrow_se',
|
|
870
|
+
...(config && { config })
|
|
871
|
+
}),
|
|
872
|
+
// ------- South west
|
|
873
|
+
southWestArrowNorthWest: targetRect => ({
|
|
874
|
+
top: getSouthTop(targetRect),
|
|
875
|
+
left: targetRect.left - sideOffset,
|
|
876
|
+
name: 'arrow_nw',
|
|
877
|
+
...(config && { config })
|
|
878
|
+
}),
|
|
879
|
+
southWestArrowNorthMiddleWest: (targetRect, balloonRect) => ({
|
|
880
|
+
top: getSouthTop(targetRect),
|
|
881
|
+
left: targetRect.left - (balloonRect.width * .25) - sideOffset,
|
|
882
|
+
name: 'arrow_nmw',
|
|
883
|
+
...(config && { config })
|
|
884
|
+
}),
|
|
885
|
+
southWestArrowNorth: (targetRect, balloonRect) => ({
|
|
886
|
+
top: getSouthTop(targetRect),
|
|
887
|
+
left: targetRect.left - balloonRect.width / 2,
|
|
888
|
+
name: 'arrow_n',
|
|
889
|
+
...(config && { config })
|
|
890
|
+
}),
|
|
891
|
+
southWestArrowNorthMiddleEast: (targetRect, balloonRect) => ({
|
|
892
|
+
top: getSouthTop(targetRect),
|
|
893
|
+
left: targetRect.left - (balloonRect.width * .75) + sideOffset,
|
|
894
|
+
name: 'arrow_nme',
|
|
895
|
+
...(config && { config })
|
|
896
|
+
}),
|
|
897
|
+
southWestArrowNorthEast: (targetRect, balloonRect) => ({
|
|
898
|
+
top: getSouthTop(targetRect),
|
|
899
|
+
left: targetRect.left - balloonRect.width + sideOffset,
|
|
900
|
+
name: 'arrow_ne',
|
|
901
|
+
...(config && { config })
|
|
902
|
+
}),
|
|
903
|
+
// ------- South
|
|
904
|
+
southArrowNorthWest: targetRect => ({
|
|
905
|
+
top: getSouthTop(targetRect),
|
|
906
|
+
left: targetRect.left + targetRect.width / 2 - sideOffset,
|
|
907
|
+
name: 'arrow_nw',
|
|
908
|
+
...(config && { config })
|
|
909
|
+
}),
|
|
910
|
+
southArrowNorthMiddleWest: (targetRect, balloonRect) => ({
|
|
911
|
+
top: getSouthTop(targetRect),
|
|
912
|
+
left: targetRect.left + targetRect.width / 2 - (balloonRect.width * 0.25) - sideOffset,
|
|
913
|
+
name: 'arrow_nmw',
|
|
914
|
+
...(config && { config })
|
|
915
|
+
}),
|
|
916
|
+
southArrowNorth: (targetRect, balloonRect) => ({
|
|
917
|
+
top: getSouthTop(targetRect),
|
|
918
|
+
left: targetRect.left + targetRect.width / 2 - balloonRect.width / 2,
|
|
919
|
+
name: 'arrow_n',
|
|
920
|
+
...(config && { config })
|
|
921
|
+
}),
|
|
922
|
+
southArrowNorthMiddleEast: (targetRect, balloonRect) => ({
|
|
923
|
+
top: getSouthTop(targetRect),
|
|
924
|
+
left: targetRect.left + targetRect.width / 2 - (balloonRect.width * 0.75) + sideOffset,
|
|
925
|
+
name: 'arrow_nme',
|
|
926
|
+
...(config && { config })
|
|
927
|
+
}),
|
|
928
|
+
southArrowNorthEast: (targetRect, balloonRect) => ({
|
|
929
|
+
top: getSouthTop(targetRect),
|
|
930
|
+
left: targetRect.left + targetRect.width / 2 - balloonRect.width + sideOffset,
|
|
931
|
+
name: 'arrow_ne',
|
|
932
|
+
...(config && { config })
|
|
933
|
+
}),
|
|
934
|
+
// ------- South east
|
|
935
|
+
southEastArrowNorthWest: targetRect => ({
|
|
936
|
+
top: getSouthTop(targetRect),
|
|
937
|
+
left: targetRect.right - sideOffset,
|
|
938
|
+
name: 'arrow_nw',
|
|
939
|
+
...(config && { config })
|
|
940
|
+
}),
|
|
941
|
+
southEastArrowNorthMiddleWest: (targetRect, balloonRect) => ({
|
|
942
|
+
top: getSouthTop(targetRect),
|
|
943
|
+
left: targetRect.right - (balloonRect.width * .25) - sideOffset,
|
|
944
|
+
name: 'arrow_nmw',
|
|
945
|
+
...(config && { config })
|
|
946
|
+
}),
|
|
947
|
+
southEastArrowNorth: (targetRect, balloonRect) => ({
|
|
948
|
+
top: getSouthTop(targetRect),
|
|
949
|
+
left: targetRect.right - balloonRect.width / 2,
|
|
950
|
+
name: 'arrow_n',
|
|
951
|
+
...(config && { config })
|
|
952
|
+
}),
|
|
953
|
+
southEastArrowNorthMiddleEast: (targetRect, balloonRect) => ({
|
|
954
|
+
top: getSouthTop(targetRect),
|
|
955
|
+
left: targetRect.right - (balloonRect.width * .75) + sideOffset,
|
|
956
|
+
name: 'arrow_nme',
|
|
957
|
+
...(config && { config })
|
|
958
|
+
}),
|
|
959
|
+
southEastArrowNorthEast: (targetRect, balloonRect) => ({
|
|
960
|
+
top: getSouthTop(targetRect),
|
|
961
|
+
left: targetRect.right - balloonRect.width + sideOffset,
|
|
962
|
+
name: 'arrow_ne',
|
|
963
|
+
...(config && { config })
|
|
964
|
+
}),
|
|
965
|
+
// ------- West
|
|
966
|
+
westArrowEast: (targetRect, balloonRect) => ({
|
|
967
|
+
top: targetRect.top + targetRect.height / 2 - balloonRect.height / 2,
|
|
968
|
+
left: targetRect.left - balloonRect.width - heightOffset,
|
|
969
|
+
name: 'arrow_e',
|
|
970
|
+
...(config && { config })
|
|
971
|
+
}),
|
|
972
|
+
// ------- East
|
|
973
|
+
eastArrowWest: (targetRect, balloonRect) => ({
|
|
974
|
+
top: targetRect.top + targetRect.height / 2 - balloonRect.height / 2,
|
|
975
|
+
left: targetRect.right + heightOffset,
|
|
976
|
+
name: 'arrow_w',
|
|
977
|
+
...(config && { config })
|
|
978
|
+
}),
|
|
979
|
+
// ------- Sticky
|
|
980
|
+
viewportStickyNorth: (targetRect, balloonRect, viewportRect) => {
|
|
981
|
+
if (!targetRect.getIntersection(viewportRect)) {
|
|
982
|
+
return null;
|
|
983
|
+
}
|
|
984
|
+
return {
|
|
985
|
+
top: viewportRect.top + stickyVerticalOffset,
|
|
986
|
+
left: targetRect.left + targetRect.width / 2 - balloonRect.width / 2,
|
|
987
|
+
name: 'arrowless',
|
|
988
|
+
config: {
|
|
989
|
+
withArrow: false,
|
|
990
|
+
...config
|
|
991
|
+
}
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
};
|
|
995
|
+
// Returns the top coordinate for positions starting with `north*`.
|
|
996
|
+
//
|
|
997
|
+
// @private
|
|
998
|
+
// @param {utils/dom/rect~Rect} targetRect A rect of the target.
|
|
999
|
+
// @param {utils/dom/rect~Rect} elementRect A rect of the balloon.
|
|
1000
|
+
// @returns {Number}
|
|
1001
|
+
function getNorthTop(targetRect, balloonRect) {
|
|
1002
|
+
return targetRect.top - balloonRect.height - heightOffset;
|
|
1003
|
+
}
|
|
1004
|
+
// Returns the top coordinate for positions starting with `south*`.
|
|
1005
|
+
//
|
|
1006
|
+
// @private
|
|
1007
|
+
// @param {utils/dom/rect~Rect} targetRect A rect of the target.
|
|
1008
|
+
// @param {utils/dom/rect~Rect} elementRect A rect of the balloon.
|
|
1009
|
+
// @returns {Number}
|
|
1010
|
+
function getSouthTop(targetRect) {
|
|
1011
|
+
return targetRect.bottom + heightOffset;
|
|
1012
|
+
}
|
|
1106
1013
|
}
|