@openui5/sap.ui.dt 1.93.3 → 1.96.1

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 (48) hide show
  1. package/.reuse/dep5 +6 -11
  2. package/THIRDPARTY.txt +10 -16
  3. package/package.json +2 -2
  4. package/src/sap/ui/dt/.library +1 -1
  5. package/src/sap/ui/dt/AggregationDesignTimeMetadata.js +1 -1
  6. package/src/sap/ui/dt/AggregationOverlay.js +1 -1
  7. package/src/sap/ui/dt/ControlObserver.js +1 -1
  8. package/src/sap/ui/dt/DOMUtil.js +1 -1
  9. package/src/sap/ui/dt/DesignTime.js +1 -1
  10. package/src/sap/ui/dt/DesignTimeMetadata.js +1 -1
  11. package/src/sap/ui/dt/ElementDesignTimeMetadata.js +2 -2
  12. package/src/sap/ui/dt/ElementOverlay.js +8 -1
  13. package/src/sap/ui/dt/ElementUtil.js +73 -1
  14. package/src/sap/ui/dt/ManagedObjectObserver.js +1 -1
  15. package/src/sap/ui/dt/MetadataPropagationUtil.js +1 -1
  16. package/src/sap/ui/dt/MutationObserver.js +1 -1
  17. package/src/sap/ui/dt/Overlay.js +1 -1
  18. package/src/sap/ui/dt/OverlayRegistry.js +1 -1
  19. package/src/sap/ui/dt/OverlayUtil.js +50 -16
  20. package/src/sap/ui/dt/Plugin.js +1 -1
  21. package/src/sap/ui/dt/ScrollbarSynchronizer.js +1 -1
  22. package/src/sap/ui/dt/SelectionManager.js +1 -1
  23. package/src/sap/ui/dt/SelectionMode.js +1 -1
  24. package/src/sap/ui/dt/TaskManager.js +1 -1
  25. package/src/sap/ui/dt/TaskRunner.js +1 -1
  26. package/src/sap/ui/dt/Util.js +1 -5
  27. package/src/sap/ui/dt/enablement/ElementEnablementTest.js +1 -1
  28. package/src/sap/ui/dt/enablement/Test.js +1 -1
  29. package/src/sap/ui/dt/enablement/Util.js +1 -1
  30. package/src/sap/ui/dt/enablement/report/LibraryReport.js +1 -1
  31. package/src/sap/ui/dt/enablement/report/QUnitReport.js +1 -1
  32. package/src/sap/ui/dt/enablement/report/Statistic.js +1 -1
  33. package/src/sap/ui/dt/enablement/report/StatisticRenderer.js +1 -1
  34. package/src/sap/ui/dt/enablement/report/Table.js +1 -1
  35. package/src/sap/ui/dt/enablement/report/TableRenderer.js +1 -1
  36. package/src/sap/ui/dt/library.js +2 -2
  37. package/src/sap/ui/dt/plugin/ContextMenu.js +121 -383
  38. package/src/sap/ui/dt/plugin/ControlDragDrop.js +1 -1
  39. package/src/sap/ui/dt/plugin/CutPaste.js +1 -1
  40. package/src/sap/ui/dt/plugin/DragDrop.js +1 -1
  41. package/src/sap/ui/dt/plugin/ElementMover.js +39 -42
  42. package/src/sap/ui/dt/plugin/MouseSelection.js +1 -1
  43. package/src/sap/ui/dt/plugin/TabHandling.js +39 -7
  44. package/src/sap/ui/dt/plugin/ToolHooks.js +1 -1
  45. package/src/sap/ui/dt/themes/base/ContextMenu.less +104 -75
  46. package/src/sap/ui/dt/util/ZIndexManager.js +1 -1
  47. package/ui5.yaml +4 -1
  48. package/src/sap/ui/dt/ContextMenuControl.js +0 -929
