@openui5/sap.ui.dt 1.140.0 → 1.141.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 (41) hide show
  1. package/THIRDPARTY.txt +2 -2
  2. package/package.json +2 -2
  3. package/src/sap/ui/dt/.library +2 -9
  4. package/src/sap/ui/dt/AggregationDesignTimeMetadata.js +1 -1
  5. package/src/sap/ui/dt/AggregationOverlay.js +1 -1
  6. package/src/sap/ui/dt/ControlObserver.js +1 -1
  7. package/src/sap/ui/dt/DOMUtil.js +1 -1
  8. package/src/sap/ui/dt/DesignTime.js +1 -1
  9. package/src/sap/ui/dt/DesignTimeMetadata.js +1 -1
  10. package/src/sap/ui/dt/ElementDesignTimeMetadata.js +1 -1
  11. package/src/sap/ui/dt/ElementOverlay.js +1 -1
  12. package/src/sap/ui/dt/ElementUtil.js +1 -1
  13. package/src/sap/ui/dt/ManagedObjectObserver.js +1 -1
  14. package/src/sap/ui/dt/MetadataPropagationUtil.js +1 -1
  15. package/src/sap/ui/dt/MutationObserver.js +1 -1
  16. package/src/sap/ui/dt/Overlay.js +1 -1
  17. package/src/sap/ui/dt/OverlayRegistry.js +1 -1
  18. package/src/sap/ui/dt/OverlayUtil.js +1 -1
  19. package/src/sap/ui/dt/Plugin.js +1 -1
  20. package/src/sap/ui/dt/ScrollbarSynchronizer.js +1 -1
  21. package/src/sap/ui/dt/SelectionManager.js +1 -1
  22. package/src/sap/ui/dt/SelectionMode.js +1 -1
  23. package/src/sap/ui/dt/TaskManager.js +1 -1
  24. package/src/sap/ui/dt/TaskRunner.js +1 -1
  25. package/src/sap/ui/dt/Util.js +1 -1
  26. package/src/sap/ui/dt/enablement/ElementEnablementTest.js +1 -1
  27. package/src/sap/ui/dt/enablement/Test.js +1 -1
  28. package/src/sap/ui/dt/enablement/Util.js +1 -1
  29. package/src/sap/ui/dt/enablement/report/LibraryReport.js +1 -1
  30. package/src/sap/ui/dt/enablement/report/QUnitReport.js +1 -1
  31. package/src/sap/ui/dt/library.js +14 -18
  32. package/src/sap/ui/dt/messagebundle.properties +7 -0
  33. package/src/sap/ui/dt/plugin/ContextMenu.js +159 -88
  34. package/src/sap/ui/dt/plugin/ControlDragDrop.js +1 -1
  35. package/src/sap/ui/dt/plugin/CutPaste.js +1 -1
  36. package/src/sap/ui/dt/plugin/DragDrop.js +1 -1
  37. package/src/sap/ui/dt/plugin/ElementMover.js +1 -1
  38. package/src/sap/ui/dt/plugin/MouseSelection.js +1 -1
  39. package/src/sap/ui/dt/plugin/ToolHooks.js +1 -1
  40. package/src/sap/ui/dt/themes/base/ContextMenu.less +76 -6
  41. package/src/sap/ui/dt/util/ZIndexManager.js +1 -1
package/THIRDPARTY.txt CHANGED
@@ -379,7 +379,7 @@ License: MIT
379
379
  License Text: https://github.com/UI5/openui5/blob/master/LICENSES/MIT.txt
380
380
  Contained in: src/sap.ui.integration/src/sap/ui/integration/thirdparty/adaptive-expressions.js
381
381
 
382
- Component: Markdown-it, version: 12.3.2
382
+ Component: Markdown-it, version: 14.1.0
383
383
  Copyright: 2014 Vitaly Puzrin, Alex Kocharin
384
384
  License: MIT
385
385
  License Text: https://github.com/UI5/openui5/blob/master/LICENSES/MIT.txt
@@ -444,7 +444,7 @@ License: Apache-2.0
444
444
  License Text: https://github.com/UI5/openui5/blob/master/LICENSES/Apache-2.0.txt
445
445
  Contained in: lib/jsdoc/ui5/plugin.js
446
446
 
447
- Component: SAP Theming Base Content, version: 11.31.1
447
+ Component: SAP Theming Base Content, version: 11.32.2-20250827135846+79bb30d311678435d61b21db26ecbe07d6b05079
448
448
  Copyright: SAP SE or an SAP affiliate company and Theming Base Content contributors
449
449
  License: Apache-2.0
450
450
  License Text: https://github.com/UI5/openui5/blob/master/LICENSES/Apache-2.0.txt
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openui5/sap.ui.dt",
3
- "version": "1.140.0",
3
+ "version": "1.141.0",
4
4
  "description": "OpenUI5 UI Library sap.ui.dt",
5
5
  "author": "SAP SE (https://www.sap.com)",
6
6
  "license": "Apache-2.0",
@@ -14,6 +14,6 @@
14
14
  "url": "https://github.com/UI5/openui5.git"
15
15
  },
16
16
  "dependencies": {
17
- "@openui5/sap.ui.core": "1.140.0"
17
+ "@openui5/sap.ui.core": "1.141.0"
18
18
  }
19
19
  }
@@ -6,7 +6,7 @@
6
6
  <copyright>OpenUI5
7
7
  * (c) Copyright 2025 SAP SE or an SAP affiliate company.
8
8
  * Licensed under the Apache License, Version 2.0 - see LICENSE.txt.</copyright>
9
- <version>1.140.0</version>
9
+ <version>1.141.0</version>
10
10
 
11
11
  <documentation>SAP UI library: sap.ui.dt (by SAP, Author)</documentation>
12
12
 
@@ -17,13 +17,6 @@
17
17
  </dependencies>
18
18
 
19
19
  <appData>
20
- <manifest xmlns="http://www.sap.com/ui5/buildext/manifest">
21
- <sap.ui5>
22
- <library>
23
- <i18n>false</i18n><!-- no default i18n bundle in this lib -->
24
- </library>
25
- </sap.ui5>
26
- </manifest>
27
20
  <selenium xmlns="http://www.sap.com/ui5/buildext/selenium" package="com.sap.ui5.selenium.dt" />
