@openui5/sap.ui.core 1.103.1 → 1.106.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 (405) hide show
  1. package/.reuse/dep5 +35 -15
  2. package/LICENSES/LicenseRef-tzdata-PublicDomain.txt +5 -0
  3. package/THIRDPARTY.txt +64 -21
  4. package/package.json +1 -1
  5. package/src/jquery.sap.dom.js +10 -10
  6. package/src/jquery.sap.global.js +24 -216
  7. package/src/jquery.sap.history.js +1 -1
  8. package/src/jquery.sap.properties.js +2 -2
  9. package/src/jquery.sap.resources.js +1 -1
  10. package/src/jquery.sap.script.js +1 -1
  11. package/src/jquery.sap.storage.js +4 -4
  12. package/src/sap/base/i18n/ResourceBundle.js +7 -11
  13. package/src/sap/base/util/LoaderExtensions.js +69 -61
  14. package/src/sap/base/util/ObjectPath.js +1 -1
  15. package/src/sap/base/util/Properties.js +1 -1
  16. package/src/sap/base/util/fetch.js +228 -0
  17. package/src/sap/base/util/mixedFetch.js +69 -0
  18. package/src/sap/base/util/restricted/_CancelablePromise.js +1 -1
  19. package/src/sap/base/util/restricted/_castArray.js +1 -1
  20. package/src/sap/base/util/restricted/_compact.js +1 -1
  21. package/src/sap/base/util/restricted/_curry.js +1 -1
  22. package/src/sap/base/util/restricted/_debounce.js +1 -1
  23. package/src/sap/base/util/restricted/_difference.js +1 -1
  24. package/src/sap/base/util/restricted/_differenceBy.js +1 -1
  25. package/src/sap/base/util/restricted/_differenceWith.js +1 -1
  26. package/src/sap/base/util/restricted/_flatMap.js +1 -1
  27. package/src/sap/base/util/restricted/_flatMapDeep.js +1 -1
  28. package/src/sap/base/util/restricted/_flatMapDepth.js +1 -1
  29. package/src/sap/base/util/restricted/_flatten.js +1 -1
  30. package/src/sap/base/util/restricted/_flattenDeep.js +1 -1
  31. package/src/sap/base/util/restricted/_flattenDepth.js +1 -1
  32. package/src/sap/base/util/restricted/_intersection.js +1 -1
  33. package/src/sap/base/util/restricted/_intersectionBy.js +1 -1
  34. package/src/sap/base/util/restricted/_intersectionWith.js +1 -1
  35. package/src/sap/base/util/restricted/_isEqual.js +1 -1
  36. package/src/sap/base/util/restricted/_isEqualWith.js +1 -1
  37. package/src/sap/base/util/restricted/_isNil.js +1 -1
  38. package/src/sap/base/util/restricted/_max.js +1 -1
  39. package/src/sap/base/util/restricted/_merge.js +1 -1
  40. package/src/sap/base/util/restricted/_mergeWith.js +1 -1
  41. package/src/sap/base/util/restricted/_min.js +1 -1
  42. package/src/sap/base/util/restricted/_omit.js +1 -1
  43. package/src/sap/base/util/restricted/_pick.js +1 -1
  44. package/src/sap/base/util/restricted/_pickBy.js +1 -1
  45. package/src/sap/base/util/restricted/_throttle.js +1 -1
  46. package/src/sap/base/util/restricted/_toArray.js +1 -1
  47. package/src/sap/base/util/restricted/_union.js +1 -1
  48. package/src/sap/base/util/restricted/_unionBy.js +1 -1
  49. package/src/sap/base/util/restricted/_unionWith.js +1 -1
  50. package/src/sap/base/util/restricted/_uniq.js +1 -1
  51. package/src/sap/base/util/restricted/_uniqBy.js +1 -1
  52. package/src/sap/base/util/restricted/_uniqWith.js +1 -1
  53. package/src/sap/base/util/restricted/_without.js +1 -1
  54. package/src/sap/base/util/restricted/_xor.js +1 -1
  55. package/src/sap/base/util/restricted/_xorBy.js +1 -1
  56. package/src/sap/base/util/restricted/_xorWith.js +1 -1
  57. package/src/sap/base/util/restricted/_zipObject.js +1 -1
  58. package/src/sap/base/util/restricted/_zipObjectDeep.js +1 -1
  59. package/src/sap/base/util/syncFetch.js +66 -0
  60. package/src/sap/ui/Device.js +5 -5
  61. package/src/sap/ui/Global.js +7 -14
  62. package/src/sap/ui/VersionInfo.js +57 -54
  63. package/src/sap/ui/base/BindingInfo.js +198 -0
  64. package/src/sap/ui/base/DataType.js +1 -1
  65. package/src/sap/ui/base/Event.js +2 -2
  66. package/src/sap/ui/base/EventProvider.js +2 -2
  67. package/src/sap/ui/base/Interface.js +1 -1
  68. package/src/sap/ui/base/ManagedObject.js +209 -979
  69. package/src/sap/ui/base/ManagedObjectMetadata.js +6 -6
  70. package/src/sap/ui/base/ManagedObjectObserver.js +2 -2
  71. package/src/sap/ui/base/Metadata.js +1 -1
  72. package/src/sap/ui/base/Object.js +1 -1
  73. package/src/sap/ui/base/ObjectPool.js +1 -1
  74. package/src/sap/ui/core/.library +72 -50
  75. package/src/sap/ui/core/AccessKeysEnablement.js +173 -0
  76. package/src/sap/ui/core/AppCacheBuster.js +65 -51
  77. package/src/sap/ui/core/BusyIndicator.js +1 -1
  78. package/src/sap/ui/core/Component.js +52 -25
  79. package/src/sap/ui/core/ComponentContainer.js +1 -1
  80. package/src/sap/ui/core/ComponentMetadata.js +16 -23
  81. package/src/sap/ui/core/ComponentSupport.js +1 -1
  82. package/src/sap/ui/core/Configuration.js +598 -358
  83. package/src/sap/ui/core/Control.js +1 -1
  84. package/src/sap/ui/core/Core.js +126 -185
  85. package/src/sap/ui/core/CustomData.js +1 -1
  86. package/src/sap/ui/core/DeclarativeSupport.js +1 -1
  87. package/src/sap/ui/core/Element.js +68 -4
  88. package/src/sap/ui/core/ElementMetadata.js +6 -4
  89. package/src/sap/ui/core/EnabledPropagator.js +1 -1
  90. package/src/sap/ui/core/EventBus.js +1 -1
  91. package/src/sap/ui/core/ExtensionPoint.js +2 -2
  92. package/src/sap/ui/core/FocusHandler.js +84 -39
  93. package/src/sap/ui/core/Fragment.js +1 -1
  94. package/src/sap/ui/core/HTML.js +1 -1
  95. package/src/sap/ui/core/History.js +1 -1
  96. package/src/sap/ui/core/Icon.js +1 -1
  97. package/src/sap/ui/core/IconPool.js +8 -8
  98. package/src/sap/ui/core/IndicationColorSupport.js +2 -2
  99. package/src/sap/ui/core/IntervalTrigger.js +1 -1
  100. package/src/sap/ui/core/InvisibleMessage.js +1 -1
  101. package/src/sap/ui/core/InvisibleRenderer.js +1 -1
  102. package/src/sap/ui/core/InvisibleText.js +4 -1
  103. package/src/sap/ui/core/Item.js +1 -1
  104. package/src/sap/ui/core/LabelEnablement.js +1 -1
  105. package/src/sap/ui/core/LayoutData.js +1 -1
  106. package/src/sap/ui/core/ListItem.js +1 -1
  107. package/src/sap/ui/core/LocalBusyIndicator.js +1 -1
  108. package/src/sap/ui/core/Locale.js +1 -1
  109. package/src/sap/ui/core/LocaleData.js +8 -51
  110. package/src/sap/ui/core/Manifest.js +3 -5
  111. package/src/sap/ui/core/Message.js +1 -1
  112. package/src/sap/ui/core/Popup.js +13 -8
  113. package/src/sap/ui/core/RenderManager.js +17 -21
  114. package/src/sap/ui/core/Renderer.js +1 -1
  115. package/src/sap/ui/core/ResizeHandler.js +28 -49
  116. package/src/sap/ui/core/ScrollBar.js +1 -1
  117. package/src/sap/ui/core/SeparatorItem.js +1 -1
  118. package/src/sap/ui/core/Title.js +1 -1
  119. package/src/sap/ui/core/TooltipBase.js +12 -13
  120. package/src/sap/ui/core/UIArea.js +13 -12
  121. package/src/sap/ui/core/UIComponent.js +3 -3
  122. package/src/sap/ui/core/UIComponentMetadata.js +1 -1
  123. package/src/sap/ui/core/ValueStateSupport.js +2 -2
  124. package/src/sap/ui/core/VariantLayoutData.js +1 -1
  125. package/src/sap/ui/core/XMLComposite.js +5 -2
  126. package/src/sap/ui/core/XMLCompositeMetadata.js +1 -1
  127. package/src/sap/ui/core/XMLTemplateProcessor.js +7 -7
  128. package/src/sap/ui/core/_ConfigurationProvider.js +187 -0
  129. package/src/sap/ui/core/_IconRegistry.js +66 -55
  130. package/src/sap/ui/core/cache/CacheManager.js +20 -16
  131. package/src/sap/ui/core/cache/CacheManagerNOP.js +5 -2
  132. package/src/sap/ui/core/cache/LRUPersistentCache.js +15 -8
  133. package/src/sap/ui/core/cldr/en.json +0 -1
  134. package/src/sap/ui/core/cldr/es_BO.json +3 -3
  135. package/src/sap/ui/core/cldr/es_CL.json +3 -3
  136. package/src/sap/ui/core/cldr/es_MX.json +3 -3
  137. package/src/sap/ui/core/cldr/es_PE.json +3 -3
  138. package/src/sap/ui/core/cldr/es_UY.json +3 -3
  139. package/src/sap/ui/core/cldr/es_VE.json +2 -2
  140. package/src/sap/ui/core/date/Buddhist.js +15 -13
  141. package/src/sap/ui/core/date/Japanese.js +0 -6
  142. package/src/sap/ui/core/date/UniversalDate.js +144 -34
  143. package/src/sap/ui/core/delegate/ItemNavigation.js +2 -2
  144. package/src/sap/ui/core/delegate/ScrollEnablement.js +7 -6
  145. package/src/sap/ui/core/dnd/DragAndDrop.js +13 -9
  146. package/src/sap/ui/core/dnd/DragDropBase.js +1 -1
  147. package/src/sap/ui/core/dnd/DragDropInfo.js +3 -3
  148. package/src/sap/ui/core/dnd/DragInfo.js +1 -1
  149. package/src/sap/ui/core/dnd/DropInfo.js +1 -1
  150. package/src/sap/ui/core/format/DateFormat.js +36 -9
  151. package/src/sap/ui/core/format/NumberFormat.js +92 -26
  152. package/src/sap/ui/core/format/TimezoneUtil.js +2 -2
  153. package/src/sap/ui/core/hyphenation/Hyphenation.js +1 -1
  154. package/src/sap/ui/core/library.js +44 -3
  155. package/src/sap/ui/core/message/ControlMessageProcessor.js +1 -1
  156. package/src/sap/ui/core/message/Message.js +1 -1
  157. package/src/sap/ui/core/message/MessageManager.js +1 -1
  158. package/src/sap/ui/core/message/MessageParser.js +1 -1
  159. package/src/sap/ui/core/message/MessageProcessor.js +1 -1
  160. package/src/sap/ui/core/messagebundle.properties +2 -0
  161. package/src/sap/ui/core/messagebundle_ar.properties +54 -53
  162. package/src/sap/ui/core/messagebundle_bg.properties +54 -53
  163. package/src/sap/ui/core/messagebundle_ca.properties +28 -27
  164. package/src/sap/ui/core/messagebundle_cs.properties +37 -36
  165. package/src/sap/ui/core/messagebundle_cy.properties +57 -56
  166. package/src/sap/ui/core/messagebundle_da.properties +53 -52
  167. package/src/sap/ui/core/messagebundle_de.properties +54 -53
  168. package/src/sap/ui/core/messagebundle_el.properties +46 -45
  169. package/src/sap/ui/core/messagebundle_en.properties +57 -56
  170. package/src/sap/ui/core/messagebundle_en_GB.properties +57 -56
  171. package/src/sap/ui/core/messagebundle_en_US_sappsd.properties +1 -0
  172. package/src/sap/ui/core/messagebundle_en_US_saprigi.properties +1 -0
  173. package/src/sap/ui/core/messagebundle_en_US_saptrc.properties +1 -0
  174. package/src/sap/ui/core/messagebundle_es.properties +42 -41
  175. package/src/sap/ui/core/messagebundle_es_MX.properties +54 -53
  176. package/src/sap/ui/core/messagebundle_et.properties +51 -50
  177. package/src/sap/ui/core/messagebundle_fi.properties +48 -47
  178. package/src/sap/ui/core/messagebundle_fr.properties +37 -36
  179. package/src/sap/ui/core/messagebundle_fr_CA.properties +22 -21
  180. package/src/sap/ui/core/messagebundle_hi.properties +42 -41
  181. package/src/sap/ui/core/messagebundle_hr.properties +55 -54
  182. package/src/sap/ui/core/messagebundle_hu.properties +56 -55
  183. package/src/sap/ui/core/messagebundle_id.properties +55 -54
  184. package/src/sap/ui/core/messagebundle_it.properties +55 -54
  185. package/src/sap/ui/core/messagebundle_iw.properties +55 -54
  186. package/src/sap/ui/core/messagebundle_ja.properties +48 -47
  187. package/src/sap/ui/core/messagebundle_kk.properties +41 -40
  188. package/src/sap/ui/core/messagebundle_ko.properties +21 -20
  189. package/src/sap/ui/core/messagebundle_lt.properties +55 -54
  190. package/src/sap/ui/core/messagebundle_lv.properties +55 -54
  191. package/src/sap/ui/core/messagebundle_ms.properties +52 -51
  192. package/src/sap/ui/core/messagebundle_nl.properties +53 -52
  193. package/src/sap/ui/core/messagebundle_no.properties +53 -52
  194. package/src/sap/ui/core/messagebundle_pl.properties +52 -51
  195. package/src/sap/ui/core/messagebundle_pt.properties +54 -53
  196. package/src/sap/ui/core/messagebundle_pt_PT.properties +55 -54
  197. package/src/sap/ui/core/messagebundle_ro.properties +56 -55
  198. package/src/sap/ui/core/messagebundle_ru.properties +52 -51
  199. package/src/sap/ui/core/messagebundle_sh.properties +57 -56
  200. package/src/sap/ui/core/messagebundle_sk.properties +54 -53
  201. package/src/sap/ui/core/messagebundle_sl.properties +56 -55
  202. package/src/sap/ui/core/messagebundle_sv.properties +52 -51
  203. package/src/sap/ui/core/messagebundle_th.properties +25 -24
  204. package/src/sap/ui/core/messagebundle_tr.properties +56 -55
  205. package/src/sap/ui/core/messagebundle_uk.properties +55 -54
  206. package/src/sap/ui/core/messagebundle_vi.properties +56 -55
  207. package/src/sap/ui/core/messagebundle_zh_CN.properties +55 -54
  208. package/src/sap/ui/core/messagebundle_zh_TW.properties +55 -54
  209. package/src/sap/ui/core/mvc/Controller.js +17 -12
  210. package/src/sap/ui/core/mvc/HTMLView.js +1 -1
  211. package/src/sap/ui/core/mvc/JSONView.js +1 -1
  212. package/src/sap/ui/core/mvc/JSView.js +2 -2
  213. package/src/sap/ui/core/mvc/TemplateView.js +1 -1
  214. package/src/sap/ui/core/mvc/View.js +7 -7
  215. package/src/sap/ui/core/mvc/XMLView.js +1 -2
  216. package/src/sap/ui/core/plugin/DeclarativeSupport.js +1 -1
  217. package/src/sap/ui/core/plugin/LessSupport.js +16 -14
  218. package/src/sap/ui/core/plugin/TemplatingSupport.js +2 -1
  219. package/src/sap/ui/core/postmessage/Bus.js +1 -1
  220. package/src/sap/ui/core/postmessage/confirmationDialog.js +1 -1
  221. package/src/sap/ui/core/routing/Router.js +4 -4
  222. package/src/sap/ui/core/routing/async/TargetCache.js +4 -0
  223. package/src/sap/ui/core/rules/App.support.js +11 -13
  224. package/src/sap/ui/core/rules/Config.support.js +14 -14
  225. package/src/sap/ui/core/rules/CoreHelper.support.js +3 -3
  226. package/src/sap/ui/core/rules/Model.support.js +8 -8
  227. package/src/sap/ui/core/rules/Rendering.support.js +1 -1
  228. package/src/sap/ui/core/rules/Theming.support.js +8 -8
  229. package/src/sap/ui/core/rules/View.support.js +20 -13
  230. package/src/sap/ui/core/search/OpenSearchProvider.js +25 -12
  231. package/src/sap/ui/core/search/SearchProvider.js +2 -2
  232. package/src/sap/ui/core/service/Service.js +1 -1
  233. package/src/sap/ui/core/service/ServiceFactory.js +1 -1
  234. package/src/sap/ui/core/service/ServiceFactoryRegistry.js +1 -1
  235. package/src/sap/ui/core/support/Hotkeys.js +2 -3
  236. package/src/sap/ui/core/support/Plugin.js +1 -1
  237. package/src/sap/ui/core/support/Support.js +3 -4
  238. package/src/sap/ui/core/support/plugins/ControlTree.js +1 -1
  239. package/src/sap/ui/core/support/plugins/Debugging.js +4 -4
  240. package/src/sap/ui/core/support/plugins/Interaction.js +1 -1
  241. package/src/sap/ui/core/support/plugins/LocalStorage.js +1 -1
  242. package/src/sap/ui/core/support/plugins/Performance.js +1 -1
  243. package/src/sap/ui/core/support/plugins/Selector.js +1 -1
  244. package/src/sap/ui/core/support/plugins/TechInfo.js +46 -33
  245. package/src/sap/ui/core/support/plugins/Trace.js +1 -1
  246. package/src/sap/ui/core/support/plugins/ViewInfo.js +3 -4
  247. package/src/sap/ui/core/support/support.html +1 -1
  248. package/src/sap/ui/core/support/techinfo/TechnicalInfo.js +3 -3
  249. package/src/sap/ui/core/themes/base/Icon.less +4 -0
  250. package/src/sap/ui/core/themes/base/LocalBusyIndicator.less +1 -1
  251. package/src/sap/ui/core/themes/base/base.less +26 -26
  252. package/src/sap/ui/core/themes/base/fonts/SAP-icons.woff2 +0 -0
  253. package/src/sap/ui/core/themes/base/global.less +5 -1
  254. package/src/sap/ui/core/themes/base/shared.less +6 -0
  255. package/src/sap/ui/core/theming/Parameters.js +52 -53
  256. package/src/sap/ui/core/tmpl/DOMAttribute.js +1 -1
  257. package/src/sap/ui/core/tmpl/DOMElement.js +1 -1
  258. package/src/sap/ui/core/tmpl/HandlebarsTemplate.js +1 -1
  259. package/src/sap/ui/core/tmpl/Template.js +7 -5
  260. package/src/sap/ui/core/tmpl/TemplateControl.js +1 -1
  261. package/src/sap/ui/core/util/AsyncHintsHelper.js +1 -1
  262. package/src/sap/ui/core/util/Export.js +1 -1
  263. package/src/sap/ui/core/util/ExportCell.js +1 -1
  264. package/src/sap/ui/core/util/ExportColumn.js +1 -1
  265. package/src/sap/ui/core/util/ExportRow.js +1 -1
  266. package/src/sap/ui/core/util/ExportType.js +1 -1
  267. package/src/sap/ui/core/util/ExportTypeCSV.js +1 -1
  268. package/src/sap/ui/core/util/File.js +1 -1
  269. package/src/sap/ui/core/util/LibraryInfo.js +61 -42
  270. package/src/sap/ui/core/util/MockServer.js +45 -71
  271. package/src/sap/ui/core/util/PasteHelper.js +1 -1
  272. package/src/sap/ui/core/util/ResponsivePaddingsEnablement.js +4 -3
  273. package/src/sap/ui/core/util/XMLPreprocessor.js +3 -3
  274. package/src/sap/ui/core/util/reflection/BaseTreeModifier.js +1 -4
  275. package/src/sap/ui/core/util/serializer/HTMLViewSerializer.js +1 -1
  276. package/src/sap/ui/core/util/serializer/Serializer.js +1 -1
  277. package/src/sap/ui/core/util/serializer/ViewSerializer.js +1 -1
  278. package/src/sap/ui/core/util/serializer/XMLViewSerializer.js +1 -1
  279. package/src/sap/ui/core/util/serializer/delegate/Delegate.js +1 -1
  280. package/src/sap/ui/core/util/serializer/delegate/HTML.js +1 -1
  281. package/src/sap/ui/core/util/serializer/delegate/XML.js +1 -1
  282. package/src/sap/ui/core/ws/ReadyState.js +1 -1
  283. package/src/sap/ui/core/ws/SapPcpWebSocket.js +1 -1
  284. package/src/sap/ui/core/ws/WebSocket.js +1 -1
  285. package/src/sap/ui/debug/ControlTree.js +1 -1
  286. package/src/sap/ui/debug/DebugEnv.js +1 -1
  287. package/src/sap/ui/debug/PropertyList.css +1 -31
  288. package/src/sap/ui/debug/PropertyList.js +6 -240
  289. package/src/sap/ui/dom/getScrollbarSize.js +1 -1
  290. package/src/sap/ui/dom/jquery/control.js +1 -0
  291. package/src/sap/ui/events/jquery/EventSimulation.js +4 -4
  292. package/src/sap/ui/model/ClientModel.js +1 -1
  293. package/src/sap/ui/model/CompositeDataState.js +1 -1
  294. package/src/sap/ui/model/CompositeType.js +1 -1
  295. package/src/sap/ui/model/Context.js +3 -0
  296. package/src/sap/ui/model/ContextBinding.js +1 -1
  297. package/src/sap/ui/model/DataState.js +3 -3
  298. package/src/sap/ui/model/ListBinding.js +2 -2
  299. package/src/sap/ui/model/ManagedObjectBindingSupport.js +871 -0
  300. package/src/sap/ui/model/MetaModel.js +1 -1
  301. package/src/sap/ui/model/Model.js +16 -5
  302. package/src/sap/ui/model/SelectionModel.js +1 -1
  303. package/src/sap/ui/model/SimpleType.js +2 -2
  304. package/src/sap/ui/model/Sorter.js +2 -2
  305. package/src/sap/ui/model/TreeAutoExpandMode.js +1 -1
  306. package/src/sap/ui/model/Type.js +1 -1
  307. package/src/sap/ui/model/_Helper.js +3 -1
  308. package/src/sap/ui/model/analytics/odata4analytics.js +2 -2
  309. package/src/sap/ui/model/base/ManagedObjectModel.js +2 -2
  310. package/src/sap/ui/model/json/JSONModel.js +2 -2
  311. package/src/sap/ui/model/message/MessageModel.js +1 -1
  312. package/src/sap/ui/model/odata/AnnotationHelper.js +4 -4
  313. package/src/sap/ui/model/odata/ODataAnnotations.js +1 -1
  314. package/src/sap/ui/model/odata/ODataMessageParser.js +4 -4
  315. package/src/sap/ui/model/odata/ODataMetaModel.js +10 -10
  316. package/src/sap/ui/model/odata/ODataMetadata.js +6 -3
  317. package/src/sap/ui/model/odata/ODataModel.js +1 -1
  318. package/src/sap/ui/model/odata/ODataTreeBindingFlat.js +459 -268
  319. package/src/sap/ui/model/odata/type/Boolean.js +1 -1
  320. package/src/sap/ui/model/odata/type/Byte.js +1 -1
  321. package/src/sap/ui/model/odata/type/Currency.js +1 -1
  322. package/src/sap/ui/model/odata/type/Date.js +1 -1
  323. package/src/sap/ui/model/odata/type/DateTime.js +1 -1
  324. package/src/sap/ui/model/odata/type/DateTimeBase.js +1 -1
  325. package/src/sap/ui/model/odata/type/DateTimeOffset.js +1 -1
  326. package/src/sap/ui/model/odata/type/DateTimeWithTimezone.js +1 -1
  327. package/src/sap/ui/model/odata/type/Decimal.js +1 -1
  328. package/src/sap/ui/model/odata/type/Double.js +1 -1
  329. package/src/sap/ui/model/odata/type/Guid.js +1 -1
  330. package/src/sap/ui/model/odata/type/Int.js +1 -1
  331. package/src/sap/ui/model/odata/type/Int16.js +1 -1
  332. package/src/sap/ui/model/odata/type/Int32.js +1 -1
  333. package/src/sap/ui/model/odata/type/Int64.js +1 -1
  334. package/src/sap/ui/model/odata/type/ODataType.js +1 -1
  335. package/src/sap/ui/model/odata/type/Raw.js +1 -1
  336. package/src/sap/ui/model/odata/type/SByte.js +1 -1
  337. package/src/sap/ui/model/odata/type/Single.js +1 -1
  338. package/src/sap/ui/model/odata/type/Stream.js +1 -1
  339. package/src/sap/ui/model/odata/type/String.js +1 -1
  340. package/src/sap/ui/model/odata/type/Time.js +1 -1
  341. package/src/sap/ui/model/odata/type/TimeOfDay.js +1 -1
  342. package/src/sap/ui/model/odata/type/Unit.js +1 -1
  343. package/src/sap/ui/model/odata/v2/Context.js +5 -5
  344. package/src/sap/ui/model/odata/v2/ODataAnnotations.js +1 -1
  345. package/src/sap/ui/model/odata/v2/ODataContextBinding.js +5 -2
  346. package/src/sap/ui/model/odata/v2/ODataListBinding.js +26 -1
  347. package/src/sap/ui/model/odata/v2/ODataModel.js +164 -125
  348. package/src/sap/ui/model/odata/v2/ODataTreeBinding.js +18 -2
  349. package/src/sap/ui/model/odata/v4/AnnotationHelper.js +3 -3
  350. package/src/sap/ui/model/odata/v4/Context.js +169 -79
  351. package/src/sap/ui/model/odata/v4/ODataBinding.js +51 -12
  352. package/src/sap/ui/model/odata/v4/ODataContextBinding.js +111 -92
  353. package/src/sap/ui/model/odata/v4/ODataListBinding.js +206 -150
  354. package/src/sap/ui/model/odata/v4/ODataMetaModel.js +13 -10
  355. package/src/sap/ui/model/odata/v4/ODataModel.js +249 -28
  356. package/src/sap/ui/model/odata/v4/ODataParentBinding.js +33 -18
  357. package/src/sap/ui/model/odata/v4/ODataPropertyBinding.js +17 -11
  358. package/src/sap/ui/model/odata/v4/ODataUtils.js +7 -4
  359. package/src/sap/ui/model/odata/v4/lib/_AggregationCache.js +142 -35
  360. package/src/sap/ui/model/odata/v4/lib/_AggregationHelper.js +167 -16
  361. package/src/sap/ui/model/odata/v4/lib/_Cache.js +388 -188
  362. package/src/sap/ui/model/odata/v4/lib/_ConcatHelper.js +2 -3
  363. package/src/sap/ui/model/odata/v4/lib/_Helper.js +119 -43
  364. package/src/sap/ui/model/odata/v4/lib/_MinMaxHelper.js +2 -3
  365. package/src/sap/ui/model/odata/v4/lib/_Requestor.js +13 -6
  366. package/src/sap/ui/model/resource/ResourceModel.js +2 -2
  367. package/src/sap/ui/model/type/Boolean.js +1 -1
  368. package/src/sap/ui/model/type/Currency.js +2 -2
  369. package/src/sap/ui/model/type/Date.js +1 -1
  370. package/src/sap/ui/model/type/DateInterval.js +1 -1
  371. package/src/sap/ui/model/type/DateTime.js +1 -1
  372. package/src/sap/ui/model/type/DateTimeInterval.js +1 -1
  373. package/src/sap/ui/model/type/FileSize.js +1 -1
  374. package/src/sap/ui/model/type/Float.js +1 -1
  375. package/src/sap/ui/model/type/Integer.js +1 -1
  376. package/src/sap/ui/model/type/String.js +2 -2
  377. package/src/sap/ui/model/type/Time.js +1 -1
  378. package/src/sap/ui/model/type/TimeInterval.js +1 -1
  379. package/src/sap/ui/model/type/Unit.js +1 -1
  380. package/src/sap/ui/model/xml/XMLModel.js +4 -2
  381. package/src/sap/ui/performance/trace/FESR.js +27 -24
  382. package/src/sap/ui/performance/trace/Interaction.js +66 -16
  383. package/src/sap/ui/qunit/QUnitUtils.js +1 -2
  384. package/src/sap/ui/qunit/sinon-qunit-bridge.js +1 -1
  385. package/src/sap/ui/qunit/utils/ControlIterator.js +1 -1
  386. package/src/sap/ui/qunit/utils/MemoryLeakCheck.js +1 -1
  387. package/src/sap/ui/test/Opa5.js +1 -1
  388. package/src/sap/ui/test/OpaBuilder.js +1 -1
  389. package/src/sap/ui/test/TestUtils.js +35 -2
  390. package/src/sap/ui/test/actions/Press.js +7 -0
  391. package/src/sap/ui/test/generic/TestBase.js +1 -1
  392. package/src/sap/ui/test/matchers/AggregationContainsPropertyEqual.js +2 -3
  393. package/src/sap/ui/test/matchers/AggregationFilled.js +2 -3
  394. package/src/sap/ui/test/matchers/AggregationLengthEquals.js +2 -3
  395. package/src/sap/ui/test/matchers/Matcher.js +9 -11
  396. package/src/sap/ui/test/opaQunit.js +15 -9
  397. package/src/sap/ui/test/pipelines/ActionPipeline.js +2 -3
  398. package/src/sap/ui/test/pipelines/MatcherPipeline.js +2 -3
  399. package/src/sap/ui/test/pipelines/PipelineFactory.js +2 -3
  400. package/src/sap/ui/thirdparty/IPv6.js +1 -1
  401. package/src/sap/ui/thirdparty/SecondLevelDomains.js +1 -1
  402. package/src/sap/ui/thirdparty/URI.js +8 -2
  403. package/src/sap/ui/thirdparty/URITemplate.js +1 -1
  404. package/src/sap/ui/util/Storage.js +1 -1
  405. package/src/sap/ui/util/XMLHelper.js +1 -1
