@openui5/sap.ui.core 1.108.0 → 1.109.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 (352) hide show
  1. package/THIRDPARTY.txt +1 -1
  2. package/package.json +1 -1
  3. package/src/jquery.sap.global.js +1 -1
  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 +125 -84
  9. package/src/sap/base/i18n/ResourceBundle.js +41 -11
  10. package/src/sap/base/util/includes.js +1 -1
  11. package/src/sap/base/util/restricted/_CancelablePromise.js +1 -1
  12. package/src/sap/base/util/restricted/_castArray.js +1 -1
  13. package/src/sap/base/util/restricted/_compact.js +1 -1
  14. package/src/sap/base/util/restricted/_curry.js +1 -1
  15. package/src/sap/base/util/restricted/_debounce.js +1 -1
  16. package/src/sap/base/util/restricted/_difference.js +1 -1
  17. package/src/sap/base/util/restricted/_differenceBy.js +1 -1
  18. package/src/sap/base/util/restricted/_differenceWith.js +1 -1
  19. package/src/sap/base/util/restricted/_flatMap.js +1 -1
  20. package/src/sap/base/util/restricted/_flatMapDeep.js +1 -1
  21. package/src/sap/base/util/restricted/_flatMapDepth.js +1 -1
  22. package/src/sap/base/util/restricted/_flatten.js +1 -1
  23. package/src/sap/base/util/restricted/_flattenDeep.js +1 -1
  24. package/src/sap/base/util/restricted/_flattenDepth.js +1 -1
  25. package/src/sap/base/util/restricted/_intersection.js +1 -1
  26. package/src/sap/base/util/restricted/_intersectionBy.js +1 -1
  27. package/src/sap/base/util/restricted/_intersectionWith.js +1 -1
  28. package/src/sap/base/util/restricted/_isEqual.js +1 -1
  29. package/src/sap/base/util/restricted/_isEqualWith.js +1 -1
  30. package/src/sap/base/util/restricted/_isNil.js +1 -1
  31. package/src/sap/base/util/restricted/_max.js +1 -1
  32. package/src/sap/base/util/restricted/_merge.js +1 -1
  33. package/src/sap/base/util/restricted/_mergeWith.js +1 -1
  34. package/src/sap/base/util/restricted/_min.js +1 -1
  35. package/src/sap/base/util/restricted/_omit.js +1 -1
  36. package/src/sap/base/util/restricted/_pick.js +1 -1
  37. package/src/sap/base/util/restricted/_pickBy.js +1 -1
  38. package/src/sap/base/util/restricted/_throttle.js +1 -1
  39. package/src/sap/base/util/restricted/_toArray.js +1 -1
  40. package/src/sap/base/util/restricted/_union.js +1 -1
  41. package/src/sap/base/util/restricted/_unionBy.js +1 -1
  42. package/src/sap/base/util/restricted/_unionWith.js +1 -1
  43. package/src/sap/base/util/restricted/_uniq.js +1 -1
  44. package/src/sap/base/util/restricted/_uniqBy.js +1 -1
  45. package/src/sap/base/util/restricted/_uniqWith.js +1 -1
  46. package/src/sap/base/util/restricted/_without.js +1 -1
  47. package/src/sap/base/util/restricted/_xor.js +1 -1
  48. package/src/sap/base/util/restricted/_xorBy.js +1 -1
  49. package/src/sap/base/util/restricted/_xorWith.js +1 -1
  50. package/src/sap/base/util/restricted/_zipObject.js +1 -1
  51. package/src/sap/base/util/restricted/_zipObjectDeep.js +1 -1
  52. package/src/sap/base/util/values.js +2 -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/Interface.js +1 -1
  58. package/src/sap/ui/base/ManagedObject.js +1 -1
  59. package/src/sap/ui/base/ManagedObjectMetadata.js +1 -1
  60. package/src/sap/ui/base/ManagedObjectObserver.js +33 -11
  61. package/src/sap/ui/base/Metadata.js +1 -1
  62. package/src/sap/ui/base/Object.js +1 -1
  63. package/src/sap/ui/base/ObjectPool.js +1 -1
  64. package/src/sap/ui/core/.library +3 -3
  65. package/src/sap/ui/core/BusyIndicator.js +1 -1
  66. package/src/sap/ui/core/Component.js +1 -1
  67. package/src/sap/ui/core/ComponentContainer.js +1 -1
  68. package/src/sap/ui/core/ComponentMetadata.js +1 -1
  69. package/src/sap/ui/core/ComponentSupport.js +1 -1
  70. package/src/sap/ui/core/Configuration.js +1 -1
  71. package/src/sap/ui/core/Control.js +1 -1
  72. package/src/sap/ui/core/Core.js +4 -4
  73. package/src/sap/ui/core/CustomData.js +1 -1
  74. package/src/sap/ui/core/DeclarativeSupport.js +1 -1
  75. package/src/sap/ui/core/Element.js +1 -1
  76. package/src/sap/ui/core/ElementMetadata.js +1 -1
  77. package/src/sap/ui/core/EnabledPropagator.js +1 -1
  78. package/src/sap/ui/core/EventBus.js +1 -1
  79. package/src/sap/ui/core/Fragment.js +1 -1
  80. package/src/sap/ui/core/HTML.js +1 -1
  81. package/src/sap/ui/core/History.js +1 -1
  82. package/src/sap/ui/core/Icon.js +1 -1
  83. package/src/sap/ui/core/IndicationColorSupport.js +1 -1
  84. package/src/sap/ui/core/IntervalTrigger.js +1 -1
  85. package/src/sap/ui/core/InvisibleMessage.js +1 -1
  86. package/src/sap/ui/core/InvisibleRenderer.js +1 -1
  87. package/src/sap/ui/core/InvisibleText.js +1 -1
  88. package/src/sap/ui/core/Item.js +1 -1
  89. package/src/sap/ui/core/LabelEnablement.js +1 -1
  90. package/src/sap/ui/core/LayoutData.js +1 -1
  91. package/src/sap/ui/core/ListItem.js +1 -1
  92. package/src/sap/ui/core/LocalBusyIndicator.js +1 -1
  93. package/src/sap/ui/core/Locale.js +1 -1
  94. package/src/sap/ui/core/LocaleData.js +133 -1
  95. package/src/sap/ui/core/Manifest.js +1 -1
  96. package/src/sap/ui/core/Message.js +1 -1
  97. package/src/sap/ui/core/RenderManager.js +82 -50
  98. package/src/sap/ui/core/Renderer.js +1 -1
  99. package/src/sap/ui/core/Rendering.js +29 -9
  100. package/src/sap/ui/core/ResizeHandler.js +1 -1
  101. package/src/sap/ui/core/ScrollBar.js +1 -1
  102. package/src/sap/ui/core/SeparatorItem.js +1 -1
  103. package/src/sap/ui/core/Title.js +1 -1
  104. package/src/sap/ui/core/TooltipBase.js +1 -1
  105. package/src/sap/ui/core/UIArea.js +7 -5
  106. package/src/sap/ui/core/UIComponent.js +1 -1
  107. package/src/sap/ui/core/UIComponentMetadata.js +1 -1
  108. package/src/sap/ui/core/ValueStateSupport.js +1 -1
  109. package/src/sap/ui/core/VariantLayoutData.js +1 -1
  110. package/src/sap/ui/core/XMLComposite.js +1 -1
  111. package/src/sap/ui/core/XMLCompositeMetadata.js +1 -1
  112. package/src/sap/ui/core/XMLTemplateProcessor.js +1 -3
  113. package/src/sap/ui/core/cldr/ar.json +330 -0
  114. package/src/sap/ui/core/cldr/ar_EG.json +330 -0
  115. package/src/sap/ui/core/cldr/ar_SA.json +330 -0
  116. package/src/sap/ui/core/cldr/bg.json +295 -0
  117. package/src/sap/ui/core/cldr/ca.json +329 -0
  118. package/src/sap/ui/core/cldr/cs.json +328 -0
  119. package/src/sap/ui/core/cldr/cy.json +260 -0
  120. package/src/sap/ui/core/cldr/da.json +295 -0
  121. package/src/sap/ui/core/cldr/de.json +329 -0
  122. package/src/sap/ui/core/cldr/de_AT.json +329 -0
  123. package/src/sap/ui/core/cldr/de_CH.json +329 -0
  124. package/src/sap/ui/core/cldr/el.json +228 -0
  125. package/src/sap/ui/core/cldr/el_CY.json +228 -0
  126. package/src/sap/ui/core/cldr/en.json +294 -0
  127. package/src/sap/ui/core/cldr/en_AU.json +294 -0
  128. package/src/sap/ui/core/cldr/en_GB.json +294 -0
  129. package/src/sap/ui/core/cldr/en_HK.json +294 -0
  130. package/src/sap/ui/core/cldr/en_IE.json +294 -0
  131. package/src/sap/ui/core/cldr/en_IN.json +294 -0
  132. package/src/sap/ui/core/cldr/en_NZ.json +294 -0
  133. package/src/sap/ui/core/cldr/en_PG.json +294 -0
  134. package/src/sap/ui/core/cldr/en_SG.json +294 -0
  135. package/src/sap/ui/core/cldr/en_ZA.json +294 -0
  136. package/src/sap/ui/core/cldr/es.json +261 -0
  137. package/src/sap/ui/core/cldr/es_AR.json +261 -0
  138. package/src/sap/ui/core/cldr/es_BO.json +261 -0
  139. package/src/sap/ui/core/cldr/es_CL.json +261 -0
  140. package/src/sap/ui/core/cldr/es_CO.json +261 -0
  141. package/src/sap/ui/core/cldr/es_MX.json +261 -0
  142. package/src/sap/ui/core/cldr/es_PE.json +261 -0
  143. package/src/sap/ui/core/cldr/es_UY.json +261 -0
  144. package/src/sap/ui/core/cldr/es_VE.json +261 -0
  145. package/src/sap/ui/core/cldr/et.json +294 -0
  146. package/src/sap/ui/core/cldr/fa.json +296 -0
  147. package/src/sap/ui/core/cldr/fi.json +328 -0
  148. package/src/sap/ui/core/cldr/fr.json +294 -0
  149. package/src/sap/ui/core/cldr/fr_BE.json +294 -0
  150. package/src/sap/ui/core/cldr/fr_CA.json +294 -0
  151. package/src/sap/ui/core/cldr/fr_CH.json +294 -0
  152. package/src/sap/ui/core/cldr/fr_LU.json +294 -0
  153. package/src/sap/ui/core/cldr/he.json +329 -0
  154. package/src/sap/ui/core/cldr/hi.json +261 -0
  155. package/src/sap/ui/core/cldr/hr.json +294 -0
  156. package/src/sap/ui/core/cldr/hu.json +362 -0
  157. package/src/sap/ui/core/cldr/id.json +294 -0
  158. package/src/sap/ui/core/cldr/it.json +294 -0
  159. package/src/sap/ui/core/cldr/it_CH.json +294 -0
  160. package/src/sap/ui/core/cldr/ja.json +328 -0
  161. package/src/sap/ui/core/cldr/kk.json +294 -0
  162. package/src/sap/ui/core/cldr/ko.json +328 -0
  163. package/src/sap/ui/core/cldr/lt.json +294 -0
  164. package/src/sap/ui/core/cldr/lv.json +294 -0
  165. package/src/sap/ui/core/cldr/ms.json +262 -0
  166. package/src/sap/ui/core/cldr/nb.json +295 -0
  167. package/src/sap/ui/core/cldr/nl.json +261 -0
  168. package/src/sap/ui/core/cldr/nl_BE.json +261 -0
  169. package/src/sap/ui/core/cldr/pl.json +328 -0
  170. package/src/sap/ui/core/cldr/pt.json +294 -0
  171. package/src/sap/ui/core/cldr/pt_PT.json +294 -0
  172. package/src/sap/ui/core/cldr/ro.json +294 -0
  173. package/src/sap/ui/core/cldr/ru.json +294 -0
  174. package/src/sap/ui/core/cldr/ru_UA.json +294 -0
  175. package/src/sap/ui/core/cldr/sk.json +328 -0
  176. package/src/sap/ui/core/cldr/sl.json +328 -0
  177. package/src/sap/ui/core/cldr/sr.json +294 -0
  178. package/src/sap/ui/core/cldr/sr_Latn.json +294 -0
  179. package/src/sap/ui/core/cldr/sv.json +295 -0
  180. package/src/sap/ui/core/cldr/th.json +362 -0
  181. package/src/sap/ui/core/cldr/tr.json +362 -0
  182. package/src/sap/ui/core/cldr/uk.json +294 -0
  183. package/src/sap/ui/core/cldr/vi.json +294 -0
  184. package/src/sap/ui/core/cldr/zh_CN.json +329 -0
  185. package/src/sap/ui/core/cldr/zh_HK.json +329 -0
  186. package/src/sap/ui/core/cldr/zh_SG.json +329 -0
  187. package/src/sap/ui/core/cldr/zh_TW.json +329 -0
  188. package/src/sap/ui/core/date/Japanese.js +30 -0
  189. package/src/sap/ui/core/delegate/ItemNavigation.js +1 -1
  190. package/src/sap/ui/core/delegate/ScrollEnablement.js +1 -1
  191. package/src/sap/ui/core/dnd/DragAndDrop.js +2 -2
  192. package/src/sap/ui/core/dnd/DragDropBase.js +1 -1
  193. package/src/sap/ui/core/dnd/DragDropInfo.js +1 -1
  194. package/src/sap/ui/core/dnd/DragInfo.js +1 -1
  195. package/src/sap/ui/core/dnd/DropInfo.js +1 -1
  196. package/src/sap/ui/core/format/DateFormat.js +122 -2
  197. package/src/sap/ui/core/format/NumberFormat.js +111 -70
  198. package/src/sap/ui/core/format/TimezoneUtil.js +2 -2
  199. package/src/sap/ui/core/hyphenation/Hyphenation.js +1 -1
  200. package/src/sap/ui/core/library.js +3 -3
  201. package/src/sap/ui/core/message/ControlMessageProcessor.js +1 -1
  202. package/src/sap/ui/core/message/Message.js +1 -1
  203. package/src/sap/ui/core/message/MessageManager.js +1 -1
  204. package/src/sap/ui/core/message/MessageParser.js +1 -1
  205. package/src/sap/ui/core/message/MessageProcessor.js +1 -1
  206. package/src/sap/ui/core/mvc/HTMLView.js +1 -1
  207. package/src/sap/ui/core/mvc/JSONView.js +1 -1
  208. package/src/sap/ui/core/mvc/JSView.js +1 -1
  209. package/src/sap/ui/core/mvc/TemplateView.js +1 -1
  210. package/src/sap/ui/core/mvc/View.js +3 -3
  211. package/src/sap/ui/core/mvc/ViewType.js +4 -0
  212. package/src/sap/ui/core/mvc/XMLView.js +1 -1
  213. package/src/sap/ui/core/plugin/DeclarativeSupport.js +1 -1
  214. package/src/sap/ui/core/plugin/LessSupport.js +1 -1
  215. package/src/sap/ui/core/plugin/TemplatingSupport.js +1 -1
  216. package/src/sap/ui/core/postmessage/Bus.js +12 -17
  217. package/src/sap/ui/core/postmessage/confirmationDialog.js +1 -1
  218. package/src/sap/ui/core/search/OpenSearchProvider.js +1 -1
  219. package/src/sap/ui/core/search/SearchProvider.js +1 -1
  220. package/src/sap/ui/core/service/Service.js +1 -1
  221. package/src/sap/ui/core/service/ServiceFactory.js +1 -1
  222. package/src/sap/ui/core/service/ServiceFactoryRegistry.js +1 -1
  223. package/src/sap/ui/core/support/Plugin.js +1 -1
  224. package/src/sap/ui/core/support/Support.js +1 -1
  225. package/src/sap/ui/core/support/plugins/ControlTree.js +1 -1
  226. package/src/sap/ui/core/support/plugins/Interaction.js +1 -1
  227. package/src/sap/ui/core/support/plugins/LocalStorage.js +1 -1
  228. package/src/sap/ui/core/support/plugins/Performance.js +1 -1
  229. package/src/sap/ui/core/support/plugins/Selector.js +1 -1
  230. package/src/sap/ui/core/support/plugins/TechInfo.js +1 -1
  231. package/src/sap/ui/core/support/plugins/Trace.js +1 -1
  232. package/src/sap/ui/core/support/plugins/ViewInfo.js +1 -1
  233. package/src/sap/ui/core/themes/base/Icon.less +17 -4
  234. package/src/sap/ui/core/themes/base/LocalBusyIndicator.less +1 -1
  235. package/src/sap/ui/core/themes/base/base.less +599 -90
  236. package/src/sap/ui/core/themes/base/global.less +64 -0
  237. package/src/sap/ui/core/themes/sap_hcb/global.less +65 -0
  238. package/src/sap/ui/core/tmpl/DOMAttribute.js +1 -1
  239. package/src/sap/ui/core/tmpl/DOMElement.js +1 -1
  240. package/src/sap/ui/core/tmpl/HandlebarsTemplate.js +1 -1
  241. package/src/sap/ui/core/tmpl/Template.js +1 -1
  242. package/src/sap/ui/core/tmpl/TemplateControl.js +1 -1
  243. package/src/sap/ui/core/util/AsyncHintsHelper.js +1 -1
  244. package/src/sap/ui/core/util/Export.js +1 -1
  245. package/src/sap/ui/core/util/ExportCell.js +1 -1
  246. package/src/sap/ui/core/util/ExportColumn.js +1 -1
  247. package/src/sap/ui/core/util/ExportRow.js +1 -1
  248. package/src/sap/ui/core/util/ExportType.js +1 -1
  249. package/src/sap/ui/core/util/ExportTypeCSV.js +1 -1
  250. package/src/sap/ui/core/util/File.js +1 -1
  251. package/src/sap/ui/core/util/LibraryInfo.js +1 -1
  252. package/src/sap/ui/core/util/MockServer.js +1 -1
  253. package/src/sap/ui/core/util/PasteHelper.js +1 -1
  254. package/src/sap/ui/core/util/reflection/XmlTreeModifier.js +1 -3
  255. package/src/sap/ui/core/util/serializer/HTMLViewSerializer.js +1 -1
  256. package/src/sap/ui/core/util/serializer/Serializer.js +1 -1
  257. package/src/sap/ui/core/util/serializer/ViewSerializer.js +1 -1
  258. package/src/sap/ui/core/util/serializer/XMLViewSerializer.js +1 -1
  259. package/src/sap/ui/core/util/serializer/delegate/Delegate.js +1 -1
  260. package/src/sap/ui/core/util/serializer/delegate/HTML.js +1 -1
  261. package/src/sap/ui/core/util/serializer/delegate/XML.js +1 -1
  262. package/src/sap/ui/core/ws/ReadyState.js +1 -1
  263. package/src/sap/ui/core/ws/SapPcpWebSocket.js +1 -1
  264. package/src/sap/ui/core/ws/WebSocket.js +1 -1
  265. package/src/sap/ui/debug/ControlTree.js +1 -1
  266. package/src/sap/ui/debug/DebugEnv.js +1 -1
  267. package/src/sap/ui/debug/PropertyList.js +1 -1
  268. package/src/sap/ui/model/ClientModel.js +1 -1
  269. package/src/sap/ui/model/CompositeDataState.js +1 -1
  270. package/src/sap/ui/model/CompositeType.js +1 -1
  271. package/src/sap/ui/model/DataState.js +1 -1
  272. package/src/sap/ui/model/MetaModel.js +1 -1
  273. package/src/sap/ui/model/Model.js +1 -1
  274. package/src/sap/ui/model/SelectionModel.js +1 -1
  275. package/src/sap/ui/model/SimpleType.js +1 -1
  276. package/src/sap/ui/model/TreeAutoExpandMode.js +1 -1
  277. package/src/sap/ui/model/Type.js +1 -1
  278. package/src/sap/ui/model/controlhelper/TreeBindingProxy.js +11 -3
  279. package/src/sap/ui/model/json/JSONModel.js +1 -1
  280. package/src/sap/ui/model/message/MessageModel.js +1 -1
  281. package/src/sap/ui/model/odata/ODataAnnotations.js +1 -1
  282. package/src/sap/ui/model/odata/ODataMessageParser.js +1 -1
  283. package/src/sap/ui/model/odata/ODataMetaModel.js +1 -1
  284. package/src/sap/ui/model/odata/ODataMetadata.js +1 -1
  285. package/src/sap/ui/model/odata/ODataModel.js +1 -1
  286. package/src/sap/ui/model/odata/type/Boolean.js +1 -1
  287. package/src/sap/ui/model/odata/type/Byte.js +1 -1
  288. package/src/sap/ui/model/odata/type/Currency.js +1 -1
  289. package/src/sap/ui/model/odata/type/Date.js +1 -1
  290. package/src/sap/ui/model/odata/type/DateTime.js +1 -1
  291. package/src/sap/ui/model/odata/type/DateTimeBase.js +1 -1
  292. package/src/sap/ui/model/odata/type/DateTimeOffset.js +1 -1
  293. package/src/sap/ui/model/odata/type/DateTimeWithTimezone.js +1 -1
  294. package/src/sap/ui/model/odata/type/Decimal.js +1 -1
  295. package/src/sap/ui/model/odata/type/Double.js +1 -1
  296. package/src/sap/ui/model/odata/type/Guid.js +1 -1
  297. package/src/sap/ui/model/odata/type/Int.js +1 -1
  298. package/src/sap/ui/model/odata/type/Int16.js +1 -1
  299. package/src/sap/ui/model/odata/type/Int32.js +1 -1
  300. package/src/sap/ui/model/odata/type/Int64.js +1 -1
  301. package/src/sap/ui/model/odata/type/ODataType.js +1 -1
  302. package/src/sap/ui/model/odata/type/Raw.js +1 -1
  303. package/src/sap/ui/model/odata/type/SByte.js +1 -1
  304. package/src/sap/ui/model/odata/type/Single.js +1 -1
  305. package/src/sap/ui/model/odata/type/Stream.js +1 -1
  306. package/src/sap/ui/model/odata/type/String.js +1 -1
  307. package/src/sap/ui/model/odata/type/Time.js +1 -1
  308. package/src/sap/ui/model/odata/type/TimeOfDay.js +1 -1
  309. package/src/sap/ui/model/odata/type/Unit.js +1 -1
  310. package/src/sap/ui/model/odata/v2/Context.js +1 -1
  311. package/src/sap/ui/model/odata/v2/ODataAnnotations.js +1 -1
  312. package/src/sap/ui/model/odata/v2/ODataListBinding.js +1 -1
  313. package/src/sap/ui/model/odata/v2/ODataModel.js +1 -1
  314. package/src/sap/ui/model/odata/v2/ODataTreeBinding.js +3 -4
  315. package/src/sap/ui/model/odata/v4/Context.js +82 -29
  316. package/src/sap/ui/model/odata/v4/ODataBinding.js +3 -0
  317. package/src/sap/ui/model/odata/v4/ODataContextBinding.js +3 -2
  318. package/src/sap/ui/model/odata/v4/ODataListBinding.js +77 -23
  319. package/src/sap/ui/model/odata/v4/ODataMetaModel.js +1 -1
  320. package/src/sap/ui/model/odata/v4/ODataModel.js +2 -2
  321. package/src/sap/ui/model/odata/v4/ODataPropertyBinding.js +1 -1
  322. package/src/sap/ui/model/odata/v4/lib/_AggregationCache.js +334 -142
  323. package/src/sap/ui/model/odata/v4/lib/_AggregationHelper.js +109 -16
  324. package/src/sap/ui/model/odata/v4/lib/_Cache.js +82 -42
  325. package/src/sap/ui/model/odata/v4/lib/_Helper.js +26 -0
  326. package/src/sap/ui/model/resource/ResourceModel.js +1 -1
  327. package/src/sap/ui/model/type/Boolean.js +1 -1
  328. package/src/sap/ui/model/type/Currency.js +1 -1
  329. package/src/sap/ui/model/type/Date.js +1 -1
  330. package/src/sap/ui/model/type/DateInterval.js +1 -1
  331. package/src/sap/ui/model/type/DateTime.js +1 -1
  332. package/src/sap/ui/model/type/DateTimeInterval.js +1 -1
  333. package/src/sap/ui/model/type/FileSize.js +1 -1
  334. package/src/sap/ui/model/type/Float.js +1 -1
  335. package/src/sap/ui/model/type/Integer.js +1 -1
  336. package/src/sap/ui/model/type/String.js +1 -1
  337. package/src/sap/ui/model/type/Time.js +1 -1
  338. package/src/sap/ui/model/type/TimeInterval.js +1 -1
  339. package/src/sap/ui/model/type/Unit.js +1 -1
  340. package/src/sap/ui/model/xml/XMLModel.js +1 -1
  341. package/src/sap/ui/qunit/QUnitUtils.js +14 -2
  342. package/src/sap/ui/qunit/utils/ControlIterator.js +1 -1
  343. package/src/sap/ui/qunit/utils/MemoryLeakCheck.js +1 -1
  344. package/src/sap/ui/test/OpaExtension.js +1 -1
  345. package/src/sap/ui/test/OpaPlugin.js +6 -4
  346. package/src/sap/ui/test/PageObjectFactory.js +11 -9
  347. package/src/sap/ui/test/RecordReplay.js +1 -1
  348. package/src/sap/ui/test/_OpaLogger.js +1 -1
  349. package/src/sap/ui/test/autowaiter/_promiseWaiter.js +4 -1
  350. package/src/sap/ui/test/generic/TestBase.js +1 -1
  351. package/src/sap/ui/util/Mobile.js +17 -18
  352. package/src/sap/ui/util/Storage.js +90 -63
