@openui5/sap.ui.core 1.99.0 → 1.100.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (355) hide show
  1. package/THIRDPARTY.txt +2 -2
  2. package/package.json +1 -1
  3. package/src/jquery.sap.global.js +6 -3
  4. package/src/jquery.sap.properties.js +1 -1
  5. package/src/jquery.sap.resources.js +1 -1
  6. package/src/jquery.sap.script.js +1 -1
  7. package/src/jquery.sap.storage.js +3 -3
  8. package/src/sap/base/Log.js +1 -1
  9. package/src/sap/base/strings/whitespaceReplacer.js +1 -1
  10. package/src/sap/base/util/LoaderExtensions.js +1 -10
  11. package/src/sap/base/util/UriParameters.js +2 -2
  12. package/src/sap/base/util/restricted/_CancelablePromise.js +1 -1
  13. package/src/sap/base/util/restricted/_castArray.js +1 -1
  14. package/src/sap/base/util/restricted/_compact.js +1 -1
  15. package/src/sap/base/util/restricted/_curry.js +1 -1
  16. package/src/sap/base/util/restricted/_debounce.js +1 -1
  17. package/src/sap/base/util/restricted/_difference.js +1 -1
  18. package/src/sap/base/util/restricted/_differenceBy.js +1 -1
  19. package/src/sap/base/util/restricted/_differenceWith.js +1 -1
  20. package/src/sap/base/util/restricted/_flatMap.js +1 -1
  21. package/src/sap/base/util/restricted/_flatMapDeep.js +1 -1
  22. package/src/sap/base/util/restricted/_flatMapDepth.js +1 -1
  23. package/src/sap/base/util/restricted/_flatten.js +1 -1
  24. package/src/sap/base/util/restricted/_flattenDeep.js +1 -1
  25. package/src/sap/base/util/restricted/_flattenDepth.js +1 -1
  26. package/src/sap/base/util/restricted/_intersection.js +1 -1
  27. package/src/sap/base/util/restricted/_intersectionBy.js +1 -1
  28. package/src/sap/base/util/restricted/_intersectionWith.js +1 -1
  29. package/src/sap/base/util/restricted/_isEqual.js +1 -1
  30. package/src/sap/base/util/restricted/_isEqualWith.js +1 -1
  31. package/src/sap/base/util/restricted/_isNil.js +1 -1
  32. package/src/sap/base/util/restricted/_max.js +1 -1
  33. package/src/sap/base/util/restricted/_merge.js +1 -1
  34. package/src/sap/base/util/restricted/_mergeWith.js +1 -1
  35. package/src/sap/base/util/restricted/_min.js +1 -1
  36. package/src/sap/base/util/restricted/_omit.js +1 -1
  37. package/src/sap/base/util/restricted/_pick.js +1 -1
  38. package/src/sap/base/util/restricted/_pickBy.js +1 -1
  39. package/src/sap/base/util/restricted/_throttle.js +1 -1
  40. package/src/sap/base/util/restricted/_toArray.js +1 -1
  41. package/src/sap/base/util/restricted/_union.js +1 -1
  42. package/src/sap/base/util/restricted/_unionBy.js +1 -1
  43. package/src/sap/base/util/restricted/_unionWith.js +1 -1
  44. package/src/sap/base/util/restricted/_uniq.js +1 -1
  45. package/src/sap/base/util/restricted/_uniqBy.js +1 -1
  46. package/src/sap/base/util/restricted/_uniqWith.js +1 -1
  47. package/src/sap/base/util/restricted/_without.js +1 -1
  48. package/src/sap/base/util/restricted/_xor.js +1 -1
  49. package/src/sap/base/util/restricted/_xorBy.js +1 -1
  50. package/src/sap/base/util/restricted/_xorWith.js +1 -1
  51. package/src/sap/base/util/restricted/_zipObject.js +1 -1
  52. package/src/sap/base/util/restricted/_zipObjectDeep.js +1 -1
  53. package/src/sap/ui/Device.js +3 -3
  54. package/src/sap/ui/Global.js +4 -4
  55. package/src/sap/ui/base/Event.js +1 -1
  56. package/src/sap/ui/base/EventProvider.js +1 -1
  57. package/src/sap/ui/base/ExpressionParser.js +1 -1
  58. package/src/sap/ui/base/Interface.js +1 -1
  59. package/src/sap/ui/base/ManagedObject.js +1 -1
  60. package/src/sap/ui/base/ManagedObjectMetadata.js +1 -1
  61. package/src/sap/ui/base/ManagedObjectObserver.js +2 -0
  62. package/src/sap/ui/base/Metadata.js +1 -1
  63. package/src/sap/ui/base/Object.js +1 -1
  64. package/src/sap/ui/base/ObjectPool.js +1 -1
  65. package/src/sap/ui/core/.library +2 -2
  66. package/src/sap/ui/core/BusyIndicator.js +1 -1
  67. package/src/sap/ui/core/Component.js +1 -1
  68. package/src/sap/ui/core/ComponentContainer.js +1 -1
  69. package/src/sap/ui/core/ComponentMetadata.js +2 -2
  70. package/src/sap/ui/core/ComponentSupport.js +1 -1
  71. package/src/sap/ui/core/Configuration.js +3 -1
  72. package/src/sap/ui/core/Control.js +1 -1
  73. package/src/sap/ui/core/Core.js +3 -1
  74. package/src/sap/ui/core/CustomData.js +1 -1
  75. package/src/sap/ui/core/DeclarativeSupport.js +1 -1
  76. package/src/sap/ui/core/Element.js +1 -1
  77. package/src/sap/ui/core/ElementMetadata.js +1 -1
  78. package/src/sap/ui/core/EnabledPropagator.js +1 -1
  79. package/src/sap/ui/core/EventBus.js +1 -1
  80. package/src/sap/ui/core/Fragment.js +1 -1
  81. package/src/sap/ui/core/HTML.js +1 -1
  82. package/src/sap/ui/core/History.js +1 -1
  83. package/src/sap/ui/core/Icon.js +17 -3
  84. package/src/sap/ui/core/IndicationColorSupport.js +1 -1
  85. package/src/sap/ui/core/IntervalTrigger.js +1 -1
  86. package/src/sap/ui/core/InvisibleMessage.js +1 -1
  87. package/src/sap/ui/core/InvisibleRenderer.js +1 -1
  88. package/src/sap/ui/core/InvisibleText.js +1 -1
  89. package/src/sap/ui/core/Item.js +1 -1
  90. package/src/sap/ui/core/LabelEnablement.js +1 -1
  91. package/src/sap/ui/core/LayoutData.js +1 -1
  92. package/src/sap/ui/core/ListItem.js +1 -1
  93. package/src/sap/ui/core/LocalBusyIndicator.js +1 -1
  94. package/src/sap/ui/core/Locale.js +1 -1
  95. package/src/sap/ui/core/LocaleData.js +24 -5
  96. package/src/sap/ui/core/Manifest.js +1 -1
  97. package/src/sap/ui/core/Message.js +1 -1
  98. package/src/sap/ui/core/Patcher.js +3 -3
  99. package/src/sap/ui/core/Popup.js +9 -6
  100. package/src/sap/ui/core/RenderManager.js +1 -1
  101. package/src/sap/ui/core/Renderer.js +1 -1
  102. package/src/sap/ui/core/ResizeHandler.js +1 -1
  103. package/src/sap/ui/core/ScrollBar.js +1 -1
  104. package/src/sap/ui/core/SeparatorItem.js +1 -1
  105. package/src/sap/ui/core/Title.js +1 -1
  106. package/src/sap/ui/core/TooltipBase.js +1 -1
  107. package/src/sap/ui/core/UIArea.js +1 -1
  108. package/src/sap/ui/core/UIComponent.js +1 -1
  109. package/src/sap/ui/core/UIComponentMetadata.js +1 -1
  110. package/src/sap/ui/core/ValueStateSupport.js +1 -1
  111. package/src/sap/ui/core/VariantLayoutData.js +1 -1
  112. package/src/sap/ui/core/XMLComposite.js +1 -1
  113. package/src/sap/ui/core/XMLCompositeMetadata.js +1 -1
  114. package/src/sap/ui/core/XMLTemplateProcessor.js +7 -6
  115. package/src/sap/ui/core/_IconRegistry.js +3 -2
  116. package/src/sap/ui/core/cache/CacheManager.js +1 -1
  117. package/src/sap/ui/core/cache/LRUPersistentCache.js +2 -1
  118. package/src/sap/ui/core/cldr/en_AU.json +1 -1
  119. package/src/sap/ui/core/date/Buddhist.js +3 -3
  120. package/src/sap/ui/core/date/Japanese.js +3 -3
  121. package/src/sap/ui/core/date/UniversalDate.js +10 -0
  122. package/src/sap/ui/core/date/UniversalDateUtils.js +1 -1
  123. package/src/sap/ui/core/delegate/ItemNavigation.js +1 -1
  124. package/src/sap/ui/core/delegate/ScrollEnablement.js +1 -1
  125. package/src/sap/ui/core/dnd/DragAndDrop.js +19 -16
  126. package/src/sap/ui/core/dnd/DragDropBase.js +1 -1
  127. package/src/sap/ui/core/dnd/DragDropInfo.js +1 -1
  128. package/src/sap/ui/core/dnd/DragInfo.js +1 -1
  129. package/src/sap/ui/core/dnd/DropInfo.js +3 -3
  130. package/src/sap/ui/core/format/DateFormat.js +125 -61
  131. package/src/sap/ui/core/format/DateFormatTimezoneDisplay.js +1 -0
  132. package/src/sap/ui/core/format/NumberFormat.js +331 -179
  133. package/src/sap/ui/core/format/TimezoneUtil.js +1 -1
  134. package/src/sap/ui/core/hyphenation/Hyphenation.js +1 -1
  135. package/src/sap/ui/core/library.js +85 -49
  136. package/src/sap/ui/core/message/ControlMessageProcessor.js +1 -1
  137. package/src/sap/ui/core/message/Message.js +1 -1
  138. package/src/sap/ui/core/message/MessageManager.js +1 -1
  139. package/src/sap/ui/core/message/MessageParser.js +1 -1
  140. package/src/sap/ui/core/message/MessageProcessor.js +1 -1
  141. package/src/sap/ui/core/messagebundle.properties +0 -2
  142. package/src/sap/ui/core/messagebundle_ar.properties +0 -1
  143. package/src/sap/ui/core/messagebundle_bg.properties +0 -1
  144. package/src/sap/ui/core/messagebundle_ca.properties +0 -1
  145. package/src/sap/ui/core/messagebundle_cs.properties +0 -1
  146. package/src/sap/ui/core/messagebundle_cy.properties +0 -1
  147. package/src/sap/ui/core/messagebundle_da.properties +0 -1
  148. package/src/sap/ui/core/messagebundle_de.properties +0 -1
  149. package/src/sap/ui/core/messagebundle_el.properties +0 -1
  150. package/src/sap/ui/core/messagebundle_en.properties +0 -1
  151. package/src/sap/ui/core/messagebundle_en_GB.properties +0 -1
  152. package/src/sap/ui/core/messagebundle_en_US_sappsd.properties +0 -1
  153. package/src/sap/ui/core/messagebundle_en_US_saptrc.properties +0 -1
  154. package/src/sap/ui/core/messagebundle_es.properties +0 -1
  155. package/src/sap/ui/core/messagebundle_es_MX.properties +0 -1
  156. package/src/sap/ui/core/messagebundle_et.properties +0 -1
  157. package/src/sap/ui/core/messagebundle_fi.properties +0 -1
  158. package/src/sap/ui/core/messagebundle_fr.properties +0 -1
  159. package/src/sap/ui/core/messagebundle_fr_CA.properties +0 -1
  160. package/src/sap/ui/core/messagebundle_hi.properties +0 -1
  161. package/src/sap/ui/core/messagebundle_hr.properties +0 -1
  162. package/src/sap/ui/core/messagebundle_hu.properties +0 -1
  163. package/src/sap/ui/core/messagebundle_id.properties +0 -1
  164. package/src/sap/ui/core/messagebundle_it.properties +0 -1
  165. package/src/sap/ui/core/messagebundle_iw.properties +0 -1
  166. package/src/sap/ui/core/messagebundle_ja.properties +0 -1
  167. package/src/sap/ui/core/messagebundle_kk.properties +0 -1
  168. package/src/sap/ui/core/messagebundle_ko.properties +1 -2
  169. package/src/sap/ui/core/messagebundle_lt.properties +0 -1
  170. package/src/sap/ui/core/messagebundle_lv.properties +0 -1
  171. package/src/sap/ui/core/messagebundle_ms.properties +0 -1
  172. package/src/sap/ui/core/messagebundle_nl.properties +0 -1
  173. package/src/sap/ui/core/messagebundle_no.properties +0 -1
  174. package/src/sap/ui/core/messagebundle_pl.properties +0 -1
  175. package/src/sap/ui/core/messagebundle_pt.properties +0 -1
  176. package/src/sap/ui/core/messagebundle_pt_PT.properties +0 -1
  177. package/src/sap/ui/core/messagebundle_ro.properties +0 -1
  178. package/src/sap/ui/core/messagebundle_ru.properties +0 -1
  179. package/src/sap/ui/core/messagebundle_sh.properties +0 -1
  180. package/src/sap/ui/core/messagebundle_sk.properties +0 -1
  181. package/src/sap/ui/core/messagebundle_sl.properties +0 -1
  182. package/src/sap/ui/core/messagebundle_sv.properties +0 -1
  183. package/src/sap/ui/core/messagebundle_th.properties +0 -1
  184. package/src/sap/ui/core/messagebundle_tr.properties +0 -1
  185. package/src/sap/ui/core/messagebundle_uk.properties +0 -1
  186. package/src/sap/ui/core/messagebundle_vi.properties +0 -1
  187. package/src/sap/ui/core/messagebundle_zh_CN.properties +0 -1
  188. package/src/sap/ui/core/messagebundle_zh_TW.properties +0 -1
  189. package/src/sap/ui/core/mvc/Controller.js +1 -1
  190. package/src/sap/ui/core/mvc/ControllerExtensionProvider.js +1 -1
  191. package/src/sap/ui/core/mvc/HTMLView.js +1 -1
  192. package/src/sap/ui/core/mvc/JSONView.js +1 -1
  193. package/src/sap/ui/core/mvc/JSView.js +1 -1
  194. package/src/sap/ui/core/mvc/TemplateView.js +1 -1
  195. package/src/sap/ui/core/mvc/View.js +1 -1
  196. package/src/sap/ui/core/mvc/XMLView.js +9 -1
  197. package/src/sap/ui/core/plugin/DeclarativeSupport.js +1 -1
  198. package/src/sap/ui/core/plugin/LessSupport.js +1 -1
  199. package/src/sap/ui/core/plugin/TemplatingSupport.js +1 -1
  200. package/src/sap/ui/core/postmessage/Bus.js +1 -1
  201. package/src/sap/ui/core/postmessage/confirmationDialog.js +1 -1
  202. package/src/sap/ui/core/rules/Misc.support.js +8 -3
  203. package/src/sap/ui/core/search/OpenSearchProvider.js +1 -1
  204. package/src/sap/ui/core/search/SearchProvider.js +1 -1
  205. package/src/sap/ui/core/service/Service.js +1 -1
  206. package/src/sap/ui/core/service/ServiceFactory.js +1 -1
  207. package/src/sap/ui/core/service/ServiceFactoryRegistry.js +1 -1
  208. package/src/sap/ui/core/support/Plugin.js +1 -1
  209. package/src/sap/ui/core/support/Support.js +3 -3
  210. package/src/sap/ui/core/support/plugins/ControlTree.js +1 -1
  211. package/src/sap/ui/core/support/plugins/Interaction.js +1 -1
  212. package/src/sap/ui/core/support/plugins/LocalStorage.js +1 -1
  213. package/src/sap/ui/core/support/plugins/Performance.js +1 -1
  214. package/src/sap/ui/core/support/plugins/Selector.js +1 -1
  215. package/src/sap/ui/core/support/plugins/TechInfo.js +1 -1
  216. package/src/sap/ui/core/support/plugins/Trace.js +1 -1
  217. package/src/sap/ui/core/support/plugins/ViewInfo.js +1 -1
  218. package/src/sap/ui/core/themes/base/CommandShortcutHints.less +1 -1
  219. package/src/sap/ui/core/themes/base/base.less +1108 -35
  220. package/src/sap/ui/core/themes/base/global.less +158 -4
  221. package/src/sap/ui/core/themes/sap_hcb/global.less +157 -2
  222. package/src/sap/ui/core/tmpl/DOMAttribute.js +1 -1
  223. package/src/sap/ui/core/tmpl/DOMElement.js +1 -1
  224. package/src/sap/ui/core/tmpl/HandlebarsTemplate.js +1 -1
  225. package/src/sap/ui/core/tmpl/Template.js +1 -1
  226. package/src/sap/ui/core/tmpl/TemplateControl.js +1 -1
  227. package/src/sap/ui/core/util/AsyncHintsHelper.js +1 -1
  228. package/src/sap/ui/core/util/Export.js +1 -1
  229. package/src/sap/ui/core/util/ExportCell.js +1 -1
  230. package/src/sap/ui/core/util/ExportColumn.js +1 -1
  231. package/src/sap/ui/core/util/ExportRow.js +1 -1
  232. package/src/sap/ui/core/util/ExportType.js +1 -1
  233. package/src/sap/ui/core/util/ExportTypeCSV.js +1 -1
  234. package/src/sap/ui/core/util/File.js +1 -1
  235. package/src/sap/ui/core/util/LibraryInfo.js +1 -1
  236. package/src/sap/ui/core/util/MockServer.js +3 -2
  237. package/src/sap/ui/core/util/PasteHelper.js +2 -2
  238. package/src/sap/ui/core/util/XMLPreprocessor.js +1 -0
  239. package/src/sap/ui/core/util/serializer/HTMLViewSerializer.js +1 -1
  240. package/src/sap/ui/core/util/serializer/Serializer.js +1 -1
  241. package/src/sap/ui/core/util/serializer/ViewSerializer.js +1 -1
  242. package/src/sap/ui/core/util/serializer/XMLViewSerializer.js +1 -1
  243. package/src/sap/ui/core/util/serializer/delegate/Delegate.js +1 -1
  244. package/src/sap/ui/core/util/serializer/delegate/HTML.js +1 -1
  245. package/src/sap/ui/core/util/serializer/delegate/XML.js +1 -1
  246. package/src/sap/ui/core/ws/ReadyState.js +1 -1
  247. package/src/sap/ui/core/ws/SapPcpWebSocket.js +1 -1
  248. package/src/sap/ui/core/ws/WebSocket.js +1 -1
  249. package/src/sap/ui/debug/ControlTree.js +1 -1
  250. package/src/sap/ui/debug/DebugEnv.js +1 -1
  251. package/src/sap/ui/debug/LogViewer.js +2 -2
  252. package/src/sap/ui/debug/PropertyList.js +1 -1
  253. package/src/sap/ui/model/ClientModel.js +1 -1
  254. package/src/sap/ui/model/CompositeBinding.js +3 -0
  255. package/src/sap/ui/model/CompositeDataState.js +1 -1
  256. package/src/sap/ui/model/CompositeType.js +13 -1
  257. package/src/sap/ui/model/DataState.js +1 -1
  258. package/src/sap/ui/model/MetaModel.js +1 -1
  259. package/src/sap/ui/model/Model.js +1 -1
  260. package/src/sap/ui/model/SelectionModel.js +1 -1
  261. package/src/sap/ui/model/SimpleType.js +1 -1
  262. package/src/sap/ui/model/TreeAutoExpandMode.js +1 -1
  263. package/src/sap/ui/model/Type.js +1 -1
  264. package/src/sap/ui/model/_Helper.js +22 -0
  265. package/src/sap/ui/model/analytics/AnalyticalBinding.js +28 -12
  266. package/src/sap/ui/model/base/ManagedObjectModel.js +8 -6
  267. package/src/sap/ui/model/json/JSONModel.js +15 -8
  268. package/src/sap/ui/model/message/MessageModel.js +1 -1
  269. package/src/sap/ui/model/odata/ODataAnnotations.js +1 -1
  270. package/src/sap/ui/model/odata/ODataMessageParser.js +1 -1
  271. package/src/sap/ui/model/odata/ODataMetaModel.js +1 -1
  272. package/src/sap/ui/model/odata/ODataMetadata.js +1 -1
  273. package/src/sap/ui/model/odata/ODataModel.js +1 -1
  274. package/src/sap/ui/model/odata/ODataPropertyBinding.js +3 -1
  275. package/src/sap/ui/model/odata/ODataTreeBindingFlat.js +1 -1
  276. package/src/sap/ui/model/odata/type/Boolean.js +1 -1
  277. package/src/sap/ui/model/odata/type/Byte.js +1 -1
  278. package/src/sap/ui/model/odata/type/Currency.js +1 -1
  279. package/src/sap/ui/model/odata/type/Date.js +1 -1
  280. package/src/sap/ui/model/odata/type/DateTime.js +1 -1
  281. package/src/sap/ui/model/odata/type/DateTimeBase.js +1 -1
  282. package/src/sap/ui/model/odata/type/DateTimeOffset.js +1 -1
  283. package/src/sap/ui/model/odata/type/DateTimeWithTimezone.js +54 -46
  284. package/src/sap/ui/model/odata/type/Decimal.js +1 -1
  285. package/src/sap/ui/model/odata/type/Double.js +1 -1
  286. package/src/sap/ui/model/odata/type/Guid.js +1 -1
  287. package/src/sap/ui/model/odata/type/Int.js +1 -1
  288. package/src/sap/ui/model/odata/type/Int16.js +1 -1
  289. package/src/sap/ui/model/odata/type/Int32.js +1 -1
  290. package/src/sap/ui/model/odata/type/Int64.js +1 -1
  291. package/src/sap/ui/model/odata/type/ODataType.js +1 -1
  292. package/src/sap/ui/model/odata/type/Raw.js +1 -1
  293. package/src/sap/ui/model/odata/type/SByte.js +1 -1
  294. package/src/sap/ui/model/odata/type/Single.js +1 -1
  295. package/src/sap/ui/model/odata/type/Stream.js +1 -1
  296. package/src/sap/ui/model/odata/type/String.js +1 -1
  297. package/src/sap/ui/model/odata/type/Time.js +1 -1
  298. package/src/sap/ui/model/odata/type/TimeOfDay.js +1 -1
  299. package/src/sap/ui/model/odata/type/Unit.js +1 -1
  300. package/src/sap/ui/model/odata/v2/Context.js +7 -3
  301. package/src/sap/ui/model/odata/v2/ODataAnnotations.js +1 -1
  302. package/src/sap/ui/model/odata/v2/ODataListBinding.js +109 -26
  303. package/src/sap/ui/model/odata/v2/ODataModel.js +236 -45
  304. package/src/sap/ui/model/odata/v2/ODataTreeBinding.js +1 -1
  305. package/src/sap/ui/model/odata/v4/Context.js +20 -22
  306. package/src/sap/ui/model/odata/v4/ODataBinding.js +50 -32
  307. package/src/sap/ui/model/odata/v4/ODataContextBinding.js +33 -5
  308. package/src/sap/ui/model/odata/v4/ODataListBinding.js +183 -46
  309. package/src/sap/ui/model/odata/v4/ODataMetaModel.js +1 -1
  310. package/src/sap/ui/model/odata/v4/ODataModel.js +185 -24
  311. package/src/sap/ui/model/odata/v4/ODataParentBinding.js +25 -57
  312. package/src/sap/ui/model/odata/v4/ODataPropertyBinding.js +3 -2
  313. package/src/sap/ui/model/odata/v4/lib/_Cache.js +146 -31
  314. package/src/sap/ui/model/odata/v4/lib/_GroupLock.js +4 -0
  315. package/src/sap/ui/model/odata/v4/lib/_Helper.js +6 -3
  316. package/src/sap/ui/model/odata/v4/lib/_Requestor.js +162 -8
  317. package/src/sap/ui/model/resource/ResourceModel.js +1 -1
  318. package/src/sap/ui/model/type/Boolean.js +1 -1
  319. package/src/sap/ui/model/type/Currency.js +1 -1
  320. package/src/sap/ui/model/type/Date.js +1 -1
  321. package/src/sap/ui/model/type/DateInterval.js +1 -1
  322. package/src/sap/ui/model/type/DateTime.js +1 -1
  323. package/src/sap/ui/model/type/DateTimeInterval.js +1 -1
  324. package/src/sap/ui/model/type/FileSize.js +1 -1
  325. package/src/sap/ui/model/type/Float.js +1 -1
  326. package/src/sap/ui/model/type/Integer.js +1 -1
  327. package/src/sap/ui/model/type/String.js +1 -1
  328. package/src/sap/ui/model/type/Time.js +1 -1
  329. package/src/sap/ui/model/type/TimeInterval.js +1 -1
  330. package/src/sap/ui/model/type/Unit.js +1 -1
  331. package/src/sap/ui/model/xml/XMLModel.js +1 -1
  332. package/src/sap/ui/performance/trace/FESR.js +1 -1
  333. package/src/sap/ui/performance/trace/FESRHelper.js +72 -0
  334. package/src/sap/ui/performance/trace/Interaction.js +6 -2
  335. package/src/sap/ui/qunit/qunit-2-css.js +4 -4
  336. package/src/sap/ui/qunit/qunit-css.js +4 -4
  337. package/src/sap/ui/qunit/utils/ControlIterator.js +1 -1
  338. package/src/sap/ui/qunit/utils/MemoryLeakCheck.js +1 -1
  339. package/src/sap/ui/test/BranchTracking.js +1 -0
  340. package/src/sap/ui/test/OpaBuilder.js +7 -7
  341. package/src/sap/ui/test/TestUtils.js +10 -0
  342. package/src/sap/ui/test/_UsageReport.js +1 -1
  343. package/src/sap/ui/test/generic/GenericTestCollection.js +176 -0
  344. package/src/sap/ui/test/generic/TestBase.js +151 -0
  345. package/src/sap/ui/test/generic/Utils.js +284 -0
  346. package/src/sap/ui/test/selectors/_ControlSelectorGenerator.js +9 -8
  347. package/src/sap/ui/test/selectors/_ControlSelectorValidator.js +1 -1
  348. package/src/sap/ui/test/starter/_setupAndStart.js +4 -0
  349. package/src/sap/ui/thirdparty/IPv6.js +1 -1
  350. package/src/sap/ui/thirdparty/SecondLevelDomains.js +1 -1
  351. package/src/sap/ui/thirdparty/URI.js +7 -3
  352. package/src/sap/ui/thirdparty/URITemplate.js +1 -1
  353. package/src/sap/ui/thirdparty/jszip.js +17 -7
  354. package/src/sap/ui/util/Mobile.js +17 -0
  355. package/src/sap/ui/util/Storage.js +1 -1
