@openui5/sap.ui.core 1.134.0 → 1.135.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 (293) hide show
  1. package/.dtsgenrc +32 -0
  2. package/THIRDPARTY.txt +2 -2
  3. package/package.json +1 -1
  4. package/src/jquery.sap.global.js +1 -1
  5. package/src/jquery.sap.properties.js +1 -1
  6. package/src/jquery.sap.resources.js +1 -1
  7. package/src/jquery.sap.script.js +1 -1
  8. package/src/jquery.sap.storage.js +3 -3
  9. package/src/sap/base/Event.js +1 -1
  10. package/src/sap/base/Eventing.js +1 -1
  11. package/src/sap/base/config.js +1 -1
  12. package/src/sap/base/i18n/LanguageFallback.js +344 -0
  13. package/src/sap/base/i18n/LanguageTag.js +1 -1
  14. package/src/sap/base/i18n/Localization.js +9 -4
  15. package/src/sap/base/i18n/ResourceBundle.js +40 -313
  16. package/src/sap/base/i18n/date/TimezoneUtils.js +1 -1
  17. package/src/sap/base/util/restricted/_CancelablePromise.js +1 -1
  18. package/src/sap/base/util/restricted/_castArray.js +1 -1
  19. package/src/sap/base/util/restricted/_compact.js +1 -1
  20. package/src/sap/base/util/restricted/_curry.js +1 -1
  21. package/src/sap/base/util/restricted/_debounce.js +1 -1
  22. package/src/sap/base/util/restricted/_difference.js +1 -1
  23. package/src/sap/base/util/restricted/_differenceBy.js +1 -1
  24. package/src/sap/base/util/restricted/_differenceWith.js +1 -1
  25. package/src/sap/base/util/restricted/_flatMap.js +1 -1
  26. package/src/sap/base/util/restricted/_flatMapDeep.js +1 -1
  27. package/src/sap/base/util/restricted/_flatMapDepth.js +1 -1
  28. package/src/sap/base/util/restricted/_flatten.js +1 -1
  29. package/src/sap/base/util/restricted/_flattenDeep.js +1 -1
  30. package/src/sap/base/util/restricted/_flattenDepth.js +1 -1
  31. package/src/sap/base/util/restricted/_intersection.js +1 -1
  32. package/src/sap/base/util/restricted/_intersectionBy.js +1 -1
  33. package/src/sap/base/util/restricted/_intersectionWith.js +1 -1
  34. package/src/sap/base/util/restricted/_isEqual.js +1 -1
  35. package/src/sap/base/util/restricted/_isEqualWith.js +1 -1
  36. package/src/sap/base/util/restricted/_isNil.js +1 -1
  37. package/src/sap/base/util/restricted/_max.js +1 -1
  38. package/src/sap/base/util/restricted/_merge.js +1 -1
  39. package/src/sap/base/util/restricted/_mergeWith.js +1 -1
  40. package/src/sap/base/util/restricted/_min.js +1 -1
  41. package/src/sap/base/util/restricted/_omit.js +1 -1
  42. package/src/sap/base/util/restricted/_pick.js +1 -1
  43. package/src/sap/base/util/restricted/_pickBy.js +1 -1
  44. package/src/sap/base/util/restricted/_throttle.js +1 -1
  45. package/src/sap/base/util/restricted/_toArray.js +1 -1
  46. package/src/sap/base/util/restricted/_union.js +1 -1
  47. package/src/sap/base/util/restricted/_unionBy.js +1 -1
  48. package/src/sap/base/util/restricted/_unionWith.js +1 -1
  49. package/src/sap/base/util/restricted/_uniq.js +1 -1
  50. package/src/sap/base/util/restricted/_uniqBy.js +1 -1
  51. package/src/sap/base/util/restricted/_uniqWith.js +1 -1
  52. package/src/sap/base/util/restricted/_without.js +1 -1
  53. package/src/sap/base/util/restricted/_xor.js +1 -1
  54. package/src/sap/base/util/restricted/_xorBy.js +1 -1
  55. package/src/sap/base/util/restricted/_xorWith.js +1 -1
  56. package/src/sap/base/util/restricted/_zipObject.js +1 -1
  57. package/src/sap/base/util/restricted/_zipObjectDeep.js +1 -1
  58. package/src/sap/ui/Device.js +3 -3
  59. package/src/sap/ui/Global.js +3 -3
  60. package/src/sap/ui/VersionInfo.js +24 -9
  61. package/src/sap/ui/base/Event.js +1 -1
  62. package/src/sap/ui/base/EventProvider.js +1 -1
  63. package/src/sap/ui/base/Interface.js +1 -1
  64. package/src/sap/ui/base/ManagedObject.js +108 -91
  65. package/src/sap/ui/base/ManagedObjectMetadata.js +1 -1
  66. package/src/sap/ui/base/Metadata.js +1 -1
  67. package/src/sap/ui/base/Object.js +1 -1
  68. package/src/sap/ui/base/ObjectPool.js +1 -1
  69. package/src/sap/ui/core/.library +1 -1
  70. package/src/sap/ui/core/BusyIndicator.js +1 -1
  71. package/src/sap/ui/core/Component.js +52 -6
  72. package/src/sap/ui/core/ComponentContainer.js +4 -2
  73. package/src/sap/ui/core/ComponentMetadata.js +1 -1
  74. package/src/sap/ui/core/ComponentSupport.js +1 -1
  75. package/src/sap/ui/core/Configuration.js +1 -1
  76. package/src/sap/ui/core/Control.js +1 -1
  77. package/src/sap/ui/core/Core.js +11 -3
  78. package/src/sap/ui/core/CustomData.js +2 -2
  79. package/src/sap/ui/core/DeclarativeSupport.js +1 -1
  80. package/src/sap/ui/core/Element.js +14 -35
  81. package/src/sap/ui/core/ElementHooks.js +35 -0
  82. package/src/sap/ui/core/ElementMetadata.js +1 -1
  83. package/src/sap/ui/core/EnabledPropagator.js +1 -1
  84. package/src/sap/ui/core/EventBus.js +1 -1
  85. package/src/sap/ui/core/Fragment.js +34 -11
  86. package/src/sap/ui/core/HTML.js +1 -1
  87. package/src/sap/ui/core/History.js +1 -1
  88. package/src/sap/ui/core/Icon.js +1 -1
  89. package/src/sap/ui/core/IconPool.js +11 -12
  90. package/src/sap/ui/core/IndicationColorSupport.js +1 -1
  91. package/src/sap/ui/core/IntervalTrigger.js +1 -1
  92. package/src/sap/ui/core/InvisibleMessage.js +1 -1
  93. package/src/sap/ui/core/InvisibleRenderer.js +1 -1
  94. package/src/sap/ui/core/InvisibleText.js +1 -1
  95. package/src/sap/ui/core/Item.js +1 -1
  96. package/src/sap/ui/core/LabelEnablement.js +1 -1
  97. package/src/sap/ui/core/LayoutData.js +1 -1
  98. package/src/sap/ui/core/Lib.js +12 -32
  99. package/src/sap/ui/core/ListItem.js +1 -1
  100. package/src/sap/ui/core/LocalBusyIndicator.js +1 -1
  101. package/src/sap/ui/core/Locale.js +1 -1
  102. package/src/sap/ui/core/LocaleData.js +67 -93
  103. package/src/sap/ui/core/Manifest.js +5 -3
  104. package/src/sap/ui/core/Message.js +1 -1
  105. package/src/sap/ui/core/RenderManager.js +1 -1
  106. package/src/sap/ui/core/Renderer.js +1 -1
  107. package/src/sap/ui/core/ResizeHandler.js +1 -1
  108. package/src/sap/ui/core/ScrollBar.js +1 -1
  109. package/src/sap/ui/core/SeparatorItem.js +1 -1
  110. package/src/sap/ui/core/ShortcutHintsMixin.js +9 -0
  111. package/src/sap/ui/core/Theming.js +98 -1
  112. package/src/sap/ui/core/Title.js +1 -1
  113. package/src/sap/ui/core/TooltipBase.js +1 -1
  114. package/src/sap/ui/core/UIArea.js +1 -1
  115. package/src/sap/ui/core/UIComponent.js +6 -3
  116. package/src/sap/ui/core/UIComponentMetadata.js +1 -1
  117. package/src/sap/ui/core/ValueStateSupport.js +1 -1
  118. package/src/sap/ui/core/VariantLayoutData.js +1 -1
  119. package/src/sap/ui/core/XMLComposite.js +1 -1
  120. package/src/sap/ui/core/XMLCompositeMetadata.js +1 -1
  121. package/src/sap/ui/core/XMLTemplateProcessor.js +5 -1
  122. package/src/sap/ui/core/_CommandPool.js +80 -0
  123. package/src/sap/ui/core/boot/KeyboardInteractionEndpoint.js +124 -0
  124. package/src/sap/ui/core/date/UI5Date.js +1 -1
  125. package/src/sap/ui/core/delegate/ItemNavigation.js +1 -1
  126. package/src/sap/ui/core/delegate/ScrollEnablement.js +1 -1
  127. package/src/sap/ui/core/dnd/DragDropBase.js +1 -1
  128. package/src/sap/ui/core/dnd/DragDropInfo.js +1 -1
  129. package/src/sap/ui/core/dnd/DragInfo.js +1 -1
  130. package/src/sap/ui/core/dnd/DropInfo.js +1 -1
  131. package/src/sap/ui/core/fieldhelp/FieldHelp.js +90 -48
  132. package/src/sap/ui/core/fieldhelp/FieldHelpCustomData.js +0 -4
  133. package/src/sap/ui/core/format/FormatUtils.js +1 -1
  134. package/src/sap/ui/core/format/TimezoneUtil.js +1 -1
  135. package/src/sap/ui/core/getCompatibilityVersion.js +1 -1
  136. package/src/sap/ui/core/hyphenation/Hyphenation.js +1 -1
  137. package/src/sap/ui/core/i18n/interaction.xml +31 -0
  138. package/src/sap/ui/core/interaction/KeyboardInteractionDisplay.js +332 -0
  139. package/src/sap/ui/core/library.js +6 -3
  140. package/src/sap/ui/core/message/ControlMessageProcessor.js +1 -1
  141. package/src/sap/ui/core/message/Message.js +1 -1
  142. package/src/sap/ui/core/message/MessageManager.js +1 -1
  143. package/src/sap/ui/core/message/MessageParser.js +1 -1
  144. package/src/sap/ui/core/message/MessageProcessor.js +1 -1
  145. package/src/sap/ui/core/messagebundle.properties +14 -0
  146. package/src/sap/ui/core/messagebundle_ro.properties +2 -2
  147. package/src/sap/ui/core/messagebundle_th.properties +1 -1
  148. package/src/sap/ui/core/messagebundle_vi.properties +2 -2
  149. package/src/sap/ui/core/mvc/Controller.js +25 -11
  150. package/src/sap/ui/core/mvc/HTMLView.js +1 -1
  151. package/src/sap/ui/core/mvc/JSONView.js +1 -1
  152. package/src/sap/ui/core/mvc/JSView.js +1 -1
  153. package/src/sap/ui/core/mvc/TemplateView.js +1 -1
  154. package/src/sap/ui/core/mvc/View.js +43 -18
  155. package/src/sap/ui/core/mvc/XMLView.js +20 -1
  156. package/src/sap/ui/core/plugin/DeclarativeSupport.js +1 -1
  157. package/src/sap/ui/core/plugin/LessSupport.js +1 -1
  158. package/src/sap/ui/core/plugin/TemplatingSupport.js +1 -1
  159. package/src/sap/ui/core/postmessage/Bus.js +1 -1
  160. package/src/sap/ui/core/postmessage/confirmationDialog.js +1 -1
  161. package/src/sap/ui/core/search/OpenSearchProvider.js +1 -1
  162. package/src/sap/ui/core/search/SearchProvider.js +1 -1
  163. package/src/sap/ui/core/service/Service.js +1 -1
  164. package/src/sap/ui/core/service/ServiceFactory.js +1 -1
  165. package/src/sap/ui/core/service/ServiceFactoryRegistry.js +1 -1
  166. package/src/sap/ui/core/support/Plugin.js +1 -1
  167. package/src/sap/ui/core/support/Support.js +1 -1
  168. package/src/sap/ui/core/support/plugins/ControlTree.js +1 -1
  169. package/src/sap/ui/core/support/plugins/Interaction.js +1 -1
  170. package/src/sap/ui/core/support/plugins/LocalStorage.js +1 -1
  171. package/src/sap/ui/core/support/plugins/Performance.js +1 -1
  172. package/src/sap/ui/core/support/plugins/Selector.js +1 -1
  173. package/src/sap/ui/core/support/plugins/TechInfo.js +1 -1
  174. package/src/sap/ui/core/support/plugins/Trace.js +1 -1
  175. package/src/sap/ui/core/support/plugins/ViewInfo.js +1 -1
  176. package/src/sap/ui/core/support/techinfo/moduleTreeHelper.js +12 -0
  177. package/src/sap/ui/core/support/usage/EventBroadcaster.js +5 -5
  178. package/src/sap/ui/core/themes/base/base.less +398 -23
  179. package/src/sap/ui/core/themes/base/global.less +7 -0
  180. package/src/sap/ui/core/themes/base/icons/favicon.ico +0 -0
  181. package/src/sap/ui/core/themes/base/skeleton.less +11 -4
  182. package/src/sap/ui/core/themes/sap_hcb/.theming +2 -1
  183. package/src/sap/ui/core/theming/ThemeHelper.js +13 -0
  184. package/src/sap/ui/core/theming/ThemeManager.js +1 -1
  185. package/src/sap/ui/core/tmpl/DOMAttribute.js +1 -1
  186. package/src/sap/ui/core/tmpl/DOMElement.js +1 -1
  187. package/src/sap/ui/core/tmpl/HandlebarsTemplate.js +1 -1
  188. package/src/sap/ui/core/tmpl/Template.js +1 -1
  189. package/src/sap/ui/core/tmpl/TemplateControl.js +1 -1
  190. package/src/sap/ui/core/util/AsyncHintsHelper.js +1 -1
  191. package/src/sap/ui/core/util/Export.js +1 -1
  192. package/src/sap/ui/core/util/ExportCell.js +1 -1
  193. package/src/sap/ui/core/util/ExportColumn.js +1 -1
  194. package/src/sap/ui/core/util/ExportRow.js +1 -1
  195. package/src/sap/ui/core/util/ExportType.js +1 -1
  196. package/src/sap/ui/core/util/ExportTypeCSV.js +1 -1
  197. package/src/sap/ui/core/util/File.js +1 -1
  198. package/src/sap/ui/core/util/LibraryInfo.js +1 -1
  199. package/src/sap/ui/core/util/MockServer.js +1 -1
  200. package/src/sap/ui/core/util/PasteHelper.js +1 -1
  201. package/src/sap/ui/core/util/serializer/HTMLViewSerializer.js +1 -1
  202. package/src/sap/ui/core/util/serializer/Serializer.js +1 -1
  203. package/src/sap/ui/core/util/serializer/ViewSerializer.js +1 -1
  204. package/src/sap/ui/core/util/serializer/XMLViewSerializer.js +1 -1
  205. package/src/sap/ui/core/util/serializer/delegate/Delegate.js +1 -1
  206. package/src/sap/ui/core/util/serializer/delegate/HTML.js +1 -1
  207. package/src/sap/ui/core/util/serializer/delegate/XML.js +1 -1
  208. package/src/sap/ui/core/webc/WebComponent.js +1 -1
  209. package/src/sap/ui/core/webc/WebComponentMetadata.js +1 -1
  210. package/src/sap/ui/core/ws/ReadyState.js +1 -1
  211. package/src/sap/ui/core/ws/SapPcpWebSocket.js +1 -1
  212. package/src/sap/ui/core/ws/WebSocket.js +1 -1
  213. package/src/sap/ui/debug/ControlTree.js +1 -1
  214. package/src/sap/ui/debug/DebugEnv.js +1 -1
  215. package/src/sap/ui/debug/PropertyList.js +1 -1
  216. package/src/sap/ui/model/ClientModel.js +1 -1
  217. package/src/sap/ui/model/CompositeDataState.js +1 -1
  218. package/src/sap/ui/model/CompositeType.js +1 -1
  219. package/src/sap/ui/model/DataState.js +1 -1
  220. package/src/sap/ui/model/MetaModel.js +1 -1
  221. package/src/sap/ui/model/Model.js +1 -1
  222. package/src/sap/ui/model/SelectionModel.js +1 -1
  223. package/src/sap/ui/model/SimpleType.js +1 -1
  224. package/src/sap/ui/model/TreeAutoExpandMode.js +1 -1
  225. package/src/sap/ui/model/Type.js +1 -1
  226. package/src/sap/ui/model/json/JSONModel.js +1 -1
  227. package/src/sap/ui/model/message/MessageModel.js +1 -1
  228. package/src/sap/ui/model/odata/ODataAnnotations.js +1 -1
  229. package/src/sap/ui/model/odata/ODataMessageParser.js +1 -1
  230. package/src/sap/ui/model/odata/ODataMetaModel.js +1 -1
  231. package/src/sap/ui/model/odata/ODataMetadata.js +5 -2
  232. package/src/sap/ui/model/odata/ODataModel.js +1 -1
  233. package/src/sap/ui/model/odata/type/Boolean.js +1 -1
  234. package/src/sap/ui/model/odata/type/Byte.js +1 -1
  235. package/src/sap/ui/model/odata/type/Currency.js +1 -1
  236. package/src/sap/ui/model/odata/type/Date.js +1 -1
  237. package/src/sap/ui/model/odata/type/DateTime.js +1 -1
  238. package/src/sap/ui/model/odata/type/DateTimeBase.js +1 -1
  239. package/src/sap/ui/model/odata/type/DateTimeOffset.js +1 -1
  240. package/src/sap/ui/model/odata/type/DateTimeWithTimezone.js +1 -1
  241. package/src/sap/ui/model/odata/type/Decimal.js +1 -1
  242. package/src/sap/ui/model/odata/type/Double.js +1 -1
  243. package/src/sap/ui/model/odata/type/Guid.js +1 -1
  244. package/src/sap/ui/model/odata/type/Int.js +1 -1
  245. package/src/sap/ui/model/odata/type/Int16.js +1 -1
  246. package/src/sap/ui/model/odata/type/Int32.js +1 -1
  247. package/src/sap/ui/model/odata/type/Int64.js +1 -1
  248. package/src/sap/ui/model/odata/type/ODataType.js +1 -1
  249. package/src/sap/ui/model/odata/type/Raw.js +1 -1
  250. package/src/sap/ui/model/odata/type/SByte.js +1 -1
  251. package/src/sap/ui/model/odata/type/Single.js +1 -1
  252. package/src/sap/ui/model/odata/type/Stream.js +1 -1
  253. package/src/sap/ui/model/odata/type/String.js +1 -1
  254. package/src/sap/ui/model/odata/type/Time.js +1 -1
  255. package/src/sap/ui/model/odata/type/TimeOfDay.js +1 -1
  256. package/src/sap/ui/model/odata/type/Unit.js +1 -1
  257. package/src/sap/ui/model/odata/v2/Context.js +1 -1
  258. package/src/sap/ui/model/odata/v2/ODataAnnotations.js +1 -1
  259. package/src/sap/ui/model/odata/v2/ODataModel.js +36 -21
  260. package/src/sap/ui/model/odata/v2/ODataTreeBinding.js +1 -1
  261. package/src/sap/ui/model/odata/v4/Context.js +88 -33
  262. package/src/sap/ui/model/odata/v4/ODataBinding.js +15 -9
  263. package/src/sap/ui/model/odata/v4/ODataContextBinding.js +4 -4
  264. package/src/sap/ui/model/odata/v4/ODataListBinding.js +84 -17
  265. package/src/sap/ui/model/odata/v4/ODataMetaModel.js +63 -4
  266. package/src/sap/ui/model/odata/v4/ODataModel.js +14 -2
  267. package/src/sap/ui/model/odata/v4/ODataParentBinding.js +5 -2
  268. package/src/sap/ui/model/odata/v4/ODataPropertyBinding.js +3 -2
  269. package/src/sap/ui/model/odata/v4/lib/_AggregationCache.js +24 -6
  270. package/src/sap/ui/model/odata/v4/lib/_Batch.js +5 -1
  271. package/src/sap/ui/model/odata/v4/lib/_Cache.js +30 -11
  272. package/src/sap/ui/model/odata/v4/lib/_Helper.js +33 -17
  273. package/src/sap/ui/model/resource/ResourceModel.js +1 -1
  274. package/src/sap/ui/model/type/Boolean.js +1 -1
  275. package/src/sap/ui/model/type/Currency.js +1 -1
  276. package/src/sap/ui/model/type/Date.js +1 -1
  277. package/src/sap/ui/model/type/DateInterval.js +1 -1
  278. package/src/sap/ui/model/type/DateTime.js +1 -1
  279. package/src/sap/ui/model/type/DateTimeInterval.js +1 -1
  280. package/src/sap/ui/model/type/FileSize.js +1 -1
  281. package/src/sap/ui/model/type/Float.js +1 -1
  282. package/src/sap/ui/model/type/Integer.js +1 -1
  283. package/src/sap/ui/model/type/String.js +1 -1
  284. package/src/sap/ui/model/type/Time.js +1 -1
  285. package/src/sap/ui/model/type/TimeInterval.js +1 -1
  286. package/src/sap/ui/model/type/Unit.js +1 -1
  287. package/src/sap/ui/model/xml/XMLModel.js +1 -1
  288. package/src/sap/ui/qunit/utils/ControlIterator.js +1 -1
  289. package/src/sap/ui/qunit/utils/MemoryLeakCheck.js +1 -1
  290. package/src/sap/ui/test/TestUtils.js +1 -1
  291. package/src/sap/ui/test/generic/TestBase.js +1 -1
  292. package/src/sap/ui/util/Storage.js +1 -1
  293. package/src/ui5loader.js +19 -3
