@openui5/sap.ui.core 1.98.0 → 1.101.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 (418) hide show
  1. package/.eslintrc.json +33 -1
  2. package/THIRDPARTY.txt +6 -6
  3. package/package.json +1 -1
  4. package/src/jquery.sap.global.js +6 -3
  5. package/src/jquery.sap.mobile.js +29 -11
  6. package/src/jquery.sap.properties.js +1 -1
  7. package/src/jquery.sap.resources.js +1 -1
  8. package/src/jquery.sap.script.js +1 -1
  9. package/src/jquery.sap.storage.js +3 -3
  10. package/src/sap/base/Log.js +1 -1
  11. package/src/sap/base/strings/whitespaceReplacer.js +1 -1
  12. package/src/sap/base/util/LoaderExtensions.js +1 -10
  13. package/src/sap/base/util/UriParameters.js +2 -2
  14. package/src/sap/base/util/restricted/_CancelablePromise.js +1 -1
  15. package/src/sap/base/util/restricted/_castArray.js +1 -1
  16. package/src/sap/base/util/restricted/_compact.js +1 -1
  17. package/src/sap/base/util/restricted/_curry.js +1 -1
  18. package/src/sap/base/util/restricted/_debounce.js +1 -1
  19. package/src/sap/base/util/restricted/_difference.js +1 -1
  20. package/src/sap/base/util/restricted/_differenceBy.js +1 -1
  21. package/src/sap/base/util/restricted/_differenceWith.js +1 -1
  22. package/src/sap/base/util/restricted/_flatMap.js +1 -1
  23. package/src/sap/base/util/restricted/_flatMapDeep.js +1 -1
  24. package/src/sap/base/util/restricted/_flatMapDepth.js +1 -1
  25. package/src/sap/base/util/restricted/_flatten.js +1 -1
  26. package/src/sap/base/util/restricted/_flattenDeep.js +1 -1
  27. package/src/sap/base/util/restricted/_flattenDepth.js +1 -1
  28. package/src/sap/base/util/restricted/_intersection.js +1 -1
  29. package/src/sap/base/util/restricted/_intersectionBy.js +1 -1
  30. package/src/sap/base/util/restricted/_intersectionWith.js +1 -1
  31. package/src/sap/base/util/restricted/_isEqual.js +1 -1
  32. package/src/sap/base/util/restricted/_isEqualWith.js +1 -1
  33. package/src/sap/base/util/restricted/_isNil.js +1 -1
  34. package/src/sap/base/util/restricted/_max.js +1 -1
  35. package/src/sap/base/util/restricted/_merge.js +1 -1
  36. package/src/sap/base/util/restricted/_mergeWith.js +1 -1
  37. package/src/sap/base/util/restricted/_min.js +1 -1
  38. package/src/sap/base/util/restricted/_omit.js +1 -1
  39. package/src/sap/base/util/restricted/_pick.js +1 -1
  40. package/src/sap/base/util/restricted/_pickBy.js +1 -1
  41. package/src/sap/base/util/restricted/_throttle.js +1 -1
  42. package/src/sap/base/util/restricted/_toArray.js +1 -1
  43. package/src/sap/base/util/restricted/_union.js +1 -1
  44. package/src/sap/base/util/restricted/_unionBy.js +1 -1
  45. package/src/sap/base/util/restricted/_unionWith.js +1 -1
  46. package/src/sap/base/util/restricted/_uniq.js +1 -1
  47. package/src/sap/base/util/restricted/_uniqBy.js +1 -1
  48. package/src/sap/base/util/restricted/_uniqWith.js +1 -1
  49. package/src/sap/base/util/restricted/_without.js +1 -1
  50. package/src/sap/base/util/restricted/_xor.js +1 -1
  51. package/src/sap/base/util/restricted/_xorBy.js +1 -1
  52. package/src/sap/base/util/restricted/_xorWith.js +1 -1
  53. package/src/sap/base/util/restricted/_zipObject.js +1 -1
  54. package/src/sap/base/util/restricted/_zipObjectDeep.js +1 -1
  55. package/src/sap/ui/Device.js +3 -3
  56. package/src/sap/ui/Global.js +4 -4
  57. package/src/sap/ui/VersionInfo.js +13 -10
  58. package/src/sap/ui/base/BindingParser.js +34 -7
  59. package/src/sap/ui/base/Event.js +1 -1
  60. package/src/sap/ui/base/EventProvider.js +2 -2
  61. package/src/sap/ui/base/ExpressionParser.js +1 -1
  62. package/src/sap/ui/base/Interface.js +1 -1
  63. package/src/sap/ui/base/ManagedObject.js +32 -22
  64. package/src/sap/ui/base/ManagedObjectMetadata.js +1 -1
  65. package/src/sap/ui/base/ManagedObjectObserver.js +2 -0
  66. package/src/sap/ui/base/ManagedObjectRegistry.js +10 -5
  67. package/src/sap/ui/base/Metadata.js +1 -1
  68. package/src/sap/ui/base/Object.js +1 -1
  69. package/src/sap/ui/base/ObjectPool.js +1 -1
  70. package/src/sap/ui/core/.library +2 -2
  71. package/src/sap/ui/core/BusyIndicator.js +1 -1
  72. package/src/sap/ui/core/Component.js +24 -20
  73. package/src/sap/ui/core/ComponentContainer.js +1 -1
  74. package/src/sap/ui/core/ComponentMetadata.js +2 -2
  75. package/src/sap/ui/core/ComponentSupport.js +1 -1
  76. package/src/sap/ui/core/Configuration.js +80 -11
  77. package/src/sap/ui/core/Control.js +2 -1
  78. package/src/sap/ui/core/Core.js +29 -12
  79. package/src/sap/ui/core/CustomData.js +1 -1
  80. package/src/sap/ui/core/DeclarativeSupport.js +1 -1
  81. package/src/sap/ui/core/Element.js +4 -7
  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/ExtensionPoint.js +6 -1
  86. package/src/sap/ui/core/FocusHandler.js +1 -1
  87. package/src/sap/ui/core/Fragment.js +1 -1
  88. package/src/sap/ui/core/HTML.js +1 -1
  89. package/src/sap/ui/core/HTMLRenderer.js +1 -1
  90. package/src/sap/ui/core/History.js +1 -1
  91. package/src/sap/ui/core/Icon.js +17 -3
  92. package/src/sap/ui/core/IconRenderer.js +1 -1
  93. package/src/sap/ui/core/IndicationColorSupport.js +1 -1
  94. package/src/sap/ui/core/IntervalTrigger.js +1 -1
  95. package/src/sap/ui/core/InvisibleMessage.js +1 -1
  96. package/src/sap/ui/core/InvisibleRenderer.js +1 -1
  97. package/src/sap/ui/core/InvisibleText.js +1 -1
  98. package/src/sap/ui/core/Item.js +1 -1
  99. package/src/sap/ui/core/LabelEnablement.js +9 -2
  100. package/src/sap/ui/core/LayoutData.js +1 -1
  101. package/src/sap/ui/core/ListItem.js +1 -1
  102. package/src/sap/ui/core/LocalBusyIndicator.js +1 -1
  103. package/src/sap/ui/core/LocalBusyIndicatorRenderer.js +2 -2
  104. package/src/sap/ui/core/Locale.js +1 -1
  105. package/src/sap/ui/core/LocaleData.js +73 -6
  106. package/src/sap/ui/core/Manifest.js +5 -3
  107. package/src/sap/ui/core/Message.js +1 -1
  108. package/src/sap/ui/core/Patcher.js +6 -4
  109. package/src/sap/ui/core/Popup.js +11 -8
  110. package/src/sap/ui/core/RenderManager.js +1 -1
  111. package/src/sap/ui/core/Renderer.js +1 -1
  112. package/src/sap/ui/core/ResizeHandler.js +1 -1
  113. package/src/sap/ui/core/ScrollBar.js +1 -1
  114. package/src/sap/ui/core/ScrollBarRenderer.js +1 -1
  115. package/src/sap/ui/core/SeparatorItem.js +1 -1
  116. package/src/sap/ui/core/Title.js +1 -1
  117. package/src/sap/ui/core/TooltipBase.js +1 -1
  118. package/src/sap/ui/core/UIArea.js +1 -1
  119. package/src/sap/ui/core/UIComponent.js +1 -1
  120. package/src/sap/ui/core/UIComponentMetadata.js +1 -1
  121. package/src/sap/ui/core/ValueStateSupport.js +1 -1
  122. package/src/sap/ui/core/VariantLayoutData.js +1 -1
  123. package/src/sap/ui/core/XMLComposite.js +1 -1
  124. package/src/sap/ui/core/XMLCompositeMetadata.js +1 -1
  125. package/src/sap/ui/core/XMLTemplateProcessor.js +27 -26
  126. package/src/sap/ui/core/_IconRegistry.js +13 -3
  127. package/src/sap/ui/core/cache/CacheManager.js +1 -1
  128. package/src/sap/ui/core/cache/LRUPersistentCache.js +2 -1
  129. package/src/sap/ui/core/cldr/en_AU.json +1 -1
  130. package/src/sap/ui/core/date/Buddhist.js +3 -3
  131. package/src/sap/ui/core/date/Japanese.js +4 -4
  132. package/src/sap/ui/core/date/UniversalDate.js +10 -0
  133. package/src/sap/ui/core/date/UniversalDateUtils.js +49 -49
  134. package/src/sap/ui/core/delegate/ItemNavigation.js +1 -1
  135. package/src/sap/ui/core/delegate/ScrollEnablement.js +9 -6
  136. package/src/sap/ui/core/dnd/DragAndDrop.js +27 -22
  137. package/src/sap/ui/core/dnd/DragDropBase.js +1 -2
  138. package/src/sap/ui/core/dnd/DragDropInfo.js +1 -1
  139. package/src/sap/ui/core/dnd/DragInfo.js +1 -1
  140. package/src/sap/ui/core/dnd/DropInfo.js +3 -3
  141. package/src/sap/ui/core/format/DateFormat.js +670 -199
  142. package/src/sap/ui/core/format/DateFormatTimezoneDisplay.js +47 -0
  143. package/src/sap/ui/core/format/ListFormat.js +2 -2
  144. package/src/sap/ui/core/format/NumberFormat.js +502 -216
  145. package/src/sap/ui/core/format/TimezoneUtil.js +248 -0
  146. package/src/sap/ui/core/hyphenation/Hyphenation.js +1 -1
  147. package/src/sap/ui/core/library.js +220 -189
  148. package/src/sap/ui/core/message/ControlMessageProcessor.js +1 -1
  149. package/src/sap/ui/core/message/Message.js +1 -1
  150. package/src/sap/ui/core/message/MessageManager.js +1 -1
  151. package/src/sap/ui/core/message/MessageParser.js +1 -1
  152. package/src/sap/ui/core/message/MessageProcessor.js +1 -1
  153. package/src/sap/ui/core/messagebundle.properties +2 -0
  154. package/src/sap/ui/core/messagebundle_ar.properties +1 -0
  155. package/src/sap/ui/core/messagebundle_bg.properties +6 -5
  156. package/src/sap/ui/core/messagebundle_ca.properties +1 -0
  157. package/src/sap/ui/core/messagebundle_cs.properties +1 -0
  158. package/src/sap/ui/core/messagebundle_cy.properties +1 -0
  159. package/src/sap/ui/core/messagebundle_da.properties +1 -0
  160. package/src/sap/ui/core/messagebundle_de.properties +2 -1
  161. package/src/sap/ui/core/messagebundle_el.properties +1 -0
  162. package/src/sap/ui/core/messagebundle_en.properties +1 -0
  163. package/src/sap/ui/core/messagebundle_en_GB.properties +1 -0
  164. package/src/sap/ui/core/messagebundle_en_US_sappsd.properties +1 -0
  165. package/src/sap/ui/core/messagebundle_en_US_saprigi.properties +1 -0
  166. package/src/sap/ui/core/messagebundle_en_US_saptrc.properties +1 -0
  167. package/src/sap/ui/core/messagebundle_es.properties +1 -0
  168. package/src/sap/ui/core/messagebundle_es_MX.properties +1 -0
  169. package/src/sap/ui/core/messagebundle_et.properties +1 -0
  170. package/src/sap/ui/core/messagebundle_fi.properties +1 -0
  171. package/src/sap/ui/core/messagebundle_fr.properties +1 -0
  172. package/src/sap/ui/core/messagebundle_fr_CA.properties +1 -0
  173. package/src/sap/ui/core/messagebundle_hi.properties +1 -0
  174. package/src/sap/ui/core/messagebundle_hr.properties +1 -0
  175. package/src/sap/ui/core/messagebundle_hu.properties +1 -0
  176. package/src/sap/ui/core/messagebundle_id.properties +3 -2
  177. package/src/sap/ui/core/messagebundle_it.properties +1 -0
  178. package/src/sap/ui/core/messagebundle_iw.properties +1 -0
  179. package/src/sap/ui/core/messagebundle_ja.properties +1 -0
  180. package/src/sap/ui/core/messagebundle_kk.properties +1 -0
  181. package/src/sap/ui/core/messagebundle_ko.properties +2 -1
  182. package/src/sap/ui/core/messagebundle_lt.properties +1 -0
  183. package/src/sap/ui/core/messagebundle_lv.properties +2 -1
  184. package/src/sap/ui/core/messagebundle_ms.properties +1 -0
  185. package/src/sap/ui/core/messagebundle_nl.properties +1 -0
  186. package/src/sap/ui/core/messagebundle_no.properties +1 -0
  187. package/src/sap/ui/core/messagebundle_pl.properties +1 -0
  188. package/src/sap/ui/core/messagebundle_pt.properties +1 -0
  189. package/src/sap/ui/core/messagebundle_pt_PT.properties +1 -0
  190. package/src/sap/ui/core/messagebundle_ro.properties +1 -0
  191. package/src/sap/ui/core/messagebundle_ru.properties +1 -0
  192. package/src/sap/ui/core/messagebundle_sh.properties +1 -0
  193. package/src/sap/ui/core/messagebundle_sk.properties +1 -0
  194. package/src/sap/ui/core/messagebundle_sl.properties +1 -0
  195. package/src/sap/ui/core/messagebundle_sv.properties +1 -0
  196. package/src/sap/ui/core/messagebundle_th.properties +1 -0
  197. package/src/sap/ui/core/messagebundle_tr.properties +1 -0
  198. package/src/sap/ui/core/messagebundle_uk.properties +1 -0
  199. package/src/sap/ui/core/messagebundle_vi.properties +1 -0
  200. package/src/sap/ui/core/messagebundle_zh_CN.properties +1 -0
  201. package/src/sap/ui/core/messagebundle_zh_TW.properties +1 -0
  202. package/src/sap/ui/core/mvc/Controller.js +1 -1
  203. package/src/sap/ui/core/mvc/ControllerExtensionProvider.js +1 -1
  204. package/src/sap/ui/core/mvc/HTMLView.js +1 -1
  205. package/src/sap/ui/core/mvc/HTMLViewRenderer.js +1 -1
  206. package/src/sap/ui/core/mvc/JSONView.js +1 -1
  207. package/src/sap/ui/core/mvc/JSONViewRenderer.js +1 -1
  208. package/src/sap/ui/core/mvc/JSView.js +1 -1
  209. package/src/sap/ui/core/mvc/JSViewRenderer.js +1 -1
  210. package/src/sap/ui/core/mvc/TemplateView.js +1 -1
  211. package/src/sap/ui/core/mvc/TemplateViewRenderer.js +1 -1
  212. package/src/sap/ui/core/mvc/View.js +1 -1
  213. package/src/sap/ui/core/mvc/ViewRenderer.js +1 -1
  214. package/src/sap/ui/core/mvc/XMLView.js +16 -4
  215. package/src/sap/ui/core/mvc/XMLViewRenderer.js +5 -2
  216. package/src/sap/ui/core/plugin/DeclarativeSupport.js +1 -1
  217. package/src/sap/ui/core/plugin/LessSupport.js +1 -1
  218. package/src/sap/ui/core/plugin/TemplatingSupport.js +1 -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 +1 -1
  222. package/src/sap/ui/core/rules/App.support.js +6 -1
  223. package/src/sap/ui/core/rules/Misc.support.js +8 -3
  224. package/src/sap/ui/core/search/OpenSearchProvider.js +1 -1
  225. package/src/sap/ui/core/search/SearchProvider.js +1 -1
  226. package/src/sap/ui/core/service/Service.js +1 -1
  227. package/src/sap/ui/core/service/ServiceFactory.js +1 -1
  228. package/src/sap/ui/core/service/ServiceFactoryRegistry.js +1 -1
  229. package/src/sap/ui/core/support/Plugin.js +29 -1
  230. package/src/sap/ui/core/support/Support.js +3 -3
  231. package/src/sap/ui/core/support/controls/InteractionSlider.js +395 -407
  232. package/src/sap/ui/core/support/plugins/Breakpoint.js +5 -5
  233. package/src/sap/ui/core/support/plugins/ControlTree.js +434 -347
  234. package/src/sap/ui/core/support/plugins/Debugging.js +153 -129
  235. package/src/sap/ui/core/support/plugins/Interaction.js +71 -85
  236. package/src/sap/ui/core/support/plugins/LocalStorage.js +1 -1
  237. package/src/sap/ui/core/support/plugins/Performance.js +10 -13
  238. package/src/sap/ui/core/support/plugins/Selector.js +1 -1
  239. package/src/sap/ui/core/support/plugins/TechInfo.js +5 -3
  240. package/src/sap/ui/core/support/plugins/Trace.js +7 -7
  241. package/src/sap/ui/core/support/plugins/ViewInfo.js +84 -22
  242. package/src/sap/ui/core/support/support.css +23 -23
  243. package/src/sap/ui/core/support/support.html +4 -6
  244. package/src/sap/ui/core/support/techinfo/TechnicalInfo.js +1 -1
  245. package/src/sap/ui/core/themes/base/CommandShortcutHints.less +1 -1
  246. package/src/sap/ui/core/themes/base/DragAndDrop.less +3 -3
  247. package/src/sap/ui/core/themes/base/base.less +1524 -54
  248. package/src/sap/ui/core/themes/base/fonts/SAP-icons.woff2 +0 -0
  249. package/src/sap/ui/core/themes/base/global.less +169 -13
  250. package/src/sap/ui/core/themes/base/shared.less +1 -0
  251. package/src/sap/ui/core/themes/sap_hcb/global.less +164 -7
  252. package/src/sap/ui/core/theming/Parameters.js +1 -1
  253. package/src/sap/ui/core/tmpl/DOMAttribute.js +1 -1
  254. package/src/sap/ui/core/tmpl/DOMElement.js +1 -1
  255. package/src/sap/ui/core/tmpl/HandlebarsTemplate.js +1 -1
  256. package/src/sap/ui/core/tmpl/Template.js +1 -1
  257. package/src/sap/ui/core/tmpl/TemplateControl.js +1 -1
  258. package/src/sap/ui/core/util/AsyncHintsHelper.js +1 -1
  259. package/src/sap/ui/core/util/Export.js +1 -1
  260. package/src/sap/ui/core/util/ExportCell.js +1 -1
  261. package/src/sap/ui/core/util/ExportColumn.js +1 -1
  262. package/src/sap/ui/core/util/ExportRow.js +1 -1
  263. package/src/sap/ui/core/util/ExportType.js +1 -1
  264. package/src/sap/ui/core/util/ExportTypeCSV.js +1 -1
  265. package/src/sap/ui/core/util/File.js +1 -1
  266. package/src/sap/ui/core/util/LibraryInfo.js +1 -1
  267. package/src/sap/ui/core/util/MockServer.js +20 -17
  268. package/src/sap/ui/core/util/PasteHelper.js +5 -5
  269. package/src/sap/ui/core/util/XMLPreprocessor.js +17 -4
  270. package/src/sap/ui/core/util/reflection/XmlTreeModifier.js +1 -1
  271. package/src/sap/ui/core/util/serializer/HTMLViewSerializer.js +1 -1
  272. package/src/sap/ui/core/util/serializer/Serializer.js +1 -1
  273. package/src/sap/ui/core/util/serializer/ViewSerializer.js +1 -1
  274. package/src/sap/ui/core/util/serializer/XMLViewSerializer.js +1 -1
  275. package/src/sap/ui/core/util/serializer/delegate/Delegate.js +1 -1
  276. package/src/sap/ui/core/util/serializer/delegate/HTML.js +1 -1
  277. package/src/sap/ui/core/util/serializer/delegate/XML.js +1 -1
  278. package/src/sap/ui/core/ws/ReadyState.js +1 -1
  279. package/src/sap/ui/core/ws/SapPcpWebSocket.js +1 -1
  280. package/src/sap/ui/core/ws/WebSocket.js +1 -1
  281. package/src/sap/ui/debug/ControlTree.js +1 -1
  282. package/src/sap/ui/debug/DebugEnv.js +1 -1
  283. package/src/sap/ui/debug/LogViewer.js +2 -2
  284. package/src/sap/ui/debug/PropertyList.js +1 -1
  285. package/src/sap/ui/dom/includeStylesheet.js +8 -3
  286. package/src/sap/ui/events/jquery/EventExtension.js +1 -1
  287. package/src/sap/ui/model/Binding.js +4 -3
  288. package/src/sap/ui/model/ClientModel.js +1 -1
  289. package/src/sap/ui/model/ClientTreeBinding.js +1 -1
  290. package/src/sap/ui/model/CompositeBinding.js +4 -1
  291. package/src/sap/ui/model/CompositeDataState.js +1 -1
  292. package/src/sap/ui/model/CompositeType.js +13 -1
  293. package/src/sap/ui/model/ContextBinding.js +1 -1
  294. package/src/sap/ui/model/DataState.js +1 -1
  295. package/src/sap/ui/model/MetaModel.js +1 -2
  296. package/src/sap/ui/model/Model.js +10 -7
  297. package/src/sap/ui/model/SelectionModel.js +1 -1
  298. package/src/sap/ui/model/SimpleType.js +1 -1
  299. package/src/sap/ui/model/TreeAutoExpandMode.js +1 -1
  300. package/src/sap/ui/model/Type.js +1 -1
  301. package/src/sap/ui/model/_Helper.js +24 -0
  302. package/src/sap/ui/model/analytics/AnalyticalBinding.js +30 -15
  303. package/src/sap/ui/model/analytics/ODataModelAdapter.js +2 -1
  304. package/src/sap/ui/model/base/ManagedObjectModel.js +9 -7
  305. package/src/sap/ui/model/json/JSONListBinding.js +1 -1
  306. package/src/sap/ui/model/json/JSONModel.js +15 -8
  307. package/src/sap/ui/model/json/JSONPropertyBinding.js +1 -1
  308. package/src/sap/ui/model/message/MessageListBinding.js +1 -1
  309. package/src/sap/ui/model/message/MessageModel.js +1 -1
  310. package/src/sap/ui/model/message/MessagePropertyBinding.js +1 -1
  311. package/src/sap/ui/model/odata/ODataAnnotations.js +1 -1
  312. package/src/sap/ui/model/odata/ODataListBinding.js +1 -1
  313. package/src/sap/ui/model/odata/ODataMessageParser.js +1 -1
  314. package/src/sap/ui/model/odata/ODataMetaModel.js +1 -1
  315. package/src/sap/ui/model/odata/ODataMetadata.js +3 -3
  316. package/src/sap/ui/model/odata/ODataModel.js +2 -2
  317. package/src/sap/ui/model/odata/ODataPropertyBinding.js +3 -1
  318. package/src/sap/ui/model/odata/ODataTreeBinding.js +1 -1
  319. package/src/sap/ui/model/odata/ODataTreeBindingFlat.js +5 -4
  320. package/src/sap/ui/model/odata/ODataUtils.js +7 -9
  321. package/src/sap/ui/model/odata/type/Boolean.js +1 -1
  322. package/src/sap/ui/model/odata/type/Byte.js +1 -1
  323. package/src/sap/ui/model/odata/type/Currency.js +1 -1
  324. package/src/sap/ui/model/odata/type/Date.js +1 -1
  325. package/src/sap/ui/model/odata/type/DateTime.js +1 -1
  326. package/src/sap/ui/model/odata/type/DateTimeBase.js +1 -1
  327. package/src/sap/ui/model/odata/type/DateTimeOffset.js +1 -1
  328. package/src/sap/ui/model/odata/type/DateTimeWithTimezone.js +349 -0
  329. package/src/sap/ui/model/odata/type/Decimal.js +1 -1
  330. package/src/sap/ui/model/odata/type/Double.js +1 -1
  331. package/src/sap/ui/model/odata/type/Guid.js +1 -1
  332. package/src/sap/ui/model/odata/type/Int.js +1 -1
  333. package/src/sap/ui/model/odata/type/Int16.js +1 -1
  334. package/src/sap/ui/model/odata/type/Int32.js +1 -1
  335. package/src/sap/ui/model/odata/type/Int64.js +1 -1
  336. package/src/sap/ui/model/odata/type/ODataType.js +1 -1
  337. package/src/sap/ui/model/odata/type/Raw.js +1 -1
  338. package/src/sap/ui/model/odata/type/SByte.js +1 -1
  339. package/src/sap/ui/model/odata/type/Single.js +1 -1
  340. package/src/sap/ui/model/odata/type/Stream.js +1 -1
  341. package/src/sap/ui/model/odata/type/String.js +1 -1
  342. package/src/sap/ui/model/odata/type/Time.js +1 -1
  343. package/src/sap/ui/model/odata/type/TimeOfDay.js +1 -1
  344. package/src/sap/ui/model/odata/type/Unit.js +1 -1
  345. package/src/sap/ui/model/odata/v2/Context.js +69 -5
  346. package/src/sap/ui/model/odata/v2/ODataAnnotations.js +1 -1
  347. package/src/sap/ui/model/odata/v2/ODataContextBinding.js +8 -4
  348. package/src/sap/ui/model/odata/v2/ODataListBinding.js +215 -78
  349. package/src/sap/ui/model/odata/v2/ODataModel.js +283 -80
  350. package/src/sap/ui/model/odata/v2/ODataTreeBinding.js +6 -4
  351. package/src/sap/ui/model/odata/v4/AnnotationHelper.js +16 -17
  352. package/src/sap/ui/model/odata/v4/Context.js +117 -76
  353. package/src/sap/ui/model/odata/v4/ODataBinding.js +62 -37
  354. package/src/sap/ui/model/odata/v4/ODataContextBinding.js +157 -169
  355. package/src/sap/ui/model/odata/v4/ODataListBinding.js +451 -262
  356. package/src/sap/ui/model/odata/v4/ODataMetaModel.js +91 -63
  357. package/src/sap/ui/model/odata/v4/ODataModel.js +478 -250
  358. package/src/sap/ui/model/odata/v4/ODataParentBinding.js +74 -83
  359. package/src/sap/ui/model/odata/v4/ODataPropertyBinding.js +65 -61
  360. package/src/sap/ui/model/odata/v4/_AnnotationHelperExpression.js +61 -6
  361. package/src/sap/ui/model/odata/v4/lib/_AggregationCache.js +15 -0
  362. package/src/sap/ui/model/odata/v4/lib/_Cache.js +336 -86
  363. package/src/sap/ui/model/odata/v4/lib/_ConcatHelper.js +5 -13
  364. package/src/sap/ui/model/odata/v4/lib/_GroupLock.js +16 -0
  365. package/src/sap/ui/model/odata/v4/lib/_Helper.js +13 -6
  366. package/src/sap/ui/model/odata/v4/lib/_MetadataConverter.js +2 -2
  367. package/src/sap/ui/model/odata/v4/lib/_Requestor.js +233 -26
  368. package/src/sap/ui/model/odata/v4/lib/_V2Requestor.js +1 -1
  369. package/src/sap/ui/model/resource/ResourceModel.js +1 -1
  370. package/src/sap/ui/model/resource/ResourcePropertyBinding.js +1 -1
  371. package/src/sap/ui/model/type/Boolean.js +1 -1
  372. package/src/sap/ui/model/type/Currency.js +1 -1
  373. package/src/sap/ui/model/type/Date.js +1 -1
  374. package/src/sap/ui/model/type/DateInterval.js +1 -1
  375. package/src/sap/ui/model/type/DateTime.js +1 -1
  376. package/src/sap/ui/model/type/DateTimeInterval.js +1 -1
  377. package/src/sap/ui/model/type/FileSize.js +1 -1
  378. package/src/sap/ui/model/type/Float.js +1 -1
  379. package/src/sap/ui/model/type/Integer.js +1 -1
  380. package/src/sap/ui/model/type/String.js +1 -1
  381. package/src/sap/ui/model/type/Time.js +1 -1
  382. package/src/sap/ui/model/type/TimeInterval.js +1 -1
  383. package/src/sap/ui/model/type/Unit.js +1 -1
  384. package/src/sap/ui/model/xml/XMLListBinding.js +1 -1
  385. package/src/sap/ui/model/xml/XMLModel.js +1 -1
  386. package/src/sap/ui/model/xml/XMLPropertyBinding.js +1 -1
  387. package/src/sap/ui/performance/trace/FESR.js +1 -1
  388. package/src/sap/ui/performance/trace/FESRHelper.js +72 -0
  389. package/src/sap/ui/performance/trace/Interaction.js +6 -2
  390. package/src/sap/ui/performance/trace/Passport.js +3 -3
  391. package/src/sap/ui/qunit/qunit-2-css.js +4 -4
  392. package/src/sap/ui/qunit/qunit-css.js +4 -4
  393. package/src/sap/ui/qunit/utils/ControlIterator.js +1 -1
  394. package/src/sap/ui/qunit/utils/MemoryLeakCheck.js +1 -1
  395. package/src/sap/ui/test/BranchTracking.js +1 -0
  396. package/src/sap/ui/test/Opa5.js +10 -6
  397. package/src/sap/ui/test/OpaBuilder.js +7 -7
  398. package/src/sap/ui/test/TestUtils.js +11 -0
  399. package/src/sap/ui/test/_UsageReport.js +1 -1
  400. package/src/sap/ui/test/generic/GenericTestCollection.js +176 -0
  401. package/src/sap/ui/test/generic/TestBase.js +151 -0
  402. package/src/sap/ui/test/generic/Utils.js +284 -0
  403. package/src/sap/ui/test/gherkin/opa5TestHarness.js +14 -5
  404. package/src/sap/ui/test/opaQunit.js +11 -10
  405. package/src/sap/ui/test/selectors/_ControlSelectorGenerator.js +9 -8
  406. package/src/sap/ui/test/selectors/_ControlSelectorValidator.js +1 -1
  407. package/src/sap/ui/test/starter/_setupAndStart.js +4 -0
  408. package/src/sap/ui/thirdparty/IPv6.js +1 -1
  409. package/src/sap/ui/thirdparty/SecondLevelDomains.js +1 -1
  410. package/src/sap/ui/thirdparty/URI.js +7 -3
  411. package/src/sap/ui/thirdparty/URITemplate.js +1 -1
  412. package/src/sap/ui/thirdparty/jqueryui/jquery-ui-datepicker.js +143 -3
  413. package/src/sap/ui/thirdparty/jqueryui/jquery-ui-position.js +8 -1
  414. package/src/sap/ui/thirdparty/jszip.js +17 -7
  415. package/src/sap/ui/thirdparty/mobify-carousel.js +1 -1
  416. package/src/sap/ui/util/Mobile.js +17 -0
  417. package/src/sap/ui/util/Storage.js +1 -1
  418. package/src/ui5loader.js +9 -5