@@ -1,929 +0,0 @@
1
- /*
2
- * ! OpenUI5
3
- * (c) Copyright 2009-2021 SAP SE or an SAP affiliate company.
4
- * Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
5
- */
6
- sap.ui.define([
7
- "sap/ui/thirdparty/jquery",
8
- "sap/ui/base/ManagedObject",
9
- "sap/base/util/deepEqual",
10
- "sap/m/library",
11
- "sap/m/Popover",
12
- "sap/m/VBox",
13
- "sap/m/HBox",
14
- "sap/m/Button",
15
- "sap/m/FlexItemData",
16
- "sap/ui/dt/OverlayRegistry",
17
- "sap/ui/dt/DOMUtil",
18
- // jQuery Plugin "rect"
19
- "sap/ui/dom/jquery/rect"
20
- ], function(
21
- jQuery,
22
- ManagedObject,
23
- DeepEqual,
24
- mobileLibrary,
25
- Popover,
26
- VBox,
27
- HBox,
28
- Button,
29
- FlexItemData,
30
- OverlayRegistry,
31
- DOMUtil
32
- ) {
33
- "use strict";
34
-
35
- var PlacementType = mobileLibrary.PlacementType;
36
-
37
- /**
38
- * Constructor for a new sap.ui.dt.ContextMenu control.
39
- *
40
- * @param {string} [sId] id for the new control, generated automatically if no id is given
41
- * @param {object} [mSettings] initial settings for the new control
42
- * @class A simple ContextMenu.
43
- * @extends sap.ui.base.ManagedObject
44
- * @author SAP SE
45
- * @version 1.93.3
46
- * @constructor
47
- * @private
48
- * @experimental
49
- * @alias sap.ui.dt.ContextMenu
50
- */
51
- var ContextMenu = ManagedObject.extend("sap.ui.dt.ContextMenuControl", {
52
- metadata: {
53
- properties: {
54
- /**
55
- * Defines the maximum number of buttons displayed in the non-expanded version of the control.
56
- * If more than n buttons are added an overflow button will be displayed instead of the nth button (n = maxButtonsDisplayed).
57
- */
58
- maxButtonsDisplayed: {
59
- type: "int",
60
- defaultValue: 4
61
- },
62
- /**
63
- * Defines the buttons on the ContextMenu
64
- * The objects should have the following properties:
65
- * text - for the button text in the expanded version and the tooltip in the non-expanded version
66
- * icon - the url of the buttons icon
67
- * handler - the function to call when the button is pressed
68
- */
69
- buttons: {
70
- type: "object[]",
71
- defaultValue: []
72
- },
73
- /**
74
- * The Style class which should be added to the ContextMenu
75
- */
76
- styleClass: {
77
- type: "string",
78
- defaultValue: ""
79
- }
80
- },
81
- events: {
82
- /**
83
- * This event is fired after opening the ContextMenu
84
- */
85
- Opened: {},
86
- /**
87
- * This event is fired after closing the ContextMenu
88
- */
89
- Closed: {},
90
- /**
91
- * This event is fired when the overfow button is pressed
92
- */
93
- OverflowButtonPressed: {}
94
- }
95
- },
96
-
97
- /**
98
- * initializes the ContextMenu by creating the internal a sap.m.Popover (with a sap.m.Flexbox as a content aggregation) in internal _popovers aggregation of the ContextMenu
99
- */
100
- init: function() {
101
- var sPopId = this.getId() + "-popover";
102
- var oPopover = new Popover(sPopId, {
103
- showHeader: false,
104
- verticalScrolling: false,
105
- placement: "Top",
106
- showArrow: true,
107
- horizontalScrolling: false,
108
- content: new HBox(sPopId + "ContentBox", {
109
- renderType: "Bare"
110
- })
111
- });
112
-
113
- // Returns the duration for the Popover's closing animation.
114
- // It particularily concerns the setting of the focus within the contextMenu
115
- oPopover._getAnimationDuration = function() {
116
- return 0;
117
- };
118
-
119
- oPopover.attachBrowserEvent("keydown", this._onKeyDown, this);
120
- this._oPopover = oPopover;
121
- oPopover.addStyleClass("sapUiDtContextMenu");
122
-
123
- var sPopExpId = this.getId() + "-popoverExp";
124
- var oPopoverExpanded = new Popover(sPopExpId, {
125
- showHeader: false,
126
- showArrow: false,
127
- verticalScrolling: true,
128
- horizontalScrolling: false,
129
- content: new VBox(sPopExpId + "ContentBox", {
130
- renderType: "Bare"
131
- })
132
- });
133
-
134
- // Returns the duration for the Popover's closing animation.
135
- // It particularily concerns the setting of the focus within the contextMenu
136
- oPopoverExpanded._getAnimationDuration = function() {
137
- return 0;
138
- };
139
-
140
- oPopoverExpanded.attachBrowserEvent("keydown", this._onKeyDown, this);
141
- this._oExpandedPopover = oPopoverExpanded;
142
- oPopoverExpanded.addStyleClass("sapUiDtContextMenu");
143
-
144
- oPopover.attachBrowserEvent("contextmenu", this._onContextMenu, this);
145
- oPopoverExpanded.attachBrowserEvent("contextmenu", this._onContextMenu, this);
146
- this.bOnInit = true;
147
- this._oLastSourceOverlay = this._oLastSourceClientRects = this._oLastPosition = null;
148
- },
149
-
150
- exit: function() {
151
- [true, false].forEach(function(bContextMenu) {
152
- this.getPopover(bContextMenu).detachBrowserEvent("contextmenu", this._onContextMenu, this);
153
- this.getPopover(bContextMenu).destroy();
154
- }.bind(this));
155
- },
156
-
157
- /**
158
- * Returns the value of the isOpen function of the popover
159
- *
160
- * @param {boolean} bContextMenu - true if the expanded context menu should be checked
161
- * @returns {boolean} Returns true if the popup is currently open
162
- */
163
- isPopupOpen: function(bContextMenu) {
164
- return this.getPopover(bContextMenu).isOpen();
165
- },
166
-
167
- /**
168
- * Opens the ContextMenu and sets the ContextMenu position by the oSource parameter.
169
- * Note: this gets called before the old Menu is closed because of asynchronus animations.
170
- * @param {sap.ui.dt.ElementOverlay} oSource - The overlay by which the Popover will be placed.
171
- * @param {boolean} bContextMenu - If the ContextMenu should appear as Context Menu
172
- * @param {Object} oContextMenuPosition - The position of the ContextMenu
173
- * @public
174
- */
175
- show: function(oSource, bContextMenu, oContextMenuPosition) {
176
- bContextMenu = !!bContextMenu;
177
- this._bCompactMode = jQuery(oSource.getDomRef()).closest(".sapUiSizeCompact").length > 0;
178
- this._bOpenAsContextMenu = bContextMenu;
179
- this._oContextMenuPosition = oContextMenuPosition;
180
- this.getPopover(true).addStyleClass(this.getStyleClass());
181
- this.getPopover(false).addStyleClass(this.getStyleClass());
182
-
183
- // creates and shows buttons specified in objects in property buttons
184
- this._showButtons(bContextMenu);
185
-
186
- if (this.bOnInit || !this.isPopupOpen()) { // if there is no other ContextMenu open currently
187
- this._finalizeOpening(oSource);
188
- this.bOnInit = false;
189
- } else {
190
- this.getPopover().oPopup.attachEventOnce("closed", this._finalizeOpening.bind(this, oSource));
191
- }
192
- },
193
-
194
- /**
195
- * Finalizes the Opening of the ContextMenu.
196
- *
197
- * @param {sap.ui.dt.ElementOverlay} oSource - The overlay by which the Popover will be placed.
198
- */
199
- _finalizeOpening: function(oSource) {
200
- this._bUseExpPop = this._bOpenAsContextMenu;
201
- if (this._bOpenAsContextMenu && this._oContextMenuPosition.x === null && this._oContextMenuPosition.y === null) {
202
- this._bOpenAsContextMenu = false;
203
- }
204
-
205
- // fires the open event after popover is opened
206
- this.getPopover().attachAfterOpen(this._handleAfterOpen, this);
207
-
208
- this.getPopover().attachBeforeClose(this._handleBeforeClose, this);
209
- this.getPopover().attachAfterClose(this._handleAfterClose, this);
210
-
211
- //place the Popover and get the target DIV
212
- this._oTarget = this._placeContextMenu(oSource, this._bOpenAsContextMenu);
213
-
214
- // set the PopOver visible
215
- this.getPopover().setVisible(true);
216
- },
217
-
218
- _showButtons: function(bContextMenu) {
219
- var aButtons = this.getButtons(bContextMenu);
220
- if (!this._bOpenAsContextMenu) {
221
- this._setButtonsForCollapsedMenu(aButtons);
222
- } else {
223
- this._makeAllButtonsVisible(aButtons);
224
- }
225
- },
226
-
227
- /**
228
- * Sets all parameters of the buttons in the non-expanded ContextMenu
229
- * @param {array} aButtons some buttons
230
- */
231
- _setButtonsForCollapsedMenu: function(aButtons) {
232
- var iButtonsEnabled = this._getNumberOfEnabledButtons(aButtons);
233
- if (iButtonsEnabled !== 0) {
234
- this._hideDisabledButtons(aButtons);
235
- }
236
-
237
- this._iButtonsVisible = this._hideButtonsInOverflow(aButtons);
238
- if (this._iButtonsVisible === this.getMaxButtonsDisplayed() && this._iButtonsVisible !== aButtons.length) {
239
- this._replaceLastVisibleButtonWithOverflowButton(aButtons);
240
- } else if (iButtonsEnabled < aButtons.length - 1 && iButtonsEnabled !== 0) {
241
- this.addOverflowButton();
242
- }
243
-
244
- iButtonsEnabled = null;
245
- },
246
-
247
- /**
248
- * Makes all buttons and their text visible
249
- * @param {array} aButtons some buttons
250
- */
251
- _makeAllButtonsVisible: function(aButtons) {
252
- this._iFirstVisibleButtonIndex = 0;
253
- aButtons.forEach(function(oButton) {
254
- oButton.setVisible(true);
255
- oButton._bInOverflow = true;
256
- });
257
- },
258
-
259
- /**
260
- * Returns the number of enabled button
261
- * Sets firstVisibleButtonIndex
262
- * @param {array} aButtons some buttons
263
- * @return {int} number of enabled buttons
264
- */
265
- _getNumberOfEnabledButtons: function(aButtons) {
266
- var iButtonsEnabled = 0;
267
- for (var i = 0; i < aButtons.length; i++) {
268
- if (aButtons[i].getEnabled()) {
269
- iButtonsEnabled++;
270
- if (!this._iFirstVisibleButtonIndex) {
271
- this._iFirstVisibleButtonIndex = i;
272
- }
273
- }
274
- }
275
-
276
- return iButtonsEnabled;
277
- },
278
-
279
- /**
280
- * Hiddes all disabled buttons and returns the number if visible buttons
281
- * @param {array} aButtons some Buttons
282
- * @return {int} the number of visible buttons
283
- */
284
- _hideDisabledButtons: function(aButtons) {
285
- var iVisibleButtons = 0;
286
- aButtons.forEach(function(oButton) {
287
- oButton.setVisible(oButton.getEnabled());
288
- if (oButton.getEnabled()) {
289
- iVisibleButtons++;
290
- }
291
- });
292
-
293
- return iVisibleButtons;
294
- },
295
-
296
- /**
297
- * Hides the buttons in overflow
298
- * @param {array} aButtons some Buttons
299
- * @return {int} the number of visible buttons
300
- */
301
- _hideButtonsInOverflow: function(aButtons) {
302
- var iVisibleButtons = 0;
303
- for (var i = 0; i < aButtons.length; i++) {
304
- if (iVisibleButtons < this.getMaxButtonsDisplayed() && aButtons[i].getVisible()) {
305
- iVisibleButtons++;
306
- } else {
307
- aButtons[i].setVisible(false);
308
- }
309
- }
310
-
311
- return iVisibleButtons;
312
- },
313
-
314
- /**
315
- * Hides the last visible button and adds an OverflowButton
316
- * @param {array} aButtons some buttons
317
- */
318
- _replaceLastVisibleButtonWithOverflowButton: function(aButtons) {
319
- for (var i = aButtons.length - 1; i >= 0; i--) {
320
- if (aButtons[i].getVisible()) {
321
- aButtons[i].setVisible(false);
322
- this.addOverflowButton();
323
- return;
324
- }
325
- }
326
- },
327
-
328
- /**
329
- * Works out how the ContextMenu shall be placed
330
- * Sets the placement property of the popover
331
- * Places a "fakeDiv" in the DOM which the popover can be opened by
332
- * @param {sap.ui.dt.ElementOverlay} oSource - The overlay by which the Popover will be placed.
333
- * @param {boolean} bContextMenu whether the ContextMenu should be opened as a context menu
334
- * @return {div} the "fakeDiv"
335
- * @private
336
- */
337
- _placeContextMenu: function(oSource, bContextMenu) {
338
- var sOverlayId = (oSource.getId && oSource.getId()) || oSource.getAttribute("overlay");
339
- var sFakeDivId = "contextMenuFakeDiv";
340
-
341
- // get Dimensions of Overlay and Viewport
342
- var oOverlayDimensions = this._getOverlayDimensions(sOverlayId);
343
- var oViewportDimensions = this._getViewportDimensions();
344
-
345
- // if the Overlay is near the top position of the Viewport, the Popover makes wrong calculation for positioning it.
346
- // The MiniMenu has been placed above the Overlay even if there has not been enough place.
347
- // Therefore we have to calculate the top position and also consider the high of the Toolbar (46 Pixels).
348
- var iFakeDivTop = oOverlayDimensions.top - 50 > oViewportDimensions.top ? 0 : oViewportDimensions.top - (oOverlayDimensions.top - 50);
349
-
350
- // place a Target DIV (for the moment at wrong position)
351
- jQuery("#" + sFakeDivId).remove();
352
- jQuery("#" + sOverlayId).append("<div id=\"" + sFakeDivId + "\" overlay=\"" + sOverlayId + "\" style = \"position: absolute; top: " + iFakeDivTop + "px; left: 0px;\"></div>");
353
- sOverlayId = null;
354
- var oFakeDiv = document.getElementById(sFakeDivId);
355
-
356
- // place the Popover invisible
357
- this.getPopover().setContentWidth(undefined);
358
- this.getPopover().setContentHeight(undefined);
359
- this.getPopover().openBy(oFakeDiv);
360
-
361
- // get Dimensions of Popover
362
- var oPopoverDimensions = this._getPopoverDimensions(!bContextMenu);
363
-
364
- // check if vertical size is too big (not bigger than 2/3 of the viewport)
365
- if (oPopoverDimensions.height >= oViewportDimensions.height * 2 / 3) {
366
- oPopoverDimensions.height = (oViewportDimensions.height * 2 / 3).toFixed(0);
367
- this.getPopover().setContentHeight(oPopoverDimensions.height + "px");
368
- }
369
-
370
- // check if horizontal size is too big
371
- if (oPopoverDimensions.width > 400) {
372
- oPopoverDimensions.width = 400;
373
- this.getPopover().setContentWidth("400px");
374
- } else {
375
- this.getPopover().setContentWidth(undefined);
376
- }
377
-
378
- // If the Menu has been closed by ESC-key and reopened again on the same Overlay, the Position of Menu should not change
379
- var bIsSameOverlay = (this._oLastSourceOverlay ? this._oLastSourceOverlay === oSource : false);
380
- var bIsSameRect = (this._oLastSourceClientRects ? DeepEqual(JSON.parse(JSON.stringify(this._oLastSourceClientRects)), JSON.parse(JSON.stringify(oSource.getDomRef().getClientRects()))) : false);
381
- if (this._oContextMenuPosition.x === "not set" && this._oContextMenuPosition.y === "not set" && bIsSameOverlay && bIsSameRect) {
382
- // Get the last x/y Positions of the current Target
383
- this._oContextMenuPosition.x = this._oLastPosition.x;
384
- this._oContextMenuPosition.y = this._oLastPosition.y;
385
- } else {
386
- // get the given x/y Positions; if no Position is given, take the upper left corner of the Overlay + 20px (looks better)
387
- this._oContextMenuPosition.x = this._oContextMenuPosition.x || parseInt(oOverlayDimensions.left + 20);
388
- this._oContextMenuPosition.y = this._oContextMenuPosition.y || parseInt(oOverlayDimensions.top + 20);
389
- }
390
-
391
- var oPosition = {};
392
-
393
- if (bContextMenu) {
394
- oPosition = this._placeAsExpandedContextMenu(this._oContextMenuPosition, oPopoverDimensions, oViewportDimensions);
395
- } else {
396
- oPosition = this._placeAsCompactContextMenu(this._oContextMenuPosition, oPopoverDimensions, oViewportDimensions);
397
- }
398
-
399
- oPosition.top -= oOverlayDimensions.top;
400
- oPosition.left -= oOverlayDimensions.left;
401
- oPosition.top = (oPosition.top < 0) ? 0 : oPosition.top;
402
- oPosition.left = (oPosition.left < 0) ? 0 : oPosition.left;
403
-
404
- // set the correct position to the target DIV
405
- oFakeDiv.style.top = oPosition.top.toFixed(0) + "px";
406
- oFakeDiv.style.left = oPosition.left.toFixed(0) + "px";
407
-
408
- return oFakeDiv;
409
- },
410
-
411
- /**
412
- * Works out how the ContextMenu shall be placed
413
- * @param {object} oContPos the context menu position
414
- * @param {object} oPopover the dimensions of the popover
415
- * @param {object} oViewport the dimensions of the viewport
416
- * @return {object} the position of the "fakeDiv"
417
- */
418
- _placeAsExpandedContextMenu: function(oContPos, oPopover, oViewport) {
419
- this.getPopover().setShowArrow(false);
420
- var oPos = {};
421
-
422
- if (oViewport.height - 10 - oContPos.y >= oPopover.height) {
423
- oPos.top = oContPos.y;
424
- this.getPopover().setPlacement("Bottom");
425
- } else if (oContPos.y >= oPopover.height) {
426
- oPos.top = oContPos.y;
427
- this.getPopover().setPlacement("Top");
428
- } else {
429
- oPos.top = oViewport.height - oPopover.height;
430
- this.getPopover().setPlacement("Bottom");
431
- }
432
-
433
- if (oViewport.width - oContPos.x >= oPopover.width) {
434
- oPos.left = oContPos.x;
435
- } else if (oContPos.x >= oPopover.width) {
436
- oPos.left = oContPos.x - oPopover.width / 2;
437
- } else {
438
- oPos.left = oViewport.width - oPopover.width;
439
- }
440
-
441
- return oPos;
442
- },
443
-
444
- /**
445
- * Works out how the ContextMenu shall be placed
446
- * @param {object} oContPos the context menu position
447
- * @param {object} oPopover the dimensions of the popover
448
- * @param {object} oViewport the dimensions of the viewport
449
- * @return {object} the position of the "fakeDiv"
450
- */
451
- _placeAsCompactContextMenu: function(oContPos, oPopover, oViewport) {
452
- this.getPopover().setShowArrow(true);
453
- var oPos = {};
454
-
455
- //Popover should appear at the top (if place available)
456
- this.getPopover().setPlacement(PlacementType.PreferredTopOrFlip);
457
-
458
- var iBtnWidth = oPopover.width / this._iButtonsVisible;
459
-
460
- // calculate the horizontal position according to RTL /LTR setting (add/substract)
461
- var iFactor = sap.ui.getCore().getConfiguration().getRTL() ? -1 : 1;
462
- oPos.left = oContPos.x + (iFactor * ((this._iButtonsVisible - 1) * iBtnWidth) / 2 + (this._getBaseFontSize() * 1 / 2));
463
- oPos.top = oContPos.y - (this._getBaseFontSize() * 1 / 2);
464
-
465
- // adjust positioning if necessary
466
- oPos.left = (oPos.left < 32) ? 32 : oPos.left;
467
- oPos.top = (oPos.top - oViewport.top < 0) ? oViewport.top : oPos.top;
468
-
469
- // check right border positioning
470
- if (oViewport.width - oPos.left < 32) {
471
- oPos.left = oViewport.width - 32;
472
- this.getPopover().addStyleClass("sapUiDtContextMenuRightArrow");
473
- } else {
474
- this.getPopover().removeStyleClass("sapUiDtContextMenuRightArrow");
475
- }
476
-
477
- // in Cozy mode the context menu is bigger, therefore we need a higher threshold for the top parameter
478
- var iCozyFactor = this._bCompactMode ? 0 : 15;
479
- if (oPos.top < (100 + iCozyFactor)) {
480
- this.getPopover().setPlacement(PlacementType.Bottom);
481
- oPos.top += 16;
482
- }
483
-
484
- return oPos;
485
- },
486
-
487
- /**
488
- * Gets the dimensions of the ContextMenu's popover
489
- * @param {boolean} bWithArrow whether the arrow width should be added
490
- * @return {object} the dimensions of the ContextMenu's popover
491
- */
492
- _getPopoverDimensions: function(bWithArrow) {
493
- var oPopover = {};
494
- var bCompact = this._bCompactMode;
495
- var fArrowHeight = this._getArrowHeight(bCompact);
496
- var iBaseFontsize = this._getBaseFontSize();
497
- this._iFirstVisibleButtonIndex = null;
498
-
499
- oPopover.height = parseInt(jQuery("#" + this.getPopover().getId()).css("height")) || 40;
500
- oPopover.width = parseInt(jQuery("#" + this.getPopover().getId()).css("width")) || 80;
501
-
502
- if (bWithArrow) {
503
- var iArr = iBaseFontsize * fArrowHeight;
504
- if (iArr) {
505
- oPopover.height += iArr;
506
- oPopover.width += iArr;
507
- }
508
- }
509
-
510
- return oPopover;
511
- },
512
-
513
- /**
514
- * Returns the height of a popover arrow
515
- * @param {boolean} bCompact wheter ContextMenu is compact
516
- * @return {float} the height of a popover arrow
517
- */
518
- _getArrowHeight: function(bCompact) {
519
- return bCompact ? 0.5625 : 0.5625;
520
- },
521
-
522
- /**
523
- * Returns the base font size in px
524
- * @return {int} the base font size in px
525
- */
526
- _getBaseFontSize: function() {
527
- return parseInt(jQuery(document.documentElement).css("fontSize"));
528
- },
529
-
530
- /**
531
- * Gets the dimensions of an overlay
532
- * @param {String} sOverlayId the overlay
533
- * @return {object} the dimensions of the overlay
534
- */
535
- _getOverlayDimensions: function(sOverlayId) {
536
- // jQuery Plugin "rect"
537
- var oOverlayDimensions = jQuery("#" + sOverlayId).rect();
538
- oOverlayDimensions.right = oOverlayDimensions.left + oOverlayDimensions.width;
539
- oOverlayDimensions.bottom = oOverlayDimensions.top + oOverlayDimensions.height;
540
-
541
- return oOverlayDimensions;
542
- },
543
-
544
- /**
545
- * Gets the dimensions of the viewport
546
- * @return {object} the dimensions of the viewport
547
- */
548
- _getViewportDimensions: function() {
549
- var oViewport = {};
550
- oViewport.width = window.innerWidth;
551
- oViewport.height = window.innerHeight;
552
- oViewport.top = parseInt(jQuery(".type_standalone").css("height")) || 0;
553
- oViewport.bottom = oViewport.top + oViewport.height;
554
-
555
- return oViewport;
556
- },
557
-
558
- _getIcon: function(sIcon) {
559
- if (sIcon === undefined || sIcon === null || typeof sIcon !== "string") {
560
- return "sap-icon://incident";
561
- }
562
- if (sIcon === "blank") {
563
- return " ";
564
- }
565
- return sIcon;
566
- },
567
-
568
- /**
569
- * Adds a overflowButton to the ContextMenu.
570
- * @returns {sap.ui.dt.ContextMenuControl} Reference to this in order to allow method chaining
571
- * @public
572
- */
573
- addOverflowButton: function() {
574
- var sOverflowButtonId = "OVERFLOW_BUTTON";
575
- var oButtonOptions = {
576
- icon: "sap-icon://overflow",
577
- type: "Transparent",
578
- enabled: true,
579
- press: this._onOverflowPress.bind(this),
580
- layoutData: new FlexItemData({})
581
- };
582
- return this._addButton(sOverflowButtonId, oButtonOptions);
583
- },
584
-
585
- /**
586
- * Adds a menu action button to the contextMenu
587
- * @param {Object} oButtonItem the button configuration item
588
- * @param {function} fnContextMenuHandler the handler function for button press event
589
- * @param {sap.ui.dt.ElementOverlay[]} aElementOverlays - Target overlays
590
- * @returns {sap.ui.dt.ContextMenuControl} Reference to this in order to allow method chaining
591
- * @public
592
- */
593
- addMenuButton: function(oButtonItem, fnContextMenuHandler, aElementOverlays) {
594
- function handler() {
595
- fnContextMenuHandler(this);
596
- }
597
- if (oButtonItem.responsible) {
598
- aElementOverlays = oButtonItem.responsible;
599
- }
600
- var sText = typeof oButtonItem.text === "function" ? oButtonItem.text(aElementOverlays[0]) : oButtonItem.text;
601
- var bEnabled = typeof oButtonItem.enabled === "function" ? oButtonItem.enabled(aElementOverlays) : oButtonItem.enabled;
602
- var oButtonOptions = {
603
- icon: this._getIcon(oButtonItem.icon),
604
- text: sText,
605
- tooltip: sText,
606
- type: "Transparent",
607
- enabled: bEnabled,
608
- press: handler,
609
- layoutData: new FlexItemData({})
610
- };
611
- return this._addButton(oButtonItem.id, oButtonOptions);
612
- },
613
-
614
- _addButton: function(sButtonItemId, oButtonOptions) {
615
- this.setProperty("buttons", this.getProperty("buttons").concat(oButtonOptions));
616
-
617
- var oButtonCustomData = { id: sButtonItemId, key: sButtonItemId };
618
- var oExpandedMenuButton = new Button(oButtonOptions);
619
- oExpandedMenuButton.data(oButtonCustomData);
620
-
621
- delete oButtonOptions.text;
622
- var oCompactMenuButton = new Button(oButtonOptions);
623
- oCompactMenuButton.data(oButtonCustomData);
624
-
625
- this.getFlexbox(true).addItem(oExpandedMenuButton);
626
- this.getFlexbox(false).addItem(oCompactMenuButton);
627
-
628
- return this;
629
- },
630
-
631
- /**
632
- * Closes the ContextMenu.
633
- * @param {boolean} bExplicitClose true if the popover has to be closed explicitly from the contextMenu. Otherwhise the closing is handled by the popover itself
634
- * @returns {sap.ui.dt.ContextMenuControl} Reference to this in order to allow method chaining
635
- * @public
636
- */
637
- close: function(bExplicitClose) {
638
- if (this.getPopover()) {
639
- if (bExplicitClose) {
640
- this.getPopover(true).close();
641
- this.getPopover(false).close();
642
- }
643
-
644
- // deletes the overflow button if there is one
645
- if (this.getProperty("buttons").length > this.getProperty("maxButtonsDisplayed")) {
646
- this.setProperty("buttons", this.getProperty("buttons").splice(0, this.getProperty("buttons").length - 1));
647
- this.getFlexbox().removeItem(this.getButtons().length - 1);
648
- }
649
- }
650
-
651
- return this;
652
- },
653
-
654
- /**
655
- * Removes a button from the ContextMenu.
656
- * @param {int} iIndex the button to remove or its index or id
657
- * @return {sap.m.OverflowToolbarButton} The removed button or null
658
- * @public
659
- */
660
- removeButton: function(iIndex) {
661
- this.setProperty("buttons", this.getProperty("buttons").splice(iIndex, 1));
662
- this.getFlexbox(true).removeItem(iIndex);
663
- return this.getFlexbox(false).removeItem(iIndex);
664
- },
665
-
666
- /**
667
- * Removes all buttons from the ContextMenu.
668
- * @return {sap.m.OverflowToolbarButton} An array of the removed buttons (might be empty)
669
- * @public
670
- */
671
- removeAllButtons: function() {
672
- this.setProperty("buttons", []);
673
- this.getFlexbox(true).removeAllItems();
674
- return this.getFlexbox(false).removeAllItems();
675
- },
676
-
677
- /**
678
- * Gets all buttons of the ContextMenu.
679
- * @return {sap.m.OverflowToolbarButton[]} returns buttons
680
- * @public
681
- */
682
- getButtons: function(bContextMenu) {
683
- return this.getFlexbox(bContextMenu).getItems();
684
- },
685
-
686
- /**
687
- * Inserts a button to the ContextMenu.
688
- * @param {sap.m.OverflowToolbarButton} oButton the to insert
689
- * @param {int} iIndex - the 0-based index the button should be inserted at
690
- * @returns {sap.ui.dt.ContextMenuControl} Reference to this in order to allow method chaining
691
- * @public
692
- */
693
- insertButton: function(oButton, iIndex) {
694
- this.getFlexbox().insertItem(oButton, iIndex);
695
- return this;
696
- },
697
-
698
- /**
699
- * Sets the Buttons of the ContextMenu
700
- * @param {Array} _aButtons the Buttons to insert
701
- * @param {function} fnContextMenuHandler - the source
702
- * @param {sap.ui.dt.ElementOverlay[]} aElementOverlays - Target overlays
703
- * @public
704
- */
705
- setButtons: function(_aButtons, fnContextMenuHandler, aElementOverlays) {
706
- this.removeAllButtons();
707
-
708
- _aButtons.forEach(function(oButton) {
709
- this.addMenuButton(oButton, fnContextMenuHandler, aElementOverlays);
710
- }.bind(this));
711
- },
712
-
713
- /**
714
- * Sets the maximum amount of Buttons
715
- * @param {int} iMBD the maximum amount of buttons to be displayed in the non-expanded version of the Context-Menu
716
- * @public
717
- */
718
- setMaxButtonsDisplayed: function(iMBD) {
719
- if (iMBD < 2) {
720
- throw Error("maxButtonsDisplayed can't be less than two!");
721
- }
722
- this.setProperty("maxButtonsDisplayed", iMBD);
723
- },
724
-
725
- /**
726
- * Returns one of the Popovers
727
- * @param {boolean} bExpanded if undefined return the currently used Popover if true return expanded Popover if false return non-expanded Popover
728
- * @return {sap.m.Popover} one of the Popovers
729
- * @public
730
- */
731
- getPopover: function(bExpanded) {
732
- if (bExpanded === undefined) {
733
- if (this._bUseExpPop) {
734
- return this._oExpandedPopover;
735
- }
736
- return this._oPopover;
737
- } else if (bExpanded) {
738
- return this._oExpandedPopover;
739
- }
740
- return this._oPopover;
741
- },
742
-
743
- /**
744
- * Returns one of the Flexboxes
745
- * @param {boolean} bExpanded if undefined return the currently used FlexBox if true return expanded FlexBox if false return non-expanded FlexBox
746
- * @return {sap.m.Flexbox} the FlexBox
747
- * @public
748
- */
749
- getFlexbox: function(bExpanded) {
750
- return this.getPopover(bExpanded).getContent()[0];
751
- },
752
-
753
- /**
754
- * Expands the ContextMenu
755
- * @param {jQuery.Event} oEvent the press event
756
- * @private
757
- */
758
- _onOverflowPress: function(oEvent) {
759
- this.fireOverflowButtonPressed({oButton: oEvent.oSource});
760
- },
761
-
762
- /**
763
- * Sets the focus on a Button if possible
764
- * @param {sap.m.Button} oButton the button on which focus should be set
765
- * @returns {boolean} true if focus was set
766
- */
767
- _setFocusOnButton: function(oButton) {
768
- if (oButton.getEnabled() && oButton.getVisible()) {
769
- oButton.focus();
770
- return true;
771
- }
772
- },
773
-
774
- /**
775
- * Handler for KeyDown Event
776
- * Changes the focus inside the ContextMenu if an Arrowkey is pressed
777
- * Allows Safari users to navigate through the ContextMenu using tab and tab+shift
778
- * Closes the MiniMenu when Escape is pressed
779
- * @param {jQuery.Event} oEvent the keyboard event
780
- */
781
- _onKeyDown: function(oEvent) {
782
- if (document.activeElement) {
783
- var sId = document.activeElement.id;
784
- switch (oEvent.key) {
785
- case "ArrowRight":
786
- this._changeFocusOnButtons(sId);
787
- break;
788
- case "ArrowLeft":
789
- this._changeFocusOnButtons(sId, true);
790
- break;
791
- case "ArrowUp":
792
- this._changeFocusOnButtons(sId, true);
793
- break;
794
- case "ArrowDown":
795
- this._changeFocusOnButtons(sId);
796
- break;
797
- case "Escape":
798
- this._rememberPosition();
799
- break;
800
- default:
801
- break;
802
- }
803
- }
804
- },
805
-
806
- /**
807
- * Changes the focus for the Buttons in ContextMenu
808
- * @param {string} sId the ID of the currently focused buttons
809
- * @param {boolean} bPrevious if true, the previous button is selected instead of the next
810
- */
811
- _changeFocusOnButtons: function(sId, bPrevious) {
812
- this.getButtons().some(function(oButton, iIndex, aArray) {
813
- if (sId === oButton.getId()) {
814
- if (bPrevious) {
815
- this._setFocusOnPreviousButton(aArray, iIndex);
816
- } else {
817
- this._setFocusOnNextButton(aArray, iIndex);
818
- }
819
- return true;
820
- }
821
- }.bind(this));
822
- },
823
-
824
- /**
825
- * Stores the current Position of the Contextmenu for opening again at same position
826
- * @private
827
- */
828
- _rememberPosition: function() {
829
- var oNode = document.getElementById(this._oTarget.getAttribute("overlay"));
830
- if (oNode) {
831
- DOMUtil.focusWithoutScrolling(oNode);
832
- this._oLastSourceOverlay = OverlayRegistry.getOverlay(oNode.id);
833
- this._oLastSourceClientRects = this._oLastSourceOverlay.getDomRef().getClientRects();
834
- } else {
835
- this._oLastSourceClientRects = null;
836
- }
837
- this._oLastPosition = {
838
- x: this._oContextMenuPosition.x,
839
- y: this._oContextMenuPosition.y
840
- };
841
- },
842
-
843
- /**
844
- * Sets focus on next button
845
- * @param {Array} aButtons the array of Buttons
846
- * @param {int} iIndex the index of the currently focused buttons
847
- */
848
- _setFocusOnNextButton: function(aButtons, iIndex) {
849
- for (var i0 = iIndex + 1; i0 < aButtons.length; i0++) {
850
- if (this._setFocusOnButton(aButtons[i0])) {
851
- return;
852
- }
853
- }
854
-
855
- for (var i1 = 0; i1 < iIndex; i1++) {
856
- if (this._setFocusOnButton(aButtons[i1])) {
857
- return;
858
- }
859
- }
860
- },
861
-
862
- /**
863
- * Sets focus on previous button
864
- * @param {Array} aButtons the array of Buttons
865
- * @param {int} iIndex the index of the currently focused buttons
866
- */
867
- _setFocusOnPreviousButton: function(aButtons, iIndex) {
868
- for (var i0 = iIndex - 1; i0 >= 0; i0--) {
869
- if (this._setFocusOnButton(aButtons[i0])) {
870
- return;
871
- }
872
- }
873
-
874
- for (var i1 = aButtons.length - 1; i1 >= iIndex; i1--) {
875
- if (this._setFocusOnButton(aButtons[i1])) {
876
- return;
877
- }
878
- }
879
- },
880
-
881
- /**
882
- * Handle Context Menu
883
- * @param {sap.ui.base.Event} oEvent event object
884
- * @private
885
- */
886
- _onContextMenu: function(oEvent) {
887
- if (oEvent.preventDefault) {
888
- oEvent.preventDefault();
889
- }
890
- },
891
-
892
- /**
893
- * Handle After Open
894
- * Sets the Popover visible and fires Event "opened"
895
- * @private
896
- */
897
- _handleAfterOpen: function() {
898
- this.getPopover().detachAfterOpen(this._handleAfterOpen, this);
899
- this.getPopover().addStyleClass("sapUiDtContextMenuVisible");
900
- this.fireOpened();
901
- },
902
-
903
- /**
904
- * Handle Before Close
905
- * Sets the Popover invisible (to avoid flickering)
906
- * @private
907
- */
908
- _handleBeforeClose: function() {
909
- this.getPopover().detachBeforeClose(this._handleBeforeClose, this);
910
- this.getPopover().removeStyleClass("sapUiDtContextMenuVisible");
911
- },
912
-
913
- /**
914
- * Handle After Close
915
- * Fires the closed event
916
- * @private
917
- */
918
- _handleAfterClose: function() {
919
- this.getPopover().detachAfterClose(this._handleAfterClose, this);
920
- this.fireClosed();
921
- },
922
-
923
- setStyleClass: function(sStyleClass) {
924
- this.setProperty("styleClass", sStyleClass);
925
- }
926
- });
927
-
928
- return ContextMenu;
929
- });