@@ -165,8 +165,20 @@ sap.ui.define([
165
165
  throw new Error("Unsupported operation mode: " + vValue);
166
166
  }
167
167
  break;
168
- case "$$canonicalPath":
169
168
  case "$$getKeepAliveContext":
169
+ if (that.isRelative() && !mParameters.$$ownRequest) {
170
+ throw new Error(
171
+ "$$getKeepAliveContext requires $$ownRequest in a relative binding");
172
+ }
173
+ ["$$aggregation", "$$canonicalPath", "$$sharedRequest"]
174
+ .forEach(function (sForbidden) {
175
+ if (sForbidden in mParameters) {
176
+ throw new Error("Cannot combine $$getKeepAliveContext and "
177
+ + sForbidden);
178
+ }
179
+ });
180
+ // falls through
181
+ case "$$canonicalPath":
170
182
  case "$$noPatch":
171
183
  case "$$ownRequest":
172
184
  case "$$patchWithoutSideEffects":
@@ -254,8 +266,8 @@ sap.ui.define([
254
266
  * The resource path
255
267
  * @param {sap.ui.model.Context} [oContext]
256
268
  * The context instance to be used, undefined for absolute bindings
257
- * @param {boolean} [bOldCacheReadOnly]
258
- * Whether the old cache is read-only and must be kept intact - not reset and reused!
269
+ * @param {boolean} [bKeepCreated]
270
+ * Whether created persisted elements shall be kept in place
259
271
  * @param {sap.ui.model.odata.v4.lib._Cache} [oOldCache]
260
272
  * The old cache, in case it may be reused
261
273
  * @returns {sap.ui.model.odata.v4.lib._Cache}
@@ -265,7 +277,7 @@ sap.ui.define([
265
277
  * @private
266
278
  */
267
279
  ODataBinding.prototype.createAndSetCache = function (mQueryOptions, sResourcePath, oContext,
268
- bOldCacheReadOnly, oOldCache) {
280
+ bKeepCreated, oOldCache) {
269
281
  var oCache, sDeepResourcePath, iGeneration;
270
282
 
271
283
  this.mCacheQueryOptions = Object.assign({}, this.oModel.mUriParameters, mQueryOptions);
@@ -289,7 +301,7 @@ sap.ui.define([
289
301
  } else {
290
302
  sDeepResourcePath = this.oModel.resolve(this.sPath, oContext).slice(1);
291
303
  oCache = this.doCreateCache(sResourcePath, this.mCacheQueryOptions, oContext,
292
- sDeepResourcePath, bOldCacheReadOnly, oOldCache);
304
+ sDeepResourcePath, bKeepCreated, oOldCache);
293
305
  if (!(this.mParameters && this.mParameters.$$sharedRequest)) {
294
306
  this.mCacheByResourcePath = this.mCacheByResourcePath || {};
295
307
  this.mCacheByResourcePath[sResourcePath] = oCache;
@@ -299,15 +311,13 @@ sap.ui.define([
299
311
  }
300
312
  } else { // absolute binding
301
313
  oCache = this.doCreateCache(sResourcePath, this.mCacheQueryOptions, undefined,
302
- undefined, bOldCacheReadOnly, oOldCache);
314
+ undefined, bKeepCreated, oOldCache);
303
315
  }
304
- if (oOldCache !== oCache) {
305
- if (oOldCache) {
306
- oOldCache.setActive(false);
307
- }
308
- if (this.mLateQueryOptions) {
309
- oCache.setLateQueryOptions(this.mLateQueryOptions);
310
- }
316
+ if (oOldCache && oOldCache !== oCache) {
317
+ oOldCache.setActive(false);
318
+ }
319
+ if (this.mLateQueryOptions) {
320
+ oCache.setLateQueryOptions(this.mLateQueryOptions);
311
321
  }
312
322
  this.oCache = oCache;
313
323
 
@@ -348,8 +358,8 @@ sap.ui.define([
348
358
  * The context instance to be used, must be <code>undefined</code> for absolute bindings
349
359
  * @param {string} [sDeepResourcePath=sResourcePath]
350
360
  * The deep resource path to be used to build the target path for bound messages
351
- * @param {boolean} [bOldCacheReadOnly]
352
- * Whether the old cache is read-only and must be kept intact - not reset and reused!
361
+ * @param {boolean} [bKeepCreated]
362
+ * Whether created persisted elements shall be kept in place
353
363
  * @param {sap.ui.model.odata.v4.lib._Cache} [oOldCache]
354
364
  * The old cache, in case it may be reused
355
365
  * @returns {sap.ui.model.odata.v4.lib._Cache}
@@ -402,9 +412,8 @@ sap.ui.define([
402
412
  * @param {boolean} [bKeepQueryOptions]
403
413
  * Whether to keep existing (late) query options and not to run auto-$expand/$select again
404
414
  * (cannot be combined with <code>bIgnoreParentCache</code>!)
405
- * @param {boolean} [bKeepCacheOnError]
406
- * If <code>true</code>, the binding data remains unchanged if the refresh fails. This implies
407
- * that the old cache must be kept intact - not reset and reused!
415
+ * @param {boolean} [bKeepCreated]
416
+ * Whether created persisted elements shall be kept in place
408
417
  * @throws {Error}
409
418
  * If auto-$expand/$select is still running and query options shall be kept (this case is just
410
419
  * not yet implemented and should not be needed)
@@ -412,7 +421,7 @@ sap.ui.define([
412
421
  * @private
413
422
  */
414
423
  ODataBinding.prototype.fetchCache = function (oContext, bIgnoreParentCache, bKeepQueryOptions,
415
- bKeepCacheOnError) {
424
+ bKeepCreated) {
416
425
  var oCache = this.oCache,
417
426
  oCallToken = {
418
427
  // propagate old cache from first call of fetchCache to the latest call
@@ -435,10 +444,10 @@ sap.ui.define([
435
444
  this.oCache = undefined;
436
445
  this.oFetchCacheCallToken = oCallToken;
437
446
  if (bKeepQueryOptions) {
438
- // asynchronously re-create an equivalent cache
447
+ // asynchronously re-create an equivalent cache, but skip auto-$expand/$select
439
448
  this.oCachePromise = SyncPromise.resolve(Promise.resolve()).then(function () {
440
449
  return that.createAndSetCache(that.mCacheQueryOptions, oCache.getResourcePath(),
441
- oContext, bKeepCacheOnError, oCache);
450
+ oContext, bKeepCreated, oCache);
442
451
  });
443
452
  return;
444
453
  }
@@ -465,7 +474,7 @@ sap.ui.define([
465
474
  throw oError;
466
475
  }
467
476
  return that.createAndSetCache(mQueryOptions, sResourcePath, oContext,
468
- bKeepCacheOnError, oCallToken.oOldCache);
477
+ bKeepCreated, oCallToken.oOldCache);
469
478
  });
470
479
  }
471
480
  that.oCache = null;
@@ -828,11 +837,12 @@ sap.ui.define([
828
837
  * Whether to ignore changes which will not be lost by APIs like
829
838
  * {@link sap.ui.model.odata.v4.ODataListBinding#changeParameters changeParameters},
830
839
  * {@link sap.ui.model.odata.v4.ODataListBinding#filter filter},
840
+ * {@link sap.ui.model.odata.v4.ODataListBinding#refresh refresh} (since 1.100.0),
831
841
  * {@link sap.ui.model.odata.v4.ODataListBinding#sort sort}, or
832
842
  * {@link sap.ui.model.odata.v4.ODataListBinding#suspend suspend} because they relate to a
833
- * {@link sap.ui.model.odata.v4.Context#setKeepAlive kept-alive} context of this binding.
834
- * Since 1.98.0, {@link sap.ui.model.odata.v4.Context#isTransient transient} contexts
835
- * of a {@link #getRootBinding root binding} are treated as kept-alive by this flag.
843
+ * {@link sap.ui.model.odata.v4.Context#setKeepAlive kept-alive} context of this binding
844
+ * (since 1.97.0). Since 1.98.0, {@link sap.ui.model.odata.v4.Context#isTransient transient}
845
+ * contexts of a {@link #getRootBinding root binding} are treated as kept-alive by this flag.
836
846
  * Since 1.99.0, the same happens for bindings using the <code>$$ownRequest</code> parameter
837
847
  * (see {@link sap.ui.model.odata.v4.ODataModel#bindList}).
838
848
  * @returns {boolean}
@@ -990,8 +1000,8 @@ sap.ui.define([
990
1000
  * the last call determines the binding's data; it is <b>independent</b> of the order of calls
991
1001
  * to {@link sap.ui.model.odata.v4.ODataModel#submitBatch} with the given group ID.
992
1002
  *
993
- * If there are pending changes, an error is thrown. Use {@link #hasPendingChanges} to check if
994
- * there are pending changes. If there are changes, call
1003
+ * If there are pending changes that cannot be ignored, an error is thrown. Use
1004
+ * {@link #hasPendingChanges} to check if there are such pending changes. If there are, call
995
1005
  * {@link sap.ui.model.odata.v4.ODataModel#submitBatch} to submit the changes or
996
1006
  * {@link sap.ui.model.odata.v4.ODataModel#resetChanges} to reset the changes before calling
997
1007
  * {@link #refresh}.
@@ -1006,10 +1016,18 @@ sap.ui.define([
1006
1016
  *
1007
1017
  * Valid values are <code>undefined</code>, '$auto', '$auto.*', '$direct' or application group
1008
1018
  * IDs as specified in {@link sap.ui.model.odata.v4.ODataModel}.
1009
- * @throws {Error}
1010
- * If the given group ID is invalid, the binding has pending changes, refresh on this
1011
- * binding is not supported, a group ID different from the binding's group ID is specified
1012
- * for a suspended binding, or a value of type boolean is given.
1019
+ * @throws {Error} If
1020
+ * <ul>
1021
+ * <li> the given group ID is invalid,
1022
+ * <li> there are pending changes that cannot be ignored,
1023
+ * <li> refresh on this binding is not supported,
1024
+ * <li> a group ID different from the binding's group ID is specified for a suspended
1025
+ * binding,
1026
+ * <li> or a value of type boolean is given.
1027
+ * </ul> Since 1.100.0, pending changes are ignored if they relate to a
1028
+ * {@link sap.ui.model.odata.v4.Context#setKeepAlive kept-alive} context of this binding, and
1029
+ * {@link sap.ui.model.odata.v4.Context#isTransient transient} contexts of a
1030
+ * {@link #getRootBinding root binding} do not count as pending changes.
1013
1031
  *
1014
1032
  * @public
1015
1033
  * @see sap.ui.model.Binding#refresh
@@ -1159,7 +1177,7 @@ sap.ui.define([
1159
1177
  if (!this.isRoot()) {
1160
1178
  throw new Error("Refresh on this binding is not supported");
1161
1179
  }
1162
- if (this.hasPendingChanges()) {
1180
+ if (this.hasPendingChanges(true)) {
1163
1181
  throw new Error("Cannot refresh due to pending changes");
1164
1182
  }
1165
1183
  this.oModel.checkGroupId(sGroupId);
@@ -74,7 +74,7 @@ sap.ui.define([
74
74
  * @mixes sap.ui.model.odata.v4.ODataParentBinding
75
75
  * @public
76
76
  * @since 1.37.0
77
- * @version 1.99.0
77
+ * @version 1.100.1
78
78
  *
79
79
  * @borrows sap.ui.model.odata.v4.ODataBinding#getGroupId as #getGroupId
80
80
  * @borrows sap.ui.model.odata.v4.ODataBinding#getRootBinding as #getRootBinding
@@ -840,9 +840,7 @@ sap.ui.define([
840
840
  * Since 1.98.0, a single-valued navigation property can be treated like a function if
841
841
  * <ul>
842
842
  * <li> it has the same type as the operation binding's parent context,
843
- * <li> that parent context is in the collection (has an index, see
844
- * {@link sap.ui.model.odata.v4.Context#getIndex}) of a list binding for a top-level entity
845
- * set,
843
+ * <li> that parent context is in a list binding for a top-level entity set,
846
844
  * <li> there is a navigation property binding which points to that same entity set,
847
845
  * <li> no operation parameters have been set,
848
846
  * <li> the <code>bReplaceWithRVC</code> parameter is used.
@@ -950,7 +948,7 @@ sap.ui.define([
950
948
  + sResolvedPath);
951
949
  }
952
950
  if (bReplaceWithRVC) {
953
- if (!this.oContext.getBinding || this.oContext.iIndex === undefined) {
951
+ if (!this.oContext.getBinding) {
954
952
  throw new Error("Cannot replace this parent context: " + this.oContext);
955
953
  }
956
954
  this.oContext.getBinding().checkKeepAlive(this.oContext);
@@ -1268,6 +1266,36 @@ sap.ui.define([
1268
1266
  && !oMetadata.$EntitySetPath.includes("/"); // case 3
1269
1267
  };
1270
1268
 
1269
+ /**
1270
+ * Refreshes all dependent bindings with the given parameters and waits for them to have
1271
+ * finished.
1272
+ *
1273
+ * @param {string} sResourcePathPrefix
1274
+ * The resource path prefix which is used to delete the dependent caches and corresponding
1275
+ * messages; may be "" but not <code>undefined</code>
1276
+ * @param {string} [sGroupId]
1277
+ * The group ID to be used for refresh
1278
+ * @param {boolean} [bCheckUpdate]
1279
+ * If <code>true</code>, a property binding is expected to check for updates
1280
+ * @param {boolean} [bKeepCacheOnError]
1281
+ * If <code>true</code>, the binding data remains unchanged if the refresh fails
1282
+ * @returns {sap.ui.base.SyncPromise}
1283
+ * A promise resolving when all dependent bindings are refreshed; it is rejected
1284
+ * when the refresh fails; the promise is resolved immediately on a suspended binding
1285
+ * @throws {Error}
1286
+ * If the binding's root binding is suspended and a group ID different from the binding's
1287
+ * group ID is given
1288
+ *
1289
+ * @private
1290
+ */
1291
+ ODataContextBinding.prototype.refreshDependentBindings = function (sResourcePathPrefix,
1292
+ sGroupId, bCheckUpdate, bKeepCacheOnError) {
1293
+ return SyncPromise.all(this.getDependentBindings().map(function (oDependentBinding) {
1294
+ return oDependentBinding.refreshInternal(sResourcePathPrefix, sGroupId, bCheckUpdate,
1295
+ bKeepCacheOnError);
1296
+ }));
1297
+ };
1298
+
1271
1299
  /**
1272
1300
  * @override
1273
1301
  * @see sap.ui.model.odata.v4.ODataBinding#refreshInternal
@@ -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.99.0
61
+ * @version 1.100.1
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
@@ -423,6 +423,9 @@ sap.ui.define([
423
423
  oOldAggregation = this.mParameters && this.mParameters.$$aggregation,
424
424
  sOldApply = this.mQueryOptions && this.mQueryOptions.$apply;
425
425
 
426
+ if ("$$getKeepAliveContext" in mParameters && "$apply" in mParameters) {
427
+ throw new Error("Cannot combine $$getKeepAliveContext and $apply");
428
+ }
426
429
  if ("$$aggregation" in mParameters) {
427
430
  if ("$apply" in mParameters) {
428
431
  throw new Error("Cannot combine $$aggregation and $apply");
@@ -979,20 +982,13 @@ sap.ui.define([
979
982
  if (this.aContexts[iStart + i] === undefined && aResults[i]) {
980
983
  bChanged = true;
981
984
  i$skipIndex = iStart + i - this.iCreatedContexts; // index on server ($skip)
982
- sPredicate = _Helper.getPrivateAnnotation(aResults[i], "predicate")
983
- || _Helper.getPrivateAnnotation(aResults[i], "transientPredicate");
985
+ sPredicate = _Helper.getPrivateAnnotation(aResults[i], "predicate");
984
986
  sContextPath = sPath + (sPredicate || "/" + i$skipIndex);
985
987
  oContext = this.mPreviousContextsByPath[sContextPath];
986
- if (oContext && (!oContext.created() || oContext.isTransient())) {
987
- // reuse the previous context, unless it is created and persisted
988
+ if (oContext && !oContext.created()) {
989
+ // reuse the previous context, unless it is created (and persisted)
988
990
  delete this.mPreviousContextsByPath[sContextPath];
989
- if (oContext.isTransient() && !this.iCreatedContexts) {
990
- // this can only happen in bindings w/o cache, where all created contexts
991
- // are active
992
- this.iCreatedContexts = this.iActiveContexts = -oContext.iIndex;
993
- } else {
994
- oContext.iIndex = i$skipIndex;
995
- }
991
+ oContext.iIndex = i$skipIndex;
996
992
  oContext.checkUpdate();
997
993
  } else {
998
994
  oContext = Context.create(oModel, this, sContextPath, i$skipIndex);
@@ -1148,7 +1144,7 @@ sap.ui.define([
1148
1144
  * @see sap.ui.model.odata.v4.ODataBinding#doCreateCache
1149
1145
  */
1150
1146
  ODataListBinding.prototype.doCreateCache = function (sResourcePath, mQueryOptions, oContext,
1151
- sDeepResourcePath, bOldCacheReadOnly, oOldCache) {
1147
+ sDeepResourcePath, bKeepCreated, oOldCache) {
1152
1148
  var sBindingPath,
1153
1149
  aKeptElementPaths,
1154
1150
  oCache,
@@ -1161,10 +1157,10 @@ sap.ui.define([
1161
1157
  return that.mPreviousContextsByPath[sPath].isKeepAlive();
1162
1158
  });
1163
1159
 
1164
- if (!bOldCacheReadOnly && (aKeptElementPaths.length || this.iCreatedContexts)) {
1160
+ if (this.iCreatedContexts || !bKeepCreated && aKeptElementPaths.length) {
1165
1161
  oOldCache.reset(aKeptElementPaths.map(function (sPath) {
1166
1162
  return _Helper.getRelativePath(sPath, sBindingPath);
1167
- }));
1163
+ }), bKeepCreated);
1168
1164
  // Note: #inheritQueryOptions as called below should not matter in case of own
1169
1165
  // requests, which are a precondition for kept-alive elements
1170
1166
  oOldCache.setQueryOptions(mQueryOptions, true);
@@ -1173,9 +1169,11 @@ sap.ui.define([
1173
1169
  }
1174
1170
  }
1175
1171
 
1176
- oCache = _AggregationCache.create(this.oModel.oRequestor, sResourcePath, sDeepResourcePath,
1177
- this.mParameters.$$aggregation, this.inheritQueryOptions(mQueryOptions, oContext),
1178
- this.oModel.bAutoExpandSelect, this.bSharedRequest);
1172
+ mQueryOptions = this.inheritQueryOptions(mQueryOptions, oContext);
1173
+ oCache = this.getCacheAndMoveKeepAliveContexts(sResourcePath, mQueryOptions)
1174
+ || _AggregationCache.create(this.oModel.oRequestor, sResourcePath, sDeepResourcePath,
1175
+ this.mParameters.$$aggregation, mQueryOptions, this.oModel.bAutoExpandSelect,
1176
+ this.bSharedRequest);
1179
1177
 
1180
1178
  if (aKeptElementPaths && aKeptElementPaths.length) {
1181
1179
  oCache.setLateQueryOptions(oOldCache.getLateQueryOptions());
@@ -1243,8 +1241,13 @@ sap.ui.define([
1243
1241
  bNew = true;
1244
1242
  }
1245
1243
  oOldContext.iIndex = undefined;
1246
- this.aContexts[iIndex] = oResult;
1247
- this.oCache.doReplaceWith(iIndex, oElement);
1244
+ if (iIndex === undefined) {
1245
+ this.mPreviousContextsByPath[sPath] = oResult;
1246
+ this.oCache.addKeptElement(oElement);
1247
+ } else {
1248
+ this.aContexts[iIndex] = oResult;
1249
+ this.oCache.doReplaceWith(iIndex, oElement);
1250
+ }
1248
1251
  if (bKeepAlive) {
1249
1252
  this.mPreviousContextsByPath[oOldContext.getPath()] = oOldContext;
1250
1253
  if (bNew) {
@@ -1826,6 +1829,62 @@ sap.ui.define([
1826
1829
  }).concat(Object.values(this.mPreviousContextsByPath));
1827
1830
  };
1828
1831
 
1832
+ /**
1833
+ * Tries to get a cache from the model. This is only relevant for the $$getKeepAlive scenario
1834
+ * when the model created a temporary binding for this binding's path. If there is such a
1835
+ * binding, its contexts are moved here, it is destroyed and its cache is returned.
1836
+ *
1837
+ * @param {string} sResourcePath
1838
+ * The resoure path for the cache
1839
+ * @param {object} mQueryOptions
1840
+ * The query options for the cache
1841
+ * @returns {sap.ui.model.odata.v4.lib._CollectionCache|undefined}
1842
+ * The cache or <code>undefined</code> if the model has no matching temporary binding
1843
+ *
1844
+ * @private
1845
+ */
1846
+ ODataListBinding.prototype.getCacheAndMoveKeepAliveContexts = function (sResourcePath,
1847
+ mQueryOptions) {
1848
+ var oBinding,
1849
+ oCache,
1850
+ that = this;
1851
+
1852
+ if (!this.mParameters.$$getKeepAliveContext) {
1853
+ return undefined;
1854
+ }
1855
+ // $$canonicalPath is not allowed, binding path and resource path are (almost) identical
1856
+ oBinding = this.oModel.releaseKeepAliveBinding("/" + sResourcePath);
1857
+ if (!oBinding) {
1858
+ return undefined;
1859
+ }
1860
+
1861
+ Object.keys(oBinding.mParameters).concat(Object.keys(this.mParameters))
1862
+ .forEach(function (sParameter) {
1863
+ if ((sParameter[0] !== "$" || sParameter === "$$patchWithoutSideEffects"
1864
+ || sParameter === "$$updateGroupId")
1865
+ && that.mParameters[sParameter] !== oBinding.mParameters[sParameter]) {
1866
+ throw new Error(that + ": parameter does not match getKeepAliveContext: "
1867
+ + sParameter);
1868
+ }
1869
+ });
1870
+ // createAndSetCache copies them to the cache later
1871
+ this.mLateQueryOptions = _Helper.clone(mQueryOptions);
1872
+ _Helper.aggregateExpandSelect(this.mLateQueryOptions, oBinding.mLateQueryOptions);
1873
+ this.mPreviousContextsByPath = oBinding.mPreviousContextsByPath;
1874
+ Object.values(this.mPreviousContextsByPath).forEach(function (oContext) {
1875
+ oContext.oBinding = that;
1876
+ });
1877
+ oCache = oBinding.oCache;
1878
+ oCache.setQueryOptions(mQueryOptions);
1879
+ // avoid that the cache is set inactive or that contexts are destroyed
1880
+ oBinding.oCache = null;
1881
+ oBinding.oCachePromise = SyncPromise.resolve(null);
1882
+ oBinding.mPreviousContextsByPath = {};
1883
+ oBinding.destroy();
1884
+
1885
+ return oCache;
1886
+ };
1887
+
1829
1888
  /**
1830
1889
  * Returns already created binding contexts for all entities in this list binding for the range
1831
1890
  * determined by the given start index <code>iStart</code> and <code>iLength</code>.
@@ -2315,30 +2374,73 @@ sap.ui.define([
2315
2374
 
2316
2375
  /**
2317
2376
  * Calls {@link sap.ui.model.odata.v4.Context#setKeepAlive} at the context for the given path
2318
- * and returns it.
2377
+ * and returns it. Since 1.100.0 the function always returns such a context. If none exists yet,
2378
+ * it is created without data and a request for its entity is sent.
2319
2379
  *
2320
2380
  * @param {string} sPath
2321
2381
  * The path of the context to be kept alive
2322
2382
  * @param {boolean} [bRequestMessages]
2323
2383
  * Whether to request messages for the context's entity
2384
+ * @param {string} [sGroupId]
2385
+ * The group ID used for read requests for the context's entity or its properties. If not
2386
+ * given, the binding's {@link #getGroupId group ID} is used. Supported since 1.100.0
2324
2387
  * @returns {sap.ui.model.odata.v4.Context|undefined}
2325
- * The kept-alive context, or <code>undefined</code> if it does not exist
2326
- * @throws {Error}
2327
- * If {@link sap.ui.model.odata.v4.Context#setKeepAlive} fails
2388
+ * The kept-alive context, or <code>undefined</code> if the binding's root binding is
2389
+ * suspended and no context with the given path exists
2390
+ * @throws {Error} If
2391
+ * <ul>
2392
+ * <li> the group ID is invalid,
2393
+ * <li> the binding is unresolved,
2394
+ * <li> the given context path does not match this binding,
2395
+ * <li> or {@link sap.ui.model.odata.v4.Context#setKeepAlive} fails
2396
+ * </ul>
2328
2397
  *
2329
2398
  * @public
2330
2399
  * @see sap.ui.model.odata.v4.Model#getKeepAliveContext
2331
2400
  * @since 1.99.0
2332
2401
  */
2333
- ODataListBinding.prototype.getKeepAliveContext = function (sPath, bRequestMessages) {
2402
+ ODataListBinding.prototype.getKeepAliveContext = function (sPath, bRequestMessages, sGroupId) {
2334
2403
  var oContext = this.mPreviousContextsByPath[sPath]
2335
2404
  || this.aContexts.find(function (oCandidate) {
2336
2405
  return oCandidate && oCandidate.getPath() === sPath;
2337
- });
2406
+ }),
2407
+ iPredicateIndex = this.oModel.getPredicateIndex(sPath),
2408
+ sResolvedPath = this.getResolvedPath();
2338
2409
 
2339
- if (oContext) {
2340
- oContext.setKeepAlive(true, oContext.fnOnBeforeDestroy, bRequestMessages);
2410
+ this.oModel.checkGroupId(sGroupId);
2411
+ if (!oContext) {
2412
+ if (!sResolvedPath) {
2413
+ throw new Error("Binding is unresolved: " + this);
2414
+ }
2415
+ if (this.isRootBindingSuspended()) {
2416
+ return undefined;
2417
+ }
2418
+ if (sPath.slice(0, iPredicateIndex) !== sResolvedPath) {
2419
+ throw new Error(this + ": Not a valid context path: " + sPath);
2420
+ }
2421
+ oContext = Context.create(this.oModel, this, sPath);
2422
+ this.mPreviousContextsByPath[sPath] = oContext;
2423
+ this.oCachePromise.then(function (oCache) {
2424
+ // call ASAP so that dependent property bindings find the entity in the cache
2425
+ var oElement = oCache.createEmptyElement(sPath.slice(iPredicateIndex));
2426
+
2427
+ if (sGroupId) {
2428
+ _Helper.setPrivateAnnotation(oElement, "groupId", sGroupId);
2429
+ }
2430
+ });
2431
+ // *request*Object so that requestProperty definitely runs after setKeepAlive and adds
2432
+ // to mLateProperties
2433
+ this.oModel.getMetaModel().requestObject(_Helper.getMetaPath(sResolvedPath) + "/")
2434
+ .then(function (oType) {
2435
+ // ensure that the key properties are requested even if unbound
2436
+ return oContext.requestProperty(oType.$Key.map(function (vKey) {
2437
+ return typeof vKey === "object" ? Object.values(vKey)[0] : vKey;
2438
+ }));
2439
+ })
2440
+ .catch(this.oModel.getReporter());
2341
2441
  }
2442
+
2443
+ oContext.setKeepAlive(true, oContext.fnOnBeforeDestroy, bRequestMessages);
2342
2444
  return oContext;
2343
2445
  };
2344
2446
 
@@ -2452,6 +2554,18 @@ sap.ui.define([
2452
2554
  };
2453
2555
 
2454
2556
  /**
2557
+ * Check whether this binding is an active $$getKeepAliveContext binding for the given path.
2558
+ *
2559
+ * @param {string} sPath - An absolute binding path
2560
+ * @returns {boolean} - Whether this binding matches
2561
+ *
2562
+ * @private
2563
+ */
2564
+ ODataListBinding.prototype.isKeepAliveBindingFor = function (sPath) {
2565
+ return this.mParameters.$$getKeepAliveContext && this.getResolvedPath() === sPath;
2566
+ };
2567
+
2568
+ /**
2455
2569
  * Enhance the inherited query options by the given query options if this binding does not have
2456
2570
  * any binding parameters. If both have a '$orderby', the resulting '$orderby' is the
2457
2571
  * concatenation of both '$orderby' with the given one first. If both have a '$filter', the
@@ -2557,16 +2671,11 @@ sap.ui.define([
2557
2671
  _bCheckUpdate, bKeepCacheOnError) {
2558
2672
  var that = this;
2559
2673
 
2560
- function onRemove(sPredicate) {
2561
- var sPath = that.getResolvedPath();
2562
-
2563
- that.mPreviousContextsByPath[sPath + sPredicate].resetKeepAlive();
2564
- }
2565
-
2566
2674
  // calls refreshInternal on all given bindings and returns an array of promises
2567
2675
  function refreshAll(aBindings) {
2568
2676
  return aBindings.map(function (oBinding) {
2569
- if (oBinding.bIsBeingDestroyed) {
2677
+ if (oBinding.bIsBeingDestroyed
2678
+ || oBinding.getContext().isKeepAlive() && oBinding.hasPendingChanges()) {
2570
2679
  return;
2571
2680
  }
2572
2681
  // Call refreshInternal with bCheckUpdate = false because property bindings
@@ -2588,6 +2697,7 @@ sap.ui.define([
2588
2697
  return this.oCachePromise.then(function (oCache) {
2589
2698
  var iActiveContexts = that.iActiveContexts,
2590
2699
  iCreatedContexts = that.iCreatedContexts,
2700
+ aContexts = that.aContexts.slice(0, iCreatedContexts),
2591
2701
  aDependentBindings,
2592
2702
  oKeptElementsPromise,
2593
2703
  oPromise = that.oRefreshPromise;
@@ -2596,7 +2706,15 @@ sap.ui.define([
2596
2706
  that.removeCachesAndMessages(sResourcePathPrefix);
2597
2707
  that.fetchCache(that.oContext, false, /*bKeepQueryOptions*/true, bKeepCacheOnError);
2598
2708
  oKeptElementsPromise = that.oCachePromise.then(function (oNewCache) {
2599
- return oNewCache.refreshKeptElements(that.lockGroup(sGroupId), onRemove);
2709
+ return oNewCache.refreshKeptElements(that.lockGroup(sGroupId),
2710
+ function onRemove(sPredicate, iIndex) {
2711
+ if (iIndex === undefined) {
2712
+ that.mPreviousContextsByPath[that.getResolvedPath() + sPredicate]
2713
+ .resetKeepAlive();
2714
+ } else { // Note: implies oContext.created()
2715
+ that.destroyCreated(that.aContexts[iIndex]);
2716
+ }
2717
+ });
2600
2718
  }).catch(function (oError) {
2601
2719
  that.oModel.reportError("Failed to refresh kept-alive elements", sClassName,
2602
2720
  oError);
@@ -2608,22 +2726,38 @@ sap.ui.define([
2608
2726
  throw oError;
2609
2727
  }
2610
2728
  return that.fetchResourcePath(that.oContext).then(function (sResourcePath) {
2729
+ var i;
2730
+
2611
2731
  if (!that.bRelative || oCache.getResourcePath() === sResourcePath) {
2612
- that.oCache = oCache;
2613
- that.oCachePromise = SyncPromise.resolve(oCache);
2732
+ if (that.oCache === oCache) {
2733
+ oCache.restore(true);
2734
+ } else { // still needed in case of _AggregationCache
2735
+ oCache.setActive(true);
2736
+ that.oCache = oCache;
2737
+ that.oCachePromise = SyncPromise.resolve(oCache);
2738
+ }
2614
2739
  that.iActiveContexts = iActiveContexts;
2615
2740
  that.iCreatedContexts = iCreatedContexts;
2616
- oCache.setActive(true);
2741
+ for (i = 0; i < iCreatedContexts; i += 1) {
2742
+ aContexts[i].iIndex = i - iCreatedContexts;
2743
+ delete that.mPreviousContextsByPath[aContexts[i].getPath()];
2744
+ }
2745
+ that.aContexts = aContexts; // restore created contexts
2617
2746
  that._fireChange({reason : ChangeReason.Change});
2618
2747
  }
2619
2748
  throw oError;
2620
2749
  });
2750
+ }).finally(function () {
2751
+ if (oCache.restore) {
2752
+ oCache.restore(false);
2753
+ }
2621
2754
  });
2622
2755
  }
2623
2756
  }
2624
2757
  // Note: after reset the dependent bindings cannot be found any more
2625
2758
  aDependentBindings = that.getDependentBindings();
2626
- that.reset(ChangeReason.Refresh, true); // this may reset that.oRefreshPromise
2759
+ // this may reset that.oRefreshPromise
2760
+ that.reset(ChangeReason.Refresh, bKeepCacheOnError ? false : undefined);
2627
2761
  return SyncPromise.all(
2628
2762
  refreshAll(aDependentBindings).concat(oPromise, oKeptElementsPromise,
2629
2763
  // Update after refresh event, otherwise $count is fetched before the request
@@ -3014,19 +3148,21 @@ sap.ui.define([
3014
3148
  * A change reason; if given, a refresh event with this reason is fired and the next
3015
3149
  * getContexts() fires a change event with this reason. Change reason "change" is ignored
3016
3150
  * as long as the binding is still empty.
3017
- * @param {boolean} [bDropTransient]
3018
- * Whether transient contexts shall also be dropped, not just created persisted ones
3151
+ * @param {boolean} [bDrop]
3152
+ * By default, all created persisted contexts are dropped while transient ones are not.
3153
+ * <code>true</code> also drops transient ones, and <code>false</code> keeps created persisted
3154
+ * that started as inactive.
3019
3155
  *
3020
3156
  * @private
3021
3157
  */
3022
- ODataListBinding.prototype.reset = function (sChangeReason, bDropTransient) {
3158
+ ODataListBinding.prototype.reset = function (sChangeReason, bDrop) {
3023
3159
  var oContext,
3024
3160
  bEmpty = this.iCurrentEnd === 0,
3025
3161
  iTransient = 0,
3026
3162
  i,
3027
3163
  that = this;
3028
3164
 
3029
- if (bDropTransient) {
3165
+ if (bDrop === true) { // drop 'em all
3030
3166
  this.iActiveContexts = 0;
3031
3167
  this.iCreatedContexts = 0;
3032
3168
  }
@@ -3036,10 +3172,11 @@ sap.ui.define([
3036
3172
  });
3037
3173
  for (i = 0; i < this.iCreatedContexts; i += 1) {
3038
3174
  oContext = this.aContexts[i];
3039
- if (oContext.isTransient()) {
3175
+ if (oContext.isTransient()
3176
+ || bDrop === false && oContext.isInactive() !== undefined) {
3040
3177
  this.aContexts[iTransient] = oContext;
3041
3178
  iTransient += 1;
3042
- } else { // Note: "created persisted" elements must be active
3179
+ } else { // Note: "created persisted" elements must be active - drop 'em
3043
3180
  this.iActiveContexts -= 1;
3044
3181
  this.mPreviousContextsByPath[oContext.getPath()] = oContext;
3045
3182
  }
@@ -157,7 +157,7 @@ sap.ui.define([
157
157
  * @hideconstructor
158
158
  * @public
159
159
  * @since 1.37.0
160
- * @version 1.99.0
160
+ * @version 1.100.1
161
161
  */
162
162
  ODataMetaModel = MetaModel.extend("sap.ui.model.odata.v4.ODataMetaModel", {
163
163
  constructor : constructor