@@ -44,7 +44,47 @@ sap.ui.define([
44
44
  patchCompleted : true,
45
45
  patchSent : true,
46
46
  refresh : true
47
- };
47
+ },
48
+ /**
49
+ * @alias sap.ui.model.odata.v4.ODataListBinding
50
+ * @author SAP SE
51
+ * @class List binding for an OData V4 model.
52
+ * An event handler can only be attached to this binding for the following events:
53
+ * 'AggregatedDataStateChange', 'change', 'createActivate', 'createCompleted',
54
+ * 'createSent', 'dataReceived', 'dataRequested', 'DataStateChange', 'patchCompleted',
55
+ * 'patchSent', and 'refresh'. For other events, an error is thrown.
56
+ * @extends sap.ui.model.ListBinding
57
+ * @hideconstructor
58
+ * @mixes sap.ui.model.odata.v4.ODataParentBinding
59
+ * @public
60
+ * @since 1.37.0
61
+ * @version 1.101.0
62
+ * @borrows sap.ui.model.odata.v4.ODataBinding#getGroupId as #getGroupId
63
+ * @borrows sap.ui.model.odata.v4.ODataBinding#getRootBinding as #getRootBinding
64
+ * @borrows sap.ui.model.odata.v4.ODataBinding#getUpdateGroupId as #getUpdateGroupId
65
+ * @borrows sap.ui.model.odata.v4.ODataBinding#hasPendingChanges as #hasPendingChanges
66
+ * @borrows sap.ui.model.odata.v4.ODataBinding#isInitial as #isInitial
67
+ * @borrows sap.ui.model.odata.v4.ODataBinding#refresh as #refresh
68
+ * @borrows sap.ui.model.odata.v4.ODataBinding#requestRefresh as #requestRefresh
69
+ * @borrows sap.ui.model.odata.v4.ODataBinding#resetChanges as #resetChanges
70
+ * @borrows sap.ui.model.odata.v4.ODataBinding#toString as #toString
71
+ * @borrows sap.ui.model.odata.v4.ODataParentBinding#attachPatchCompleted as
72
+ * #attachPatchCompleted
73
+ * @borrows sap.ui.model.odata.v4.ODataParentBinding#attachPatchSent as #attachPatchSent
74
+ * @borrows sap.ui.model.odata.v4.ODataParentBinding#changeParameters as #changeParameters
75
+ * @borrows sap.ui.model.odata.v4.ODataParentBinding#detachPatchCompleted as
76
+ * #detachPatchCompleted
77
+ * @borrows sap.ui.model.odata.v4.ODataParentBinding#detachPatchSent as #detachPatchSent
78
+ * @borrows sap.ui.model.odata.v4.ODataParentBinding#resume as #resume
79
+ * @borrows sap.ui.model.odata.v4.ODataParentBinding#suspend as #suspend
80
+ */
81
+ ODataListBinding = ListBinding.extend("sap.ui.model.odata.v4.ODataListBinding", {
82
+ constructor : constructor
83
+ });
84
+
85
+ //*********************************************************************************************
86
+ // ODataListBinding
87
+ //*********************************************************************************************
48
88
 