28
21
  <!-- excludes for the JSCoverage -->
29
22
  <jscoverage xmlns="http://www.sap.com/ui5/buildext/jscoverage" >
@@ -37,4 +30,4 @@
37
30
  </ownership>
38
31
  </appData>
39
32
 
40
- </library>
33
+ </library>
@@ -23,7 +23,7 @@ function(
23
23
  * @extends sap.ui.dt.DesignTimeMetadata
24
24
  *
25
25
  * @author SAP SE
26
- * @version 1.140.0
26
+ * @version 1.141.0
27
27
  *
28
28
  * @constructor
29
29
  * @private
@@ -33,7 +33,7 @@ function(
33
33
  * @extends sap.ui.dt.Overlay
34
34
  *
35
35
  * @author SAP SE
36
- * @version 1.140.0
36
+ * @version 1.141.0
37
37
  *
38
38
  * @constructor
39
39
  * @private
@@ -22,7 +22,7 @@ function(ManagedObjectObserver) {
22
22
  * @extends sap.ui.dt.ManagedObjectObserver
23
23
  *
24
24
  * @author SAP SE
25
- * @version 1.140.0
25
+ * @version 1.141.0
26
26
  *
27
27
  * @constructor
28
28
  * @private
@@ -25,7 +25,7 @@ sap.ui.define([
25
25
  *
26
26
  * @namespace
27
27
  * @author SAP SE
28
- * @version 1.140.0
28
+ * @version 1.141.0
29
29
  *
30
30
  * @private
31
31
  * @since 1.30
@@ -69,7 +69,7 @@ sap.ui.define([
69
69
  * @extends sap.ui.base.ManagedObject
70
70
  *
71
71
  * @author SAP SE
72
- * @version 1.140.0
72
+ * @version 1.141.0
73
73
  *
74
74
  * @constructor
75
75
  * @private
@@ -45,7 +45,7 @@ sap.ui.define([
45
45
  * @extends sap.ui.base.ManagedObject
46
46
  *
47
47
  * @author SAP SE
48
- * @version 1.140.0
48
+ * @version 1.141.0
49
49
  *
50
50
  * @constructor
51
51
  * @private
@@ -27,7 +27,7 @@ sap.ui.define([
27
27
  * @extends sap.ui.dt.DesignTimeMetadata
28
28
  *
29
29
  * @author SAP SE
30
- * @version 1.140.0
30
+ * @version 1.141.0
31
31
  *
32
32
  * @constructor
33
33
  * @private
@@ -55,7 +55,7 @@ sap.ui.define([
55
55
  * @extends sap.ui.dt.Overlay
56
56
  *
57
57
  * @author SAP SE
58
- * @version 1.140.0
58
+ * @version 1.141.0
59
59
  *
60
60
  * @constructor
61
61
  * @private
@@ -29,7 +29,7 @@ sap.ui.define([
29
29
  *
30
30
  * @namespace
31
31
  * @author SAP SE
32
- * @version 1.140.0
32
+ * @version 1.141.0
33
33
  *
34
34
  * @private
35
35
  * @since 1.30
@@ -23,7 +23,7 @@ sap.ui.define([
23
23
  * @class The ManagedObjectObserver observes changes of a ManagedObject and propagates them via events.
24
24
  * @extends sap.ui.base.ManagedObject
25
25
  * @author SAP SE
26
- * @version 1.140.0
26
+ * @version 1.141.0
27
27
  * @constructor
28
28
  * @private
29
29
  * @since 1.30
@@ -21,7 +21,7 @@ sap.ui.define([
21
21
  *
22
22
  * @namespace
23
23
  * @author SAP SE
24
- * @version 1.140.0
24
+ * @version 1.141.0
25
25
  * @private
26
26
  * @since 1.54
27
27
  * @alias sap.ui.dt.MetadataPropagationUtil
@@ -30,7 +30,7 @@ sap.ui.define([
30
30
  * @class The MutationObserver observes changes of a ManagedObject and propagates them via events.
31
31
  * @extends sap.ui.base.ManagedObject
32
32
  * @author SAP SE
33
- * @version 1.140.0
33
+ * @version 1.141.0
34
34
  * @constructor
35
35
  * @private
36
36
  * @since 1.30
@@ -42,7 +42,7 @@ sap.ui.define([
42
42
  * @extends sap.ui.core.Element
43
43
  *
44
44
  * @author SAP SE
45
- * @version 1.140.0
45
+ * @version 1.141.0
46
46
  *
47
47
  * @constructor
48
48
  * @private
@@ -23,7 +23,7 @@ function(
23
23
  *
24
24
  * @namespace
25
25
  * @author SAP SE
26
- * @version 1.140.0
26
+ * @version 1.141.0
27
27
  *
28
28
  * @private
29
29
  * @since 1.30
@@ -21,7 +21,7 @@ sap.ui.define([
21
21
  *
22
22
  * @namespace
23
23
  * @author SAP SE
24
- * @version 1.140.0
24
+ * @version 1.141.0
25
25
  * @private
26
26
  * @since 1.30
27
27
  * @alias sap.ui.dt.OverlayUtil
@@ -27,7 +27,7 @@ sap.ui.define([
27
27
  * @extends sap.ui.base.ManagedObject
28
28
  *
29
29
  * @author SAP SE
30
- * @version 1.140.0
30
+ * @version 1.141.0
31
31
  *
32
32
  * @constructor
33
33
  * @private
@@ -22,7 +22,7 @@ function(
22
22
  * @extends sap.ui.base.ManagedObject
23
23
  *
24
24
  * @author SAP SE
25
- * @version 1.140.0
25
+ * @version 1.141.0
26
26
  *
27
27
  * @constructor
28
28
  * @private
@@ -32,7 +32,7 @@ function(
32
32
  * @extends sap.ui.base.ManagedObject
33
33
  *
34
34
  * @author SAP SE
35
- * @version 1.140.0
35
+ * @version 1.141.0
36
36
  *
37
37
  * @constructor
38
38
  * @private
@@ -16,7 +16,7 @@ sap.ui.define(function() {
16
16
  * @namespace
17
17
  * @name sap.ui.dt.SelectionMode
18
18
  * @author SAP SE
19
- * @version 1.140.0
19
+ * @version 1.141.0
20
20
  * @private
21
21
  */
22
22
  return {
@@ -21,7 +21,7 @@ function(
21
21
  * The TaskManager keeps list of task and allows to manage them via simple API.
22
22
  *
23
23
  * @author SAP SE
24
- * @version 1.140.0
24
+ * @version 1.141.0
25
25
  *
26
26
  * @constructor
27
27
  * @private
@@ -24,7 +24,7 @@ function(
24
24
  * TaskRunner run tasks defined in sap.ui.dt.TaskManager.
25
25
  *
26
26
  * @author SAP SE
27
- * @version 1.140.0
27
+ * @version 1.141.0
28
28
  *
29
29
  * @constructor
30
30
  * @private
@@ -20,7 +20,7 @@ sap.ui.define([
20
20
  *
21
21
  * @namespace
22
22
  * @author SAP SE
23
- * @version 1.140.0
23
+ * @version 1.141.0
24
24
  *
25
25
  * @private
26
26
  * @since 1.54
@@ -37,7 +37,7 @@ sap.ui.define([
37
37
  * @extends sap.ui.dt.test.Test
38
38
  *
39
39
  * @author SAP SE
40
- * @version 1.140.0
40
+ * @version 1.141.0
41
41
  *
42
42
  * @constructor
43
43
  * @private
@@ -22,7 +22,7 @@ sap.ui.define([
22
22
  * @extends sap.ui.base.ManagedObject
23
23
  *
24
24
  * @author SAP SE
25
- * @version 1.140.0
25
+ * @version 1.141.0
26
26
  *
27
27
  * @constructor
28
28
  * @private
@@ -22,7 +22,7 @@ sap.ui.define([
22
22
  * @namespace
23
23
  *
24
24
  * @author SAP SE
25
- * @version 1.140.0
25
+ * @version 1.141.0
26
26
  *
27
27
  * @private
28
28
  * @static
@@ -27,7 +27,7 @@ sap.ui.define([
27
27
  * @extends sap.ui.dt.enablement.Test
28
28
  *
29
29
  * @author SAP SE
30
- * @version 1.140.0
30
+ * @version 1.141.0
31
31
  *
32
32
  * @constructor
33
33
  * @private
@@ -24,7 +24,7 @@ sap.ui.define([
24
24
  * @extends sap.ui.base.ManagedObject
25
25
  *
26
26
  * @author SAP SE
27
- * @version 1.140.0
27
+ * @version 1.141.0
28
28
  *
29
29
  * @constructor
30
30
  * @private
@@ -20,7 +20,7 @@ sap.ui.define([
20
20
  /**
21
21
  * Object containing the aggregation configuration
22
22
  *
23
- * @typedef {object} sap.ui.dt.DesignTimeMetadata.Aggregation
23
+ * @typedef {object} sap.ui.dt.designtime.DesignTimeMetadata.Aggregation
24
24
  * @property {boolean|function} [ignore = false] - Used to ignore the aggregation (and all its children) at design time.
25
25
  * For example, this can be used to ignore deprecated or duplicated aggregations as well as aggregations irrelevant during the design time (such as dependents).
26
26
  * If the value is true, then no overlays will be created for the aggregation and its children.
@@ -44,47 +44,44 @@ sap.ui.define([
44
44
  * It can be used if you need to know the relevantContainer during the execution of the function.
45
45
  * @property {boolean|function} [propagateRelevantContainer] - Defines the relevant container control for the actions which belong to successor controls.
46
46
  *
47
- * @private
48
- * @ui5-restricted
47
+ * @public
49
48
  */
50
49
 
51
50
  /**
52
51
  * Object containing the aggregation configuration
53
52
  *
54
- * @typedef {object} sap.ui.dt.DesignTimeMetadata.Property
53
+ * @typedef {object} sap.ui.dt.designtime.DesignTimeMetadata.Property
55
54
  * @property {boolean|function} [ignore = false] - Used to ignore the property at design time.
56
55
  * For example, this can be used to ignore deprecated properties or properties that shall not be changed during design time.
57
56
  *
58
- * @private
59
- * @ui5-restricted
57
+ * @public
60
58
  */
61
59
 
62
60
  /**
63
61
  * Object containing the association configuration
64
62
  *
65
- * @typedef {object} sap.ui.dt.DesignTimeMetadata.Association
63
+ * @typedef {object} sap.ui.dt.designtime.DesignTimeMetadata.Association
66
64
  * @property {boolean} aggregationLike - Can be used to tell the design time that it should follow the association hierarchy.
67
65
  * This is used by controls like e.g. the componentContainer that should allow to follow the association component,
68
66
  * which defines the control hierarchy but is not a real aggregation (more isolation, regarding model propagation/rendering/eventing/...).
69
67
  *
70
- * @private
71
- * @ui5-restricted
68
+ * @public
72
69
  */
73
70
 
74
71
  /**
75
72
  * Object containing a sample design time configuration
76
73
  *
77
- * @typedef {object} sap.ui.dt.DesignTimeMetadata
74
+ * @typedef {object} sap.ui.dt.designtime.DesignTimeMetadata
78
75
  * @property {object|function} name - Specify or calculate a speaking name for the control (which is understandable to key users).
79
76
  * This is needed for the "reveal" action to show the names in the context menu (Add <name in singular> and Available <name in plural>).
80
77
  * Name your control based on the general UI concept and follow the guidance from https://experience.sap.com/fiori-design/.
81
78
  * Example: Key users don't care about the difference between a smart, mobile or responsive version of a form, it's just a form.
82
79
  * @property {string|function} name.singular - i18n key from library's design-time resource bundle or function returning the translated text
83
80
  * @property {string|function} name.plural - i18n key from library's design-time resource bundle or function returning the translated text
84
- * @property {function} [getLabel] - Allows you to return the label texts of the control, that is useful in outlines, context menus
85
- * and e.g. "add" dialogs so that users can identify which of the controls of this type is meant (e.g. the product price).
86
- * Our default implementation tries getText() and then getLabelText(). If it's not available,
87
- * it tries getLabel().getText(), then getTitle(), and then getId()
81
+ * @property {function} [getLabel] - Allows to provide a customized getter for the control label that is used in
82
+ * outlines, context menus and actions like "reveal" or "rename".
83
+ * The default implementation tries to get the following properties in that order:
84
+ * <code>text</code>, <code>labelText</code>, <code>label</code>, <code>title</code>, <code>heading</code>, <code>dataSourceLabel</code>
88
85
  * @property {string|function} [domRef] - Defines the DOM reference of the control
89
86
  * @property {function} isVisible - Needed for Elements that are not derived from sap.ui.core.Control.
90
87
  * The function should return the visibility of the Element as a boolean (true = visible).
@@ -113,8 +110,7 @@ sap.ui.define([
113
110
  * @property {function} tool.start - Called when the tool is started
114
111
  * @property {function} tool.stop - Called when the tool is stopped
115
112
  *
116
- * @private
117
- * @ui5-restricted
113
+ * @public
118
114
  */
119
115
 
120
116
  /**
@@ -123,7 +119,7 @@ sap.ui.define([
123
119
  * @namespace
124
120
  * @alias sap.ui.dt
125
121
  * @author SAP SE
126
- * @version 1.140.0
122
+ * @version 1.141.0
127
123
  * @since 1.30
128
124
  * @private
129
125
  * @ui5-restricted
@@ -131,7 +127,7 @@ sap.ui.define([
131
127
  var thisLib = Lib.init({
132
128
  name: "sap.ui.dt",
133
129
  apiVersion: 2,
134
- version: "1.140.0",
130
+ version: "1.141.0",
135
131
  dependencies: ["sap.ui.core"],
136
132
  types: [],
137
133
  interfaces: [],
@@ -0,0 +1,7 @@
1
+ #This is the resource bundle for the sap.ui.rta library
2
+ # __ldi.translation.uuid=6cb30b13-cebe-4851-a2f1-eb261e580bc7
3
+
4
+ #XHED: Header for the Extended Actions
5
+ CTX_EXTENDED_ACTIONS_HEADER=Extended Actions
6
+ #YDES: Description for the Extended Actions Header
7
+ CTX_EXTENDED_ACTIONS_HEADER_DESCRIPTION=This helps you quickly find key functions from related controls that are relevant here.
@@ -3,32 +3,29 @@
3
3
  * (c) Copyright 2025 SAP SE or an SAP affiliate company.
4
4
  * Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
5
5
  */
6
-
7
6
  sap.ui.define([
8
7
  "sap/base/assert",
9
8
  "sap/m/Button",
10
- "sap/m/FlexBox",
11
- "sap/m/FormattedText",
12
9
  "sap/m/Menu",
13
10
  "sap/m/MenuItem",
14
11
  "sap/ui/base/DesignTime",
12
+ "sap/ui/core/Lib",
15
13
  "sap/ui/dt/util/_createPromise",
16
- "sap/ui/dt/OverlayRegistry",
17
14
  "sap/ui/dt/Plugin",
15
+ "sap/ui/dt/OverlayRegistry",
18
16
  "sap/ui/dt/Util",
19
17
  "sap/ui/events/KeyCodes",
20
18
  "sap/ui/Device"
21
19
  ], function(
22
20
  assert,
23
21
  Button,
24
- FlexBox,
25
- FormattedText,
26
22
  Menu,
27
23
  MenuItem,
28
24
  BaseDesignTime,
25
+ Lib,
29
26
  _createPromise,
30
- OverlayRegistry,
31
27
  Plugin,
28
+ OverlayRegistry,
32
29
  DtUtil,
33
30
  KeyCodes,
34
31
  Device
@@ -43,7 +40,7 @@ sap.ui.define([
43
40
  * @class The ContextMenu registers event handler to open the context menu. Menu entries can dynamically be added
44
41
  * @extends sap.ui.dt.Plugin
45
42
  * @author SAP SE
46
- * @version 1.140.0
43
+ * @version 1.141.0
47
44
  * @constructor
48
45
  * @private
49
46
  * @since 1.53
@@ -66,10 +63,10 @@ sap.ui.define([
66
63
  closedContextMenu: {}
67
64
  }
68
65
  }
69
-
70
66
  });
71
67
 
72
68
  const sMainStyleClass = "sapUiDtContextMenu";
69
+ const oTextResources = Lib.getResourceBundleFor("sap.ui.dt");
73
70
 
74
71
  ContextMenu.prototype.init = function() {
75
72
  this.oContextMenuControl = new Menu();
@@ -78,6 +75,7 @@ sap.ui.define([
78
75
  this.oContextMenuControl.addStyleClass(sMainStyleClass);
79
76
  this._aMenuItems = [];
80
77
  this._aGroupedItems = [];
78
+ this._bHasPropagatedMenuItems = false;
81
79
  this._aSubMenus = [];
82
80
  };
83
81
 
@@ -166,6 +164,12 @@ sap.ui.define([
166
164
  const aMenuItemsWithPropagatingControl = aMenuItems.map((oMenuItem) => {
167
165
  oMenuItem.propagatingControl = oPropagatedActionInfo.propagatingControl;
168
166
  oMenuItem.propagatingControlName = oPropagatedActionInfo.propagatingControlName;
167
+ if (BaseDesignTime.isDesignModeEnabled() || !oMenuItem.propagatingControlName) {
168
+ // in design mode we use the technical name of the propagating control
169
+ // if no name is provided by the plugin
170
+ oMenuItem.propagatingControlName =
171
+ oPropagatedActionInfo.propagatingControl.getMetadata().getName().split(".").pop();
172
+ }
169
173
  return oMenuItem;
170
174
  });
171
175
  resolve(aMenuItemsWithPropagatingControl);
@@ -175,7 +179,6 @@ sap.ui.define([
175
179
  return null;
176
180
  }).filter(Boolean);
177
181
  }
178
-
179
182
  /**
180
183
  * Opens the Context Menu
181
184
  * @param {sap.ui.dt.Overlay} oOverlay - Overlay object
@@ -184,50 +187,116 @@ sap.ui.define([
184
187
  */
185
188
  ContextMenu.prototype.open = function(oOverlay, bIsSubMenu, oEvent) {
186
189
  let aSelectedOverlays;
187
- function addMenuItems(oMenu, aMenuItems) {
188
- let bStartsSection = !!aMenuItems[0]?.propagatingControl;
189
- let oTargetOverlay = oOverlay;
190
- let aTargetSelectedOverlays = aSelectedOverlays;
191
- aMenuItems.forEach(function(oMenuItem, index) {
192
- if (oMenuItem.propagatingControl) {
193
- oTargetOverlay = OverlayRegistry.getOverlay(oMenuItem.propagatingControl);
194
- aTargetSelectedOverlays = [oTargetOverlay];
190
+ const sExtendedMenuTitle = oTextResources.getText("CTX_EXTENDED_ACTIONS_HEADER");
191
+ const sExtendedMenuTooltip = oTextResources.getText("CTX_EXTENDED_ACTIONS_HEADER_DESCRIPTION");
192
+ const oElement = oOverlay.getElement();
193
+ const oElementDesignTimeMetadata = oOverlay.getDesignTimeMetadata();
194
+ this.sSelectedControlName = oElementDesignTimeMetadata.getName(oElement)?.singular
195
+ || oElement.getMetadata().getName().split(".").pop();
196
+ this.bHasExtendedActionsTitleSet = false;
197
+
198
+ function addMenuItems(oMenu, aMenuItems, sPropagatedControlName, bIsSubMenu, bAddAsNormalActions) {
199
+ const fnRemoveFocusability = function() {
200
+ return false;
201
+ };
202
+ if (sPropagatedControlName) {
203
+ // Extended Actions for a propagated control
204
+ if (!bAddAsNormalActions) {
205
+ // only add the title once, not for each propagated control
206
+ if (!this.bHasExtendedActionsTitleSet) {
207
+ this.bHasExtendedActionsTitleSet = true;
208
+ const oExtendedActionsItem = new MenuItem({
209
+ key: "CTX_EXTENDED_MENU_TITLE",
210
+ id: "CTX_EXTENDED_MENU_TITLE",
211
+ text: sExtendedMenuTitle,
212
+ enabled: false
213
+ });
214
+ oExtendedActionsItem.addStyleClass("sapUiDtContextMenuExtendedActionsTitle");
215
+ oExtendedActionsItem.setTooltip(sExtendedMenuTooltip);
216
+ // prevent focusability of the title item
217
+ oExtendedActionsItem.isFocusable = fnRemoveFocusability;
218
+ oMenu.addItem(oExtendedActionsItem);
219
+ }
220
+ // we have to provide a unique ID for each propagated control
221
+ // (in case there are multiple propagated controls in the menu)
222
+ const sId = `CTX_PROPAGATED_CONTROL_NAME_${sPropagatedControlName.replace(/[\.\s]/g, "_").toUpperCase()}`;
223
+ const oTitleMenuItem = new MenuItem({
224
+ key: sId,
225
+ id: sId,
226
+ text: sPropagatedControlName,
227
+ enabled: false
228
+ });
229
+ oTitleMenuItem.addStyleClass("sapUiDtContextMenuPropagatedControlTitle");
230
+ // prevent focusability of the title item
231
+ oTitleMenuItem.isFocusable = fnRemoveFocusability;
232
+ oMenu.addItem(oTitleMenuItem);
195
233
  }
196
- const sText = typeof oMenuItem.text === "function" ? oMenuItem.text(oTargetOverlay) : oMenuItem.text;
197
- const bEnabled = typeof oMenuItem.enabled === "function" ? oMenuItem.enabled(aTargetSelectedOverlays) : oMenuItem.enabled;
198
- const oMenuItemInstance = new MenuItem({
199
- key: oMenuItem.id,
200
- icon: oMenuItem.icon,
201
- text: sText,
202
- enabled: bEnabled,
203
- startsSection: bStartsSection
204
- });
205
-
206
- oMenu.addItem(oMenuItemInstance);
207
-
208
- // Add end content to the menu item
209
- if (oMenuItem.propagatingControlName || oMenuItem.additionalInfo) {
210
- const oFlexBox = new FlexBox({
211
- justifyContent: "SpaceBetween",
212
- alignItems: "Center"
234
+ aMenuItems.forEach(function(oMenuItem) {
235
+ const oTargetOverlay = OverlayRegistry.getOverlay(oMenuItem.propagatingControl);
236
+ const aTargetSelectedOverlays = [oTargetOverlay];
237
+ const sText = typeof oMenuItem.text === "function" ? oMenuItem.text(oTargetOverlay) : oMenuItem.text;
238
+ const bEnabled = typeof oMenuItem.enabled === "function"
239
+ ? oMenuItem.enabled(aTargetSelectedOverlays)
240
+ : oMenuItem.enabled;
241
+ const oMenuItemInstance = new MenuItem({
242
+ key: oMenuItem.id,
243
+ icon: oMenuItem.icon,
244
+ text: sText,
245
+ enabled: bEnabled
213
246
  });
214
- if (oMenuItem.propagatingControlName) {
215
- oFlexBox.addItem(new FormattedText({
216
- htmlText: `<strong>${oMenuItem.propagatingControlName}</strong>`
217
- }));
247
+
248
+ if (!bAddAsNormalActions) {
249
+ oMenuItemInstance.addStyleClass("sapUiDtContextMenuPropagatedItem");
218
250
  }
251
+ oMenu.addItem(oMenuItemInstance);
252
+ // Add end content to the menu item
219
253
  if (oMenuItem.additionalInfo) {
220
254
  const oAdditionalInfoButton = createAdditionalInfo.call(this, oMenuItem);
221
- oFlexBox.addItem(oAdditionalInfoButton);
255
+ oMenuItemInstance.addEndContent(oAdditionalInfoButton);
222
256
  }
223
- oMenuItemInstance.addEndContent(oFlexBox);
257
+ }.bind(this));
258
+ } else {
259
+ // Standard actions for the current context element
260
+ const aTargetSelectedOverlays = aSelectedOverlays;
261
+ if (!bIsSubMenu) {
262
+ const oTitleMenuItem = new MenuItem({
263
+ key: "CTX_CONTROL_NAME",
264
+ id: "CTX_CONTROL_NAME",
265
+ text: this.sSelectedControlName,
266
+ enabled: false
267
+ });
268
+ oTitleMenuItem.addStyleClass("sapUiDtContextMenuControlTitle");
269
+ // prevent focusability of the title item
270
+ oTitleMenuItem.isFocusable = fnRemoveFocusability;
271
+ oMenu.addItem(oTitleMenuItem);
224
272
  }
273
+ aMenuItems.forEach(function(oMenuItem, index) {
274
+ const sText = typeof oMenuItem.text === "function" ? oMenuItem.text(oOverlay) : oMenuItem.text;
275
+ const bEnabled = typeof oMenuItem.enabled === "function"
276
+ ? oMenuItem.enabled(aTargetSelectedOverlays)
277
+ : oMenuItem.enabled;
278
+ const oMenuItemInstance = new MenuItem({
279
+ key: oMenuItem.id,
280
+ icon: oMenuItem.icon,
281
+ text: sText,
282
+ enabled: bEnabled
283
+ });
225
284
 
226
- if (oMenuItem.submenu) {
227
- addMenuItems.call(this, oMenu.getItems()[index], oMenuItem.submenu);
228
- }
229
- bStartsSection = false;
230
- }.bind(this));
285
+ oMenu.addItem(oMenuItemInstance);
286
+
287
+ // Add end content to the menu item
288
+ if (oMenuItem.additionalInfo) {
289
+ const oAdditionalInfoButton = createAdditionalInfo.call(this, oMenuItem);
290
+ oMenuItemInstance.addEndContent(oAdditionalInfoButton);
291
+ }
292
+
293
+ if (oMenuItem.submenu) {
294
+ const bIsSubMenu = true;
295
+ // we need to add one to the index, because we added the control name as first item
296
+ addMenuItems.call(this, oMenu.getItems()[index + 1], oMenuItem.submenu, undefined, bIsSubMenu);
297
+ }
298
+ }.bind(this));
299
+ }
231
300
  }
232
301
 
233
302
  const oNewContextElement = oOverlay.getElement();
@@ -269,7 +338,7 @@ sap.ui.define([
269
338
  this._fnCancelMenuPromise = oDtSyncPromise.cancel;
270
339
  oPromise = oDtSyncPromise.promise
271
340
  .then(function() {
272
- this._aGroupedItems = [];
341
+ this._bHasPropagatedMenuItems = false;
273
342
  this._aSubMenus = [];
274
343
  const aPluginItemPromises = [];
275
344
  const aPlugins = this.getDesignTime().getPlugins();
@@ -286,7 +355,6 @@ sap.ui.define([
286
355
  if (aSelectedOverlays.length === 1) {
287
356
  aPropagatedMenuItemPromises = collectPropagatedMenuItemPromises(aPlugins, aSelectedOverlays[0]);
288
357
  }
289
-
290
358
  const oPluginItemsPromise = _createPromise(function(resolve, reject) {
291
359
  aPluginItemPromises.push(...aPropagatedMenuItemPromises);
292
360
  Promise.all(aPluginItemPromises).then(resolve).catch(reject);
@@ -295,20 +363,25 @@ sap.ui.define([
295
363
  return oPluginItemsPromise.promise;
296
364
  }.bind(this))
297
365
  .then(function(aPluginMenuItems) {
298
- return aPluginMenuItems.reduce(function(aConcatenatedMenuItems, aMenuItems) {
299
- return aConcatenatedMenuItems.concat(aMenuItems);
300
- });
366
+ if (aPluginMenuItems.length > 0) {
367
+ return aPluginMenuItems.reduce(function(aConcatinatedMenuItems, aMenuItems) {
368
+ return aConcatinatedMenuItems.concat(aMenuItems);
369
+ });
370
+ }
371
+ return aPluginMenuItems;
301
372
  })
302
373
  .then(function(aPluginMenuItems) {
303
374
  aPluginMenuItems.forEach(function(mMenuItem) {
304
375
  if (mMenuItem.submenu !== undefined) {
305
376
  this._addSubMenu(mMenuItem);
377
+ } else if (mMenuItem.propagatingControlName !== undefined) {
378
+ this._addMenuItemToGroup(mMenuItem);
379
+ this.addMenuItem(mMenuItem, true);
306
380
  } else {
307
381
  this.addMenuItem(mMenuItem, true);
308
382
  }
309
383
  }.bind(this));
310
384
 
311
- this._addItemGroupsToMenu();
312
385
  delete this._fnCancelMenuPromise;
313
386
  }.bind(this));
314
387
  }
@@ -319,15 +392,28 @@ sap.ui.define([
319
392
  });
320
393
 
321
394
  if (aAllMenuItems.length > 0) {
395
+ const bIsSubMenu = false;
322
396
  const aMenuItems = this._sortMenuItems(aAllMenuItems.filter((mMenuItem) => !mMenuItem.propagatingControl));
323
- const aPropagatedMenuItems = this._sortMenuItems(aAllMenuItems.filter((mMenuItem) => mMenuItem.propagatingControl));
324
- addMenuItems.call(this, this.oContextMenuControl, aMenuItems);
325
- addMenuItems.call(this, this.oContextMenuControl, aPropagatedMenuItems, true);
397
+ addMenuItems.call(this, this.oContextMenuControl, aMenuItems, undefined, bIsSubMenu);
398
+ this._aGroupedItems.forEach(function(oPropagatedMenuItemGroup) {
399
+ const bAddAsNormalActions = (oPropagatedMenuItemGroup.sGroupName === this.sSelectedControlName);
400
+ addMenuItems.call(
401
+ this,
402
+ this.oContextMenuControl,
403
+ oPropagatedMenuItemGroup.aGroupedItems,
404
+ oPropagatedMenuItemGroup.sGroupName,
405
+ bIsSubMenu,
406
+ bAddAsNormalActions
407
+ );
408
+ }.bind(this));
326
409
  // we have to distinguish between the mouse and the keyboard event
327
410
  const oOpenerRef = (oEvent.type === "keyup") ? oOverlay : undefined;
411
+ // Set focus to the overlay before opening the context menu to ensure that the keyboard
412
+ // navigation works properly after closing, as the popover restores the focus
413
+ // to the last focused element before opening (which can be a non-selectable overlay).
414
+ oOverlay.focus();
328
415
  this.oContextMenuControl.openAsContextMenu(oEvent, oOpenerRef);
329
416
  }
330
-
331
417
  this.fireOpenedContextMenu();
332
418
  }.bind(this))
333
419
  .catch(function(oError) {
@@ -478,6 +564,7 @@ sap.ui.define([
478
564
  * Called when ContextMenu gets closed
479
565
  */
480
566
  ContextMenu.prototype._contextMenuClosed = function() {
567
+ this._aGroupedItems = [];
481
568
  this.fireClosedContextMenu();
482
569
  };
483
570
 
@@ -508,12 +595,7 @@ sap.ui.define([
508
595
  if (Device.os.ios) {
509
596
  return false;
510
597
  }
511
-
512
- if (this.getDesignTime().getBusyPlugins().length) {
513
- return true;
514
- }
515
-
516
- return false;
598
+ return !!this.getDesignTime().getBusyPlugins().length;
517
599
  };
518
600
 
519
601
  /**
@@ -521,18 +603,28 @@ sap.ui.define([
521
603
  * @param {object} mMenuItem The menu item to add to a group
522
604
  */
523
605
  ContextMenu.prototype._addMenuItemToGroup = function(mMenuItem) {
606
+ const sGroupName = mMenuItem.propagatingControlName;
524
607
  const bGroupExists = this._aGroupedItems.some(function(_oGroupedItem) {
525
- if (_oGroupedItem.sGroupName === mMenuItem.group) {
608
+ if (_oGroupedItem.sGroupName === sGroupName) {
526
609
  _oGroupedItem.aGroupedItems.push(mMenuItem);
527
610
  return true;
528
611
  }
529
612
  });
530
613
 
531
614
  if (!bGroupExists) {
532
- this._aGroupedItems.push({
533
- sGroupName: mMenuItem.group,
534
- aGroupedItems: [mMenuItem]
535
- });
615
+ if (sGroupName !== this.sSelectedControlName) {
616
+ this._aGroupedItems.push({
617
+ sGroupName: mMenuItem.propagatingControlName,
618
+ aGroupedItems: [mMenuItem]
619
+ });
620
+ this._bHasPropagatedMenuItems = true;
621
+ } else {
622
+ // ensure that the group with the same name as the current control is always on top
623
+ this._aGroupedItems.unshift({
624
+ sGroupName: mMenuItem.propagatingControlName,
625
+ aGroupedItems: [mMenuItem]
626
+ });
627
+ }
536
628
  }
537
629
  };
538
630
 
@@ -553,26 +645,5 @@ sap.ui.define([
553
645
  this.addMenuItem(mMenuItem, true);
554
646
  };
555
647
 
556
- /**
557
- * Adds the grouped menu item to the collapsed version of a ContextMenu
558
- */
559
- ContextMenu.prototype._addItemGroupsToMenu = function() {
560
- this._aGroupedItems.forEach(function(oGroupedItem) {
561
- // If there is only one menu item that belongs to a group we don't need that group
562
- if (oGroupedItem.aGroupedItems.length === 1) {
563
- this.addMenuItem(oGroupedItem.aGroupedItems[0], true);
564
- } else {
565
- this.addMenuItem({
566
- id: `${oGroupedItem.sGroupName}-groupItem`,
567
- enabled: true,
568
- text: oGroupedItem.sGroupName,
569
- icon: oGroupedItem.aGroupedItems[0].icon,
570
- rank: oGroupedItem.aGroupedItems[0].rank,
571
- submenu: oGroupedItem.aGroupedItems
572
- }, true);
573
- }
574
- }.bind(this));
575
- };
576
-
577
648
  return ContextMenu;
578
649
  });
@@ -26,7 +26,7 @@ sap.ui.define([
26
26
  * @class The ControlDragDrop enables D&D functionality for the overlays based on aggregation types
27
27
  * @extends sap.ui.dt.plugin.DragDrop
28
28
  * @author SAP SE
29
- * @version 1.140.0
29
+ * @version 1.141.0
30
30
  * @constructor
31
31
  * @private
32
32
  * @since 1.30
@@ -33,7 +33,7 @@ sap.ui.define([
33
33
  * @class The CutPaste enables Cut & Paste functionality for the overlays based on aggregation types
34
34
  * @extends sap.ui.dt.Plugin
35
35
  * @author SAP SE
36
- * @version 1.140.0
36
+ * @version 1.141.0
37
37
  * @constructor
38
38
  * @private
39
39
  * @since 1.34
@@ -36,7 +36,7 @@ sap.ui.define([
36
36
  * @extends sap.ui.dt.Plugin
37
37
  *
38
38
  * @author SAP SE
39
- * @version 1.140.0
39
+ * @version 1.141.0
40
40
  *
41
41
  * @constructor
42
42
  * @private
@@ -30,7 +30,7 @@ sap.ui.define([
30
30
  * @class The ElementMover enables movement of UI5 elements based on aggregation types, which can be used by drag and
31
31
  * drop or cut and paste behavior.
32
32
  * @author SAP SE
33
- * @version 1.140.0
33
+ * @version 1.141.0
34
34
  * @constructor
35
35
  * @private
36
36
  * @since 1.34
@@ -22,7 +22,7 @@ function(Plugin) {
22
22
  * @extends sap.ui.dt.Plugin
23
23
  *
24
24
  * @author SAP SE
25
- * @version 1.140.0
25
+ * @version 1.141.0
26
26
  *
27
27
  * @constructor
28
28
  * @private
@@ -16,7 +16,7 @@ sap.ui.define([
16
16
  *
17
17
  * @extends sap.ui.dt.Plugin
18
18
  * @author SAP SE
19
- * @version 1.140.0
19
+ * @version 1.141.0
20
20
  * @constructor
21
21
  * @private
22
22
  * @since 1.61
@@ -1,7 +1,10 @@
1
1
  /******************************************************************
2
2
  Style of the DT Contextmenu - base Theme
3
3
  *******************************************************************/
4
- @_sap_ui_dt_ContextMenu_MnuItemTextColor: @sapUiBaseText;
4
+ @_sap_ui_dt_ContextMenu_MnuItemTextColor: var(--sapTextColor); // #000
5
+ @_sap_ui_dt_ContextMenu_MnuItemIconColor: var(--sapContent_NonInteractiveIconColor); // #111
6
+ @_sap_ui_dt_ContextMenu_PrpgtedMnuItemBGColor: var(--sapList_AlternatingBackground); // darken(#111, 10);
7
+ @_sap_ui_dt_ContextMenu_PrpgtedTitleBorderColor: var(--sapShell_BorderColor); // #111
5
8
 
6
9
  .sapUiDtContextMenu.sapMMenu {
7
10
  .sapMMenuList {
@@ -30,7 +33,7 @@
30
33
  }
31
34
  }
32
35
  .sapUiIcon {
33
- color: @_sap_ui_dt_ContextMenu_MnuItemTextColor !important;
36
+ color: @_sap_ui_dt_ContextMenu_MnuItemIconColor !important;
34
37
  }
35
38
  }
36
39
  }
@@ -38,6 +41,66 @@
38
41
  &.sapMMenuItemDisabled {
39
42
  opacity: 0.5;
40
43
  }
44
+
45
+ // style for control names
46
+ &.sapUiDtContextMenuControlTitle {
47
+ opacity: 1;
48
+ height: 1.5rem;
49
+ .sapMMenuItemIcon {
50
+ display: none;
51
+ }
52
+ .sapMMenuItemText {
53
+ font-weight: bold;
54
+ color: @_sap_ui_dt_ContextMenu_MnuItemTextColor;
55
+ }
56
+ }
57
+
58
+ // Style for title "Extended Actions"
59
+ &.sapUiDtContextMenuExtendedActionsTitle {
60
+ opacity: 1;
61
+ height: 2rem;
62
+ text-align: center;
63
+ background-color: @_sap_ui_dt_ContextMenu_PrpgtedMnuItemBGColor;
64
+ border-top: 0.063rem solid @_sap_ui_dt_ContextMenu_PrpgtedTitleBorderColor;
65
+ border-bottom: 0.063rem solid @_sap_ui_dt_ContextMenu_PrpgtedTitleBorderColor;
66
+ border-radius: 0;
67
+ padding: 0.313rem 0.625rem;
68
+ .sapMMenuItemIcon {
69
+ display: none;
70
+ }
71
+ .sapMMenuItemText {
72
+ color: @_sap_ui_dt_ContextMenu_MnuItemTextColor;
73
+ }
74
+ }
75
+
76
+ // style for names of propagated controls
77
+ &.sapUiDtContextMenuPropagatedControlTitle {
78
+ opacity: 1;
79
+ height: 1.5rem;
80
+ background-color: @_sap_ui_dt_ContextMenu_PrpgtedMnuItemBGColor;
81
+ margin: 0!important;
82
+ padding: 0.313rem 0.625rem;
83
+ .sapMMenuItemIcon {
84
+ display: none;
85
+ }
86
+ .sapMMenuItemText {
87
+ font-weight: bold;
88
+ color: @_sap_ui_dt_ContextMenu_MnuItemTextColor;
89
+ }
90
+ }
91
+
92
+ // style for propagated menu items
93
+ &.sapUiDtContextMenuPropagatedItem {
94
+ margin: 0!important;
95
+ &:not(:hover) {
96
+ background-color: @_sap_ui_dt_ContextMenu_PrpgtedMnuItemBGColor;
97
+ }
98
+ &.sapMMenuItemDisabled{
99
+ &:hover {
100
+ background-color: @_sap_ui_dt_ContextMenu_PrpgtedMnuItemBGColor;
101
+ }
102
+ }
103
+ }
41
104
  }
42
105
  }
43
106
  }
@@ -59,7 +122,7 @@
59
122
  }
60
123
 
61
124
  .sapUiSizeCompact .sapMMenu.sapUiDtContextMenu {
62
- .sapMMenuItem {
125
+ .sapMMenuItem:not(.sapUiDtContextMenuControlTitle):not(.sapUiDtContextMenuPropagatedControlTitle):not(.sapUiDtContextMenuExtendedActionsTitle) {
63
126
  height: 2.25rem;
64
127
  padding: 0 0.25rem;
65
128
 
@@ -77,8 +140,15 @@
77
140
  }
78
141
 
79
142
  html.sap-desktop, html.sap-tablet {
80
-
81
- & .sapUiSizeCozy .sapUiDtContextMenu.sapMMenu .sapMMenuList > .sapMMenuItem > .sapMMenuItemIcon + .sapMMenuItemText {
82
- margin-left: 1.75rem;
143
+ .sapUiSizeCozy {
144
+ .sapUiDtContextMenu.sapMMenu {
145
+ .sapMMenuList {
146
+ .sapMMenuItem:not(.sapUiDtContextMenuPropagatedControlTitle):not(.sapUiDtContextMenuControlTitle):not(.sapUiDtContextMenuExtendedActionsTitle) {
147
+ .sapMMenuItemIcon + .sapMMenuItemText {
148
+ margin-left: 1.75rem;
149
+ }
150
+ }
151
+ }
152
+ }
83
153
  }
84
154
  }
@@ -28,7 +28,7 @@ sap.ui.define([
28
28
  *
29
29
  * @namespace
30
30
  * @author SAP SE
31
- * @version 1.140.0
31
+ * @version 1.141.0
32
32
  *
33
33
  * @private
34
34
  * @since 1.64