@@ -41,6 +41,7 @@ sap.ui.define([
41
41
  * Whether a grand total is needed
42
42
  *
43
43
  * @alias sap.ui.model.odata.v4.lib._AggregationCache
44
+ * @borrows sap.ui.model.odata.v4.lib._CollectionCache#requestSideEffects as #requestSideEffects
44
45
  * @constructor
45
46
  * @extends sap.ui.model.odata.v4.lib._Cache
46
47
  * @private
@@ -73,6 +74,7 @@ sap.ui.define([
73
74
  });
74
75
  }
75
76
  this.oFirstLevel = this.createGroupLevelCache(null, bHasGrandTotal || !!fnLeaves);
77
+ this.requestSideEffects = this.oFirstLevel.requestSideEffects; // @borrows ...
76
78
  this.oGrandTotalPromise = undefined;
77
79
  if (bHasGrandTotal) {
78
80
  this.oGrandTotalPromise = new SyncPromise(function (resolve) {
@@ -132,31 +134,31 @@ sap.ui.define([
132
134
 
133
135
  function addElement(oElement, i) {
134
136
  var oOldElement = aElements[iOffset + i],
135
- oParent,
137
+ oOtherElement,
136
138
  sPredicate = _Helper.getPrivateAnnotation(oElement, "predicate");
137
139
 
138
140
  if (oOldElement) { // check before overwriting
139
141
  if (oOldElement === oElement) {
140
142
  return;
141
143
  }
142
- oParent = _Helper.getPrivateAnnotation(oOldElement, "parent");
143
- if (!oParent) {
144
- throw new Error("Unexpected element");
145
- }
146
- if (oParent !== oCache
147
- || _Helper.getPrivateAnnotation(oOldElement, "index") !== iStart + i) {
148
- throw new Error("Wrong placeholder");
149
- }
144
+ _AggregationHelper
145
+ .beforeOverwritePlaceholder(oOldElement, oElement, oCache, iStart + i);
150
146
  } else if (iOffset + i >= aElements.length) {
151
147
  throw new Error("Array index out of bounds: " + (iOffset + i));
152
148
  }
153
- if (sPredicate in aElements.$byPredicate
154
- && aElements.$byPredicate[sPredicate] !== oElement) {
149
+ oOtherElement = aElements.$byPredicate[sPredicate];
150
+ if (oOtherElement && oOtherElement !== oElement
151
+ && !(oOtherElement instanceof SyncPromise)) {
155
152
  throw new Error("Duplicate predicate: " + sPredicate);
156
153
  }
157
154
 
158
- aElements[iOffset + i] = oElement;
159
- aElements.$byPredicate[sPredicate] = oElement;
155
+ aElements.$byPredicate[sPredicate] = aElements[iOffset + i] = oElement;
156
+
157
+ if (oCache) {
158
+ // remember index & parent for #requestSideEffects
159
+ _Helper.setPrivateAnnotation(oElement, "index", iStart + i);
160
+ _Helper.setPrivateAnnotation(oElement, "parent", oCache);
161
+ }
160
162
  }
161
163
 
162
164
  if (iOffset < 0) {
@@ -169,6 +171,23 @@ sap.ui.define([
169
171
  }
170
172
  };
171
173
 
174
+ /**
175
+ * Deletes the "$apply" system query option before side effects are requested.
176
+ *
177
+ * @param {object} mQueryOptions
178
+ * A modifiable map of key-value pairs representing the query string
179
+ * @throws {Error}
180
+ * If no recursive hierarchy is used
181
+ *
182
+ * @see sap.ui.model.odata.v4.lib._CollectionCache#requestSideEffects
183
+ */
184
+ _AggregationCache.prototype.beforeRequestSideEffects = function (mQueryOptions) {
185
+ if (!this.oAggregation.hierarchyQualifier) {
186
+ throw new Error("Missing recursive hierarchy");
187
+ }
188
+ delete mQueryOptions.$apply;
189
+ };
190
+
172
191
  /**
173
192
  * Collapses the group node at the given path.
174
193
  *
@@ -195,20 +214,26 @@ sap.ui.define([
195
214
  iCount += 1;
196
215
  }
197
216
 
198
- oCollapsed = _Helper.getPrivateAnnotation(oGroupNode, "collapsed");
217
+ oCollapsed = _AggregationHelper.getCollapsedObject(oGroupNode);
199
218
  _Helper.updateAll(this.mChangeListeners, sGroupNodePath, oGroupNode, oCollapsed);
200
219
 
201
220
  iDescendants = _Helper.getPrivateAnnotation(oGroupNode, "descendants");
202
221
  if (iDescendants) { // => this.oAggregation.expandTo > 1
222
+ // Note: "descendants" refers to LimitedDescendantCountProperty and counts descendants
223
+ // within "top pyramid" only!
203
224
  iGroupNodeLevel = this.oAggregation.expandTo;
204
225
  }
205
226
  while (i < aElements.length) {
206
227
  if (aElements[i]["@$ui5.node.level"] <= iGroupNodeLevel) {
207
- // Note: level 1 is used for placeholders of 1st level cache!
228
+ // Note: level 0 or 1 is used for initial placeholders of 1st level cache!
208
229
  if (!iDescendants) {
209
230
  break; // we've reached a sibling of the collapsed node
210
231
  }
211
232
  iDescendants -= 1;
233
+ if (aElements[i]["@$ui5.node.isExpanded"] === false) {
234
+ // skip descendants of manually collapsed node
235
+ iDescendants -= _Helper.getPrivateAnnotation(aElements[i], "descendants") || 0;
236
+ }
212
237
  }
213
238
  collapse(i);
214
239
  i += 1;
@@ -275,7 +300,7 @@ sap.ui.define([
275
300
  mQueryOptions.$count = true;
276
301
  oCache = _Cache.create(this.oRequestor, this.sResourcePath, mQueryOptions, true);
277
302
  oCache.calculateKeyPredicate = oAggregation.hierarchyQualifier
278
- ? _AggregationCache.calculateKeyPredicateRH.bind(null, oGroupNode)
303
+ ? _AggregationCache.calculateKeyPredicateRH.bind(null, oGroupNode, oAggregation)
279
304
  : _AggregationCache.calculateKeyPredicate.bind(null, oGroupNode, aGroupBy,
280
305
  aAllProperties, bLeaf, bTotal);
281
306
 
@@ -305,6 +330,7 @@ sap.ui.define([
305
330
  : vGroupNodeOrPath,
306
331
  iIndex,
307
332
  aSpliced = _Helper.getPrivateAnnotation(oGroupNode, "spliced"),
333
+ bStale,
308
334
  that = this;
309
335
 
310
336
  if (vGroupNodeOrPath !== oGroupNode) {
@@ -315,6 +341,7 @@ sap.ui.define([
315
341
 
316
342
  if (aSpliced) {
317
343
  _Helper.deletePrivateAnnotation(oGroupNode, "spliced");
344
+ bStale = aSpliced.$stale;
318
345
 
319
346
  iIndex = aElements.indexOf(oGroupNode) + 1;
320
347
  // insert aSpliced at iIndex
@@ -323,20 +350,21 @@ sap.ui.define([
323
350
 
324
351
  iCount = aSpliced.length;
325
352
  this.aElements.$count = aElements.$count + iCount;
326
- aSpliced.forEach(function (oElement) {
353
+ aSpliced.forEach(function (oElement, i) {
327
354
  var sPredicate = _Helper.getPrivateAnnotation(oElement, "predicate");
328
355
 
329
- if (sPredicate) {
330
- that.aElements.$byPredicate[sPredicate] = oElement;
331
- if (_Helper.hasPrivateAnnotation(oElement, "expanding")) {
332
- _Helper.deletePrivateAnnotation(oElement, "expanding");
333
- iCount += that.expand(_GroupLock.$cached, oElement).getResult();
356
+ if (!_Helper.hasPrivateAnnotation(oElement, "placeholder")) {
357
+ if (bStale) {
358
+ that.replaceByPlaceholder(iIndex + i, oElement, sPredicate);
359
+ } else {
360
+ that.aElements.$byPredicate[sPredicate] = oElement;
361
+ if (_Helper.hasPrivateAnnotation(oElement, "expanding")) {
362
+ _Helper.deletePrivateAnnotation(oElement, "expanding");
363
+ iCount += that.expand(_GroupLock.$cached, oElement).getResult();
364
+ }
334
365
  }
335
366
  }
336
367
  });
337
- _Helper.updateAll(that.mChangeListeners, vGroupNodeOrPath, oGroupNode,
338
- {"@$ui5.node.groupLevelCount" :
339
- _Helper.getPrivateAnnotation(oGroupNode, "groupLevelCount")});
340
368
  return SyncPromise.resolve(iCount);
341
369
  }
342
370
 
@@ -350,7 +378,7 @@ sap.ui.define([
350
378
  return oCache.read(0, this.iReadLength, 0, oGroupLock).then(function (oResult) {
351
379
  var iIndex = that.aElements.indexOf(oGroupNode) + 1,
352
380
  iLevel = oGroupNode["@$ui5.node.level"],
353
- oSubtotals = _Helper.getPrivateAnnotation(oGroupNode, "collapsed"),
381
+ oSubtotals = _AggregationHelper.getCollapsedObject(oGroupNode),
354
382
  // Note: there is at least one key for "@$ui5.node.isExpanded"; there are more keys
355
383
  // if and only if subtotals are actually being requested and only or also shown at
356
384
  // bottom
@@ -369,6 +397,10 @@ sap.ui.define([
369
397
  }
370
398
 
371
399
  iCount = oResult.value.$count;
400
+ if (_Helper.hasPrivateAnnotation(oGroupNode, "groupLevelCount")
401
+ && _Helper.getPrivateAnnotation(oGroupNode, "groupLevelCount") !== iCount) {
402
+ throw new Error("Unexpected structural change: groupLevelCount");
403
+ }
372
404
  _Helper.setPrivateAnnotation(oGroupNode, "groupLevelCount", iCount);
373
405
  _Helper.updateAll(that.mChangeListeners, vGroupNodeOrPath, oGroupNode,
374
406
  {"@$ui5.node.groupLevelCount" : iCount});
@@ -406,7 +438,7 @@ sap.ui.define([
406
438
  }, function (oError) {
407
439
  // Note: typeof vGroupNodeOrPath === "string"
408
440
  _Helper.updateAll(that.mChangeListeners, vGroupNodeOrPath, oGroupNode,
409
- _Helper.getPrivateAnnotation(oGroupNode, "collapsed"));
441
+ _AggregationHelper.getCollapsedObject(oGroupNode));
410
442
 
411
443
  throw oError;
412
444
  });
@@ -437,6 +469,8 @@ sap.ui.define([
437
469
  */
438
470
  _AggregationCache.prototype.fetchValue = function (oGroupLock, sPath, fnDataRequested,
439
471
  oListener) {
472
+ var that = this;
473
+
440
474
  if (sPath === "$count") {
441
475
  if (this.oLeavesPromise) {
442
476
  return this.oLeavesPromise;
@@ -451,9 +485,45 @@ sap.ui.define([
451
485
  return this.oFirstLevel.fetchValue(oGroupLock, sPath, fnDataRequested, oListener);
452
486
  }
453
487
 
454
- this.registerChangeListener(sPath, oListener);
488
+ return SyncPromise.resolve(this.aElements.$byPredicate[sPath.split("/")[0]])
489
+ .then(function () {
490
+ that.registerChangeListener(sPath, oListener);
491
+
492
+ return that.drillDown(that.aElements, sPath, oGroupLock);
493
+ });
494
+ };
495
+
496
+ /**
497
+ * Determines the list of visible elements determined by the given predicates. All other
498
+ * elements are replaced by placeholders (lazily).
499
+ *
500
+ * @param {string[]} aPredicates
501
+ * The key predicates of the elements to request side effects for
502
+ * @returns {object[]}
503
+ * The list of visible elements
504
+ *
505
+ * @private
506
+ * @see sap.ui.model.odata.v4.lib._CollectionCache#filterVisibleElements
507
+ * @see sap.ui.model.odata.v4.lib._CollectionCache#requestSideEffects
508
+ */
509
+ _AggregationCache.prototype.filterVisibleElements = function (aPredicates) {
510
+ var mPredicates = {}, // a set of the predicates (as map to true) to speed up the search
511
+ that = this;
512
+
513
+ aPredicates.forEach(function (sPredicate) {
514
+ mPredicates[sPredicate] = true;
515
+ });
516
+
517
+ return this.aElements.filter(function (oElement, i) {
518
+ var sPredicate = _Helper.getPrivateAnnotation(oElement, "predicate");
519
+
520
+ if (mPredicates[sPredicate]) {
521
+ _AggregationHelper.markSplicedStale(oElement);
522
+ return true; // keep and request
523
+ }
455
524
 
456
- return this.drillDown(this.aElements, sPath, oGroupLock);
525
+ that.replaceByPlaceholder(i, oElement, sPredicate);
526
+ });
457
527
  };
458
528
 
459
529
  /**
@@ -476,7 +546,7 @@ sap.ui.define([
476
546
  }
477
547
 
478
548
  aAllElements = this.aElements.map(function (oElement) {
479
- return _Helper.hasPrivateAnnotation(oElement, "parent") ? undefined : oElement;
549
+ return _Helper.hasPrivateAnnotation(oElement, "placeholder") ? undefined : oElement;
480
550
  });
481
551
  aAllElements.$count = this.aElements.$count;
482
552
 
@@ -516,6 +586,14 @@ sap.ui.define([
516
586
  return this.sDownloadUrl;
517
587
  };
518
588
 
589
+ /**
590
+ * @override
591
+ * @see sap.ui.model.odata.v4.lib._Cache#isDeletingInOtherGroup
592
+ */
593
+ _AggregationCache.prototype.isDeletingInOtherGroup = function (_sGroupId) {
594
+ return false;
595
+ };
596
+
519
597
  /**
520
598
  * Returns a promise to be resolved with an OData object for a range of the requested data.
521
599
  *
@@ -525,11 +603,7 @@ sap.ui.define([
525
603
  * The length of the range; <code>Infinity</code> is supported
526
604
  * @param {number} iPrefetchLength
527
605
  * The number of rows to read before and after the given range; with this it is possible to
528
- * prefetch data for a paged access. The cache ensures that at least half the prefetch length
529
- * is available left and right of the requested range without a further request. If data is
530
- * missing on one side, the full prefetch length is added at this side.
531
- * <code>Infinity</code> is supported. In case server-driven paging (@odata.nextLink) has been
532
- * encountered before, this parameter is ignored.
606
+ * prefetch data for a paged access. <code>Infinity</code> is supported.
533
607
  * @param {sap.ui.model.odata.v4.lib._GroupLock} oGroupLock
534
608
  * A lock for the group to associate the requests with
535
609
  * @param {function} [fnDataRequested]
@@ -540,8 +614,7 @@ sap.ui.define([
540
614
  * "@odata.context" and the rows as an array in the property <code>value</code>, enhanced
541
615
  * with a number property <code>$count</code> representing the element count on server-side;
542
616
  * <code>$count</code> may be <code>undefined</code>, but not <code>Infinity</code>). If an
543
- * HTTP request fails, the error from the _Requestor is returned and the requested range is
544
- * reset to <code>undefined</code>.
617
+ * HTTP request fails, the error from the _Requestor is returned.
545
618
  * The promise is rejected if a conflicting {@link #collapse} happens before the response
546
619
  * arrives, in this case the error has the property <code>canceled</code> with value
547
620
  * <code>true</code>.
@@ -554,12 +627,12 @@ sap.ui.define([
554
627
  _AggregationCache.prototype.read = function (iIndex, iLength, iPrefetchLength, oGroupLock,
555
628
  fnDataRequested) {
556
629
  var oCurrentParent,
630
+ oElement,
557
631
  iFirstLevelIndex = iIndex,
558
632
  iFirstLevelLength = iLength,
559
633
  oGapParent,
560
634
  iGapStart,
561
- bHasGrandTotal = !!this.oGrandTotalPromise,
562
- bHasGrandTotalAtTop = bHasGrandTotal
635
+ bHasGrandTotalAtTop = this.oGrandTotalPromise
563
636
  && this.oAggregation.grandTotalAtBottomOnly !== true,
564
637
  aReadPromises = [],
565
638
  i, n,
@@ -573,47 +646,9 @@ sap.ui.define([
573
646
  * @param {number} iGapEnd end of gap, exclusive
574
647
  */
575
648
  function readGap(iGapStart, iGapEnd) {
576
- var oCache = oGapParent,
577
- mQueryOptions = oGapParent.getQueryOptions(),
578
- iStart = _Helper.getPrivateAnnotation(that.aElements[iGapStart], "index"),
579
- oStartElement = that.aElements[iGapStart];
580
-
581
- if (mQueryOptions.$count) { // $count not needed anymore, 1st read was done by #expand
582
- delete mQueryOptions.$count;
583
- oGapParent.setQueryOptions(mQueryOptions, true);
584
- }
585
-
586
649
  aReadPromises.push(
587
- oGapParent.read(iStart, iGapEnd - iGapStart, 0, oGroupLock.getUnlockedCopy(),
588
- fnDataRequested)
589
- .then(function (oResult) {
590
- var bGapHasMoved = false,
591
- oError;
592
-
593
- // Note: aElements[iGapStart] may have changed by a parallel operation
594
- if (oStartElement !== that.aElements[iGapStart]
595
- && oResult.value[0] !== that.aElements[iGapStart]) {
596
- // start of the gap has moved meanwhile
597
- bGapHasMoved = true;
598
- iGapStart = that.aElements.indexOf(oStartElement);
599
- if (iGapStart < 0) {
600
- iGapStart = that.aElements.indexOf(oResult.value[0]);
601
- if (iGapStart < 0) {
602
- oError = new Error("Collapse before read has finished");
603
- oError.canceled = true;
604
- throw oError;
605
- }
606
- }
607
- }
608
-
609
- that.addElements(oResult.value, iGapStart, oCache, iStart);
610
-
611
- if (bGapHasMoved) {
612
- oError = new Error("Collapse or expand before read has finished");
613
- oError.canceled = true;
614
- throw oError;
615
- }
616
- }));
650
+ that.readGap(oGapParent, iGapStart, iGapEnd, oGroupLock.getUnlockedCopy(),
651
+ fnDataRequested));
617
652
  }
618
653
 
619
654
  if (bHasGrandTotalAtTop && !iIndex && iLength === 1) {
@@ -625,7 +660,9 @@ sap.ui.define([
625
660
  return this.oGrandTotalPromise.then(function (oGrandTotal) {
626
661
  return {value : [oGrandTotal]};
627
662
  });
628
- } else if (this.aElements.$count === undefined) {
663
+ }
664
+
665
+ if (this.aElements.$count === undefined) {
629
666
  this.iReadLength = iLength + iPrefetchLength;
630
667
  if (bHasGrandTotalAtTop) { // account for grand total row at top
631
668
  if (iFirstLevelIndex) {
@@ -634,57 +671,15 @@ sap.ui.define([
634
671
  iFirstLevelLength -= 1;
635
672
  }
636
673
  }
637
-
638
674
  aReadPromises.push(
639
- this.oFirstLevel.read(iFirstLevelIndex, iFirstLevelLength, iPrefetchLength,
640
- oGroupLock, fnDataRequested)
641
- .then(function (oResult) {
642
- // Note: this code must be idempotent, it might well run twice!
643
- var oGrandTotal,
644
- oGrandTotalCopy,
645
- iOffset = 0, // offset for 1st level data rows
646
- j;
647
-
648
- that.aElements.length = that.aElements.$count = oResult.value.$count;
649
-
650
- if (bHasGrandTotal) {
651
- that.aElements.$count += 1;
652
- that.aElements.length += 1;
653
- oGrandTotal = that.oGrandTotalPromise.getResult();
654
-
655
- switch (that.oAggregation.grandTotalAtBottomOnly) {
656
- case false: // top & bottom
657
- iOffset = 1;
658
- that.aElements.$count += 1;
659
- that.aElements.length += 1;
660
- that.addElements(oGrandTotal, 0);
661
- oGrandTotalCopy
662
- = _Helper.getPrivateAnnotation(oGrandTotal, "copy");
663
- that.addElements(oGrandTotalCopy, that.aElements.length - 1);
664
- break;
665
-
666
- case true: // bottom
667
- that.addElements(oGrandTotal, that.aElements.length - 1);
668
- break;
669
-
670
- default: // top
671
- iOffset = 1;
672
- that.addElements(oGrandTotal, 0);
673
- }
674
- }
675
-
676
- that.addElements(oResult.value, iFirstLevelIndex + iOffset,
677
- that.oFirstLevel, iFirstLevelIndex);
678
- for (j = 0; j < that.aElements.$count; j += 1) {
679
- if (!that.aElements[j]) {
680
- that.aElements[j] = _AggregationHelper.createPlaceholder(1,
681
- j - iOffset, that.oFirstLevel);
682
- }
683
- }
684
- }));
675
+ this.readFirst(iFirstLevelIndex, iFirstLevelLength, iPrefetchLength,
676
+ oGroupLock, fnDataRequested));
685
677
  } else {
686
678
  for (i = iIndex, n = Math.min(iIndex + iLength, this.aElements.length); i < n; i += 1) {
687
- oCurrentParent = _Helper.getPrivateAnnotation(this.aElements[i], "parent");
679
+ oElement = this.aElements[i];
680
+ oCurrentParent = _Helper.hasPrivateAnnotation(oElement, "placeholder")
681
+ ? _Helper.getPrivateAnnotation(oElement, "parent")
682
+ : undefined;
688
683
  if (oCurrentParent !== oGapParent) {
689
684
  if (iGapStart !== undefined) { // end of gap
690
685
  readGap(iGapStart, i);
@@ -694,6 +689,12 @@ sap.ui.define([
694
689
  iGapStart = i;
695
690
  oGapParent = oCurrentParent;
696
691
  }
692
+ } else if (iGapStart !== undefined
693
+ && _Helper.getPrivateAnnotation(oElement, "index")
694
+ !== _Helper.getPrivateAnnotation(this.aElements[i - 1], "index") + 1) {
695
+ // Note: w/ side effect, indices might not be consecutive => split gap
696
+ readGap(iGapStart, i);
697
+ iGapStart = i;
697
698
  }
698
699
  }
699
700
  if (iGapStart !== undefined) { // gap at end
@@ -711,6 +712,159 @@ sap.ui.define([
711
712
  });
712
713
  };
713
714
 
715
+ /**
716
+ * Returns a promise to be resolved with an OData object for the first range of data requested.
717
+ *
718
+ * @param {number} iStart
719
+ * The start index of the range
720
+ * @param {number} iLength
721
+ * The length of the range; <code>Infinity</code> is supported
722
+ * @param {number} iPrefetchLength
723
+ * The number of rows to read before and after the given range; with this it is possible to
724
+ * prefetch data for a paged access. code>Infinity</code> is supported.
725
+ * @param {sap.ui.model.odata.v4.lib._GroupLock} oGroupLock
726
+ * A lock for the group to associate the requests with
727
+ * @param {function} [fnDataRequested]
728
+ * The function is called just before a back-end request is sent.
729
+ * If no back-end request is needed, the function is not called.
730
+ * @returns {sap.ui.base.SyncPromise}
731
+ * A promise resolving without a defined result when the read is finished, or rejecting in
732
+ * case of an error
733
+ * @throws {Error} If given index or length is less than 0
734
+ *
735
+ * @private
736
+ */
737
+ _AggregationCache.prototype.readFirst = function (iStart, iLength, iPrefetchLength, oGroupLock,
738
+ fnDataRequested) {
739
+ var that = this;
740
+
741
+ return this.oFirstLevel.read(iStart, iLength, iPrefetchLength, oGroupLock, fnDataRequested)
742
+ .then(function (oResult) {
743
+ // Note: this code must be idempotent, it might well run twice!
744
+ var oGrandTotal,
745
+ oGrandTotalCopy,
746
+ iOffset = 0, // offset for 1st level data rows
747
+ j;
748
+
749
+ that.aElements.length = that.aElements.$count = oResult.value.$count;
750
+
751
+ if (that.oGrandTotalPromise) {
752
+ that.aElements.$count += 1;
753
+ that.aElements.length += 1;
754
+ oGrandTotal = that.oGrandTotalPromise.getResult();
755
+
756
+ switch (that.oAggregation.grandTotalAtBottomOnly) {
757
+ case false: // top & bottom
758
+ iOffset = 1;
759
+ that.aElements.$count += 1;
760
+ that.aElements.length += 1;
761
+ that.addElements(oGrandTotal, 0);
762
+ oGrandTotalCopy
763
+ = _Helper.getPrivateAnnotation(oGrandTotal, "copy");
764
+ that.addElements(oGrandTotalCopy, that.aElements.length - 1);
765
+ break;
766
+
767
+ case true: // bottom
768
+ that.addElements(oGrandTotal, that.aElements.length - 1);
769
+ break;
770
+
771
+ default: // top
772
+ iOffset = 1;
773
+ that.addElements(oGrandTotal, 0);
774
+ }
775
+ }
776
+
777
+ that.addElements(oResult.value, iStart + iOffset, that.oFirstLevel, iStart);
778
+ for (j = 0; j < that.aElements.$count; j += 1) {
779
+ if (!that.aElements[j]) {
780
+ that.aElements[j] = _AggregationHelper.createPlaceholder(
781
+ that.oAggregation.expandTo > 1 ? /*don't know*/0 : 1,
782
+ j - iOffset, that.oFirstLevel);
783
+ }
784
+ }
785
+ });
786
+ };
787
+
788
+ /**
789
+ * Reads the given gap from the given cache and replaces the gap with the read's result.
790
+ *
791
+ * @param {sap.ui.model.odata.v4.lib._CollectionCache} oCache
792
+ * The collection cache to read data from
793
+ * @param {number} iStart
794
+ * Start of gap, inclusive
795
+ * @param {number} iEnd
796
+ * End of gap, exclusive
797
+ * @param {sap.ui.model.odata.v4.lib._GroupLock} oGroupLock
798
+ * A lock for the group to associate the requests with
799
+ * @param {function} [fnDataRequested]
800
+ * The function is called just before a back-end request is sent.
801
+ * If no back-end request is needed, the function is not called.
802
+ * @returns {sap.ui.base.SyncPromise}
803
+ * A promise resolving without a defined result when the read is finished, or rejecting in
804
+ * case of an error
805
+ * @throws {Error} If index of placeholder at start of gap is less than 0, or if end of gap is
806
+ * before start
807
+ *
808
+ * @private
809
+ */
810
+ _AggregationCache.prototype.readGap = function (oCache, iStart, iEnd, oGroupLock,
811
+ fnDataRequested) {
812
+ var sPredicate,
813
+ oPromise,
814
+ mQueryOptions = oCache.getQueryOptions(),
815
+ iIndex = _Helper.getPrivateAnnotation(this.aElements[iStart], "index"),
816
+ oStartElement = this.aElements[iStart],
817
+ i,
818
+ that = this;
819
+
820
+ if (mQueryOptions.$count) { // $count not needed anymore, 1st read was done by #expand
821
+ delete mQueryOptions.$count;
822
+ oCache.setQueryOptions(mQueryOptions, true);
823
+ }
824
+
825
+ oPromise = oCache.read(iIndex, iEnd - iStart, 0, oGroupLock, fnDataRequested)
826
+ .then(function (oResult) {
827
+ // Note: this code must be idempotent, it might well run twice!
828
+ var bGapHasMoved = false,
829
+ oError;
830
+
831
+ // Note: aElements[iGapStart] may have changed by a parallel operation
832
+ if (oStartElement !== that.aElements[iStart]
833
+ && oResult.value[0] !== that.aElements[iStart]) {
834
+ // start of the gap has moved meanwhile
835
+ bGapHasMoved = true;
836
+ iStart = that.aElements.indexOf(oStartElement);
837
+ if (iStart < 0) {
838
+ iStart = that.aElements.indexOf(oResult.value[0]);
839
+ if (iStart < 0) {
840
+ oError = new Error("Collapse before read has finished");
841
+ oError.canceled = true;
842
+ throw oError;
843
+ }
844
+ }
845
+ }
846
+
847
+ that.addElements(oResult.value, iStart, oCache, iIndex);
848
+
849
+ if (bGapHasMoved) {
850
+ oError = new Error("Collapse or expand before read has finished");
851
+ oError.canceled = true;
852
+ throw oError;
853
+ }
854
+ });
855
+ if (oPromise.isPending()) {
856
+ for (i = iStart; i < iEnd; i += 1) {
857
+ sPredicate = _Helper.getPrivateAnnotation(this.aElements[i], "predicate");
858
+
859
+ if (sPredicate) {
860
+ this.aElements.$byPredicate[sPredicate] = oPromise;
861
+ }
862
+ }
863
+ }
864
+
865
+ return oPromise;
866
+ };
867
+
714
868
  /**
715
869
  * Refreshes the kept-alive elements. Nothing to do here, we have no kept-alive elements.
716
870
  *
@@ -719,6 +873,35 @@ sap.ui.define([
719
873
  */
720
874
  _AggregationCache.prototype.refreshKeptElements = function () {};
721
875
 
876
+ /**
877
+ * Replaces the given element, which is at the given position and has the given predicate, with
878
+ * a placeholder which keeps all private annotations. The original element is removed from its
879
+ * corresponding cache and must not be used any longer.
880
+ *
881
+ * @param {number} iIndex - Its index
882
+ * @param {object} oElement - An element
883
+ * @param {string} sPredicate - Its predicate
884
+ *
885
+ * @private
886
+ */
887
+ _AggregationCache.prototype.replaceByPlaceholder = function (iIndex, oElement, sPredicate) {
888
+ if (_Helper.hasPrivateAnnotation(oElement, "placeholder")) {
889
+ return;
890
+ }
891
+
892
+ _AggregationHelper.markSplicedStale(oElement);
893
+ this.aElements[iIndex] = {
894
+ "@$ui5._" : Object.assign(oElement["@$ui5._"], {placeholder : true}),
895
+ "@$ui5.node.isExpanded" : oElement["@$ui5.node.isExpanded"],
896
+ "@$ui5.node.level" : oElement["@$ui5.node.level"]
897
+ };
898
+ delete this.aElements.$byPredicate[sPredicate];
899
+
900
+ // drop original element from its cache's collection
901
+ _Helper.getPrivateAnnotation(oElement, "parent")
902
+ .drop(_Helper.getPrivateAnnotation(oElement, "index"), sPredicate);
903
+ };
904
+
722
905
  /**
723
906
  * Returns the cache's URL.
724
907
  *
@@ -805,6 +988,9 @@ sap.ui.define([
805
988
  *
806
989
  * @param {object} [oGroupNode]
807
990
  * The group node or <code>undefined</code> for an element of the first level cache
991
+ * @param {object} oAggregation
992
+ * An object holding the information needed for a recursive hierarchy; must already be
993
+ * normalized by {@link _AggregationHelper.buildApply4Hierarchy}
808
994
  * @param {object} oElement
809
995
  * The element for which to calculate the key predicate
810
996
  * @param {object} mTypeForMetaPath
@@ -817,17 +1003,19 @@ sap.ui.define([
817
1003
  * @public
818
1004
  */
819
1005
  // @override sap.ui.model.odata.v4.lib._Cache#calculateKeyPredicate
820
- _AggregationCache.calculateKeyPredicateRH = function (oGroupNode, oElement, mTypeForMetaPath,
821
- sMetaPath) {
822
- var iLevel = 1,
1006
+ _AggregationCache.calculateKeyPredicateRH = function (oGroupNode, oAggregation, oElement,
1007
+ mTypeForMetaPath, sMetaPath) {
1008
+ var sDistanceFromRootProperty = oAggregation.$DistanceFromRootProperty,
1009
+ sDrillStateProperty = oAggregation.$DrillStateProperty,
823
1010
  bIsExpanded,
1011
+ iLevel = 1,
1012
+ sLimitedDescendantCountProperty = oAggregation.$LimitedDescendantCountProperty,
824
1013
  sPredicate = _Helper.getKeyPredicate(oElement, sMetaPath, mTypeForMetaPath);
825
1014
 
826
1015
  _Helper.setPrivateAnnotation(oElement, "predicate", sPredicate);
827
- switch (oElement.DrillState) {
1016
+ switch (oElement[sDrillStateProperty]) {
828
1017
  case "expanded":
829
1018
  bIsExpanded = true;
830
- _AggregationHelper.getOrCreateExpandedObject({/*oAggregation*/}, oElement);
831
1019
  break;
832
1020
 
833
1021
  case "collapsed":
@@ -841,17 +1029,19 @@ sap.ui.define([
841
1029
  }
842
1030
  if (oGroupNode) {
843
1031
  iLevel = oGroupNode["@$ui5.node.level"] + 1;
844
- } else if (oElement.DistanceFromRoot) {
845
- iLevel = oElement.DistanceFromRoot + 1;
1032
+ } else if (oElement[sDistanceFromRootProperty]) { // Edm.Int64
1033
+ iLevel = parseInt(oElement[sDistanceFromRootProperty]) + 1;
846
1034
  }
847
1035
  // set the node values
848
1036
  _AggregationHelper.setAnnotations(oElement, bIsExpanded, /*bIsTotal*/undefined, iLevel);
849
- if (oElement.DescendantCount) {
850
- _Helper.setPrivateAnnotation(oElement, "descendants", oElement.DescendantCount);
1037
+ if (oElement[sLimitedDescendantCountProperty]
1038
+ && oElement[sLimitedDescendantCountProperty] !== "0") { // Edm.Int64
1039
+ _Helper.setPrivateAnnotation(oElement, "descendants",
1040
+ parseInt(oElement[sLimitedDescendantCountProperty]));
851
1041
  }
852
- delete oElement.DescendantCount;
853
- delete oElement.DistanceFromRoot;
854
- delete oElement.DrillState;
1042
+ delete oElement[sDistanceFromRootProperty];
1043
+ delete oElement[sDrillStateProperty];
1044
+ delete oElement[sLimitedDescendantCountProperty];
855
1045
 
856
1046
  return sPredicate;
857
1047
  };
@@ -863,7 +1053,8 @@ sap.ui.define([
863
1053
  * @param {sap.ui.model.odata.v4.lib._Requestor} oRequestor
864
1054
  * The requestor
865
1055
  * @param {string} sResourcePath
866
- * A resource path relative to the service URL; it must not contain a query string<br>
1056
+ * A resource path relative to the service URL; it must not contain a query string
1057
+ * <br>
867
1058
  * Example: Products
868
1059
  * @param {string} sDeepResourcePath
869
1060
  * The deep resource path to be used to build the target path for bound messages
@@ -874,7 +1065,8 @@ sap.ui.define([
874
1065
  * @param {object} mQueryOptions
875
1066
  * A map of key-value pairs representing the query string, the value in this pair has to
876
1067
  * be a string or an array of strings; if it is an array, the resulting query string
877
- * repeats the key for each array value.<br>
1068
+ * repeats the key for each array value.
1069
+ * <br>
878
1070
  * Examples:
879
1071
  * {foo : "bar", "bar" : "baz"} results in the query string "foo=bar&bar=baz"
880
1072
  * {foo : ["bar", "baz"]} results in the query string "foo=bar&foo=baz"