49
89
  /**
50
90
  * Do <strong>NOT</strong> call this private constructor, but rather use
@@ -64,98 +104,63 @@ sap.ui.define([
64
104
  * Map of binding parameters
65
105
  * @throws {Error}
66
106
  * If incorrect binding parameters are provided or an unsupported operation mode is used
67
- *
68
- * @alias sap.ui.model.odata.v4.ODataListBinding
69
- * @author SAP SE
70
- * @class List binding for an OData V4 model.
71
- * An event handler can only be attached to this binding for the following events:
72
- * 'AggregatedDataStateChange', 'change', 'createActivate', 'createCompleted', 'createSent',
73
- * 'dataReceived', 'dataRequested', 'DataStateChange', 'patchCompleted', 'patchSent', and
74
- * 'refresh'. For other events, an error is thrown.
75
- * @extends sap.ui.model.ListBinding
76
- * @hideconstructor
77
- * @mixes sap.ui.model.odata.v4.ODataParentBinding
78
- * @public
79
- * @since 1.37.0
80
- * @version 1.98.0
81
- * @borrows sap.ui.model.odata.v4.ODataBinding#getGroupId as #getGroupId
82
- * @borrows sap.ui.model.odata.v4.ODataBinding#getRootBinding as #getRootBinding
83
- * @borrows sap.ui.model.odata.v4.ODataBinding#getUpdateGroupId as #getUpdateGroupId
84
- * @borrows sap.ui.model.odata.v4.ODataBinding#hasPendingChanges as #hasPendingChanges
85
- * @borrows sap.ui.model.odata.v4.ODataBinding#isInitial as #isInitial
86
- * @borrows sap.ui.model.odata.v4.ODataBinding#refresh as #refresh
87
- * @borrows sap.ui.model.odata.v4.ODataBinding#requestRefresh as #requestRefresh
88
- * @borrows sap.ui.model.odata.v4.ODataBinding#resetChanges as #resetChanges
89
- * @borrows sap.ui.model.odata.v4.ODataBinding#toString as #toString
90
- * @borrows sap.ui.model.odata.v4.ODataParentBinding#attachPatchCompleted as
91
- * #attachPatchCompleted
92
- * @borrows sap.ui.model.odata.v4.ODataParentBinding#attachPatchSent as #attachPatchSent
93
- * @borrows sap.ui.model.odata.v4.ODataParentBinding#changeParameters as #changeParameters
94
- * @borrows sap.ui.model.odata.v4.ODataParentBinding#detachPatchCompleted as
95
- * #detachPatchCompleted
96
- * @borrows sap.ui.model.odata.v4.ODataParentBinding#detachPatchSent as #detachPatchSent
97
- * @borrows sap.ui.model.odata.v4.ODataParentBinding#resume as #resume
98
- * @borrows sap.ui.model.odata.v4.ODataParentBinding#suspend as #suspend
99
- */
100
- var ODataListBinding = ListBinding.extend("sap.ui.model.odata.v4.ODataListBinding", {
101
- constructor : function (oModel, sPath, oContext, vSorters, vFilters, mParameters) {
102
- ListBinding.call(this, oModel, sPath);
103
- // initialize mixin members
104
- asODataParentBinding.call(this);
105
-
106
- if (sPath.endsWith("/")) {
107
- throw new Error("Invalid path: " + sPath);
108
- }
109
-
110
- mParameters = _Helper.clone(mParameters) || {};
111
- this.checkBindingParameters(mParameters, ["$$aggregation", "$$canonicalPath",
112
- "$$groupId", "$$operationMode", "$$ownRequest", "$$patchWithoutSideEffects",
113
- "$$sharedRequest", "$$updateGroupId"]);
114
- // number of active (client-side) created contexts in aContexts
115
- this.iActiveContexts = 0;
116
- this.aApplicationFilters = _Helper.toArray(vFilters);
117
- this.sChangeReason = oModel.bAutoExpandSelect && !mParameters.$$aggregation
118
- ? "AddVirtualContext"
119
- : undefined;
120
- this.iCreatedContexts = 0; // number of (client-side) created contexts in aContexts
121
- this.oDiff = undefined;
122
- this.aFilters = [];
123
- this.sGroupId = mParameters.$$groupId;
124
- this.bHasAnalyticalInfo = false;
125
- this.oHeaderContext = this.bRelative
126
- ? null
127
- : Context.createNewContext(oModel, this, sPath);
128
- this.sOperationMode = mParameters.$$operationMode || oModel.sOperationMode;
129
- // map<string,sap.ui.model.odata.v4.Context>
130
- // Maps a string path to a v4.Context with that path. A context may either be
131
- // - an element of this.aContexts (then it knows its index) or
132
- // - a value of this.mPreviousContextsByPath.
133
- // Contexts which have previously been part of this.aContexts are parked here for
134
- // reuse (and thus still remember their index) and get destroyed by
135
- // #destroyPreviousContexts after the next call to #createContexts.
136
- // A kept-alive context may be parked here for a longer time, with undefined index.
137
- this.mPreviousContextsByPath = {};
138
- this.aPreviousData = [];
139
- this.bSharedRequest = mParameters.$$sharedRequest || oModel.bSharedRequests;
140
- this.aSorters = _Helper.toArray(vSorters);
141
- this.sUpdateGroupId = mParameters.$$updateGroupId;
142
- // Note: $$operationMode is validated before, oModel.sOperationMode also
143
- // Just check for the case that no mode was specified, but sort/filter takes place
144
- if (!this.sOperationMode
145
- && (this.aSorters.length || this.aApplicationFilters.length)) {
146
- throw new Error("Unsupported operation mode: " + this.sOperationMode);
147
- }
148
-
149
- // Note: clone() dropped $$aggregation : undefined, which is good
150
- this.applyParameters(mParameters); // calls #reset
151
- if (!this.bRelative || oContext && !oContext.fetchValue) { // @see #isRoot
152
- // do this before #setContext fires an event!
153
- this.createReadGroupLock(this.getGroupId(), true);
154
- }
155
- this.setContext(oContext);
156
- oModel.bindingCreated(this);
157
- }
158
- });
107
+ */
108
+ function constructor(oModel, sPath, oContext, vSorters, vFilters, mParameters) {
109
+ ListBinding.call(this, oModel, sPath);
110
+ // initialize mixin members
111
+ asODataParentBinding.call(this);
112
+
113
+ if (sPath.endsWith("/")) {
114
+ throw new Error("Invalid path: " + sPath);
115
+ }
116
+
117
+ mParameters = _Helper.clone(mParameters) || {};
118
+ this.checkBindingParameters(mParameters, ["$$aggregation", "$$canonicalPath",
119
+ "$$getKeepAliveContext", "$$groupId", "$$operationMode", "$$ownRequest",
120
+ "$$patchWithoutSideEffects", "$$sharedRequest", "$$updateGroupId"]);
121
+ // number of active (client-side) created contexts in aContexts
122
+ this.iActiveContexts = 0;
123
+ this.aApplicationFilters = _Helper.toArray(vFilters);
124
+ this.sChangeReason = oModel.bAutoExpandSelect && !mParameters.$$aggregation
125
+ ? "AddVirtualContext"
126
+ : undefined;
127
+ this.iCreatedContexts = 0; // number of (client-side) created contexts in aContexts
128
+ this.oDiff = undefined;
129
+ this.aFilters = [];
130
+ this.sGroupId = mParameters.$$groupId;
131
+ this.bHasAnalyticalInfo = false;
132
+ this.oHeaderContext = this.bRelative
133
+ ? null
134
+ : Context.createNewContext(oModel, this, sPath);
135
+ this.sOperationMode = mParameters.$$operationMode || oModel.sOperationMode;
136
+ // map<string,sap.ui.model.odata.v4.Context>
137
+ // Maps a string path to a v4.Context with that path. A context may either be
138
+ // - an element of this.aContexts (then it knows its index) or
139
+ // - a value of this.mPreviousContextsByPath.
140
+ // Contexts which have previously been part of this.aContexts are parked here for
141
+ // reuse (and thus still remember their index) and get destroyed by
142
+ // #destroyPreviousContexts after the next call to #createContexts.
143
+ // A kept-alive context may be parked here for a longer time, with undefined index.
144
+ this.mPreviousContextsByPath = {};
145
+ this.aPreviousData = [];
146
+ this.bSharedRequest = mParameters.$$sharedRequest || oModel.bSharedRequests;
147
+ this.aSorters = _Helper.toArray(vSorters);
148
+ this.sUpdateGroupId = mParameters.$$updateGroupId;
149
+ // Note: $$operationMode is validated before, oModel.sOperationMode also
150
+ // Just check for the case that no mode was specified, but sort/filter takes place
151
+ if (!this.sOperationMode && (this.aSorters.length || this.aApplicationFilters.length)) {
152
+ throw new Error("Unsupported operation mode: " + this.sOperationMode);
153
+ }
154
+
155
+ // Note: clone() dropped $$aggregation : undefined, which is good
156
+ this.applyParameters(mParameters); // calls #reset
157
+ if (!this.bRelative || oContext && !oContext.fetchValue) { // @see #isRoot
158
+ // do this before #setContext fires an event!
159
+ this.createReadGroupLock(this.getGroupId(), true);
160
+ }
161
+ this.setContext(oContext);
162
+ oModel.bindingCreated(this);
163
+ }
159
164
 