@@ -58,7 +58,7 @@ sap.ui.define([
58
58
  * @mixes sap.ui.model.odata.v4.ODataParentBinding
59
59
  * @public
60
60
  * @since 1.37.0
61
- * @version 1.103.1
61
+ * @version 1.106.0
62
62
  * @borrows sap.ui.model.odata.v4.ODataBinding#getGroupId as #getGroupId
63
63
  * @borrows sap.ui.model.odata.v4.ODataBinding#getRootBinding as #getRootBinding
64
64
  * @borrows sap.ui.model.odata.v4.ODataBinding#getUpdateGroupId as #getUpdateGroupId
@@ -121,10 +121,13 @@ sap.ui.define([
121
121
  // number of active (client-side) created contexts in aContexts
122
122
  this.iActiveContexts = 0;
123
123
  this.aApplicationFilters = _Helper.toArray(vFilters);
124
- this.sChangeReason = oModel.bAutoExpandSelect && !mParameters.$$aggregation
124
+ this.sChangeReason = oModel.bAutoExpandSelect && !_Helper.isDataAggregation(mParameters)
125
125
  ? "AddVirtualContext"
126
126
  : undefined;
127
+ // BEWARE: #doReplaceWith can insert a context w/ negative index, but w/o #created promise
128
+ // into aContexts' area of "created contexts"!
127
129
  this.iCreatedContexts = 0; // number of (client-side) created contexts in aContexts
130
+ this.iDeletedContexts = 0; // number of (client-side) deleted contexts
128
131
  this.oDiff = undefined;
129
132
  this.aFilters = [];
130
133
  this.sGroupId = mParameters.$$groupId;
@@ -264,7 +267,7 @@ sap.ui.define([
264
267
  * Whether not to request the new count from the server; useful in case of
265
268
  * {@link sap.ui.model.odata.v4.Context#replaceWith} where it is known that the count remains
266
269
  * unchanged; w/o a lock this should be true
267
- * @returns {Promise}
270
+ * @returns {sap.ui.base.SyncPromise}
268
271
  * A promise which is resolved without a result in case of success, or rejected with an
269
272
  * instance of <code>Error</code> in case of failure.
270
273
  * @throws {Error}
@@ -274,8 +277,10 @@ sap.ui.define([
274
277
  */
275
278
  ODataListBinding.prototype._delete = function (oGroupLock, sEditUrl, oContext, oETagEntity,
276
279
  bDoNotRequestCount) {
277
- var bDestroy,
278
- bFireChange = false,
280
+ // When deleting a context with negative index, iCreatedContexts et al. must be adjusted.
281
+ // However, when re-inserting, the context has lost its index. Beware: Do NOT use the
282
+ // created() promise, because doReplaceWith places a context w/o the promise here.
283
+ var bCreated = oContext.iIndex < 0,
279
284
  sPath = oContext.iIndex === undefined
280
285
  // context is not in aContexts -> use the predicate
281
286
  ? _Helper.getRelativePath(oContext.getPath(), this.oHeaderContext.getPath())
@@ -283,61 +288,56 @@ sap.ui.define([
283
288
  bReadCount = false,
284
289
  that = this;
285
290
 
286
- return this.deleteFromCache(oGroupLock, sEditUrl, sPath, oETagEntity, bDoNotRequestCount,
287
- function (iIndex, aEntities) {
288
- var sContextPath, sPredicate, sResolvedPath, i$skipIndex, i;
291
+ if (oGroupLock && oContext.iIndex === undefined
292
+ && this.oModel.isApiGroup(oGroupLock.getGroupId())) {
293
+ throw new Error("Cannot delete a kept-alive context in an API group when it is not in"
294
+ + " the collection");
295
+ }
289
296
 
290
- if (oContext.isKeepAlive()) {
291
- oContext.resetKeepAlive(); // ensure that it is destroyed later
292
- bDestroy = true;
293
- }
294
- if (oContext.created()) {
295
- // happens only for a created context that is not transient anymore
296
- that.destroyCreated(oContext);
297
- bFireChange = true;
298
- } else if (iIndex >= 0) {
299
- // prepare all contexts for deletion
300
- for (i = iIndex; i < that.aContexts.length; i += 1) {
301
- oContext = that.aContexts[i];
302
- if (oContext) {
303
- that.mPreviousContextsByPath[oContext.getPath()] = oContext;
304
- }
297
+ this.iDeletedContexts += 1;
298
+
299
+ return this.deleteFromCache(oGroupLock, sEditUrl, sPath, oETagEntity, bDoNotRequestCount,
300
+ function (iIndex, iOffset) {
301
+ if (iIndex !== undefined) {
302
+ // An entity can only be deleted when its key predicate is known. So we can be
303
+ // sure to have key predicates and the contexts a related to entities and not
304
+ // rows. -> Shift them and adjust the indexes
305
+ if (iOffset > 0) { // we're re-inserting
306
+ delete that.mPreviousContextsByPath[oContext.getPath()];
307
+ that.aContexts.splice(iIndex, 0, oContext);
308
+ } else { // we're deleting
309
+ that.mPreviousContextsByPath[oContext.getPath()] = oContext;
310
+ that.aContexts.splice(iIndex, 1);
311
+ oContext.iIndex = undefined;
312
+ // fire asynchronously so that multiple deletes only update the table once
313
+ Promise.resolve().then(function () {
314
+ that._fireChange({reason : ChangeReason.Remove});
315
+ });
305
316
  }
306
- sResolvedPath = that.getResolvedPath();
307
- that.aContexts.splice(iIndex, 1); // adjust the contexts array
308
- for (i = iIndex; i < that.aContexts.length; i += 1) {
309
- if (that.aContexts[i]) {
310
- i$skipIndex = i - that.iCreatedContexts;
311
- // calculate the context path and try to re-use the context for it
312
- sPredicate = _Helper.getPrivateAnnotation(aEntities[i], "predicate");
313
- sContextPath = sResolvedPath + (sPredicate || "/" + i$skipIndex);
314
- oContext = that.mPreviousContextsByPath[sContextPath];
315
- if (oContext) {
316
- delete that.mPreviousContextsByPath[sContextPath];
317
- if (oContext.iIndex === i$skipIndex) {
318
- oContext.checkUpdate(); // same row, but different data
319
- } else {
320
- oContext.iIndex = i$skipIndex; // same data, but different row
321
- }
322
- } else {
323
- oContext
324
- = Context.create(that.oModel, that, sContextPath, i$skipIndex);
325
- }
326
- that.aContexts[i] = oContext;
327
- }
317
+ if (bCreated) {
318
+ that.iCreatedContexts += iOffset;
319
+ that.iActiveContexts += iOffset;
320
+ } else {
321
+ // iMaxLength is the number of server rows w/o the created entities
322
+ that.iMaxLength += iOffset; // this doesn't change Infinity
328
323
  }
329
- that.iMaxLength -= 1; // this doesn't change Infinity
330
- bFireChange = true;
324
+ that.aContexts.forEach(function (oContext0, i) {
325
+ oContext0.iIndex = i - that.iCreatedContexts;
326
+ });
331
327
  } else if (that.bLengthFinal) {
332
328
  // a kept-alive context is not in aContexts -> read the count afterwards
333
329
  bReadCount = true;
334
330
  }
335
- // Do not destroy the context immediately to avoid timing issues with dependent
336
- // bindings, keep it in mPreviousContextsByPath to destroy it later
337
331
  }
338
332
  ).then(function () {
339
333
  var iOldMaxLength = that.iMaxLength;
340
334
 
335
+ that.iDeletedContexts -= 1;
336
+ if (!that.iDeletedContexts && !that.iCreatedContexts) {
337
+ // all (created) contexts finally gone -> free to create at any end
338
+ that.bFirstCreateAtEnd = undefined;
339
+ }
340
+ oContext.resetKeepAlive();
341
341
  if (bReadCount) {
342
342
  that.iMaxLength = that.fetchValue("$count", undefined, true).getResult()
343
343
  - that.iActiveContexts;
@@ -345,18 +345,17 @@ sap.ui.define([
345
345
  // Note: Although we know that oContext is not in aContexts, a "change" event needs
346
346
  // to be fired in order to notify the control about the new length, for example, to
347
347
  // update the 'More' button or the scrollbar.
348
- bFireChange = iOldMaxLength !== that.iMaxLength;
349
- }
350
- // Fire the change asynchronously so that Cache#delete is finished and #getContexts can
351
- // read the data synchronously. This is important for extended change detection.
352
- // Without change event there is no destroyPreviousContexts and a kept-alive context
353
- // must be destroyed here.
354
- if (bFireChange) {
355
- that._fireChange({reason : ChangeReason.Remove});
356
- } else if (bDestroy) {
357
- delete that.mPreviousContextsByPath[oContext.getPath()];
358
- oContext.destroy();
348
+ if (iOldMaxLength !== that.iMaxLength) {
349
+ that._fireChange({reason : ChangeReason.Remove});
350
+ }
359
351
  }
352
+ oContext.iIndex = Context.VIRTUAL; // prevent further cache access via this context
353
+ that.oModel.addPrerenderingTask(
354
+ that.destroyPreviousContexts.bind(that, [oContext.getPath()]));
355
+ }, function (oError) {
356
+ that.iDeletedContexts -= 1;
357
+ that._fireChange({reason : ChangeReason.Insert});
358
+ throw oError;
360
359
  });
361
360
  };
362
361
 
@@ -431,7 +430,10 @@ sap.ui.define([
431
430
  if ("$apply" in mParameters) {
432
431
  throw new Error("Cannot combine $$aggregation and $apply");
433
432
  }
434
- // Note: this validates mParameters.$$aggregation!
433
+ if (!sChangeReason) { // called from c'tor or #setAggregation
434
+ _AggregationHelper.validateAggregation(mParameters.$$aggregation, this.sPath,
435
+ this.oModel.oInterface.fetchMetadata, this.oModel.bAutoExpandSelect);
436
+ }
435
437
  sApply = _AggregationHelper.buildApply(mParameters.$$aggregation).$apply;
436
438
  }
437
439
  this.mQueryOptions = this.oModel.buildQueryOptions(mParameters, true);
@@ -558,7 +560,12 @@ sap.ui.define([
558
560
  * If a back-end request fails, the 'dataReceived' event provides an <code>Error</code> in the
559
561
  * 'error' event parameter.
560
562
  *
563
+ * Since 1.106 this event is bubbled up to the model, unless a listener calls
564
+ * {@link sap.ui.base.Event#cancelBubble oEvent.cancelBubble()}.
565
+ *
561
566
  * @param {sap.ui.base.Event} oEvent
567
+ * @param {function} oEvent.cancelBubble
568
+ * A callback function to prevent that the event is bubbled up to the model
562
569
  * @param {object} oEvent.getParameters()
563
570
  * @param {object} [oEvent.getParameters().data]
564
571
  * An empty data object if a back-end request succeeds
@@ -567,6 +574,7 @@ sap.ui.define([
567
574
  *
568
575
  * @event sap.ui.model.odata.v4.ODataListBinding#dataReceived
569
576
  * @public
577
+ * @see sap.ui.model.odata.v4.ODataModel#event:dataReceived
570
578
  * @since 1.37.0
571
579
  */
572
580
 
@@ -576,10 +584,16 @@ sap.ui.define([
576
584
  * for example to switch on a busy indicator. Registered event handlers are called without
577
585
  * parameters.
578
586
  *
587
+ * Since 1.106 this event is bubbled up to the model, unless a listener calls
588
+ * {@link sap.ui.base.Event#cancelBubble oEvent.cancelBubble()}.
589
+ *
579
590
  * @param {sap.ui.base.Event} oEvent
591
+ * @param {function} oEvent.cancelBubble
592
+ * A callback function to prevent that the event is bubbled up to the model
580
593
  *
581
594
  * @event sap.ui.model.odata.v4.ODataListBinding#dataRequested
582
595
  * @public
596
+ * @see sap.ui.model.odata.v4.ODataModel#event:dataRequested
583
597
  * @since 1.37.0
584
598
  */
585
599
 
@@ -868,7 +882,7 @@ sap.ui.define([
868
882
  return;
869
883
  }
870
884
 
871
- that.destroyCreated(oContext);
885
+ that.removeCreated(oContext);
872
886
  return Promise.resolve().then(function () {
873
887
  // Fire the change asynchronously so that Cache#delete is finished and #getContexts
874
888
  // can read the data synchronously. This is important for extended change detection.
@@ -1075,35 +1089,6 @@ sap.ui.define([
1075
1089
  ListBinding.prototype.destroy.call(this);
1076
1090
  };
1077
1091
 
1078
- /**
1079
- * Removes the given context for a created entity from the list of contexts and destroys it
1080
- * later so that the control has time to handle the context's dependent bindings before.
1081
- *
1082
- * @param {sap.ui.model.odata.v4.Context} oContext
1083
- * The context instance for the created entity to be destroyed
1084
- *
1085
- * @private
1086
- */
1087
- ODataListBinding.prototype.destroyCreated = function (oContext) {
1088
- var iIndex = oContext.getModelIndex(),
1089
- i;
1090
-
1091
- this.iCreatedContexts -= 1;
1092
- if (!oContext.isInactive()) {
1093
- this.iActiveContexts -= 1;
1094
- }
1095
- for (i = 0; i < iIndex; i += 1) {
1096
- this.aContexts[i].iIndex += 1;
1097
- }
1098
- if (!this.iCreatedContexts) {
1099
- this.bFirstCreateAtEnd = undefined;
1100
- }
1101
- this.aContexts.splice(iIndex, 1);
1102
- this.destroyLater(oContext);
1103
- // The path of all contexts in aContexts after the removed one is untouched, still points to
1104
- // the same data, hence no checkUpdate is needed.
1105
- };
1106
-
1107
1092
  /**
1108
1093
  * Destroys the given context later so that the control has time to handle the context's
1109
1094
  * dependent bindings before.
@@ -1128,9 +1113,9 @@ sap.ui.define([
1128
1113
  * Removes and destroys contexts from mPreviousContextsByPath.
1129
1114
  *
1130
1115
  * @param {string[]} [aPathsToDelete]
1131
- * If given, only contexts with paths in this list except kept-alive ones are removed and
1132
- * destroyed (transient contexts are removed only); otherwise all contexts in the list are
1133
- * removed and destroyed
1116
+ * If given, only contexts with paths in this list except kept-alive and deleted ones are
1117
+ * removed and destroyed (transient contexts are removed only); otherwise all contexts in the
1118
+ * list are removed and destroyed
1134
1119
  *
1135
1120
  * @private
1136
1121
  */
@@ -1142,7 +1127,7 @@ sap.ui.define([
1142
1127
  var oContext = mPreviousContextsByPath[sPath];
1143
1128
 
1144
1129
  if (oContext) {
1145
- if (aPathsToDelete && oContext.isKeepAlive()) {
1130
+ if (aPathsToDelete && (oContext.isKeepAlive() || oContext.isDeleted())) {
1146
1131
  oContext.iIndex = undefined;
1147
1132
  } else {
1148
1133
  if (!oContext.isTransient()) {
@@ -1224,8 +1209,7 @@ sap.ui.define([
1224
1209
  * @private
1225
1210
  */
1226
1211
  ODataListBinding.prototype.doReplaceWith = function (oOldContext, oElement, sPredicate) {
1227
- var iIndex = oOldContext.iIndex,
1228
- bKeepAlive = oOldContext.isKeepAlive(),
1212
+ var iModelIndex = oOldContext.getModelIndex(),
1229
1213
  bNew,
1230
1214
  fnOnBeforeDestroy = oOldContext.fnOnBeforeDestroy,
1231
1215
  fnOnBeforeDestroyClone,
@@ -1239,21 +1223,21 @@ sap.ui.define([
1239
1223
  if (oResult.iIndex !== undefined) {
1240
1224
  throw new Error("Unexpected index: " + oResult);
1241
1225
  }
1242
- oResult.iIndex = iIndex;
1226
+ oResult.iIndex = oOldContext.iIndex;
1243
1227
  delete this.mPreviousContextsByPath[sPath];
1244
1228
  } else {
1245
- oResult = Context.create(this.oModel, this, sPath, iIndex);
1229
+ oResult = Context.create(this.oModel, this, sPath, oOldContext.iIndex);
1246
1230
  bNew = true;
1247
1231
  }
1248
- oOldContext.iIndex = undefined;
1249
- if (iIndex === undefined) {
1232
+ if (iModelIndex === undefined) { // => oOldContext.iIndex === undefined
1250
1233
  this.mPreviousContextsByPath[sPath] = oResult;
1251
1234
  this.oCache.addKeptElement(oElement);
1252
1235
  } else {
1253
- this.aContexts[iIndex] = oResult;
1254
- this.oCache.doReplaceWith(iIndex, oElement);
1236
+ oOldContext.iIndex = undefined;
1237
+ this.aContexts[iModelIndex] = oResult;
1238
+ this.oCache.doReplaceWith(iModelIndex, oElement);
1255
1239
  }
1256
- if (bKeepAlive) {
1240
+ if (oOldContext.isKeepAlive()) {
1257
1241
  this.mPreviousContextsByPath[oOldContext.getPath()] = oOldContext;
1258
1242
  if (bNew) {
1259
1243
  if (fnOnBeforeDestroy) {
@@ -1263,7 +1247,7 @@ sap.ui.define([
1263
1247
  }
1264
1248
  oResult.setKeepAlive(true, fnOnBeforeDestroyClone);
1265
1249
  }
1266
- } else {
1250
+ } else { // Note: w/o a key predicate, oOldContext cannot be kept alive
1267
1251
  this.destroyLater(oOldContext);
1268
1252
  }
1269
1253
  this._fireChange({reason : ChangeReason.Change});
@@ -1765,9 +1749,10 @@ sap.ui.define([
1765
1749
  * If there are pending changes that cannot be ignored or if an unsupported operation mode is
1766
1750
  * used (see {@link sap.ui.model.odata.v4.ODataModel#bindList}). Since 1.97.0, pending changes
1767
1751
  * are ignored if they relate to a
1768
- * {@link sap.ui.model.odata.v4.Context#setKeepAlive kept-alive} context of this binding.
1752
+ * {@link sap.ui.model.odata.v4.Context#isKeepAlive kept-alive} context of this binding.
1769
1753
  * Since 1.98.0, {@link sap.ui.model.odata.v4.Context#isTransient transient} contexts
1770
- * of a {@link #getRootBinding root binding} do not count as pending changes.
1754
+ * of a {@link #getRootBinding root binding} do not count as pending changes. Pending
1755
+ * {@link sap.ui.model.odata.v4.Context#delete deletions} lead to an error.
1771
1756
  *
1772
1757
  * @public
1773
1758
  * @see sap.ui.model.ListBinding#filter
@@ -1782,11 +1767,16 @@ sap.ui.define([
1782
1767
  throw new Error("Operation mode has to be sap.ui.model.odata.OperationMode.Server");
1783
1768
  }
1784
1769
 
1785
- if (sFilterType === FilterType.Control && _Helper.deepEqual(aFilters, this.aFilters)
1786
- || _Helper.deepEqual(aFilters, this.aApplicationFilters)) {
1770
+ if (sFilterType === FilterType.Control
1771
+ ? _Helper.deepEqual(aFilters, this.aFilters)
1772
+ : _Helper.deepEqual(aFilters, this.aApplicationFilters)) {
1787
1773
  return this;
1788
1774
  }
1789
1775
 
1776
+ if (this.iDeletedContexts) {
1777
+ throw new Error("Cannot filter when delete requests are pending");
1778
+ }
1779
+
1790
1780
  if (this.hasPendingChanges(true)) {
1791
1781
  throw new Error("Cannot filter due to pending changes");
1792
1782
  }
@@ -1832,8 +1822,9 @@ sap.ui.define([
1832
1822
  * {@link #getCurrentContexts}, this method does not request any data from a back end and does
1833
1823
  * not change the binding's state. In contrast to {@link #getCurrentContexts}, it does not only
1834
1824
  * return those contexts that were last requested by a control, but all contexts that are
1835
- * currently available in the binding, including kept-alive contexts. To filter out kept-alive
1836
- * contexts that are not part of the list, you could check whether the index is
1825
+ * currently available in the binding, including
1826
+ * {@link sap.ui.model.odata.v4.Context#isKeepAlive kept-alive} contexts. To filter out
1827
+ * kept-alive contexts that are not part of the list, you could check whether the index is
1837
1828
  * <code>undefined</code>, as described in {@link sap.ui.model.odata.v4.Context#getIndex}.
1838
1829
  *
1839
1830
  * @returns {sap.ui.model.odata.v4.Context[]}
@@ -1960,6 +1951,7 @@ sap.ui.define([
1960
1951
  bDataRequested = false,
1961
1952
  bFireChange = false,
1962
1953
  oGroupLock,
1954
+ bPreventBubbling,
1963
1955
  oPromise,
1964
1956
  bRefreshEvent = !!this.sChangeReason, // ignored for "*VirtualContext"
1965
1957
  sResolvedPath = this.getResolvedPath(),
@@ -2014,6 +2006,7 @@ sap.ui.define([
2014
2006
  }
2015
2007
  if (!that.isRootBindingSuspended()) {
2016
2008
  // request data (before removing virtual context), but avoid E.C.D.
2009
+ // (see BCP: 2270085692 for some interesting discussions)
2017
2010
  that.bUseExtendedChangeDetection = false;
2018
2011
  that.getContexts(iStart, iLength, iMaximumPrefetchSize);
2019
2012
  that.bUseExtendedChangeDetection = bOld;
@@ -2050,14 +2043,15 @@ sap.ui.define([
2050
2043
  oGroupLock = this.oReadGroupLock;
2051
2044
  this.oReadGroupLock = undefined;
2052
2045
  if (!this.oDiff) { // w/o E.C.D there won't be a diff
2046
+ // before fetchContexts needing it and resolveRefreshPromise destroying it
2047
+ bPreventBubbling = this.isRefreshWithoutBubbling();
2053
2048
  // make sure "refresh" is followed by async "change"
2054
2049
  oPromise = this.fetchContexts(iStart, iLength, iMaximumPrefetchSize, oGroupLock,
2055
2050
  /*bAsync*/bRefreshEvent, function () {
2056
2051
  bDataRequested = true;
2057
- that.fireDataRequested();
2052
+ that.fireDataRequested(bPreventBubbling);
2058
2053
  });
2059
- this.resolveRefreshPromise(oPromise);
2060
- oPromise.then(function (bChanged) {
2054
+ this.resolveRefreshPromise(oPromise).then(function (bChanged) {
2061
2055
  if (that.bUseExtendedChangeDetection) {
2062
2056
  that.oDiff = {
2063
2057
  aDiff : that.getDiff(iLength),
@@ -2072,12 +2066,13 @@ sap.ui.define([
2072
2066
  }
2073
2067
  }
2074
2068
  if (bDataRequested) {
2075
- that.fireDataReceived({data : {}});
2069
+ that.fireDataReceived({data : {}}, bPreventBubbling);
2076
2070
  }
2077
2071
  }, function (oError) {
2078
2072
  // cache shares promises for concurrent read
2079
2073
  if (bDataRequested) {
2080
- that.fireDataReceived(oError.canceled ? {data : {}} : {error : oError});
2074
+ that.fireDataReceived(oError.canceled ? {data : {}} : {error : oError},
2075
+ bPreventBubbling);
2081
2076
  }
2082
2077
  throw oError;
2083
2078
  }).catch(function (oError) {
@@ -2373,7 +2368,7 @@ sap.ui.define([
2373
2368
  /**
2374
2369
  * Returns the header context which allows binding to <code>$count</code>.
2375
2370
  *
2376
- * @returns {sap.ui.model.odata.v4.Context}
2371
+ * @returns {sap.ui.model.odata.v4.Context|null}
2377
2372
  * The header context or <code>null</code> if the binding is relative and has no context
2378
2373
  *
2379
2374
  * @public
@@ -2724,6 +2719,10 @@ sap.ui.define([
2724
2719
  });
2725
2720
  }
2726
2721
 
2722
+ if (this.iDeletedContexts) {
2723
+ throw new Error("Cannot refresh when delete requests are pending");
2724
+ }
2725
+
2727
2726
  if (this.isRootBindingSuspended()) {
2728
2727
  // Note: side-effects (incl. refresh) are forbidden while suspended
2729
2728
  this.refreshSuspended(sGroupId);
@@ -2746,7 +2745,9 @@ sap.ui.define([
2746
2745
  bKeepCacheOnError ? sGroupId : undefined);
2747
2746
  oKeptElementsPromise = that.refreshKeptElements(sGroupId);
2748
2747
  if (that.iCurrentEnd > 0) {
2749
- oPromise = that.createRefreshPromise().catch(function (oError) {
2748
+ oPromise = that.createRefreshPromise(
2749
+ /*bPreventBubbling*/bKeepCacheOnError
2750
+ ).catch(function (oError) {
2750
2751
  if (!bKeepCacheOnError || oError.canceled) {
2751
2752
  throw oError;
2752
2753
  }
@@ -2781,8 +2782,8 @@ sap.ui.define([
2781
2782
  }
2782
2783
  // Note: after reset the dependent bindings cannot be found any more
2783
2784
  aDependentBindings = that.getDependentBindings();
2784
- // this may reset that.oRefreshPromise
2785
- that.reset(ChangeReason.Refresh, bKeepCacheOnError ? false : undefined, sGroupId);
2785
+ that.reset(ChangeReason.Refresh, !oCache || (bKeepCacheOnError ? false : undefined),
2786
+ sGroupId); // this may reset that.oRefreshPromise
2786
2787
  return SyncPromise.all(
2787
2788
  refreshAll(aDependentBindings).concat(oPromise, oKeptElementsPromise)
2788
2789
  ).then(function () {
@@ -2815,7 +2816,7 @@ sap.ui.define([
2815
2816
  that.mPreviousContextsByPath[that.getResolvedPath() + sPredicate]
2816
2817
  .resetKeepAlive();
2817
2818
  } else { // Note: implies oContext.created()
2818
- that.destroyCreated(that.aContexts[iIndex]);
2819
+ that.removeCreated(that.aContexts[iIndex]);
2819
2820
  }
2820
2821
  });
2821
2822
  }).catch(function (oError) {
@@ -2839,8 +2840,9 @@ sap.ui.define([
2839
2840
  * destroyed, see {@link sap.ui.model.Context#destroy}.
2840
2841
  * Supported since 1.55.0
2841
2842
  *
2842
- * A removed context is destroyed unless it is kept alive
2843
- * (see {@link sap.ui.model.odata.v4.Context#isKeepAlive}) and still exists on the server.
2843
+ * A removed context is destroyed unless it is
2844
+ * {@link sap.ui.model.odata.v4.Context#isKeepAlive kept alive} and still exists on the
2845
+ * server.
2844
2846
  * @returns {sap.ui.base.SyncPromise}
2845
2847
  * A promise which resolves without a defined value when the entity is updated in the cache,
2846
2848
  * or rejects if the refresh failed.
@@ -2891,8 +2893,8 @@ sap.ui.define([
2891
2893
  var iIndex = oContext.getModelIndex(),
2892
2894
  i;
2893
2895
 
2894
- if (oContext.created()) {
2895
- that.destroyCreated(oContext);
2896
+ if (oContext.iIndex < 0) {
2897
+ that.removeCreated(oContext);
2896
2898
  bDestroyed = true;
2897
2899
  } else {
2898
2900
  if (iIndex === undefined) { // -> bStillAlive === false
@@ -2965,6 +2967,38 @@ sap.ui.define([
2965
2967
  });
2966
2968
  };
2967
2969
 
2970
+ /**
2971
+ * Removes the given context for a created entity from the list of contexts and - unless it is
2972
+ * kept alive - destroys it later so that the control has time to handle the context's dependent
2973
+ * bindings before.
2974
+ *
2975
+ * @param {sap.ui.model.odata.v4.Context} oContext
2976
+ * The context instance for the created entity to be destroyed
2977
+ *
2978
+ * @private
2979
+ */
2980
+ ODataListBinding.prototype.removeCreated = function (oContext) {
2981
+ var iIndex = oContext.getModelIndex(),
2982
+ i;
2983
+
2984
+ this.iCreatedContexts -= 1;
2985
+ if (!oContext.isInactive()) {
2986
+ this.iActiveContexts -= 1;
2987
+ }
2988
+ for (i = 0; i < iIndex; i += 1) {
2989
+ this.aContexts[i].iIndex += 1;
2990
+ }
2991
+ if (!this.iCreatedContexts) {
2992
+ this.bFirstCreateAtEnd = undefined;
2993
+ }
2994
+ this.aContexts.splice(iIndex, 1);
2995
+ if (!oContext.isKeepAlive()) {
2996
+ this.destroyLater(oContext);
2997
+ }
2998
+ // The path of all contexts in aContexts after the removed one is untouched, still points to
2999
+ // the same data, hence no checkUpdate is needed.
3000
+ };
3001
+
2968
3002
  /**
2969
3003
  * Requests the entities for the given index range of the binding's collection and resolves with
2970
3004
  * the corresponding contexts.
@@ -3056,7 +3090,7 @@ sap.ui.define([
3056
3090
  * A callback function to filter only relevant messages. The callback returns whether the
3057
3091
  * given {@link sap.ui.core.message.Message} is considered. If no callback function is given,
3058
3092
  * all messages are considered.
3059
- * @returns {Promise<sap.ui.model.Filter>}
3093
+ * @returns {Promise<sap.ui.model.Filter|null>}
3060
3094
  * A Promise that resolves with a {@link sap.ui.model.Filter} representing the entries with
3061
3095
  * messages; it resolves with <code>null</code> if the binding is not resolved or if there is
3062
3096
  * no message for any entry
@@ -3114,9 +3148,6 @@ sap.ui.define([
3114
3148
  var aContexts,
3115
3149
  bMissingPredicate,
3116
3150
  oModel = this.oModel,
3117
- // Hash set of collection-valued navigation property meta paths (relative to the cache's
3118
- // root) which need to be refreshed, maps string to <code>true</code>
3119
- mNavigationPropertyPaths = {},
3120
3151
  aPredicates,
3121
3152
  aPromises,
3122
3153
  // since this is called from a context or a parent binding, the binding is resolved
@@ -3159,7 +3190,7 @@ sap.ui.define([
3159
3190
  aContexts = [oContext];
3160
3191
  } else {
3161
3192
  aContexts = this.getCurrentContexts().filter(function (oContext0) {
3162
- return !oContext0.isTransient();
3193
+ return oContext0 && !oContext0.isTransient();
3163
3194
  });
3164
3195
  // add kept-alive contexts outside collection
3165
3196
  Object.keys(this.mPreviousContextsByPath).forEach(function (sPath) {
@@ -3178,11 +3209,10 @@ sap.ui.define([
3178
3209
  });
3179
3210
  if (!bMissingPredicate) {
3180
3211
  aPromises = this.oCache
3181
- ? [this.oCache.requestSideEffects(this.lockGroup(sGroupId),
3182
- aPaths, mNavigationPropertyPaths, aPredicates, bSingle)]
3212
+ ? [this.oCache.requestSideEffects(this.lockGroup(sGroupId), aPaths, aPredicates,
3213
+ bSingle)]
3183
3214
  : []; // can happen if invoked via absolute side effect
3184
- this.visitSideEffects(sGroupId, aPaths, bSingle ? oContext : undefined,
3185
- mNavigationPropertyPaths, aPromises);
3215
+ this.visitSideEffects(sGroupId, aPaths, bSingle ? oContext : undefined, aPromises);
3186
3216
 
3187
3217
  return SyncPromise.all(aPromises.map(reportError)).then(function () {
3188
3218
  return that.refreshDependentListBindingsWithoutCache();
@@ -3367,7 +3397,7 @@ sap.ui.define([
3367
3397
  *
3368
3398
  * @param {object} [oAggregation]
3369
3399
  * An object holding the information needed for data aggregation; see also
3370
- * <a href="http://docs.oasis-open.org/odata/odata-data-aggregation-ext/v4.0/">OData
3400
+ * <a href="https://docs.oasis-open.org/odata/odata-data-aggregation-ext/v4.0/">OData
3371
3401
  * Extension for Data Aggregation Version 4.0</a>. Since 1.76.0, <code>undefined</code> can be
3372
3402
  * used to remove the data aggregation object, which allows to set <code>$apply</code>
3373
3403
  * explicitly afterwards. <code>null</code> is not supported.<br>
@@ -3375,7 +3405,11 @@ sap.ui.define([
3375
3405
  * used to turn on the handling of grand totals like in 1.84.0, using aggregates of aggregates
3376
3406
  * and thus allowing to filter by aggregated properties while grand totals are needed. Beware
3377
3407
  * that methods like "average" or "countdistinct" are not compatible with this approach, and
3378
- * it cannot be combined with group levels.
3408
+ * it cannot be combined with group levels.<br>
3409
+ * Since 1.105.0, either a recursive hierarchy or pure data aggregation is supported, but no
3410
+ * mix; <code>hierarchyQualifier</code> is the leading property that decides between those two
3411
+ * use cases - this is an <b>experimental API</b> and is only supported if the model uses the
3412
+ * <code>autoExpandSelect</code> parameter!
3379
3413
  * @param {object} [oAggregation.aggregate]
3380
3414
  * A map from aggregatable property names or aliases to objects containing the following
3381
3415
  * details:
@@ -3397,6 +3431,9 @@ sap.ui.define([
3397
3431
  * there is only one, or <code>null</code> otherwise ("multi-unit situation"). (SQL
3398
3432
  * suggestion: <code>CASE WHEN MIN(Unit) = MAX(Unit) THEN MIN(Unit) END</code>)
3399
3433
  * </ul>
3434
+ * @param {number} [oAggregation.expandTo=1]
3435
+ * The number of initially expanded levels as a positive integer (@experimental as of version
3436
+ * 1.105.0), supported only if a <code>hierarchyQualifier</code> is given.
3400
3437
  * @param {boolean} [oAggregation.grandTotalAtBottomOnly]
3401
3438
  * Tells whether the grand totals for aggregatable properties are displayed at the bottom only
3402
3439
  * (since 1.86.0); <code>true</code> for bottom only, <code>false</code> for top and bottom,
@@ -3414,10 +3451,17 @@ sap.ui.define([
3414
3451
  * A list of groupable property names used to determine group levels. They may, but don't need
3415
3452
  * to, be repeated in <code>oAggregation.group</code>. Group levels cannot be combined with
3416
3453
  * filtering for aggregated properties or (since 1.93.0) with "$search".
3454
+ * @param {string} [oAggregation.hierarchyQualifier]
3455
+ * The qualifier for the pair of "Org.OData.Aggregation.V1.RecursiveHierarchy" and
3456
+ * "com.sap.vocabularies.Hierarchy.v1.RecursiveHierarchy" annotations at this binding's
3457
+ * entity type (@experimental as of version 1.105.0). If present, a recursive hierarchy
3458
+ * without data aggregation is defined, and the only other supported properties are
3459
+ * <code>expandTo</code> and <code>search</code>. A recursive hierarchy cannot be combined
3460
+ * with "$search".
3417
3461
  * @param {string} [oAggregation.search]
3418
- * Like the <a
3419
- * href="https://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part2-url-conventions.html">
3420
- * "5.1.7 System Query Option $search"</a>, but applied before data aggregation
3462
+ * Like the <a href=
3463
+ * "https://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part2-url-conventions.html#_Search_System_Query"
3464
+ * >"5.1.7 System Query Option $search"</a>, but applied before data aggregation
3421
3465
  * (since 1.93.0). Note that certain content will break the syntax of the system query option
3422
3466
  * <code>$apply</code> and result in an invalid request. If the OData service supports the
3423
3467
  * proposal <a href="https://issues.oasis-open.org/browse/ODATA-1452">ODATA-1452</a>, then
@@ -3433,8 +3477,11 @@ sap.ui.define([
3433
3477
  * <ul>
3434
3478
  * <li> the given data aggregation object is unsupported,
3435
3479
  * <li> the <code>$apply</code> system query option has been specified explicitly before,
3436
- * <li> the binding has a kept-alive context,
3437
- * <li> there are pending changes
3480
+ * <li> the binding has a {@link sap.ui.model.odata.v4.Context#isKeepAlive kept-alive}
3481
+ * context,
3482
+ * <li> there are pending changes,
3483
+ * <li> a recursive hierarchy is requested, but the model does not use the
3484
+ * <code>autoExpandSelect</code> parameter.
3438
3485
  * </ul>
3439
3486
  * @example <caption>First group level is product category including subtotals for the net
3440
3487
  * amount in display currency. On leaf level, transaction currency is used as an additional
@@ -3566,13 +3613,18 @@ sap.ui.define([
3566
3613
  * the dynamic sorters.
3567
3614
  * @returns {this}
3568
3615
  * <code>this</code> to facilitate method chaining
3569
- * @throws {Error}
3570
- * If there are pending changes that cannot be ignored or if an unsupported operation mode is
3571
- * used (see {@link sap.ui.model.odata.v4.ODataModel#bindList}). Since 1.97.0, pending changes
3572
- * are ignored if they relate to a
3573
- * {@link sap.ui.model.odata.v4.Context#setKeepAlive kept-alive} context of this binding.
3574
- * Since 1.98.0, {@link sap.ui.model.odata.v4.Context#isTransient transient} contexts
3575
- * of a {@link #getRootBinding root binding} do not count as pending changes.
3616
+ * @throws {Error} If
3617
+ * <ul>
3618
+ * <li> there are pending changes that cannot be ignored,
3619
+ * <li> an unsupported operation mode is used (see
3620
+ * {@link sap.ui.model.odata.v4.ODataModel#bindList}). Since 1.97.0, pending changes are
3621
+ * ignored if they relate to a
3622
+ * {@link sap.ui.model.odata.v4.Context#isKeepAlive kept-alive} context of this binding.
3623
+ * Since 1.98.0, {@link sap.ui.model.odata.v4.Context#isTransient transient} contexts of a
3624
+ * {@link #getRootBinding root binding} do not count as pending changes.
3625
+ * <li> contexts are {@link sap.ui.model.data.v4.Context#delete deleted} on the client, but
3626
+ * the server request has not finished yet.
3627
+ * </ul>
3576
3628
  *
3577
3629
  * @public
3578
3630
  * @see sap.ui.model.ListBinding#sort
@@ -3590,6 +3642,10 @@ sap.ui.define([
3590
3642
  return this;
3591
3643
  }
3592
3644
 
3645
+ if (this.iDeletedContexts) {
3646
+ throw new Error("Cannot sort when delete requests are pending");
3647
+ }
3648
+
3593
3649
  if (this.hasPendingChanges(true)) {
3594
3650
  throw new Error("Cannot sort due to pending changes");
3595
3651
  }
@@ -3624,8 +3680,8 @@ sap.ui.define([
3624
3680
  *
3625
3681
  * @param {object[]} aAggregation
3626
3682
  * An array with objects holding the information needed for data aggregation; see also
3627
- * <a href="http://docs.oasis-open.org/odata/odata-data-aggregation-ext/v4.0/">OData Extension
3628
- * for Data Aggregation Version 4.0</a>
3683
+ * <a href="https://docs.oasis-open.org/odata/odata-data-aggregation-ext/v4.0/">OData
3684
+ * Extension for Data Aggregation Version 4.0</a>
3629
3685
  * @param {string} aAggregation[].name
3630
3686
  * The name of an OData property. A property which is neither a dimension nor a measure, but
3631
3687
  * for instance a text property or in some cases a unit property, has no further details.