@@ -342,7 +342,9 @@ sap.ui.define([
342
342
  * @param {sap.ui.model.Context} [oContext]
343
343
  * The context instance to be used, undefined for absolute bindings
344
344
  * @param {string} [sGroupId]
345
- * The group ID used for a side-effects refresh, if applicable
345
+ * The group ID; mandatory if <code>bSideEffectsRefresh</code> is set
346
+ * @param {boolean} [bSideEffectsRefresh]
347
+ * Whether to perform a side-effects refresh
346
348
  * @param {sap.ui.model.odata.v4.lib._Cache} [oOldCache]
347
349
  * The old cache, in case it may be reused
348
350
  * @returns {sap.ui.model.odata.v4.lib._Cache}
@@ -352,7 +354,7 @@ sap.ui.define([
352
354
  * @private
353
355
  */
354
356
  ODataBinding.prototype.createAndSetCache = function (mQueryOptions, sResourcePath, oContext,
355
- sGroupId, oOldCache) {
357
+ sGroupId, bSideEffectsRefresh, oOldCache) {
356
358
  var oCache, sDeepResourcePath, iGeneration;
357
359
 
358
360
  this.mCacheQueryOptions = Object.assign({}, this.oModel.mUriParameters, mQueryOptions);
@@ -365,7 +367,7 @@ sap.ui.define([
365
367
  } else {
366
368
  sDeepResourcePath = this.oModel.resolve(this.sPath, oContext).slice(1);
367
369
  oCache = this.doCreateCache(sResourcePath, this.mCacheQueryOptions, oContext,
368
- sDeepResourcePath, sGroupId, oOldCache);
370
+ sDeepResourcePath, sGroupId, bSideEffectsRefresh, oOldCache);
369
371
  if (!(this.mParameters && this.mParameters.$$sharedRequest)) {
370
372
  this.mCacheByResourcePath ??= {};
371
373
  this.mCacheByResourcePath[sResourcePath] = oCache;
@@ -375,7 +377,7 @@ sap.ui.define([
375
377
  }
376
378
  } else { // absolute binding
377
379
  oCache = this.doCreateCache(sResourcePath, this.mCacheQueryOptions, undefined,
378
- undefined, sGroupId, oOldCache);
380
+ undefined, sGroupId, bSideEffectsRefresh, oOldCache);
379
381
  }
380
382
  if (oOldCache && oOldCache !== oCache) {
381
383
  this.deregisterChangeListener();
@@ -434,7 +436,9 @@ sap.ui.define([
434
436
  * @param {string} [sDeepResourcePath=sResourcePath]
435
437
  * The deep resource path to be used to build the target path for bound messages
436
438
  * @param {string} [sGroupId]
437
- * The group ID used for a side-effects refresh, if applicable
439
+ * The group ID; mandatory if <code>bSideEffectsRefresh</code> is set
440
+ * @param {boolean} [bSideEffectsRefresh]
441
+ * Whether to perform a side-effects refresh
438
442
  * @param {sap.ui.model.odata.v4.lib._Cache} [oOldCache]
439
443
  * The old cache, in case it may be reused
440
444
  * @returns {sap.ui.model.odata.v4.lib._Cache}
@@ -483,7 +487,9 @@ sap.ui.define([
483
487
  * Whether to keep existing (late) query options and not to run auto-$expand/$select again
484
488
  * (cannot be combined with <code>bIgnoreParentCache</code>!)
485
489
  * @param {string} [sGroupId]
486
- * The group ID used for a side-effects refresh, if applicable
490
+ * The group ID; mandatory if <code>bSideEffectsRefresh</code> is set
491
+ * @param {boolean} [bSideEffectsRefresh]
492
+ * Whether to perform a side-effects refresh
487
493
  * @throws {Error}
488
494
  * If auto-$expand/$select is still running and query options shall be kept (this case is just
489
495
  * not yet implemented and should not be needed)
@@ -491,7 +497,7 @@ sap.ui.define([
491
497
  * @private
492
498
  */
493
499
  ODataBinding.prototype.fetchCache = function (oContext, bIgnoreParentCache, bKeepQueryOptions,
494
- sGroupId) {
500
+ sGroupId, bSideEffectsRefresh) {
495
501
  var oCache = this.oCache,
496
502
  oCallToken = {
497
503
  // propagate old cache from first call of fetchCache to the latest call
@@ -517,7 +523,7 @@ sap.ui.define([
517
523
  // asynchronously re-create an equivalent cache, but skip auto-$expand/$select
518
524
  this.oCachePromise = SyncPromise.resolve(Promise.resolve()).then(function () {
519
525
  return that.createAndSetCache(that.mCacheQueryOptions, oCache.getResourcePath(),
520
- oContext, sGroupId, oCache);
526
+ oContext, sGroupId, bSideEffectsRefresh, oCache);
521
527
  });
522
528
  return;
523
529
  }
@@ -555,7 +561,7 @@ sap.ui.define([
555
561
  return that.oModel.waitForKeepAliveBinding(that).then(function () {
556
562
  that.oFetchCacheCallToken = undefined; // cleanup
557
563
  return that.createAndSetCache(mQueryOptions, sResourcePath, oContext,
558
- sGroupId, oCallToken.oOldCache);
564
+ sGroupId, bSideEffectsRefresh, oCallToken.oOldCache);
559
565
  });
560
566
  });
561
567
  }
@@ -74,7 +74,7 @@ sap.ui.define([
74
74
  * @mixes sap.ui.model.odata.v4.ODataParentBinding
75
75
  * @public
76
76
  * @since 1.37.0
77
- * @version 1.134.0
77
+ * @version 1.135.0
78
78
  *
79
79
  * @borrows sap.ui.model.odata.v4.ODataBinding#getGroupId as #getGroupId
80
80
  * @borrows sap.ui.model.odata.v4.ODataBinding#getRootBinding as #getRootBinding
@@ -1133,7 +1133,7 @@ sap.ui.define([
1133
1133
  return undefined;
1134
1134
  }
1135
1135
  return sBindingParameterPath.split("/").map((sSegment, i) => {
1136
- return sSegment.slice(0, sSegment.lastIndexOf("("))
1136
+ return sSegment.slice(0, sSegment.indexOf("("))
1137
1137
  + (i ? sPredicate : sPartnerPredicate);
1138
1138
  }).join("/");
1139
1139
  };
@@ -1588,8 +1588,8 @@ sap.ui.define([
1588
1588
  that.mAggregatedQueryOptions = that.mLateQueryOptions;
1589
1589
  that.mLateQueryOptions = undefined;
1590
1590
  }
1591
- that.fetchCache(that.oContext, false, /*bKeepQueryOptions*/false,
1592
- bKeepCacheOnError ? sGroupId : undefined);
1591
+ that.fetchCache(that.oContext, false, /*bKeepQueryOptions*/false, sGroupId,
1592
+ bKeepCacheOnError);
1593
1593
  // Do not fire a change event, or else ManagedObject destroys and recreates the
1594
1594
  // binding hierarchy causing a flood of events.
1595
1595
  if (bHasChangeListeners) {
@@ -59,7 +59,7 @@ sap.ui.define([
59
59
  * @mixes sap.ui.model.odata.v4.ODataParentBinding
60
60
  * @public
61
61
  * @since 1.37.0
62
- * @version 1.134.0
62
+ * @version 1.135.0
63
63
  * @borrows sap.ui.model.odata.v4.ODataBinding#getGroupId as #getGroupId
64
64
  * @borrows sap.ui.model.odata.v4.ODataBinding#getRootBinding as #getRootBinding
65
65
  * @borrows sap.ui.model.odata.v4.ODataBinding#getUpdateGroupId as #getUpdateGroupId
@@ -193,14 +193,20 @@ sap.ui.define([
193
193
  /**
194
194
  * Returns all currently existing contexts of this list binding in no special order.
195
195
  *
196
+ * @param {boolean} [bNoCreated]
197
+ * Whether to exclude created contexts
196
198
  * @returns {sap.ui.model.odata.v4.Context[]}
197
199
  * All currently existing contexts of this list binding, in no special order
198
200
  *
199
201
  * @private
200
202
  * @see #getAllCurrentContexts
201
203
  */
202
- ODataListBinding.prototype._getAllExistingContexts = function () {
203
- return (this.aContexts ?? []).filter(function (oContext) {
204
+ ODataListBinding.prototype._getAllExistingContexts = function (bNoCreated) {
205
+ let aContexts = this.aContexts ?? [];
206
+ if (bNoCreated) {
207
+ aContexts = aContexts.slice(this.iCreatedContexts);
208
+ }
209
+ return aContexts.filter(function (oContext) {
204
210
  return oContext;
205
211
  }).concat(Object.values(this.mPreviousContextsByPath).filter(function (oContext) {
206
212
  return oContext.isEffectivelyKeptAlive();
@@ -1500,7 +1506,7 @@ sap.ui.define([
1500
1506
  * @see sap.ui.model.odata.v4.ODataBinding#doCreateCache
1501
1507
  */
1502
1508
  ODataListBinding.prototype.doCreateCache = function (sResourcePath, mQueryOptions, oContext,
1503
- sDeepResourcePath, sGroupId, oOldCache) {
1509
+ sDeepResourcePath, sGroupId, bSideEffectsRefresh, oOldCache) {
1504
1510
  var oCache,
1505
1511
  aKeepAlivePredicates,
1506
1512
  mKeptElementsByPredicate,
@@ -1518,12 +1524,14 @@ sap.ui.define([
1518
1524
  && oOldCache instanceof _AggregationCache) {
1519
1525
  if (bResetViaSideEffects && this.mParameters.$$aggregation?.hierarchyQualifier) {
1520
1526
  sGroupId = this.getGroupId(); // reset via a side-effects refresh
1527
+ bSideEffectsRefresh = true;
1521
1528
  oOldCache.resetOutOfPlace();
1522
1529
  }
1530
+ this.validateSelection(oOldCache, sGroupId);
1523
1531
  // Note: #inheritQueryOptions as called below should not matter in case of own
1524
1532
  // requests, which are a precondition for kept-alive elements
1525
- oOldCache.reset(aKeepAlivePredicates, sGroupId, mQueryOptions,
1526
- this.mParameters.$$aggregation, this.isGrouped());
1533
+ oOldCache.reset(aKeepAlivePredicates, bSideEffectsRefresh ? sGroupId : undefined,
1534
+ mQueryOptions, this.mParameters.$$aggregation, this.isGrouped());
1527
1535
 
1528
1536
  return oOldCache;
1529
1537
  }
@@ -2867,9 +2875,7 @@ sap.ui.define([
2867
2875
  * @since 1.91.0
2868
2876
  */
2869
2877
  ODataListBinding.prototype.getCount = function () {
2870
- var oHeaderContext = this.getHeaderContext();
2871
-
2872
- return oHeaderContext ? oHeaderContext.getProperty("$count") : undefined;
2878
+ return this.getHeaderContext()?.getProperty("$count");
2873
2879
  };
2874
2880
 
2875
2881
  /**
@@ -3306,6 +3312,25 @@ sap.ui.define([
3306
3312
  return this.mQueryOptions;
3307
3313
  };
3308
3314
 
3315
+ /**
3316
+ * Returns the count of selected elements as a number of type <code>Edm.Int64</code>. The count
3317
+ * is bindable via the header context (see {@link #getHeaderContext}) and path
3318
+ * <code>$selectionCount</code>; it is either available synchronously or unknown. It is unknown
3319
+ * if the binding is relative but has no context and also if the list binding's
3320
+ * {@link sap.ui.model.odata.v4.ODataListBinding#getHeaderContext header context} is selected
3321
+ * ("select all").
3322
+ *
3323
+ * @returns {number|undefined}
3324
+ * The count of selected elements or <code>undefined</code> if the count or the header
3325
+ * context is not available.
3326
+ *
3327
+ * @public
3328
+ * @since 1.135.0
3329
+ */
3330
+ ODataListBinding.prototype.getSelectionCount = function () {
3331
+ return this.getHeaderContext()?.getProperty("$selectionCount");
3332
+ };
3333
+
3309
3334
  /**
3310
3335
  * Returns true if the binding has {@link sap.ui.model.Filter.NONE} in its filters.
3311
3336
  *
@@ -3628,13 +3653,14 @@ sap.ui.define([
3628
3653
  * Moves the given (child) node to the given parent, just before the given next sibling. An
3629
3654
  * expanded (child) node is silently collapsed before and expanded after the move. A collapsed
3630
3655
  * parent is automatically expanded; so is a leaf. The (child) node is added to the parent at
3631
- * its proper position ("in place") and simply "persisted". Specifying a next sibling always
3632
- * leads to a subsequent side-effects refresh within the same $batch, but still the moved
3633
- * (child) node's index is updated to the new position.
3656
+ * its proper position ("in place") and simply "persisted". If needed, a subsequent side-effects
3657
+ * refresh within the same $batch is requested, but still the moved (child) node's index is
3658
+ * updated to the new position.
3634
3659
  *
3635
3660
  * @param {sap.ui.model.odata.v4.Context} oChildContext - The (child) node to be moved
3636
3661
  * @param {sap.ui.model.odata.v4.Context|null} oParentContext - The new parent's context
3637
3662
  * @param {sap.ui.model.odata.v4.Context|null} [oSiblingContext] - The next sibling's context
3663
+ * @param {boolean} [bCopy] - Whether the node should be copied instead of moved
3638
3664
  * @returns {sap.ui.base.SyncPromise<void>}
3639
3665
  * A promise which is resolved without a defined result when the move is finished, or
3640
3666
  * rejected in case of an error
@@ -3643,7 +3669,8 @@ sap.ui.define([
3643
3669
  *
3644
3670
  * @private
3645
3671
  */
3646
- ODataListBinding.prototype.move = function (oChildContext, oParentContext, oSiblingContext) {
3672
+ ODataListBinding.prototype.move = function (oChildContext, oParentContext, oSiblingContext,
3673
+ bCopy) {
3647
3674
  /*
3648
3675
  * Sets the <code>iIndex</code> of every context instance inside the given range. Allows for
3649
3676
  * start greater than end and swaps both in that case.
@@ -3681,7 +3708,7 @@ sap.ui.define([
3681
3708
  : oChildContext.getPath().slice(1);
3682
3709
  const bUpdateSiblingIndex = oSiblingContext?.isEffectivelyKeptAlive();
3683
3710
  const {promise : oPromise, refresh : bRefresh} = this.oCache.move(oGroupLock, sChildPath,
3684
- sParentPath, sSiblingPath, sNonCanonicalChildPath, bUpdateSiblingIndex);
3711
+ sParentPath, sSiblingPath, sNonCanonicalChildPath, bUpdateSiblingIndex, bCopy);
3685
3712
 
3686
3713
  if (bRefresh) {
3687
3714
  return SyncPromise.all([
@@ -3887,7 +3914,7 @@ sap.ui.define([
3887
3914
  oCache.reset([]);
3888
3915
  } else {
3889
3916
  that.fetchCache(that.oContext, false, /*bKeepQueryOptions*/true,
3890
- bKeepCacheOnError ? sGroupId : undefined);
3917
+ sGroupId, bKeepCacheOnError);
3891
3918
  oKeptElementsPromise = that.refreshKeptElements(sGroupId,
3892
3919
  /*bIgnorePendingChanges*/ bKeepCacheOnError);
3893
3920
  if (that.iCurrentEnd > 0) {
@@ -4082,6 +4109,7 @@ sap.ui.define([
4082
4109
 
4083
4110
  if (!bStillAlive) {
4084
4111
  bDestroyed = true;
4112
+ oContext.doSetSelected(false, true);
4085
4113
  oContext.destroy();
4086
4114
  }
4087
4115
  }
@@ -4340,8 +4368,7 @@ sap.ui.define([
4340
4368
  /**
4341
4369
  * Requests selected contexts matching the binding's filters and ordered by its sorters. A
4342
4370
  * context which is selected but no longer part of this list binding's collection (that is,
4343
- * which doesn't match the filters) is not returned but still shown as selected on the UI
4344
- * (see {@link #requestSelectionValidation}).
4371
+ * which doesn't match the filters) is not returned but still shown as selected on the UI.
4345
4372
  *
4346
4373
  * Note: Data for all selected contexts is reread from the server, even if it is already
4347
4374
  * available on the client. Any data updates are reflected on the UI but no order is changed.
@@ -5178,6 +5205,46 @@ sap.ui.define([
5178
5205
  }
5179
5206
  };
5180
5207
 
5208
+ /**
5209
+ * Validates the selected contexts against the list binding's filter criteria and removes the
5210
+ * selection from contexts that no longer match.
5211
+ *
5212
+ * @param {sap.ui.model.odata.v4.lib._Cache} oCache
5213
+ * The cache to be used
5214
+ * @param {string} [sGroupId]
5215
+ * The group ID to be used for the request
5216
+ *
5217
+ * @private
5218
+ */
5219
+ ODataListBinding.prototype.validateSelection = function (oCache, sGroupId) {
5220
+ if (!this.mParameters.$$clearSelectionOnFilter || "$$aggregation" in this.mParameters
5221
+ || this.oHeaderContext.isSelected()) {
5222
+ return;
5223
+ }
5224
+
5225
+ const aSelectedContexts = this._getAllExistingContexts(true)
5226
+ .filter((oContext) => oContext.isSelected());
5227
+
5228
+ if (!aSelectedContexts.length) {
5229
+ return;
5230
+ }
5231
+
5232
+ const iStartOfPredicate = this.getResolvedPath().length;
5233
+ const aPredicatesIn = aSelectedContexts
5234
+ .map((oContext) => oContext.getPath().slice(iStartOfPredicate));
5235
+ oCache.requestFilteredOrderedPredicates(aPredicatesIn, this.lockGroup(sGroupId), true)
5236
+ .then((aPredicatesOut) => {
5237
+ const oPredicates = new Set(aPredicatesOut);
5238
+ aSelectedContexts.forEach((oContext) => {
5239
+ if (!oPredicates.has(oContext.getPath().slice(iStartOfPredicate))) {
5240
+ oContext.setSelected(false);
5241
+ }
5242
+ });
5243
+ }, (oError) => {
5244
+ this.oModel.reportError("Failed to validate selection", sClassName, oError);
5245
+ });
5246
+ };
5247
+
5181
5248
  //*********************************************************************************************
5182
5249
  // "static" functions
5183
5250
  //*********************************************************************************************
@@ -60,7 +60,45 @@ sap.ui.define([
60
60
  oBooleanType,
61
61
  mCodeListUrl2Promise = {},
62
62
  DEBUG = Log.Level.DEBUG,
63
- aInt64Names = ["$count", "@$ui5.node.groupLevelCount", "@$ui5.node.level"],
63
+ oGeoJSON = {
64
+ $kind : "ComplexType",
65
+ $OpenType : true,
66
+ bbox : {
67
+ $kind : "Property",
68
+ $Type : "Edm.Double",
69
+ $isCollection : true
70
+ },
71
+ type : {
72
+ $kind : "Property",
73
+ $Nullable : false,
74
+ $Type : "Edm.String"
75
+ }
76
+ },
77
+ oGeometry = {
78
+ ...oGeoJSON, // "$BaseType" : "GeoJSON",
79
+ coordinates : {
80
+ $kind : "Property",
81
+ $Nullable : false,
82
+ $Type : "Edm.Double",
83
+ $isCollection : true
84
+ }
85
+ },
86
+ mEdmScope = {
87
+ "Edm.Geography" : {...oGeoJSON, $Abstract : true},
88
+ "Edm.GeographyLineString" : oGeometry,
89
+ "Edm.GeographyMultiLineString" : oGeometry,
90
+ "Edm.GeographyMultiPoint" : oGeometry,
91
+ "Edm.GeographyMultiPolygon" : oGeometry,
92
+ "Edm.GeographyPoint" : oGeometry,
93
+ "Edm.GeographyPolygon" : oGeometry
94
+ // Note: same for "Edm.Geometry*", see end of file
95
+ },
96
+ aInt64Names = [
97
+ "$count",
98
+ "$selectionCount",
99
+ "@$ui5.node.groupLevelCount",
100
+ "@$ui5.node.level"
101
+ ],
64
102
  oInt64Type,
65
103
  rLeftBraces = /\$\(/g,
66
104
  rNumber = /^-?\d+$/,
@@ -157,7 +195,7 @@ sap.ui.define([
157
195
  * @hideconstructor
158
196
  * @public
159
197
  * @since 1.37.0
160
- * @version 1.134.0
198
+ * @version 1.135.0
161
199
  */
162
200
  ODataMetaModel = MetaModel.extend("sap.ui.model.odata.v4.ODataMetaModel", {
163
201
  constructor : constructor
@@ -1091,7 +1129,7 @@ sap.ui.define([
1091
1129
  if (!bPrefetch) {
1092
1130
  aPromises.push(this.oModel._requestAnnotationChanges());
1093
1131
  this.oMetadataPromise = SyncPromise.all(aPromises).then(function (aMetadata) {
1094
- var mScope = aMetadata[0];
1132
+ var mScope = Object.assign(aMetadata[0], mEdmScope);
1095
1133
 
1096
1134
  that.aAnnotationChanges = aMetadata.pop();
1097
1135
  that._mergeAnnotations(mScope, aMetadata.slice(1));
@@ -1785,7 +1823,7 @@ sap.ui.define([
1785
1823
  return oProperty["$ui5.type"];
1786
1824
  }
1787
1825
 
1788
- if (oProperty.$isCollection) {
1826
+ if (oProperty.$isCollection && !rNumber.test(sLastSegment)) {
1789
1827
  Log.warning("Unsupported collection type, using " + oType.getName(), sPath,
1790
1828
  sODataMetaModel);
1791
1829
  } else {
@@ -2675,6 +2713,22 @@ sap.ui.define([
2675
2713
  ODataMetaModel.prototype.getValueListType
2676
2714
  = _Helper.createGetMethod("fetchValueListType", true);
2677
2715
 
2716
+ /**
2717
+ * Tells whether this metadata model's service prefers requests to use a resource path with
2718
+ * navigation properties instead of a canonical path, thus reflecting the object composition.
2719
+ * See "com.sap.vocabularies.Common.v1.AddressViaNavigationPath" for more details.
2720
+ *
2721
+ * @returns {boolean|undefined}
2722
+ * <code>true</code> if the "com.sap.vocabularies.Common.v1.AddressViaNavigationPath" tag is
2723
+ * present, <code>undefined</code> if it is missing or metadata is not (yet) available
2724
+ *
2725
+ * @public
2726
+ * @since 1.135.0
2727
+ */
2728
+ ODataMetaModel.prototype.isAddressViaNavigationPath = function () {
2729
+ return this.getObject("/@com.sap.vocabularies.Common.v1.AddressViaNavigationPath");
2730
+ };
2731
+
2678
2732
  /**
2679
2733
  * Method not supported
2680
2734
  *
@@ -3706,5 +3760,10 @@ sap.ui.define([
3706
3760
  mCodeListUrl2Promise = {};
3707
3761
  };
3708
3762
 
3763
+ Object.keys(mEdmScope).forEach((sGeographyName) => {
3764
+ const sGeometryName = sGeographyName.replace("Geography", "Geometry");
3765
+ mEdmScope[sGeometryName] = mEdmScope[sGeographyName];
3766
+ });
3767
+
3709
3768
  return ODataMetaModel;
3710
3769
  });
@@ -240,7 +240,7 @@ sap.ui.define([
240
240
  * @extends sap.ui.model.Model
241
241
  * @public
242
242
  * @since 1.37.0
243
- * @version 1.134.0
243
+ * @version 1.135.0
244
244
  */
245
245
  ODataModel = Model.extend("sap.ui.model.odata.v4.ODataModel",
246
246
  /** @lends sap.ui.model.odata.v4.ODataModel.prototype */{
@@ -928,7 +928,11 @@ sap.ui.define([
928
928
  * @param {boolean} [mParameters.$$clearSelectionOnFilter]
929
929
  * Whether the selection state of the list binding is cleared when a filter is changed; this
930
930
  * includes dynamic filters, '$filter', '$search', and <code>$$aggregation.search</code>.
931
- * Supported since 1.120.13.
931
+ * Supported since 1.120.13. Since 1.135.0, the selection state is validated when reloading
932
+ * the list binding's data. The
933
+ * {@link sap.ui.model.odata.v4.Context#isSelected selection states of contexts} which no
934
+ * longer match the current filter are reset. <b>Note:</b> The selection state is not
935
+ * validated if the <code>$$aggregation</code> parameter is used.
932
936
  * @param {boolean} [mParameters.$$getKeepAliveContext]
933
937
  * Whether this binding is considered for a match when {@link #getKeepAliveContext} is called;
934
938
  * only the value <code>true</code> is allowed. Must not be combined with <code>$apply</code>,
@@ -1045,6 +1049,14 @@ sap.ui.define([
1045
1049
  * is also supported (since 1.130.0) for complex types and collections thereof; for entity
1046
1050
  * types, use {@link #bindContext} instead.
1047
1051
  *
1052
+ * Since 1.135.0, the binding may also point to an array element inside a collection of
1053
+ * primitive type, for example in the context of geography locations. Let's assume
1054
+ * "GeoLocation" is a structural property of type "Edm.GeographyPoint", then "coordinates" is a
1055
+ * structural property of type "Collection(Edm.Double)":
1056
+ * <pre>
1057
+ * &lt;Text id="longitude" text="{Address/GeoLocation/coordinates/0}"/>
1058
+ * </pre>
1059
+ *
1048
1060
  * @param {string} sPath
1049
1061
  * The binding path in the model; must not end with a slash
1050
1062
  * @param {sap.ui.model.Context} [oContext]
@@ -276,7 +276,9 @@ sap.ui.define([
276
276
  /**
277
277
  * Changes this binding's parameters and refreshes the binding. Since 1.111.0, a list binding's
278
278
  * header context is deselected, but (since 1.120.13) only if the binding parameter
279
- * '$$clearSelectionOnFilter' is set and the '$filter' or '$search' parameter is changed.
279
+ * '$$clearSelectionOnFilter' is set and the '$filter' or '$search' parameter is changed. In all
280
+ * other cases, the caller of this method needs to evaluate whether the changed parameters
281
+ * invalidate the current selection and then deselect the header context if needed.
280
282
  *
281
283
  * If there are pending changes that cannot be ignored, an error is thrown. Use
282
284
  * {@link #hasPendingChanges} to check if there are such pending changes. If there are, call
@@ -870,7 +872,8 @@ sap.ui.define([
870
872
  }
871
873
 
872
874
  if (bDependsOnOperation || sReducedChildMetaPath === "$count"
873
- || sReducedChildMetaPath.endsWith("/$count")) {
875
+ || sReducedChildMetaPath.endsWith("/$count")
876
+ || sReducedChildMetaPath === "$selectionCount") {
874
877
  return sReducedPath;
875
878
  }
876
879
 
@@ -42,7 +42,7 @@ sap.ui.define([
42
42
  * @mixes sap.ui.model.odata.v4.ODataBinding
43
43
  * @public
44
44
  * @since 1.37.0
45
- * @version 1.134.0
45
+ * @version 1.135.0
46
46
  * @borrows sap.ui.model.odata.v4.ODataBinding#getGroupId as #getGroupId
47
47
  * @borrows sap.ui.model.odata.v4.ODataBinding#getRootBinding as #getRootBinding
48
48
  * @borrows sap.ui.model.odata.v4.ODataBinding#getUpdateGroupId as #getUpdateGroupId
@@ -541,7 +541,8 @@ sap.ui.define([
541
541
  if (that.oCache && that.oCache.reset) {
542
542
  that.oCache.reset();
543
543
  } else {
544
- that.fetchCache(that.oContext, false, /*bKeepQueryOptions*/true, bKeepCacheOnError);
544
+ that.fetchCache(that.oContext, false, /*bKeepQueryOptions*/true, sGroupId,
545
+ bKeepCacheOnError);
545
546
  }
546
547
 
547
548
  if (bCheckUpdate) {
@@ -1487,7 +1487,9 @@ sap.ui.define([
1487
1487
  * a PATCH request for "<parent navigation>@odata.bind". A <code>null</code> parent turns the
1488
1488
  * child into a root. The optional sibling path invokes an action for moving the (child) node
1489
1489
  * before the given sibling (or with <code>null</code> to the last sibling position) by sending
1490
- * a POST request for the "ChangeNextSiblingAction".
1490
+ * a POST request for the "ChangeNextSiblingAction". If the optional parameter
1491
+ * <code>bCopy</code> is set, it invokes an action for copying the (child) node by sending a
1492
+ * POST request for the "CopyAction".
1491
1493
  *
1492
1494
  * @param {sap.ui.model.odata.v4.lib._GroupLock} oGroupLock
1493
1495
  * A lock for the group to associate the requests with
@@ -1502,6 +1504,8 @@ sap.ui.define([
1502
1504
  * <code>sSiblingPath</code> is given
1503
1505
  * @param {boolean} [bRequestSiblingRank]
1504
1506
  * Whether to request the next sibling's rank and return its new index
1507
+ * @param {boolean} [bCopy]
1508
+ * Whether the node should be copied instead of moved
1505
1509
  * @returns {{promise : sap.ui.base.SyncPromise<function():number|number[]>, refresh : boolean}}
1506
1510
  * An object with two properties:
1507
1511
  * - <code>promise</code>: A promise which is resolved when the move is finished, or rejected
@@ -1519,12 +1523,12 @@ sap.ui.define([
1519
1523
  * @public
1520
1524
  */
1521
1525
  _AggregationCache.prototype.move = function (oGroupLock, sChildPath, sParentPath, sSiblingPath,
1522
- sNonCanonicalChildPath, bRequestSiblingRank) {
1526
+ sNonCanonicalChildPath, bRequestSiblingRank, bCopy) {
1523
1527
  let bRefreshNeeded = !this.bUnifiedCache;
1524
1528
 
1525
1529
  const sChildPredicate = sChildPath.slice(sChildPath.indexOf("("));
1526
1530
  const oChildNode = this.aElements.$byPredicate[sChildPredicate];
1527
- if (this.oTreeState.isOutOfPlace(sChildPredicate)) {
1531
+ if (!bCopy && this.oTreeState.isOutOfPlace(sChildPredicate)) {
1528
1532
  // remove OOP for all descendants (incl. itself) of a moved OOP node
1529
1533
  this.oTreeState.deleteOutOfPlace(sChildPredicate);
1530
1534
  delete oChildNode["@$ui5.context.isTransient"];
@@ -1579,6 +1583,19 @@ sap.ui.define([
1579
1583
  }
1580
1584
  };
1581
1585
 
1586
+ let oCopyActionPromise;
1587
+ if (bCopy) {
1588
+ bRefreshNeeded = true;
1589
+ oCopyActionPromise = this.oRequestor.request("POST", sChildPath + "/"
1590
+ + this.oAggregation.$Actions.CopyAction, oGroupLock.getUnlockedCopy(), {
1591
+ "If-Match" : oChildNode,
1592
+ Prefer : "return=minimal"
1593
+ }, {});
1594
+ // Note: "$-1" references the previous request. Requests with the same path could
1595
+ // possibly be merged, but it is not allowed to invoke several moves at the same time
1596
+ sChildPath = "$-1";
1597
+ }
1598
+
1582
1599
  let oPromise = SyncPromise.all([
1583
1600
  this.oRequestor.request("PATCH", sChildPath, oGroupLock, {
1584
1601
  "If-Match" : oChildNode,
@@ -1587,10 +1604,11 @@ sap.ui.define([
1587
1604
  /*fnSubmit*/null, function fnCancel() { /*nothing to do*/ }),
1588
1605
  invokeNextSibling(),
1589
1606
  this.requestRank(oChildNode, oGroupLock, bRefreshNeeded),
1590
- bRequestSiblingRank && this.requestRank(oSiblingNode, oGroupLock, true)
1607
+ bRequestSiblingRank && this.requestRank(oSiblingNode, oGroupLock, true),
1608
+ oCopyActionPromise
1591
1609
  ]);
1592
1610
 
1593
- if (bRefreshNeeded) {
1611
+ if (bRefreshNeeded) { // side-effects refresh needed
1594
1612
  oPromise = oPromise.then(([,, iRank, iSiblingRank]) => {
1595
1613
  return () => { // Note: caller MUST wait for side-effects refresh first
1596
1614
  return [
@@ -1642,7 +1660,7 @@ sap.ui.define([
1642
1660
 
1643
1661
  return [iResult, iNewIndex, iCount];
1644
1662
  });
1645
- } // else: side-effects refresh needed, nothing to do here!
1663
+ }
1646
1664
 
1647
1665
  return {promise : oPromise, refresh : bRefreshNeeded};
1648
1666
  };
@@ -294,7 +294,11 @@ sap.ui.define([
294
294
  if (iChangeSetIndex !== undefined && sUrl[0] === "$") {
295
295
  // adjust URL if it starts with a Content-ID reference by adding the change set
296
296
  // index
297
- sUrl = sUrl.replace(rContentIdReference, "$&." + iChangeSetIndex);
297
+ if (sUrl === "$-1") { // reference the previous request
298
+ sUrl = "$" + (iRequestIndex - 1) + "." + iChangeSetIndex;
299
+ } else {
300
+ sUrl = sUrl.replace(rContentIdReference, "$&." + iChangeSetIndex);
301
+ }
298
302
  }
299
303
 
300
304
  aRequestBody = aRequestBody.concat(