160
165
  asODataParentBinding(ODataListBinding.prototype);
161
166
 
@@ -418,6 +423,9 @@ sap.ui.define([
418
423
  oOldAggregation = this.mParameters && this.mParameters.$$aggregation,
419
424
  sOldApply = this.mQueryOptions && this.mQueryOptions.$apply;
420
425
 
426
+ if ("$$getKeepAliveContext" in mParameters && "$apply" in mParameters) {
427
+ throw new Error("Cannot combine $$getKeepAliveContext and $apply");
428
+ }
421
429
  if ("$$aggregation" in mParameters) {
422
430
  if ("$apply" in mParameters) {
423
431
  throw new Error("Cannot combine $$aggregation and $apply");
@@ -493,6 +501,7 @@ sap.ui.define([
493
501
  *
494
502
  * @event sap.ui.model.odata.v4.ODataListBinding#createActivate
495
503
  * @public
504
+ * @see sap.ui.model.odata.v4.Context#isInactive
496
505
  * @since 1.98.0
497
506
  */
498
507
 
@@ -731,10 +740,10 @@ sap.ui.define([
731
740
  * {@link #getUpdateGroupId}.
732
741
  *
733
742
  * You can call {@link sap.ui.model.odata.v4.Context#delete} to delete the created context
734
- * again. As long as the context is transient (see
735
- * {@link sap.ui.model.odata.v4.Context#isTransient}), {@link #resetChanges} and a call to
736
- * {@link sap.ui.model.odata.v4.ODataModel#resetChanges} with the update group ID as parameter
737
- * also delete the created context together with other changes.
743
+ * again. As long as the context is {@link sap.ui.model.odata.v4.Context#isTransient transient}
744
+ * and {@link sap.ui.model.odata.v4.Context#isInactive active}, {@link #resetChanges} and a call
745
+ * to {@link sap.ui.model.odata.v4.ODataModel#resetChanges} with the update group ID as
746
+ * parameter also delete the created context together with other changes.
738
747
  *
739
748
  * If the creation of the entity on the server failed, the creation is repeated
740
749
  * automatically. If the binding's update group ID has
@@ -780,13 +789,21 @@ sap.ui.define([
780
789
  * @param {boolean} [bSkipRefresh]
781
790
  * Whether an automatic refresh of the created entity will be skipped
782
791
  * @param {boolean} [bAtEnd]
783
- * Whether the entity is inserted at the end of the list. When creating multiple entities,
784
- * this parameter must have the same value for each entity. Supported since 1.66.0
792
+ * Whether the entity is inserted at the end of the list. Supported since 1.66.0.
793
+ * Since 1.99.0 the first insertion determines the overall position of created contexts
794
+ * within the binding's context list. Every succeeding insertion is relative to the created
795
+ * contexts within this list.
785
796
  * @param {boolean} [bInactive]
786
797
  * Create an inactive context. Such a context will only be sent to the server after the first
787
798
  * property update. From then on it behaves like any other created context. This parameter is
788
799
  * experimental and its implementation may still change. Do not use it in productive code yet.
789
800
  * Supported since 1.97.0
801
+ * <p>
802
+ * Since 1.98.0, when the first property updates happens, the context is no longer
803
+ * {@link sap.ui.model.odata.v4.Context#isInactive inactive} and the
804
+ * {@link sap.ui.model.odata.v4.ODataListBinding#event:createActivate createActivate} event
805
+ * is fired. While inactive, it does not count as a {@link #hasPendingChanges pending change}
806
+ * and does not contribute to the {@link #getCount count}.
790
807
  * @returns {sap.ui.model.odata.v4.Context}
791
808
  * The context object for the created entity; its method
792
809
  * {@link sap.ui.model.odata.v4.Context#created} returns a promise that is resolved when the
@@ -795,11 +812,9 @@ sap.ui.define([
795
812
  * <ul>
796
813
  * <li> the binding's root binding is suspended,
797
814
  * <li> a relative binding is unresolved,
798
- * <li> entities are created both at the start and at the end,
815
+ * <li> entities are created first at the end and then at the start,
799
816
  * <li> <code>bAtEnd</code> is <code>true</code> and the binding does not know the final
800
817
  * length,
801
- * <li> <code>bInactive</code> is <code>true</code> and the update group ID does not have
802
- * {@link sap.ui.model.odata.v4.SubmitMode.Auto}.
803
818
  * <li> <code>bInactive</code> is <code>true</code>, the list binding is relative and does
804
819
  * not use the <code>$$ownRequest</code> parameter
805
820
  * (see {@link sap.ui.model.odata.v4.ODataModel#bindList})
@@ -816,6 +831,7 @@ sap.ui.define([
816
831
  sResolvedPath = this.getResolvedPath(),
817
832
  sTransientPredicate = "($uid=" + uid() + ")",
818
833
  sTransientPath = sResolvedPath + sTransientPredicate,
834
+ i,
819
835
  that = this;
820
836
 
821
837
  if (!sResolvedPath) {
@@ -829,27 +845,29 @@ sap.ui.define([
829
845
  throw new Error(
830
846
  "Must know the final length to create at the end. Consider setting $count");
831
847
  }
832
- if (this.bCreatedAtEnd !== undefined && this.bCreatedAtEnd !== bAtEnd) {
833
- throw new Error("Creating entities at the start and at the end is not supported.");
848
+ if (this.bFirstCreateAtEnd && !bAtEnd) {
849
+ throw new Error("Cannot create at the start after creation at end");
834
850
  }
835
-
836
851
  if (bInactive) {
837
852
  if (this.isRelative() && !this.mParameters.$$ownRequest) {
838
853
  throw new Error("Missing $$ownRequest at " + this);
839
854
  }
840
- if (!this.oModel.isAutoGroup(sGroupId)) {
841
- throw new Error("bInactive only supported for update group with SubmitMode.Auto: "
842
- + this);
843
- }
844
855
  sGroupId = "$inactive." + sGroupId;
845
856
  } else {
846
857
  this.iActiveContexts += 1;
847
858
  }
848
859
 
849
- this.bCreatedAtEnd = bAtEnd;
860
+ if (this.bFirstCreateAtEnd === undefined) {
861
+ this.bFirstCreateAtEnd = bAtEnd;
862
+ }
850
863
 
851
864
  // only for createInCache
852
865
  oGroupLock = this.lockGroup(sGroupId, true, true, function () {
866
+ if (!that.aContexts.includes(oContext)) { // #setContext changed the parent context
867
+ oContext.destroy();
868
+ return;
869
+ }
870
+
853
871
  that.destroyCreated(oContext);
854
872
  return Promise.resolve().then(function () {
855
873
  // Fire the change asynchronously so that Cache#delete is finished and #getContexts
@@ -858,7 +876,7 @@ sap.ui.define([
858
876
  });
859
877
  });
860
878
  oCreatePromise = this.createInCache(oGroupLock, oCreatePathPromise, sResolvedPath,
861
- sTransientPredicate, oInitialData,
879
+ sTransientPredicate, oInitialData, this.bFirstCreateAtEnd !== bAtEnd,
862
880
  function (oError) { // error callback
863
881
  that.oModel.reportError("POST on '" + oCreatePathPromise
864
882
  + "' failed; will be repeated automatically", sClassName, oError);
@@ -868,7 +886,7 @@ sap.ui.define([
868
886
  function () { // submit callback
869
887
  that.fireEvent("createSent", {context : oContext});
870
888
  }
871
- ).then(function (oCreatedEntity) {
889
+ ).then(function (oCreatedEntity) { // the entity was created on the server
872
890
  var sGroupId, sPredicate;
873
891
 
874
892
  if (!(oInitialData && oInitialData["@$ui5.keepTransientPath"])) {
@@ -885,7 +903,7 @@ sap.ui.define([
885
903
  return oContext.refreshDependentBindings(oContext.getPath().slice(1), sGroupId,
886
904
  /*bCheckUpdate*/true);
887
905
  }
888
- if (!that.oModel.isDirectGroup(sGroupId) && !that.oModel.isAutoGroup(sGroupId)) {
906
+ if (that.oModel.isApiGroup(sGroupId)) {
889
907
  sGroupId = "$auto";
890
908
  }
891
909
 
@@ -898,7 +916,22 @@ sap.ui.define([
898
916
  this.iCreatedContexts += 1;
899
917
  oContext = Context.create(this.oModel, this, sTransientPath, -this.iCreatedContexts,
900
918
  oCreatePromise, bInactive);
901
- this.aContexts.unshift(oContext);
919
+ oContext.fetchValue("", null, true).then(function (oElement) {
920
+ if (oElement) {
921
+ _Helper.setPrivateAnnotation(oElement, "context", oContext);
922
+ _Helper.setPrivateAnnotation(oElement, "firstCreateAtEnd",
923
+ that.bFirstCreateAtEnd);
924
+ } // else: context already destroyed
925
+ });
926
+
927
+ if (this.bFirstCreateAtEnd !== bAtEnd) {
928
+ this.aContexts.splice(this.iCreatedContexts - 1, 0, oContext);
929
+ for (i = this.iCreatedContexts - 1; i >= 0; i -= 1) {
930
+ this.aContexts[i].iIndex = i - this.iCreatedContexts;
931
+ }
932
+ } else {
933
+ this.aContexts.unshift(oContext);
934
+ }
902
935
  this._fireChange({reason : ChangeReason.Add});
903
936
 
904
937
  return oContext;
@@ -961,20 +994,13 @@ sap.ui.define([
961
994
  if (this.aContexts[iStart + i] === undefined && aResults[i]) {
962
995
  bChanged = true;
963
996
  i$skipIndex = iStart + i - this.iCreatedContexts; // index on server ($skip)
964
- sPredicate = _Helper.getPrivateAnnotation(aResults[i], "predicate")
965
- || _Helper.getPrivateAnnotation(aResults[i], "transientPredicate");
997
+ sPredicate = _Helper.getPrivateAnnotation(aResults[i], "predicate");
966
998
  sContextPath = sPath + (sPredicate || "/" + i$skipIndex);
967
999
  oContext = this.mPreviousContextsByPath[sContextPath];
968
- if (oContext && (!oContext.created() || oContext.isTransient())) {
969
- // reuse the previous context, unless it is created and persisted
1000
+ if (oContext && !oContext.created()) {
1001
+ // reuse the previous context, unless it is created (and persisted)
970
1002
  delete this.mPreviousContextsByPath[sContextPath];
971
- if (oContext.isTransient() && !this.iCreatedContexts) {
972
- // this can only happen in bindings w/o cache, where all created contexts
973
- // are active
974
- this.iCreatedContexts = this.iActiveContexts = -oContext.iIndex;
975
- } else {
976
- oContext.iIndex = i$skipIndex;
977
- }
1003
+ oContext.iIndex = i$skipIndex;
978
1004
  oContext.checkUpdate();
979
1005
  } else {
980
1006
  oContext = Context.create(oModel, this, sContextPath, i$skipIndex);
@@ -1038,7 +1064,7 @@ sap.ui.define([
1038
1064
  this.oDiff = undefined;
1039
1065
  this.aFilters = undefined;
1040
1066
  this.oHeaderContext = undefined;
1041
- // this.mParameters = undefined;
1067
+ // this.mParameters = undefined;
1042
1068
  this.mPreviousContextsByPath = undefined;
1043
1069
  this.aPreviousData = undefined;
1044
1070
  this.mQueryOptions = undefined;
@@ -1069,7 +1095,7 @@ sap.ui.define([
1069
1095
  this.aContexts[i].iIndex += 1;
1070
1096
  }
1071
1097
  if (!this.iCreatedContexts) {
1072
- this.bCreatedAtEnd = undefined;
1098
+ this.bFirstCreateAtEnd = undefined;
1073
1099
  }
1074
1100
  this.aContexts.splice(iIndex, 1);
1075
1101
  this.destroyLater(oContext);
@@ -1102,7 +1128,8 @@ sap.ui.define([
1102
1128
  *
1103
1129
  * @param {string[]} [aPathsToDelete]
1104
1130
  * If given, only contexts with paths in this list except kept-alive ones are removed and
1105
- * destroyed; otherwise all contexts in the list are removed and destroyed
1131
+ * destroyed (transient contexts are removed only); otherwise all contexts in the list are
1132
+ * removed and destroyed
1106
1133
  *
1107
1134
  * @private
1108
1135
  */
@@ -1117,7 +1144,9 @@ sap.ui.define([
1117
1144
  if (aPathsToDelete && oContext.isKeepAlive()) {
1118
1145
  oContext.iIndex = undefined;
1119
1146
  } else {
1120
- oContext.destroy();
1147
+ if (!oContext.isTransient()) {
1148
+ oContext.destroy();
1149
+ }
1121
1150
  delete mPreviousContextsByPath[sPath];
1122
1151
  }
1123
1152
  }
@@ -1130,10 +1159,9 @@ sap.ui.define([
1130
1159
  * @see sap.ui.model.odata.v4.ODataBinding#doCreateCache
1131
1160
  */
1132
1161
  ODataListBinding.prototype.doCreateCache = function (sResourcePath, mQueryOptions, oContext,
1133
- sDeepResourcePath, bOldCacheReadOnly, oOldCache) {
1162
+ sDeepResourcePath, sGroupId, oOldCache) {
1134
1163
  var sBindingPath,
1135
1164
  aKeptElementPaths,
1136
- oCache,
1137
1165
  that = this;
1138
1166
 
1139
1167
  if (oOldCache && oOldCache.getResourcePath() === sResourcePath
@@ -1143,10 +1171,10 @@ sap.ui.define([
1143
1171
  return that.mPreviousContextsByPath[sPath].isKeepAlive();
1144
1172
  });
1145
1173
 
1146
- if (!bOldCacheReadOnly && (aKeptElementPaths.length || this.iCreatedContexts)) {
1174
+ if (this.iCreatedContexts || aKeptElementPaths.length) {
1147
1175
  oOldCache.reset(aKeptElementPaths.map(function (sPath) {
1148
1176
  return _Helper.getRelativePath(sPath, sBindingPath);
1149
- }));
1177
+ }), sGroupId);
1150
1178
  // Note: #inheritQueryOptions as called below should not matter in case of own
1151
1179
  // requests, which are a precondition for kept-alive elements
1152
1180
  oOldCache.setQueryOptions(mQueryOptions, true);
@@ -1155,20 +1183,12 @@ sap.ui.define([
1155
1183
  }
1156
1184
  }
1157
1185
 
1158
- oCache = _AggregationCache.create(this.oModel.oRequestor, sResourcePath, sDeepResourcePath,
1159
- this.mParameters.$$aggregation, this.inheritQueryOptions(mQueryOptions, oContext),
1160
- this.oModel.bAutoExpandSelect, this.bSharedRequest);
1161
-
1162
- if (aKeptElementPaths && aKeptElementPaths.length) {
1163
- oCache.setLateQueryOptions(oOldCache.getLateQueryOptions());
1164
- aKeptElementPaths.forEach(function (sPath) {
1165
- oCache.addKeptElement(
1166
- oOldCache.getValue(_Helper.getRelativePath(sPath, sBindingPath)));
1167
- that.mPreviousContextsByPath[sPath].checkUpdate(); // add change listeners
1168
- });
1169
- }
1186
+ mQueryOptions = this.inheritQueryOptions(mQueryOptions, oContext);
1170
1187
 
1171
- return oCache;
1188
+ return this.getCacheAndMoveKeepAliveContexts(sResourcePath, mQueryOptions)
1189
+ || _AggregationCache.create(this.oModel.oRequestor, sResourcePath, sDeepResourcePath,
1190
+ this.mParameters.$$aggregation, mQueryOptions, this.oModel.bAutoExpandSelect,
1191
+ this.bSharedRequest);
1172
1192
  };
1173
1193
 
1174
1194
  /**
@@ -1225,8 +1245,13 @@ sap.ui.define([
1225
1245
  bNew = true;
1226
1246
  }
1227
1247
  oOldContext.iIndex = undefined;
1228
- this.aContexts[iIndex] = oResult;
1229
- this.oCache.doReplaceWith(iIndex, oElement);
1248
+ if (iIndex === undefined) {
1249
+ this.mPreviousContextsByPath[sPath] = oResult;
1250
+ this.oCache.addKeptElement(oElement);
1251
+ } else {
1252
+ this.aContexts[iIndex] = oResult;
1253
+ this.oCache.doReplaceWith(iIndex, oElement);
1254
+ }
1230
1255
  if (bKeepAlive) {
1231
1256
  this.mPreviousContextsByPath[oOldContext.getPath()] = oOldContext;
1232
1257
  if (bNew) {
@@ -1338,7 +1363,7 @@ sap.ui.define([
1338
1363
  var oPromise,
1339
1364
  that = this;
1340
1365
 
1341
- if (this.bCreatedAtEnd) {
1366
+ if (this.bFirstCreateAtEnd) {
1342
1367
  // Note: We still have to read iLength rows in this case to get all entities from
1343
1368
  // the server. The created entities then are placed behind using the calculated or
1344
1369
  // estimated length.
@@ -1713,6 +1738,8 @@ sap.ui.define([
1713
1738
  * used (see {@link sap.ui.model.odata.v4.ODataModel#bindList}). Since 1.97.0, pending changes
1714
1739
  * are ignored if they relate to a
1715
1740
  * {@link sap.ui.model.odata.v4.Context#setKeepAlive kept-alive} context of this binding.
1741
+ * Since 1.98.0, {@link sap.ui.model.odata.v4.Context#isTransient transient} contexts
1742
+ * of a {@link #getRootBinding root binding} do not count as pending changes.
1716
1743
  *
1717
1744
  * @public
1718
1745
  * @see sap.ui.model.ListBinding#filter
@@ -1788,9 +1815,78 @@ sap.ui.define([
1788
1815
  * @since 1.98.0
1789
1816
  */
1790
1817
  ODataListBinding.prototype.getAllCurrentContexts = function () {
1818
+ var aElements = [];
1819
+
1820
+ this.withCache(function (oCache, sPath) {
1821
+ aElements = oCache.getAllElements(sPath);
1822
+ }, "", /*bSync*/true);
1823
+
1824
+ if (this.createContexts(0, aElements)) {
1825
+ // In the case that a control has requested new data and the data request is already
1826
+ // completed, but the new contexts are not yet created, we have to ensure that a change
1827
+ // event is fired to inform the control about these new contexts.
1828
+ this._fireChange({reason : ChangeReason.Change});
1829
+ }
1830
+
1791
1831
  return this.aContexts.filter(function (oContext) {
1792
- return oContext;
1793
- }).concat(Object.values(this.mPreviousContextsByPath));
1832
+ return oContext;
1833
+ }).concat(Object.values(this.mPreviousContextsByPath));
1834
+ };
1835
+
1836
+ /**
1837
+ * Tries to get a cache from the model. This is only relevant for the $$getKeepAlive scenario
1838
+ * when the model created a temporary binding for this binding's path. If there is such a
1839
+ * binding, its contexts are moved here, it is destroyed and its cache is returned.
1840
+ *
1841
+ * @param {string} sResourcePath
1842
+ * The resoure path for the cache
1843
+ * @param {object} mQueryOptions
1844
+ * The query options for the cache
1845
+ * @returns {sap.ui.model.odata.v4.lib._CollectionCache|undefined}
1846
+ * The cache or <code>undefined</code> if the model has no matching temporary binding
1847
+ *
1848
+ * @private
1849
+ */
1850
+ ODataListBinding.prototype.getCacheAndMoveKeepAliveContexts = function (sResourcePath,
1851
+ mQueryOptions) {
1852
+ var oBinding,
1853
+ oCache,
1854
+ that = this;
1855
+
1856
+ if (!this.mParameters.$$getKeepAliveContext) {
1857
+ return undefined;
1858
+ }
1859
+ // $$canonicalPath is not allowed, binding path and resource path are (almost) identical
1860
+ oBinding = this.oModel.releaseKeepAliveBinding("/" + sResourcePath);
1861
+ if (!oBinding) {
1862
+ return undefined;
1863
+ }
1864
+
1865
+ Object.keys(oBinding.mParameters).concat(Object.keys(this.mParameters))
1866
+ .forEach(function (sParameter) {
1867
+ if ((sParameter[0] !== "$" || sParameter === "$$patchWithoutSideEffects"
1868
+ || sParameter === "$$updateGroupId")
1869
+ && that.mParameters[sParameter] !== oBinding.mParameters[sParameter]) {
1870
+ throw new Error(that + ": parameter does not match getKeepAliveContext: "
1871
+ + sParameter);
1872
+ }
1873
+ });
1874
+ // createAndSetCache copies them to the cache later
1875
+ this.mLateQueryOptions = _Helper.clone(mQueryOptions);
1876
+ _Helper.aggregateExpandSelect(this.mLateQueryOptions, oBinding.mLateQueryOptions);
1877
+ this.mPreviousContextsByPath = oBinding.mPreviousContextsByPath;
1878
+ Object.values(this.mPreviousContextsByPath).forEach(function (oContext) {
1879
+ oContext.oBinding = that;
1880
+ });
1881
+ oCache = oBinding.oCache;
1882
+ oCache.setQueryOptions(mQueryOptions);
1883
+ // avoid that the cache is set inactive or that contexts are destroyed
1884
+ oBinding.oCache = null;
1885
+ oBinding.oCachePromise = SyncPromise.resolve(null);
1886
+ oBinding.mPreviousContextsByPath = {};
1887
+ oBinding.destroy();
1888
+
1889
+ return oCache;
1794
1890
  };
1795
1891
 
1796
1892
  /**
@@ -1926,7 +2022,7 @@ sap.ui.define([
1926
2022
  if (!this.oDiff) { // w/o E.C.D there won't be a diff
1927
2023
  // make sure "refresh" is followed by async "change"
1928
2024
  oPromise = this.fetchContexts(iStart, iLength, iMaximumPrefetchSize, oGroupLock,
1929
- /*bAsync=*/bRefreshEvent, function () {
2025
+ /*bAsync*/bRefreshEvent, function () {
1930
2026
  bDataRequested = true;
1931
2027
  that.fireDataRequested();
1932
2028
  });
@@ -1997,7 +2093,7 @@ sap.ui.define([
1997
2093
  ODataListBinding.prototype.getContextsInViewOrder = function (iStart, iLength) {
1998
2094
  var aContexts, iCount, i;
1999
2095
 
2000
- if (this.bCreatedAtEnd) {
2096
+ if (this.bFirstCreateAtEnd) {
2001
2097
  aContexts = [];
2002
2098
  iCount = Math.min(iLength, this.getLength() - iStart);
2003
2099
  for (i = 0; i < iCount; i += 1) {
@@ -2014,10 +2110,12 @@ sap.ui.define([
2014
2110
  * Returns the count of elements.
2015
2111
  *
2016
2112
  * If known, the value represents the sum of the element count of the collection on the server
2017
- * and the number of transient entities created on the client. Otherwise, it is
2018
- * <code>undefined</code>. The value is a number of type <code>Edm.Int64</code>. Since 1.91.0,
2019
- * in case of data aggregation with group levels, the count is the leaf count on the server; it
2020
- * is only determined if the <code>$count</code> system query option is given.
2113
+ * and the number of {@link sap.ui.model.odata.v4.Context#isInactive active}
2114
+ * {@link sap.ui.model.odata.v4.Context#isTransient transient} entities created on the client.
2115
+ * Otherwise, it is <code>undefined</code>. The value is a number of type
2116
+ * <code>Edm.Int64</code>. Since 1.91.0, in case of data aggregation with group levels, the
2117
+ * count is the leaf count on the server; it is only determined if the <code>$count</code>
2118
+ * system query option is given.
2021
2119
  *
2022
2120
  * The count is known to the binding in the following situations:
2023
2121
  * <ul>
@@ -2071,8 +2169,10 @@ sap.ui.define([
2071
2169
 
2072
2170
  aContexts = this.getContextsInViewOrder(this.iCurrentBegin, iLength);
2073
2171
 
2074
- while (aContexts.length < iLength) {
2075
- aContexts.push(undefined);
2172
+ if (iLength < Infinity) {
2173
+ while (aContexts.length < iLength) {
2174
+ aContexts.push(undefined);
2175
+ }
2076
2176
  }
2077
2177
 
2078
2178
  return aContexts;
@@ -2264,7 +2364,7 @@ sap.ui.define([
2264
2364
  * @private
2265
2365
  */
2266
2366
  ODataListBinding.prototype.getModelIndex = function (iViewIndex) {
2267
- if (!this.bCreatedAtEnd) {
2367
+ if (!this.bFirstCreateAtEnd) {
2268
2368
  return iViewIndex;
2269
2369
  }
2270
2370
  if (!this.bLengthFinal) { // created at end, but the read is pending and $count unknown yet
@@ -2272,9 +2372,80 @@ sap.ui.define([
2272
2372
  }
2273
2373
  return iViewIndex < this.getLength() - this.iCreatedContexts
2274
2374
  ? iViewIndex + this.iCreatedContexts
2375
+ // Note: the created rows are mirrored at the end
2275
2376
  : this.getLength() - iViewIndex - 1;
2276
2377
  };
2277
2378
 
2379
+ /**
2380
+ * Calls {@link sap.ui.model.odata.v4.Context#setKeepAlive} at the context for the given path
2381
+ * and returns it. Since 1.100.0 the function always returns such a context. If none exists yet,
2382
+ * it is created without data and a request for its entity is sent.
2383
+ *
2384
+ * @param {string} sPath
2385
+ * The path of the context to be kept alive
2386
+ * @param {boolean} [bRequestMessages]
2387
+ * Whether to request messages for the context's entity
2388
+ * @param {string} [sGroupId]
2389
+ * The group ID used for read requests for the context's entity or its properties. If not
2390
+ * given, the binding's {@link #getGroupId group ID} is used. Supported since 1.100.0
2391
+ * @returns {sap.ui.model.odata.v4.Context}
2392
+ * The kept-alive context
2393
+ * @throws {Error} If
2394
+ * <ul>
2395
+ * <li> the group ID is invalid,
2396
+ * <li> the binding is unresolved,
2397
+ * <li> the given context path does not match this binding,
2398
+ * <li> the binding's root binding is suspended,
2399
+ * <li> or {@link sap.ui.model.odata.v4.Context#setKeepAlive} fails
2400
+ * </ul>
2401
+ *
2402
+ * @public
2403
+ * @see sap.ui.model.odata.v4.Model#getKeepAliveContext
2404
+ * @since 1.99.0
2405
+ */
2406
+ ODataListBinding.prototype.getKeepAliveContext = function (sPath, bRequestMessages, sGroupId) {
2407
+ var oContext = this.mPreviousContextsByPath[sPath]
2408
+ || this.aContexts.find(function (oCandidate) {
2409
+ return oCandidate && oCandidate.getPath() === sPath;
2410
+ }),
2411
+ iPredicateIndex = this.oModel.getPredicateIndex(sPath),
2412
+ sResolvedPath = this.getResolvedPath();
2413
+
2414
+ this.checkSuspended();
2415
+ this.oModel.checkGroupId(sGroupId);
2416
+ if (!oContext) {
2417
+ if (!sResolvedPath) {
2418
+ throw new Error("Binding is unresolved: " + this);
2419
+ }
2420
+ if (sPath.slice(0, iPredicateIndex) !== sResolvedPath) {
2421
+ throw new Error(this + ": Not a valid context path: " + sPath);
2422
+ }
2423
+ oContext = Context.create(this.oModel, this, sPath);
2424
+ this.mPreviousContextsByPath[sPath] = oContext;
2425
+ this.oCachePromise.then(function (oCache) {
2426
+ // call ASAP so that dependent property bindings find the entity in the cache
2427
+ var oElement = oCache.createEmptyElement(sPath.slice(iPredicateIndex));
2428
+
2429
+ if (sGroupId) {
2430
+ _Helper.setPrivateAnnotation(oElement, "groupId", sGroupId);
2431
+ }
2432
+ });
2433
+ // *request*Object so that requestProperty definitely runs after setKeepAlive and adds
2434
+ // to mLateProperties
2435
+ this.oModel.getMetaModel().requestObject(_Helper.getMetaPath(sResolvedPath) + "/")
2436
+ .then(function (oType) {
2437
+ // ensure that the key properties are requested even if unbound
2438
+ return oContext.requestProperty(oType.$Key.map(function (vKey) {
2439
+ return typeof vKey === "object" ? Object.values(vKey)[0] : vKey;
2440
+ }));
2441
+ })
2442
+ .catch(this.oModel.getReporter());
2443
+ }
2444
+
2445
+ oContext.setKeepAlive(true, oContext.fnOnBeforeDestroy, bRequestMessages);
2446
+ return oContext;
2447
+ };
2448
+
2278
2449
  /**
2279
2450
  * Returns the number of entries in the list. As long as the client does not know the size on
2280
2451
  * the server, an estimated length is returned.
@@ -2450,6 +2621,36 @@ sap.ui.define([
2450
2621
  }
2451
2622
  };
2452
2623
 
2624
+ /**
2625
+ * Returns whether the overall position of created entries is at the end of the list; this is
2626
+ * determined by the first call to {@link #create}.
2627
+ *
2628
+ * @returns {boolean|undefined}
2629
+ * Whether the overall position of created contexts is at the end, or <code>undefined</code>
2630
+ * if there are no created contexts
2631
+ *
2632
+ * @public
2633
+ * @since 1.99.0
2634
+ */
2635
+ ODataListBinding.prototype.isFirstCreateAtEnd = function () {
2636
+ return this.bFirstCreateAtEnd;
2637
+ };
2638
+
2639
+ /**
2640
+ * Check whether this binding is an active $$getKeepAliveContext binding for the given path.
2641
+ *
2642
+ * @param {string} sPath - An absolute binding path
2643
+ * @returns {boolean} - Whether this binding matches
2644
+ *
2645
+ * @private
2646
+ */
2647
+ ODataListBinding.prototype.isKeepAliveBindingFor = function (sPath) {
2648
+ // When suspended it matches if it already has contexts. Then its getKeepAliveContext fails.
2649
+ return this.mParameters.$$getKeepAliveContext && this.getResolvedPath() === sPath
2650
+ && (!this.isRootBindingSuspended() || this.aContexts.length
2651
+ || Object.keys(this.mPreviousContextsByPath).length);
2652
+ };
2653
+
2453
2654
  /**
2454
2655
  * Returns <code>true</code> if the length has been determined by the data returned from
2455
2656
  * server. If the length is a client side estimation <code>false</code> is returned.
@@ -2467,64 +2668,6 @@ sap.ui.define([
2467
2668
  return this.bLengthFinal;
2468
2669
  };
2469
2670
 
2470
- /**
2471
- * Makes the given context a row context of this binding. Adds the entity data to the cache.
2472
- * Makes the context kept-alive.
2473
- *
2474
- * @param {sap.ui.model.odata.v4.Context} oEntityContext
2475
- * A context pointing to an entity
2476
- * @throws {Error}
2477
- * If the binding is not suspended, setKeepAlive is not possible, the resource paths do not
2478
- * match, the entity's key predicate is unknown, the context binding's $expand contains
2479
- * collections, or the context binding is still reading
2480
- *
2481
- * @private
2482
- */
2483
- ODataListBinding.prototype.moveEntityHere = function (oEntityContext) {
2484
- var oEntity,
2485
- oEntityFetchValuePromise,
2486
- sEntityPath = oEntityContext.getPath(),
2487
- mEntityQueryOptions = oEntityContext.getBinding().getInheritableQueryOptions(),
2488
- sRelativePath = _Helper.getRelativePath(sEntityPath, this.oHeaderContext.getPath());
2489
-
2490
- if (!sRelativePath || sRelativePath.includes("/")) {
2491
- throw new Error(this + ": " + sEntityPath + " is not an entity of the collection");
2492
- }
2493
- if (!this.getRootBinding().isSuspended()) {
2494
- throw new Error(this + ": must be suspended");
2495
- }
2496
- this.checkKeepAlive(oEntityContext);
2497
-
2498
- // take the value from the context binding's cache
2499
- oEntityFetchValuePromise = oEntityContext.fetchValue(null, null, /*bCached*/true);
2500
- if (oEntityFetchValuePromise.isPending()) {
2501
- throw new Error("Cannot move the entity; the context binding has not finished loading: "
2502
- + oEntityContext.getBinding());
2503
- }
2504
- oEntity = oEntityFetchValuePromise.getResult();
2505
-
2506
- if (!_Helper.getPrivateAnnotation(oEntity, "predicate")) {
2507
- throw new Error("No key predicate known at " + sEntityPath);
2508
- }
2509
-
2510
- // add the context binding's query options as late query options
2511
- if (!this.aggregateQueryOptions(mEntityQueryOptions, _Helper.getMetaPath(sEntityPath),
2512
- /*bImmutable*/true)) {
2513
- throw new Error(oEntityContext + ": could not move the entity. Probably a list binding"
2514
- + " w/o $$ownRequest depends on it");
2515
- }
2516
-
2517
- this.getRootBinding().resume();
2518
- oEntityContext.oBinding = this;
2519
- this.mPreviousContextsByPath[sEntityPath] = oEntityContext;
2520
- this.oCachePromise.then(function (oCache) {
2521
- oCache.addKeptElement(oEntity);
2522
- // setKeepAlive looks into the cache, so this had to wait
2523
- oEntityContext.setKeepAlive(true);
2524
- oEntityContext.checkUpdate(); // create listeners in this binding's cache
2525
- });
2526
- };
2527
-
2528
2671
  /**
2529
2672
  * @override
2530
2673
  * @see sap.ui.model.odata.v4.ODataBinding#refreshInternal
@@ -2533,16 +2676,11 @@ sap.ui.define([
2533
2676
  _bCheckUpdate, bKeepCacheOnError) {
2534
2677
  var that = this;
2535
2678
 
2536
- function onRemove(sPredicate) {
2537
- var sPath = that.getResolvedPath();
2538
-
2539
- that.mPreviousContextsByPath[sPath + sPredicate].resetKeepAlive();
2540
- }
2541
-
2542
2679
  // calls refreshInternal on all given bindings and returns an array of promises
2543
2680
  function refreshAll(aBindings) {
2544
2681
  return aBindings.map(function (oBinding) {
2545
- if (oBinding.bIsBeingDestroyed) {
2682
+ if (oBinding.bIsBeingDestroyed
2683
+ || oBinding.getContext().isKeepAlive() && oBinding.hasPendingChanges()) {
2546
2684
  return;
2547
2685
  }
2548
2686
  // Call refreshInternal with bCheckUpdate = false because property bindings
@@ -2564,15 +2702,25 @@ sap.ui.define([
2564
2702
  return this.oCachePromise.then(function (oCache) {
2565
2703
  var iActiveContexts = that.iActiveContexts,
2566
2704
  iCreatedContexts = that.iCreatedContexts,
2705
+ aContexts = that.aContexts.slice(0, iCreatedContexts),
2567
2706
  aDependentBindings,
2568
2707
  oKeptElementsPromise,
2569
2708
  oPromise = that.oRefreshPromise;
2570
2709
 
2571
2710
  if (oCache && !oPromise) { // do not refresh twice
2572
2711
  that.removeCachesAndMessages(sResourcePathPrefix);
2573
- that.fetchCache(that.oContext, false, /*bKeepQueryOptions*/true, bKeepCacheOnError);
2712
+ that.fetchCache(that.oContext, false, /*bKeepQueryOptions*/true,
2713
+ bKeepCacheOnError ? sGroupId : undefined);
2574
2714
  oKeptElementsPromise = that.oCachePromise.then(function (oNewCache) {
2575
- return oNewCache.refreshKeptElements(that.lockGroup(sGroupId), onRemove);
2715
+ return oNewCache.refreshKeptElements(that.lockGroup(sGroupId),
2716
+ function onRemove(sPredicate, iIndex) {
2717
+ if (iIndex === undefined) {
2718
+ that.mPreviousContextsByPath[that.getResolvedPath() + sPredicate]
2719
+ .resetKeepAlive();
2720
+ } else { // Note: implies oContext.created()
2721
+ that.destroyCreated(that.aContexts[iIndex]);
2722
+ }
2723
+ });
2576
2724
  }).catch(function (oError) {
2577
2725
  that.oModel.reportError("Failed to refresh kept-alive elements", sClassName,
2578
2726
  oError);
@@ -2584,27 +2732,45 @@ sap.ui.define([
2584
2732
  throw oError;
2585
2733
  }
2586
2734
  return that.fetchResourcePath(that.oContext).then(function (sResourcePath) {
2735
+ var i;
2736
+
2587
2737
  if (!that.bRelative || oCache.getResourcePath() === sResourcePath) {
2588
- that.oCache = oCache;
2589
- that.oCachePromise = SyncPromise.resolve(oCache);
2738
+ if (that.oCache === oCache) {
2739
+ oCache.restore(true);
2740
+ } else { // still needed in case of _AggregationCache
2741
+ oCache.setActive(true);
2742
+ that.oCache = oCache;
2743
+ that.oCachePromise = SyncPromise.resolve(oCache);
2744
+ }
2590
2745
  that.iActiveContexts = iActiveContexts;
2591
2746
  that.iCreatedContexts = iCreatedContexts;
2592
- oCache.setActive(true);
2747
+ for (i = 0; i < iCreatedContexts; i += 1) {
2748
+ aContexts[i].iIndex = i - iCreatedContexts;
2749
+ delete that.mPreviousContextsByPath[aContexts[i].getPath()];
2750
+ }
2751
+ that.aContexts = aContexts; // restore created contexts
2593
2752
  that._fireChange({reason : ChangeReason.Change});
2594
2753
  }
2595
2754
  throw oError;
2596
2755
  });
2756
+ }).finally(function () {
2757
+ if (oCache.restore) {
2758
+ oCache.restore(false);
2759
+ }
2597
2760
  });
2598
2761
  }
2599
2762
  }
2600
2763
  // Note: after reset the dependent bindings cannot be found any more
2601
2764
  aDependentBindings = that.getDependentBindings();
2602
- that.reset(ChangeReason.Refresh, true); // this may reset that.oRefreshPromise
2765
+ // this may reset that.oRefreshPromise
2766
+ that.reset(ChangeReason.Refresh, bKeepCacheOnError ? false : undefined, sGroupId);
2603
2767
  return SyncPromise.all(
2604
- refreshAll(aDependentBindings).concat(oPromise, oKeptElementsPromise,
2605
- // Update after refresh event, otherwise $count is fetched before the request
2606
- that.oHeaderContext.checkUpdate()) // this is NOT done by refreshAll!
2607
- );
2768
+ refreshAll(aDependentBindings).concat(oPromise, oKeptElementsPromise)
2769
+ ).then(function () {
2770
+ // Update after refresh event, otherwise $count is fetched before the request.
2771
+ // Avoid update in case bKeepCacheOnError needs to roll back.
2772
+ return that.oHeaderContext.checkUpdateInternal(); // this is NOT done by refreshAll!
2773
+ });
2608
2774
  });
2609
2775
  };
2610
2776
 
@@ -2990,19 +3156,25 @@ sap.ui.define([
2990
3156
  * A change reason; if given, a refresh event with this reason is fired and the next
2991
3157
  * getContexts() fires a change event with this reason. Change reason "change" is ignored
2992
3158
  * as long as the binding is still empty.
2993
- * @param {boolean} [bDropTransient]
2994
- * Whether transient contexts shall also be dropped, not just created persisted ones
3159
+ * @param {boolean} [bDrop]
3160
+ * By default, all created persisted contexts are dropped while transient ones are not.
3161
+ * <code>true</code> also drops transient ones, and <code>false</code> keeps inline creation
3162
+ * rows only and transient ones where the POST is not within the same $batch as the GET for
3163
+ * the side-effects refresh.
3164
+ * @param {string} [sGroupId]
3165
+ * The group ID to be used for refresh; used only in case <code>bDrop === false</code>
2995
3166
  *
2996
3167
  * @private
2997
3168
  */
2998
- ODataListBinding.prototype.reset = function (sChangeReason, bDropTransient) {
3169
+ ODataListBinding.prototype.reset = function (sChangeReason, bDrop, sGroupId) {
2999
3170
  var oContext,
3171
+ iCreated = 0, // index (and finally number) of created elements that we keep
3000
3172
  bEmpty = this.iCurrentEnd === 0,
3001
- iTransient = 0,
3173
+ bKeepTransient = sGroupId && sGroupId !== this.getUpdateGroupId(),
3002
3174
  i,
3003
3175
  that = this;
3004
3176
 
3005
- if (bDropTransient) {
3177
+ if (bDrop === true) { // drop 'em all
3006
3178
  this.iActiveContexts = 0;
3007
3179
  this.iCreatedContexts = 0;
3008
3180
  }
@@ -3012,26 +3184,29 @@ sap.ui.define([
3012
3184
  });
3013
3185
  for (i = 0; i < this.iCreatedContexts; i += 1) {
3014
3186
  oContext = this.aContexts[i];
3015
- if (oContext.isTransient()) {
3016
- this.aContexts[iTransient] = oContext;
3017
- iTransient += 1;
3018
- } else { // Note: "created persisted" elements must be active
3187
+ if (bDrop === false
3188
+ ? bKeepTransient && oContext.isTransient()
3189
+ || oContext.isInactive() !== undefined
3190
+ : oContext.isTransient()) {
3191
+ this.aContexts[iCreated] = oContext;
3192
+ iCreated += 1;
3193
+ } else { // Note: inactive elements are always kept
3019
3194
  this.iActiveContexts -= 1;
3020
3195
  this.mPreviousContextsByPath[oContext.getPath()] = oContext;
3021
3196
  }
3022
3197
  }
3023
- for (i = 0; i < iTransient; i += 1) {
3024
- this.aContexts[i].iIndex = i - iTransient;
3198
+ for (i = 0; i < iCreated; i += 1) {
3199
+ this.aContexts[i].iIndex = i - iCreated;
3025
3200
  }
3026
3201
  // Note: no strict need to keep the reference here
3027
- this.aContexts.length = this.iCreatedContexts = iTransient;
3202
+ this.aContexts.length = this.iCreatedContexts = iCreated;
3028
3203
  } else {
3029
3204
  this.aContexts = [];
3030
3205
  }
3031
3206
  if (!this.iCreatedContexts) {
3032
3207
  // true if contexts have been created at the end, false if contexts have been created at
3033
3208
  // the start, undefined if there are no created contexts
3034
- this.bCreatedAtEnd = undefined;
3209
+ this.bFirstCreateAtEnd = undefined;
3035
3210
  }
3036
3211
  // the range of array indices for getCurrentContexts
3037
3212
  this.iCurrentBegin = this.iCurrentEnd = 0;
@@ -3069,6 +3244,28 @@ sap.ui.define([
3069
3244
  this.aContexts.forEach(reset);
3070
3245
  };
3071
3246
 
3247
+ /**
3248
+ * Restores all created elements, the bFirstCreateAtEnd flag and the iCreatedContexts,
3249
+ * iActiveContexts counters from cache to this list binding.
3250
+ *
3251
+ * @private
3252
+ */
3253
+ ODataListBinding.prototype.restoreCreated = function () {
3254
+ var that = this;
3255
+
3256
+ this.withCache(function (oCache, sPath) {
3257
+ oCache.getCreatedElements(sPath).forEach(function (oElement, i) {
3258
+ that.aContexts[i] = _Helper.getPrivateAnnotation(oElement, "context");
3259
+ that.bFirstCreateAtEnd
3260
+ = _Helper.getPrivateAnnotation(oElement, "firstCreateAtEnd");
3261
+ that.iCreatedContexts += 1;
3262
+ if (!oElement["@$ui5.context.isInactive"]) {
3263
+ that.iActiveContexts += 1;
3264
+ }
3265
+ });
3266
+ }).catch(this.oModel.getReporter());
3267
+ };
3268
+
3072
3269
  /**
3073
3270
  * @override
3074
3271
  * @see sap.ui.model.odata.v4.ODataParentBinding#resumeInternal
@@ -3239,35 +3436,25 @@ sap.ui.define([
3239
3436
  * @param {sap.ui.model.Context} oContext
3240
3437
  * The context object
3241
3438
  * @throws {Error}
3242
- * If the binding's root binding is suspended, or for relative bindings containing transient
3243
- * entities
3439
+ * If the binding's root binding is suspended
3244
3440
  *
3245
3441
  * @private
3246
3442
  */
3247
3443
  // @override sap.ui.model.Binding#setContext
3248
3444
  ODataListBinding.prototype.setContext = function (oContext) {
3249
- var sResolvedPath,
3250
- i,
3251
- that = this;
3445
+ var sResolvedPath;
3252
3446
 
3253
3447
  if (this.oContext !== oContext) {
3254
3448
  if (this.bRelative) {
3255
3449
  this.checkSuspended(true);
3256
- for (i = 0; i < that.iCreatedContexts; i += 1) {
3257
- if (that.aContexts[i].isTransient()) {
3258
- // to allow switching the context for new created entities (transient or
3259
- // not), we first have to implement a store/restore mechanism for them
3260
- throw new Error("setContext on relative binding is forbidden if a "
3261
- + "transient entity exists: " + that);
3262
- }
3263
- }
3264
3450
  // Keep the header context even if we lose the parent context, so that the header
3265
3451
  // context remains unchanged if the parent context is temporarily dropped during a
3266
3452
  // refresh.
3267
- this.reset();
3453
+ this.reset(/*sChangeReason*/undefined, /*bDrop*/true);
3268
3454
  this.resetKeepAlive(); // before fetchCache to avoid that it copies data
3269
3455
  this.fetchCache(oContext);
3270
3456
  if (oContext) {
3457
+ this.restoreCreated();
3271
3458
  sResolvedPath = this.oModel.resolve(this.sPath, oContext);
3272
3459
  // Note: oHeaderContext is missing only if called from c'tor
3273
3460
  if (this.oHeaderContext && this.oHeaderContext.getPath() !== sResolvedPath) {
@@ -3328,6 +3515,8 @@ sap.ui.define([
3328
3515
  * used (see {@link sap.ui.model.odata.v4.ODataModel#bindList}). Since 1.97.0, pending changes
3329
3516
  * are ignored if they relate to a
3330
3517
  * {@link sap.ui.model.odata.v4.Context#setKeepAlive kept-alive} context of this binding.
3518
+ * Since 1.98.0, {@link sap.ui.model.odata.v4.Context#isTransient transient} contexts
3519
+ * of a {@link #getRootBinding root binding} do not count as pending changes.
3331
3520
  *
3332
3521
  * @public
3333
3522
  * @see sap.ui.model.ListBinding#sort