@openui5/sap.ui.core 1.96.2 → 1.97.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 (302) hide show
  1. package/.eslintrc.json +2 -2
  2. package/.reuse/dep5 +1 -1
  3. package/THIRDPARTY.txt +2 -1
  4. package/package.json +1 -1
  5. package/src/jquery.sap.global.js +1 -1
  6. package/src/jquery.sap.properties.js +1 -1
  7. package/src/jquery.sap.resources.js +2 -2
  8. package/src/jquery.sap.script.js +1 -1
  9. package/src/jquery.sap.storage.js +3 -3
  10. package/src/sap/base/util/restricted/_CancelablePromise.js +1 -1
  11. package/src/sap/base/util/restricted/_castArray.js +1 -1
  12. package/src/sap/base/util/restricted/_compact.js +1 -1
  13. package/src/sap/base/util/restricted/_curry.js +1 -1
  14. package/src/sap/base/util/restricted/_debounce.js +1 -1
  15. package/src/sap/base/util/restricted/_difference.js +1 -1
  16. package/src/sap/base/util/restricted/_differenceBy.js +1 -1
  17. package/src/sap/base/util/restricted/_differenceWith.js +1 -1
  18. package/src/sap/base/util/restricted/_flatMap.js +1 -1
  19. package/src/sap/base/util/restricted/_flatMapDeep.js +1 -1
  20. package/src/sap/base/util/restricted/_flatMapDepth.js +1 -1
  21. package/src/sap/base/util/restricted/_flatten.js +1 -1
  22. package/src/sap/base/util/restricted/_flattenDeep.js +1 -1
  23. package/src/sap/base/util/restricted/_flattenDepth.js +1 -1
  24. package/src/sap/base/util/restricted/_intersection.js +1 -1
  25. package/src/sap/base/util/restricted/_intersectionBy.js +1 -1
  26. package/src/sap/base/util/restricted/_intersectionWith.js +1 -1
  27. package/src/sap/base/util/restricted/_isEqual.js +1 -1
  28. package/src/sap/base/util/restricted/_isEqualWith.js +1 -1
  29. package/src/sap/base/util/restricted/_isNil.js +1 -1
  30. package/src/sap/base/util/restricted/_max.js +1 -1
  31. package/src/sap/base/util/restricted/_merge.js +1 -1
  32. package/src/sap/base/util/restricted/_mergeWith.js +1 -1
  33. package/src/sap/base/util/restricted/_min.js +1 -1
  34. package/src/sap/base/util/restricted/_omit.js +1 -1
  35. package/src/sap/base/util/restricted/_pick.js +1 -1
  36. package/src/sap/base/util/restricted/_pickBy.js +1 -1
  37. package/src/sap/base/util/restricted/_throttle.js +1 -1
  38. package/src/sap/base/util/restricted/_toArray.js +1 -1
  39. package/src/sap/base/util/restricted/_union.js +1 -1
  40. package/src/sap/base/util/restricted/_unionBy.js +1 -1
  41. package/src/sap/base/util/restricted/_unionWith.js +1 -1
  42. package/src/sap/base/util/restricted/_uniq.js +1 -1
  43. package/src/sap/base/util/restricted/_uniqBy.js +1 -1
  44. package/src/sap/base/util/restricted/_uniqWith.js +1 -1
  45. package/src/sap/base/util/restricted/_without.js +1 -1
  46. package/src/sap/base/util/restricted/_xor.js +1 -1
  47. package/src/sap/base/util/restricted/_xorBy.js +1 -1
  48. package/src/sap/base/util/restricted/_xorWith.js +1 -1
  49. package/src/sap/base/util/restricted/_zipObject.js +1 -1
  50. package/src/sap/base/util/restricted/_zipObjectDeep.js +1 -1
  51. package/src/sap/ui/Device.js +4 -4
  52. package/src/sap/ui/Global.js +11 -16
  53. package/src/sap/ui/base/Event.js +1 -1
  54. package/src/sap/ui/base/EventProvider.js +1 -1
  55. package/src/sap/ui/base/Interface.js +1 -1
  56. package/src/sap/ui/base/ManagedObject.js +3 -3
  57. package/src/sap/ui/base/ManagedObjectMetadata.js +1 -1
  58. package/src/sap/ui/base/Metadata.js +1 -3
  59. package/src/sap/ui/base/Object.js +1 -1
  60. package/src/sap/ui/base/ObjectPool.js +1 -1
  61. package/src/sap/ui/core/.library +1 -27
  62. package/src/sap/ui/core/AppCacheBuster.js +4 -4
  63. package/src/sap/ui/core/BusyIndicator.js +1 -1
  64. package/src/sap/ui/core/Component.js +31 -9
  65. package/src/sap/ui/core/ComponentContainer.js +1 -1
  66. package/src/sap/ui/core/ComponentMetadata.js +1 -1
  67. package/src/sap/ui/core/ComponentSupport.js +1 -1
  68. package/src/sap/ui/core/Control.js +2 -2
  69. package/src/sap/ui/core/Core.js +2 -2
  70. package/src/sap/ui/core/CustomData.js +1 -1
  71. package/src/sap/ui/core/DeclarativeSupport.js +1 -1
  72. package/src/sap/ui/core/Element.js +2 -6
  73. package/src/sap/ui/core/ElementMetadata.js +1 -1
  74. package/src/sap/ui/core/EnabledPropagator.js +1 -1
  75. package/src/sap/ui/core/EventBus.js +1 -1
  76. package/src/sap/ui/core/Fragment.js +1 -1
  77. package/src/sap/ui/core/HTML.js +3 -3
  78. package/src/sap/ui/core/History.js +1 -1
  79. package/src/sap/ui/core/Icon.js +1 -1
  80. package/src/sap/ui/core/IndicationColorSupport.js +1 -1
  81. package/src/sap/ui/core/IntervalTrigger.js +1 -1
  82. package/src/sap/ui/core/InvisibleMessage.js +1 -1
  83. package/src/sap/ui/core/InvisibleRenderer.js +1 -1
  84. package/src/sap/ui/core/InvisibleText.js +1 -1
  85. package/src/sap/ui/core/Item.js +1 -1
  86. package/src/sap/ui/core/LabelEnablement.js +1 -1
  87. package/src/sap/ui/core/LayoutData.js +1 -1
  88. package/src/sap/ui/core/ListItem.js +1 -1
  89. package/src/sap/ui/core/LocalBusyIndicator.js +1 -1
  90. package/src/sap/ui/core/Locale.js +1 -1
  91. package/src/sap/ui/core/LocaleData.js +3 -3
  92. package/src/sap/ui/core/Manifest.js +1 -1
  93. package/src/sap/ui/core/Message.js +1 -1
  94. package/src/sap/ui/core/RenderManager.js +3 -3
  95. package/src/sap/ui/core/Renderer.js +1 -1
  96. package/src/sap/ui/core/ResizeHandler.js +1 -1
  97. package/src/sap/ui/core/ScrollBar.js +4 -3
  98. package/src/sap/ui/core/SeparatorItem.js +1 -1
  99. package/src/sap/ui/core/ThemeCheck.js +2 -2
  100. package/src/sap/ui/core/Title.js +1 -1
  101. package/src/sap/ui/core/TooltipBase.js +1 -1
  102. package/src/sap/ui/core/UIArea.js +3 -3
  103. package/src/sap/ui/core/UIComponent.js +1 -1
  104. package/src/sap/ui/core/UIComponentMetadata.js +1 -1
  105. package/src/sap/ui/core/ValueStateSupport.js +1 -1
  106. package/src/sap/ui/core/VariantLayoutData.js +1 -1
  107. package/src/sap/ui/core/XMLComposite.js +1 -1
  108. package/src/sap/ui/core/XMLCompositeMetadata.js +1 -1
  109. package/src/sap/ui/core/XMLTemplateProcessor.js +19 -5
  110. package/src/sap/ui/core/cache/LRUPersistentCache.js +4 -2
  111. package/src/sap/ui/core/date/UniversalDateUtils.js +33 -0
  112. package/src/sap/ui/core/delegate/ItemNavigation.js +1 -1
  113. package/src/sap/ui/core/delegate/ScrollEnablement.js +1 -1
  114. package/src/sap/ui/core/dnd/DragDropBase.js +1 -1
  115. package/src/sap/ui/core/dnd/DragDropInfo.js +1 -1
  116. package/src/sap/ui/core/dnd/DragInfo.js +1 -1
  117. package/src/sap/ui/core/dnd/DropInfo.js +1 -1
  118. package/src/sap/ui/core/hyphenation/Hyphenation.js +1 -1
  119. package/src/sap/ui/core/library.js +5 -5
  120. package/src/sap/ui/core/message/ControlMessageProcessor.js +5 -5
  121. package/src/sap/ui/core/message/Message.js +1 -1
  122. package/src/sap/ui/core/message/MessageManager.js +1 -1
  123. package/src/sap/ui/core/message/MessageParser.js +1 -1
  124. package/src/sap/ui/core/message/MessageProcessor.js +22 -12
  125. package/src/sap/ui/core/messagebundle_fr.properties +7 -7
  126. package/src/sap/ui/core/messagebundle_ru.properties +21 -21
  127. package/src/sap/ui/core/mvc/Controller.js +4 -4
  128. package/src/sap/ui/core/mvc/HTMLView.js +1 -1
  129. package/src/sap/ui/core/mvc/JSONView.js +1 -1
  130. package/src/sap/ui/core/mvc/JSView.js +1 -1
  131. package/src/sap/ui/core/mvc/TemplateView.js +1 -1
  132. package/src/sap/ui/core/mvc/View.js +1 -1
  133. package/src/sap/ui/core/mvc/XMLView.js +1 -1
  134. package/src/sap/ui/core/plugin/DeclarativeSupport.js +1 -1
  135. package/src/sap/ui/core/plugin/LessSupport.js +1 -1
  136. package/src/sap/ui/core/plugin/TemplatingSupport.js +1 -1
  137. package/src/sap/ui/core/postmessage/Bus.js +1 -1
  138. package/src/sap/ui/core/postmessage/confirmationDialog.js +1 -1
  139. package/src/sap/ui/core/rules/Misc.support.js +51 -1
  140. package/src/sap/ui/core/rules/Rendering.support.js +1 -4
  141. package/src/sap/ui/core/rules/View.support.js +14 -46
  142. package/src/sap/ui/core/search/OpenSearchProvider.js +1 -1
  143. package/src/sap/ui/core/search/SearchProvider.js +1 -1
  144. package/src/sap/ui/core/service/Service.js +1 -1
  145. package/src/sap/ui/core/service/ServiceFactory.js +1 -1
  146. package/src/sap/ui/core/service/ServiceFactoryRegistry.js +1 -1
  147. package/src/sap/ui/core/support/Plugin.js +2 -2
  148. package/src/sap/ui/core/support/RuleEngineOpaExtension.js +0 -1
  149. package/src/sap/ui/core/support/Support.js +1 -1
  150. package/src/sap/ui/core/support/controls/TreeViewer.js +1 -1
  151. package/src/sap/ui/core/support/plugins/ControlTree.js +1 -1
  152. package/src/sap/ui/core/support/plugins/Interaction.js +1 -1
  153. package/src/sap/ui/core/support/plugins/LocalStorage.js +1 -1
  154. package/src/sap/ui/core/support/plugins/Performance.js +1 -2
  155. package/src/sap/ui/core/support/plugins/Selector.js +1 -1
  156. package/src/sap/ui/core/support/plugins/TechInfo.js +1 -1
  157. package/src/sap/ui/core/support/plugins/Trace.js +1 -1
  158. package/src/sap/ui/core/support/plugins/ViewInfo.js +1 -1
  159. package/src/sap/ui/core/support/techinfo/TechnicalInfo.js +1 -1
  160. package/src/sap/ui/core/support/trace/E2eTraceLib.js +3 -3
  161. package/src/sap/ui/core/tmpl/DOMAttribute.js +1 -1
  162. package/src/sap/ui/core/tmpl/DOMElement.js +1 -1
  163. package/src/sap/ui/core/tmpl/HandlebarsTemplate.js +1 -1
  164. package/src/sap/ui/core/tmpl/Template.js +1 -1
  165. package/src/sap/ui/core/tmpl/TemplateControl.js +1 -1
  166. package/src/sap/ui/core/util/AsyncHintsHelper.js +1 -1
  167. package/src/sap/ui/core/util/Export.js +1 -1
  168. package/src/sap/ui/core/util/ExportCell.js +1 -1
  169. package/src/sap/ui/core/util/ExportColumn.js +1 -1
  170. package/src/sap/ui/core/util/ExportRow.js +1 -1
  171. package/src/sap/ui/core/util/ExportType.js +1 -1
  172. package/src/sap/ui/core/util/ExportTypeCSV.js +1 -1
  173. package/src/sap/ui/core/util/File.js +1 -1
  174. package/src/sap/ui/core/util/LibraryInfo.js +1 -1
  175. package/src/sap/ui/core/util/MockServer.js +2 -2
  176. package/src/sap/ui/core/util/PasteHelper.js +1 -1
  177. package/src/sap/ui/core/util/reflection/JsControlTreeModifier.js +4 -4
  178. package/src/sap/ui/core/util/serializer/HTMLViewSerializer.js +1 -1
  179. package/src/sap/ui/core/util/serializer/Serializer.js +1 -1
  180. package/src/sap/ui/core/util/serializer/ViewSerializer.js +1 -1
  181. package/src/sap/ui/core/util/serializer/XMLViewSerializer.js +1 -1
  182. package/src/sap/ui/core/util/serializer/delegate/Delegate.js +1 -1
  183. package/src/sap/ui/core/util/serializer/delegate/HTML.js +1 -1
  184. package/src/sap/ui/core/util/serializer/delegate/XML.js +1 -1
  185. package/src/sap/ui/core/ws/ReadyState.js +1 -1
  186. package/src/sap/ui/core/ws/SapPcpWebSocket.js +1 -1
  187. package/src/sap/ui/core/ws/WebSocket.js +1 -1
  188. package/src/sap/ui/debug/ControlTree.js +1 -1
  189. package/src/sap/ui/debug/DebugEnv.js +1 -1
  190. package/src/sap/ui/debug/PropertyList.js +1 -1
  191. package/src/sap/ui/model/ChangeReason.js +1 -1
  192. package/src/sap/ui/model/ClientListBinding.js +7 -0
  193. package/src/sap/ui/model/ClientModel.js +6 -5
  194. package/src/sap/ui/model/ClientTreeBindingAdapter.js +1 -1
  195. package/src/sap/ui/model/CompositeDataState.js +1 -1
  196. package/src/sap/ui/model/CompositeType.js +1 -1
  197. package/src/sap/ui/model/DataState.js +1 -1
  198. package/src/sap/ui/model/ListBinding.js +24 -5
  199. package/src/sap/ui/model/MetaModel.js +1 -1
  200. package/src/sap/ui/model/Model.js +5 -10
  201. package/src/sap/ui/model/SelectionModel.js +1 -1
  202. package/src/sap/ui/model/SimpleType.js +1 -1
  203. package/src/sap/ui/model/TreeAutoExpandMode.js +1 -1
  204. package/src/sap/ui/model/TreeBindingAdapter.js +0 -2
  205. package/src/sap/ui/model/TreeBindingUtils.js +2 -0
  206. package/src/sap/ui/model/Type.js +1 -1
  207. package/src/sap/ui/model/analytics/AnalyticalBinding.js +12 -6
  208. package/src/sap/ui/model/analytics/AnalyticalTreeBindingAdapter.js +16 -18
  209. package/src/sap/ui/model/json/JSONModel.js +7 -7
  210. package/src/sap/ui/model/json/JSONPropertyBinding.js +1 -1
  211. package/src/sap/ui/model/message/MessageModel.js +3 -3
  212. package/src/sap/ui/model/message/MessagePropertyBinding.js +1 -1
  213. package/src/sap/ui/model/odata/AnnotationHelper.js +2 -2
  214. package/src/sap/ui/model/odata/AnnotationParser.js +4 -2
  215. package/src/sap/ui/model/odata/ODataAnnotations.js +1 -1
  216. package/src/sap/ui/model/odata/ODataListBinding.js +61 -38
  217. package/src/sap/ui/model/odata/ODataMessageParser.js +2 -2
  218. package/src/sap/ui/model/odata/ODataMetaModel.js +3 -3
  219. package/src/sap/ui/model/odata/ODataMetadata.js +136 -85
  220. package/src/sap/ui/model/odata/ODataModel.js +442 -215
  221. package/src/sap/ui/model/odata/ODataPropertyBinding.js +7 -5
  222. package/src/sap/ui/model/odata/ODataTreeBindingAdapter.js +27 -17
  223. package/src/sap/ui/model/odata/ODataTreeBindingFlat.js +440 -260
  224. package/src/sap/ui/model/odata/ODataUtils.js +24 -9
  225. package/src/sap/ui/model/odata/_AnnotationHelperBasics.js +2 -1
  226. package/src/sap/ui/model/odata/_AnnotationHelperExpression.js +10 -8
  227. package/src/sap/ui/model/odata/_ODataMetaModelUtils.js +6 -4
  228. package/src/sap/ui/model/odata/type/Boolean.js +1 -1
  229. package/src/sap/ui/model/odata/type/Byte.js +1 -1
  230. package/src/sap/ui/model/odata/type/Currency.js +1 -1
  231. package/src/sap/ui/model/odata/type/Date.js +1 -1
  232. package/src/sap/ui/model/odata/type/DateTime.js +1 -1
  233. package/src/sap/ui/model/odata/type/DateTimeBase.js +1 -1
  234. package/src/sap/ui/model/odata/type/DateTimeOffset.js +1 -1
  235. package/src/sap/ui/model/odata/type/Decimal.js +5 -1
  236. package/src/sap/ui/model/odata/type/Double.js +1 -1
  237. package/src/sap/ui/model/odata/type/Guid.js +1 -1
  238. package/src/sap/ui/model/odata/type/Int.js +1 -1
  239. package/src/sap/ui/model/odata/type/Int16.js +1 -1
  240. package/src/sap/ui/model/odata/type/Int32.js +1 -1
  241. package/src/sap/ui/model/odata/type/Int64.js +1 -1
  242. package/src/sap/ui/model/odata/type/ODataType.js +1 -1
  243. package/src/sap/ui/model/odata/type/Raw.js +1 -1
  244. package/src/sap/ui/model/odata/type/SByte.js +1 -1
  245. package/src/sap/ui/model/odata/type/Single.js +1 -1
  246. package/src/sap/ui/model/odata/type/Stream.js +1 -1
  247. package/src/sap/ui/model/odata/type/String.js +1 -1
  248. package/src/sap/ui/model/odata/type/Time.js +1 -1
  249. package/src/sap/ui/model/odata/type/TimeOfDay.js +1 -1
  250. package/src/sap/ui/model/odata/type/Unit.js +1 -1
  251. package/src/sap/ui/model/odata/type/UnitMixin.js +0 -1
  252. package/src/sap/ui/model/odata/v2/Context.js +42 -11
  253. package/src/sap/ui/model/odata/v2/ODataAnnotations.js +1 -1
  254. package/src/sap/ui/model/odata/v2/ODataListBinding.js +205 -88
  255. package/src/sap/ui/model/odata/v2/ODataModel.js +154 -89
  256. package/src/sap/ui/model/odata/v2/ODataTreeBinding.js +162 -89
  257. package/src/sap/ui/model/odata/v2/_CreatedContextsCache.js +52 -2
  258. package/src/sap/ui/model/odata/v4/Context.js +48 -7
  259. package/src/sap/ui/model/odata/v4/ODataBinding.js +55 -24
  260. package/src/sap/ui/model/odata/v4/ODataContextBinding.js +67 -19
  261. package/src/sap/ui/model/odata/v4/ODataListBinding.js +211 -78
  262. package/src/sap/ui/model/odata/v4/ODataMetaModel.js +1 -1
  263. package/src/sap/ui/model/odata/v4/ODataModel.js +2 -1
  264. package/src/sap/ui/model/odata/v4/ODataParentBinding.js +36 -23
  265. package/src/sap/ui/model/odata/v4/ODataPropertyBinding.js +3 -3
  266. package/src/sap/ui/model/odata/v4/lib/_Cache.js +106 -11
  267. package/src/sap/ui/model/odata/v4/lib/_Helper.js +33 -3
  268. package/src/sap/ui/model/odata/v4/lib/_Requestor.js +11 -2
  269. package/src/sap/ui/model/resource/ResourceModel.js +1 -1
  270. package/src/sap/ui/model/type/Boolean.js +1 -1
  271. package/src/sap/ui/model/type/Currency.js +1 -1
  272. package/src/sap/ui/model/type/Date.js +1 -1
  273. package/src/sap/ui/model/type/DateInterval.js +1 -1
  274. package/src/sap/ui/model/type/DateTime.js +1 -1
  275. package/src/sap/ui/model/type/DateTimeInterval.js +1 -1
  276. package/src/sap/ui/model/type/FileSize.js +1 -1
  277. package/src/sap/ui/model/type/Float.js +1 -1
  278. package/src/sap/ui/model/type/Integer.js +1 -1
  279. package/src/sap/ui/model/type/String.js +1 -1
  280. package/src/sap/ui/model/type/Time.js +1 -1
  281. package/src/sap/ui/model/type/TimeInterval.js +1 -1
  282. package/src/sap/ui/model/type/Unit.js +1 -1
  283. package/src/sap/ui/model/xml/XMLModel.js +5 -5
  284. package/src/sap/ui/model/xml/XMLPropertyBinding.js +1 -1
  285. package/src/sap/ui/qunit/utils/ControlIterator.js +1 -1
  286. package/src/sap/ui/qunit/utils/MemoryLeakCheck.js +1 -1
  287. package/src/sap/ui/test/actions/Action.js +9 -2
  288. package/src/sap/ui/test/actions/Press.js +28 -1
  289. package/src/sap/ui/test/generic/_EnforceSemanticRendering.js +111 -0
  290. package/src/sap/ui/util/Mobile.js +28 -39
  291. package/src/sap/ui/util/Storage.js +1 -1
  292. package/src/ui5loader.js +6 -6
  293. package/ui5.yaml +244 -1
  294. package/src/sap/ui/core/CustomizingConfiguration.js +0 -47
  295. package/src/sap/ui/thirdparty/baseuri.js +0 -1
  296. package/src/sap/ui/thirdparty/es6-object-assign.js +0 -1
  297. package/src/sap/ui/thirdparty/es6-promise.js +0 -1
  298. package/src/sap/ui/thirdparty/es6-shim-nopromise.js +0 -1
  299. package/src/sap/ui/thirdparty/es6-string-methods.js +0 -1
  300. package/src/sap/ui/thirdparty/flexie.js +0 -1
  301. package/src/sap/ui/thirdparty/unorm.js +0 -1
  302. package/src/sap/ui/thirdparty/unormdata.js +0 -1
@@ -95,6 +95,8 @@ sap.ui.define([
95
95
 
96
96
  /**
97
97
  * Sets the number of expanded levels.
98
+ *
99
+ * @param {number} iLevels The number of levels which should be expanded, minimum is 0
98
100
  */
99
101
  ODataTreeBindingFlat.prototype.setNumberOfExpandedLevels = function(iLevels) {
100
102
  this.resetData();
@@ -218,12 +220,20 @@ sap.ui.define([
218
220
  }
219
221
  };
220
222
 
223
+ /**
224
+ * Calculates the $skip and $top for the OData request.
225
+ *
226
+ * @param {object[]} aMissing An array of missing nodes
227
+ * @returns {object} An object with <code>skip</code> and <code>top</code>
228
+ */
221
229
  ODataTreeBindingFlat.prototype._calculateRequestParameters = function (aMissing) {
222
- var oParent = aMissing[0].parent;
223
- var iMissingSkip = aMissing[0].positionInParent;
224
- var iMissingLength = Math.min(iMissingSkip + Math.max(this._iThreshold, aMissing.length), oParent.children.length);
230
+ var i,
231
+ iMissingSkip = aMissing[0].positionInParent,
232
+ oParent = aMissing[0].parent,
233
+ iMissingLength = Math.min(iMissingSkip + Math.max(this._iThreshold, aMissing.length),
234
+ oParent.children.length);
225
235
 
226
- for (var i = iMissingSkip; i < iMissingLength; i++) {
236
+ for (i = iMissingSkip; i < iMissingLength; i++) {
227
237
  var oChild = oParent.children[i];
228
238
  if (oChild) {
229
239
  break;
@@ -238,10 +248,17 @@ sap.ui.define([
238
248
 
239
249
  /**
240
250
  * Cuts out a piece from the tree.
251
+ *
252
+ * @param {number} iStartIndex The first index to cut out
253
+ * @param {number} iLength The number of nodes to cut
254
+ *
255
+ * @returns {object[]} The cut nodes
241
256
  * @private
242
257
  */
243
258
  ODataTreeBindingFlat.prototype._retrieveNodeSection = function (iStartIndex, iLength) {
244
- return this._bReadOnly ? this._indexRetrieveNodeSection(iStartIndex, iLength) : this._mapRetrieveNodeSection(iStartIndex, iLength);
259
+ return this._bReadOnly
260
+ ? this._indexRetrieveNodeSection(iStartIndex, iLength)
261
+ : this._mapRetrieveNodeSection(iStartIndex, iLength);
245
262
  };
246
263
 
247
264
  ODataTreeBindingFlat.prototype._mapRetrieveNodeSection = function (iStartIndex, iLength) {
@@ -275,7 +292,7 @@ sap.ui.define([
275
292
  ODataTreeBindingFlat.prototype._indexRetrieveNodeSection = function (iStartIndex, iLength) {
276
293
  var i, aNodes = [], oNodeInfo, oNode;
277
294
 
278
- for (i = iStartIndex ; i < iStartIndex + iLength ; i++) {
295
+ for (i = iStartIndex; i < iStartIndex + iLength; i++) {
279
296
  oNodeInfo = this.getNodeInfoByRowIndex(i);
280
297
  if (oNodeInfo.index !== undefined && oNodeInfo.index < this._aNodes.length) {
281
298
  oNode = this._aNodes[oNodeInfo.index];
@@ -348,12 +365,16 @@ sap.ui.define([
348
365
  * @private
349
366
  */
350
367
  ODataTreeBindingFlat.prototype._map = function (fnMap) {
351
- var oRecursionBreaker = {broken: false};
368
+ var fnCheckNodeForAddedSubtrees, fnTraverseAddedSubtree, fnTraverseDeepSubtree,
369
+ fnTraverseFlatSubtree,
370
+ oRecursionBreaker = {broken: false};
352
371
 
353
372
  /**
354
373
  * Helper function to iterate all added subtrees of a node.
374
+ *
375
+ * @param {object} oNode The node to check for subtrees
355
376
  */
356
- var fnCheckNodeForAddedSubtrees = function (oNode) {
377
+ fnCheckNodeForAddedSubtrees = function (oNode) {
357
378
  // if there are subnodes added to the current node -> traverse them first (added nodes are at the top, before any children)
358
379
  if (oNode.addedSubtrees.length > 0 && !oNode.nodeState.collapsed) {
359
380
  // an added subtree can be either a deep or a flat tree (depending on the addContexts) call
@@ -373,10 +394,12 @@ sap.ui.define([
373
394
  *
374
395
  * Decides if the traversal has to branche over to a flat or a deep part of the tree.
375
396
  *
376
- * @param {object} oNode the parent node
377
- * @param {object} the subtree handle, inside there is either a deep or a flat tree stored
397
+ * @param {object} oNode
398
+ * The parent node
399
+ * @param {object} oSubtreeHandle
400
+ * The subtree handle, inside there is either a deep or a flat tree stored
378
401
  */
379
- var fnTraverseAddedSubtree = function (oNode, oSubtreeHandle) {
402
+ fnTraverseAddedSubtree = function (oNode, oSubtreeHandle) {
380
403
  var oSubtree = oSubtreeHandle._getSubtree();
381
404
 
382
405
  if (oSubtreeHandle) {
@@ -404,8 +427,10 @@ sap.ui.define([
404
427
  * @param {boolean} bIgnore a flag to indicate if the node should be mapped
405
428
  * @param {object} oParent the parent node of oNode
406
429
  * @param {int} iPositionInParent the position of oNode in the children-array of oParent
430
+ * @param {object} [oIgnoreRemoveForNode] Newly inserted node which shouldn't be ignored
407
431
  */
408
- var fnTraverseDeepSubtree = function (oNode, bIgnore, oParent, iPositionInParent, oIgnoreRemoveForNode) {
432
+ fnTraverseDeepSubtree
433
+ = function (oNode, bIgnore, oParent, iPositionInParent, oIgnoreRemoveForNode) {
409
434
  // ignore node if it was already mapped or is removed (except if it was reinserted, denoted by oIgnoreRemoveForNode)
410
435
  if (!bIgnore) {
411
436
  if (!oNode.nodeState.removed || oIgnoreRemoveForNode == oNode) {
@@ -446,8 +471,21 @@ sap.ui.define([
446
471
 
447
472
  /**
448
473
  * Traverses a flat portion of the tree (or rather the given array).
474
+ *
475
+ * @param {object[]} aFlatTree
476
+ * The flat tree to traverse
477
+ * @param {number} iServerIndexOffset
478
+ * The server-index position, used to calculate $skip/$top
479
+ * @param {object} oIgnoreRemoveForNode
480
+ * Newly inserted node which shouldn't be ignored
481
+ * @param {number} iSubtreeBaseLevel
482
+ * Base level of the subtree
483
+ * @param {number} iNewParentBaseLevel
484
+ * Base level of the new parent
449
485
  */
450
- var fnTraverseFlatSubtree = function (aFlatTree, iServerIndexOffset, oIgnoreRemoveForNode, iSubtreeBaseLevel, iNewParentBaseLevel) {
486
+ fnTraverseFlatSubtree
487
+ = function (aFlatTree, iServerIndexOffset, oIgnoreRemoveForNode, iSubtreeBaseLevel,
488
+ iNewParentBaseLevel) {
451
489
  //count the nodes until we find the correct index
452
490
  for (var i = 0; i < aFlatTree.length; i++) {
453
491
  var oNode = aFlatTree[i];
@@ -488,19 +526,17 @@ sap.ui.define([
488
526
  // jump over collapsed nodes by the enclosing magnitude
489
527
  if (!oNode.initiallyCollapsed && oNode.nodeState.collapsed) {
490
528
  i += oNode.magnitude;
491
- } else {
529
+ } else if (oNode.initiallyCollapsed && oNode.nodeState.expanded) {
492
530
  // look into expanded nodes deeper than the initial expand level
493
- if (oNode.initiallyCollapsed && oNode.nodeState.expanded) {
494
- // the node itself will be ignored, since its fnMap was already called
495
- fnTraverseDeepSubtree(oNode, true);
496
- if (oRecursionBreaker.broken) {
497
- return;
498
- }
499
- } else if (!oNode.initiallyCollapsed && oNode.nodeState.expanded) {
500
- // before going to the next flat node (children|sibling), we look at the added subtrees in between
501
- // this is only necessary for expanded server-indexed nodes
502
- fnCheckNodeForAddedSubtrees(oNode);
531
+ // the node itself will be ignored, since its fnMap was already called
532
+ fnTraverseDeepSubtree(oNode, true);
533
+ if (oRecursionBreaker.broken) {
534
+ return;
503
535
  }
536
+ } else if (!oNode.initiallyCollapsed && oNode.nodeState.expanded) {
537
+ // before going to the next flat node (children|sibling), we look at the added subtrees in between
538
+ // this is only necessary for expanded server-indexed nodes
539
+ fnCheckNodeForAddedSubtrees(oNode);
504
540
  }
505
541
  }
506
542
 
@@ -579,9 +615,8 @@ sap.ui.define([
579
615
  var oEntry, sKey, iIndex, i,
580
616
  // the function is used to test whether one of its ascendant is expanded after the selectAll
581
617
  fnTest = function(oNode, index) {
582
- if (!oNode.isDeepOne && !oNode.initiallyCollapsed && oNode.serverIndex < iIndex && oNode.serverIndex + oNode.magnitude >= iIndex) {
583
- return true;
584
- }
618
+ return (!oNode.isDeepOne && !oNode.initiallyCollapsed
619
+ && oNode.serverIndex < iIndex && oNode.serverIndex + oNode.magnitude >= iIndex);
585
620
  };
586
621
 
587
622
 
@@ -636,7 +671,7 @@ sap.ui.define([
636
671
  this._iLowestServerLevel = Math.min(this._iLowestServerLevel, oNode.level);
637
672
  }
638
673
 
639
- // slection update if we are in select-all mode
674
+ // selection update if we are in select-all mode
640
675
  if (this._bSelectAll) {
641
676
  if (!this._aExpandedAfterSelectAll.some(fnTest)) {
642
677
  this.setNodeSelection(oNode, true);
@@ -726,9 +761,6 @@ sap.ui.define([
726
761
  aFilters = aFilters.concat(this.aApplicationFilters);
727
762
  }
728
763
 
729
- // TODO: Add additional filters to the read call, as soon as back-end implementations support it
730
- // Something like this: aFilters = [new sap.ui.model.Filter([hierarchyFilters].concat(this.aFilters))];
731
-
732
764
  var sAbsolutePath = this.getResolvedPath();
733
765
  if (sAbsolutePath) {
734
766
  oRequest.oRequestHandle = this.oModel.read(sAbsolutePath, {
@@ -1022,8 +1054,6 @@ sap.ui.define([
1022
1054
  aFilters = aFilters.concat(this.aApplicationFilters);
1023
1055
  }
1024
1056
 
1025
- // TODO: Add additional filters to the read call, as soon as back-end implementations support it
1026
- // Something like this: aFilters = [new sap.ui.model.Filter([hierarchyFilters].concat(this.aFilters))];
1027
1057
  var sAbsolutePath = this.getResolvedPath();
1028
1058
  if (sAbsolutePath) {
1029
1059
  oRequest.oRequestHandle = this.oModel.read(sAbsolutePath, {
@@ -1112,7 +1142,7 @@ sap.ui.define([
1112
1142
  * Merges the subtree in <code>oData</code> into the inner structure and expands it
1113
1143
  *
1114
1144
  * @param {object} oData The content which contains the nodes from the backed
1115
- * @param {object} oParentNode The parent node of the subtree
1145
+ * @param {object} oSubTreeRootNode The root node of the subtree
1116
1146
  */
1117
1147
  ODataTreeBindingFlat.prototype._addSubTree = function(oData, oSubTreeRootNode) {
1118
1148
  if (oData.results && oData.results.length > 0) {
@@ -1282,6 +1312,9 @@ sap.ui.define([
1282
1312
  /**
1283
1313
  * Finds the node object sitting at iRowIndex.
1284
1314
  * Does not directly correlate to the nodes position in its containing array.
1315
+ *
1316
+ * @param {number} iRowIndex The index of the node
1317
+ * @returns {object|undefined} The found node or <code>undefined</code> if the tree is initial
1285
1318
  */
1286
1319
  ODataTreeBindingFlat.prototype.findNode = function (iRowIndex) {
1287
1320
  return this._bReadOnly ? this._indexFindNode(iRowIndex) : this._mapFindNode(iRowIndex);
@@ -1289,10 +1322,13 @@ sap.ui.define([
1289
1322
 
1290
1323
  /**
1291
1324
  * The findNode implementation using the _map algorithm in a WRITE scenario.
1325
+ *
1326
+ * @param {number} iRowIndex The index of the node
1327
+ * @returns {object|undefined} The found node or <code>undefined</code> if the tree is initial
1292
1328
  */
1293
1329
  ODataTreeBindingFlat.prototype._mapFindNode = function (iRowIndex) {
1294
1330
  if (this.isInitial()) {
1295
- return;
1331
+ return undefined;
1296
1332
  }
1297
1333
 
1298
1334
  // first make a cache lookup
@@ -1317,10 +1353,13 @@ sap.ui.define([
1317
1353
 
1318
1354
  /**
1319
1355
  * The findNode implementation using the index-calculation algorithm in a READ scenario.
1356
+ *
1357
+ * @param {number} iRowIndex The index of the node
1358
+ * @returns {object|undefined} The found node or <code>undefined</code> if the tree is initial
1320
1359
  */
1321
1360
  ODataTreeBindingFlat.prototype._indexFindNode = function (iRowIndex) {
1322
1361
  if (this.isInitial()) {
1323
- return;
1362
+ return undefined;
1324
1363
  }
1325
1364
 
1326
1365
  // first make a cache lookup
@@ -1329,8 +1368,7 @@ sap.ui.define([
1329
1368
  return oNode;
1330
1369
  }
1331
1370
 
1332
- var oNodeInfo = this.getNodeInfoByRowIndex(iRowIndex),
1333
- oNode;
1371
+ var oNodeInfo = this.getNodeInfoByRowIndex(iRowIndex);
1334
1372
 
1335
1373
  if (oNodeInfo.parent) {
1336
1374
  oNode = oNodeInfo.parent.children[oNodeInfo.childIndex];
@@ -1345,6 +1383,8 @@ sap.ui.define([
1345
1383
 
1346
1384
  /**
1347
1385
  * Toggles a row index between expanded and collapsed.
1386
+ *
1387
+ * @param {number} iRowIndex The index of the row
1348
1388
  */
1349
1389
  ODataTreeBindingFlat.prototype.toggleIndex = function(iRowIndex) {
1350
1390
 
@@ -1362,8 +1402,9 @@ sap.ui.define([
1362
1402
 
1363
1403
  /**
1364
1404
  * Expands a node or index.
1365
- * @param vRowIndex either an index or a node instance
1366
- * @param {boolean} bSuppressChange if set to true, no change event will be fired
1405
+ *
1406
+ * @param {any} vRowIndex Either an index or a node instance
1407
+ * @param {boolean} bSuppressChange Whether the change event should be suppressed
1367
1408
  */
1368
1409
  ODataTreeBindingFlat.prototype.expand = function (vRowIndex, bSuppressChange) {
1369
1410
  var oToggledNode = vRowIndex;
@@ -1453,8 +1494,9 @@ sap.ui.define([
1453
1494
 
1454
1495
  /**
1455
1496
  * Collapses the given node or index.
1456
- * @param vRowIndex either an index or a node instance
1457
- * @param {boolean} bSuppressChange if set to true, there will be no change event fired
1497
+ *
1498
+ * @param {any} vRowIndex Either an index or a node instance
1499
+ * @param {boolean} bSuppressChange Whether the change event should be suppressed
1458
1500
  */
1459
1501
  ODataTreeBindingFlat.prototype.collapse = function (vRowIndex, bSuppressChange) {
1460
1502
  var oToggledNode = vRowIndex;
@@ -1552,7 +1594,9 @@ sap.ui.define([
1552
1594
  };
1553
1595
 
1554
1596
  /**
1555
- * Removes the selection for nodes which are contained in a removed OR collapsed subtree.
1597
+ * Returns an array containing nodes that are selected but invisible.
1598
+ *
1599
+ * @returns {object[]} The invisible and selected nodes
1556
1600
  * @private
1557
1601
  */
1558
1602
  ODataTreeBindingFlat.prototype._getInvisibleSelectedNodes = function () {
@@ -1582,6 +1626,8 @@ sap.ui.define([
1582
1626
 
1583
1627
  /**
1584
1628
  * Removes the selection on all nodes inside invisible subtrees (removed OR collapsed).
1629
+ *
1630
+ * @param {boolean} bForceDeselect Whether the deselect is forced
1585
1631
  * @private
1586
1632
  */
1587
1633
  ODataTreeBindingFlat.prototype._cleanUpSelection = function (bForceDeselect) {
@@ -1604,7 +1650,12 @@ sap.ui.define([
1604
1650
  };
1605
1651
 
1606
1652
  /**
1607
- * Checks if the oChild node is inside the subtree with root oAncestor.
1653
+ * Checks if the <code>oChild</code> node is inside the subtree with root oAncestor.
1654
+ *
1655
+ * @param {object} oAncestor The root of the subtree
1656
+ * @param {object} oChild The child
1657
+ *
1658
+ * @returns {boolean} Whether the child is inside the subtree
1608
1659
  */
1609
1660
  ODataTreeBindingFlat.prototype._isInSubtree = function (oAncestor, oChild) {
1610
1661
  var bIsInSubtree = false;
@@ -1622,11 +1673,15 @@ sap.ui.define([
1622
1673
  };
1623
1674
 
1624
1675
  /**
1625
- * Backtracking up the tree hierarchy.
1626
- * fnUp is called for all nodes.
1627
- * @param oNode the start node of the upwards traversal
1628
- * @param {function} fnUp callback for the backtracking
1629
- * @param {boolean} bOldParent a flag to specify if the new or old/original parent should be used for traversal
1676
+ * Backtrack up the tree hierarchy. <code>fnUp</code> is called for all nodes.
1677
+ *
1678
+ * @param {object} oNode
1679
+ * The start node of the upwards traversal
1680
+ * @param {function} fnUp
1681
+ * Callback for the backtracking
1682
+ * @param {boolean} bOldParent
1683
+ * A flag to specify if the new or old/original parent should be used for traversal
1684
+ *
1630
1685
  * @private
1631
1686
  */
1632
1687
  ODataTreeBindingFlat.prototype._up = function(oNode, fnUp, bOldParent) {
@@ -1643,10 +1698,12 @@ sap.ui.define([
1643
1698
 
1644
1699
  /**
1645
1700
  * Backtrack in a deep part of the tree.
1646
- * @param oNode
1647
- * @param {function} fnUp
1648
- * @param oBreaker
1649
- * @param {boolean} bOldParent
1701
+ *
1702
+ * @param {object} oNode The start node of the upwards traversal
1703
+ * @param {function} fnUp Callback for the backtracking
1704
+ * @param {object} oBreaker The recursion breaker
1705
+ * @param {boolean} bOldParent Unused
1706
+ *
1650
1707
  * @private
1651
1708
  */
1652
1709
  ODataTreeBindingFlat.prototype._structuralUp = function(oNode, fnUp, oBreaker, bOldParent) {
@@ -1666,10 +1723,12 @@ sap.ui.define([
1666
1723
 
1667
1724
  /**
1668
1725
  * Backtrack in a flat part of the tree
1669
- * @param oNode
1670
- * @param {function} fnUp
1671
- * @param oBreaker
1672
- * @param {boolean} bInitial
1726
+ *
1727
+ * @param {object} oNode The start node of the upwards traversal
1728
+ * @param {function} fnUp Callback for the backtracking
1729
+ * @param {object} oBreaker The recursion breaker
1730
+ * @param {boolean} bInitial Whether the tree is initial
1731
+ *
1673
1732
  * @private
1674
1733
  */
1675
1734
  ODataTreeBindingFlat.prototype._flatUp = function(oNode, fnUp, oBreaker, bInitial) {
@@ -1677,7 +1736,7 @@ sap.ui.define([
1677
1736
  i = bInitial ? iServerIndex - 1 : iServerIndex,
1678
1737
  oChangedNode, oParent;
1679
1738
 
1680
- for (; i >= 0 ; i--) {
1739
+ for (; i >= 0; i--) {
1681
1740
  if (this._aNodeChanges[i]) {
1682
1741
  oChangedNode = this._aNodes[i];
1683
1742
  if (oChangedNode.initiallyCollapsed) {
@@ -1706,10 +1765,14 @@ sap.ui.define([
1706
1765
 
1707
1766
  /**
1708
1767
  * Retrieves the parent node of a node.
1709
- * Either the current parent or the original one set by initial the back-end request.
1768
+ * Either the current parent or the original one set initially by the back-end request.
1769
+ *
1710
1770
  * @param {object} oNode
1711
- * @param {boolean} [bOldParent=false] if set to true, the original parent will be returned.
1712
- * @returns {object} Parent node of the given node.
1771
+ * The node
1772
+ * @param {boolean} [bOldParent=false]
1773
+ * If set to <code>true</code>, the original parent will be returned.
1774
+ * @returns {object}
1775
+ * Parent node of the given node
1713
1776
  */
1714
1777
  ODataTreeBindingFlat.prototype._getParent = function(oNode, bOldParent) {
1715
1778
  return bOldParent ? oNode.originalParent : oNode.parent;
@@ -1725,6 +1788,8 @@ sap.ui.define([
1725
1788
 
1726
1789
  /**
1727
1790
  * Calculates the Length-Delta for the index-calculation algorithm.
1791
+ *
1792
+ * @returns {number} The calculated length-delta
1728
1793
  */
1729
1794
  ODataTreeBindingFlat.prototype._indexCleanTreeStateMaps = function () {
1730
1795
  return this._calcIndexDelta(this._aNodes.length);
@@ -1732,6 +1797,8 @@ sap.ui.define([
1732
1797
 
1733
1798
  /**
1734
1799
  * Calculates the Length-Delta for the _map algorithm.
1800
+ *
1801
+ * @returns {number} The calculated length-delta
1735
1802
  */
1736
1803
  ODataTreeBindingFlat.prototype._mapCleanTreeStateMaps = function () {
1737
1804
  var aAllChangedNodes = this._aCollapsed.concat(this._aRemoved).concat(this._aExpanded).concat(this._aAdded),
@@ -1752,7 +1819,8 @@ sap.ui.define([
1752
1819
  * Visibility Check Matrix:
1753
1820
  * VO = Visible in Old Parent
1754
1821
  * VN = Visible in New Parent
1755
- * Delta-Sign, the sign which is used to determine if the magnitude should be added, substracted OR ignored.
1822
+ * Delta-Sign, the sign which is used to determine if the magnitude should be added,
1823
+ * subtracted OR ignored.
1756
1824
  *
1757
1825
  * VO | VN | Delta-Sign
1758
1826
  * ----|----|-----------
@@ -1778,7 +1846,8 @@ sap.ui.define([
1778
1846
  // first assume the newly added node is visible
1779
1847
  bVisible = true;
1780
1848
  // check whether it's visible under the current parent
1781
- // even when it's moved to a new parent, only the new parent needs to be considered because the newly added node doesn't
1849
+ // even when it's moved to a new parent, only the new parent needs to be
1850
+ // considered because the newly added node doesn't
1782
1851
  // have any contribution to the magnitude of the old parent.
1783
1852
  this._up(oNode, fnCheckVisible, false /*current/new parent*/);
1784
1853
 
@@ -1786,53 +1855,57 @@ sap.ui.define([
1786
1855
  iDelta++;
1787
1856
  }
1788
1857
  }
1789
- } else {
1790
- if (oNode.nodeState.collapsed || oNode.nodeState.expanded || oNode.nodeState.removed) {
1791
- // first assume the node is visible
1792
- bVisible = true;
1793
- this._up(oNode, fnCheckVisible, false /* current/new parent */);
1794
- // if the node isn't hidden by one of its current ancestors
1795
- if (bVisible) {
1796
- // if the node is removed and not reinserted, its children and itself should be substracted
1797
- if (oNode.nodeState.removed && !oNode.nodeState.reinserted) {
1798
- // deep or initiallyCollapsed nodes only substract themselves.
1799
- if (oNode.isDeepOne || oNode.initiallyCollapsed) {
1800
- iDelta -= 1;
1801
- } else {
1802
- // server indexed nodes always subtract their magnitude
1803
- iDelta -= (oNode.magnitude + 1);
1804
- }
1858
+ } else if (oNode.nodeState.collapsed || oNode.nodeState.expanded ||
1859
+ oNode.nodeState.removed) {
1860
+ // first assume the node is visible
1861
+ bVisible = true;
1862
+ this._up(oNode, fnCheckVisible, false /* current/new parent */);
1863
+ // if the node isn't hidden by one of its current ancestors
1864
+ if (bVisible) {
1865
+ // if the node is removed and not reinserted, its children and itself should be
1866
+ // subtracted
1867
+ if (oNode.nodeState.removed && !oNode.nodeState.reinserted) {
1868
+ // deep or initiallyCollapsed nodes only subtract themselves.
1869
+ if (oNode.isDeepOne || oNode.initiallyCollapsed) {
1870
+ iDelta -= 1;
1805
1871
  } else {
1806
- // if the node which is expanded after the initial loading is collapsed, its magnitude needs to be substracted.
1807
- if (oNode.nodeState.collapsed && oNode.serverIndex !== undefined && !oNode.initiallyCollapsed) {
1808
- iDelta -= oNode.magnitude;
1809
- }
1810
- // if the node which is manually expanded after the initial loading, its direct children length (not magnitude) needs to be added
1811
- if (oNode.nodeState.expanded && (oNode.isDeepOne || oNode.initiallyCollapsed)) {
1812
- iDelta += oNode.children.length;
1813
- }
1872
+ // server indexed nodes always subtract their magnitude
1873
+ iDelta -= (oNode.magnitude + 1);
1874
+ }
1875
+ } else {
1876
+ // if the node which is expanded after the initial loading is collapsed, its
1877
+ // magnitude needs to be subtracted.
1878
+ if (oNode.nodeState.collapsed && oNode.serverIndex !== undefined
1879
+ && !oNode.initiallyCollapsed) {
1880
+ iDelta -= oNode.magnitude;
1881
+ }
1882
+ // if the node which is manually expanded after the initial loading, its
1883
+ // direct children length (not magnitude) needs to be added
1884
+ if (oNode.nodeState.expanded
1885
+ && (oNode.isDeepOne || oNode.initiallyCollapsed)) {
1886
+ iDelta += oNode.children.length;
1814
1887
  }
1815
1888
  }
1816
- if (oNode.nodeState.reinserted) {
1817
- // if it's reinserted, check it's visibility between the new and old parent. Then decide how it influences the delta.
1818
- bVisibleNewParent = bVisible;
1819
- bVisible = true;
1820
- this._up(oNode, fnCheckVisible, true /*old parent*/);
1821
- var iVisibilityFactor = (aCheckMatrix[bVisible | 0][bVisibleNewParent | 0]);
1822
- // iVisibilityFactor is either 0, 1 or -1.
1823
- // 1 and -1 are the relevant factors here, otherwise the node is not visible
1824
- if (iVisibilityFactor) {
1825
- if (oNode.isDeepOne) {
1826
- iDelta += iVisibilityFactor * 1;
1827
- } else {
1828
- // re-inserted visible nodes, which are initially collapsed only contribute to the length +1
1829
- // they only count themselves, their children have already been added (if they were visible)
1830
- if (oNode.initiallyCollapsed) {
1831
- iDelta += iVisibilityFactor;
1832
- } else {
1833
- iDelta += iVisibilityFactor * (1 + oNode.magnitude);
1834
- }
1835
- }
1889
+ }
1890
+ if (oNode.nodeState.reinserted) {
1891
+ // if it's reinserted, check it's visibility between the new and old parent.
1892
+ // Then decide how it influences the delta.
1893
+ bVisibleNewParent = bVisible;
1894
+ bVisible = true;
1895
+ this._up(oNode, fnCheckVisible, true /*old parent*/);
1896
+ var iVisibilityFactor = (aCheckMatrix[bVisible | 0][bVisibleNewParent | 0]);
1897
+ // iVisibilityFactor is either 0, 1 or -1.
1898
+ // 1 and -1 are the relevant factors here, otherwise the node is not visible
1899
+ if (iVisibilityFactor) {
1900
+ if (oNode.isDeepOne) {
1901
+ iDelta += iVisibilityFactor * 1;
1902
+ } else if (oNode.initiallyCollapsed) {
1903
+ // re-inserted visible nodes, which are initially collapsed only
1904
+ // contribute to the length +1; they only count themselves, their
1905
+ // children have already been added (if they were visible)
1906
+ iDelta += iVisibilityFactor;
1907
+ } else {
1908
+ iDelta += iVisibilityFactor * (1 + oNode.magnitude);
1836
1909
  }
1837
1910
  }
1838
1911
  }
@@ -1843,7 +1916,10 @@ sap.ui.define([
1843
1916
  };
1844
1917
 
1845
1918
  /**
1846
- * Returns if the count was received already and we know how many entries there will be in total.
1919
+ * Returns whether the count was received already and we know how many entries there will be in
1920
+ * total.
1921
+ *
1922
+ * @returns {boolean} Whether the length is final
1847
1923
  */
1848
1924
  ODataTreeBindingFlat.prototype.isLengthFinal = function () {
1849
1925
  return this._bLengthFinal;
@@ -1852,6 +1928,8 @@ sap.ui.define([
1852
1928
  /**
1853
1929
  * The length of the binding regards the expanded state of the tree.
1854
1930
  * So the length is the direct length of the tables scrollbar.
1931
+ *
1932
+ * @returns {number} The length of the binding
1855
1933
  */
1856
1934
  ODataTreeBindingFlat.prototype.getLength = function () {
1857
1935
  return this._aNodes.length + this._iLengthDelta;
@@ -1859,10 +1937,16 @@ sap.ui.define([
1859
1937
 
1860
1938
  /**
1861
1939
  * Retrieves the context for a given index.
1940
+ *
1941
+ * @param {number} iRowIndex
1942
+ * The index
1943
+ * @returns {sap.ui.model.Context|undefined}
1944
+ * The context or <code>undefined</code> if the binding is inital or no node was found for the
1945
+ * index
1862
1946
  */
1863
1947
  ODataTreeBindingFlat.prototype.getContextByIndex = function (iRowIndex) {
1864
1948
  if (this.isInitial()) {
1865
- return;
1949
+ return undefined;
1866
1950
  }
1867
1951
 
1868
1952
  var oNode = this.findNode(iRowIndex);
@@ -1872,10 +1956,15 @@ sap.ui.define([
1872
1956
 
1873
1957
  /**
1874
1958
  * Retrieves the context for a given index.
1959
+ *
1960
+ * @param {number} iRowIndex
1961
+ * The index
1962
+ * @returns {object|undefined}
1963
+ * The found node or <code>undefined</code> if the binding is inital or no node was found
1875
1964
  */
1876
1965
  ODataTreeBindingFlat.prototype.getNodeByIndex = function (iRowIndex) {
1877
1966
  if (this.isInitial()) {
1878
- return;
1967
+ return undefined;
1879
1968
  }
1880
1969
 
1881
1970
  var oNode = this.findNode(iRowIndex);
@@ -1885,6 +1974,9 @@ sap.ui.define([
1885
1974
 
1886
1975
  /**
1887
1976
  * Checks if an index is expanded
1977
+ *
1978
+ * @param {number} iRowIndex The index
1979
+ * @returns {boolean} Whether the index is expanded
1888
1980
  */
1889
1981
  ODataTreeBindingFlat.prototype.isExpanded = function(iRowIndex) {
1890
1982
  var oNode = this.findNode(iRowIndex);
@@ -1911,17 +2003,17 @@ sap.ui.define([
1911
2003
  };
1912
2004
 
1913
2005
  /**
1914
- * Checks if a node has children.
1915
- * API function for TreeTable.
1916
- * @param oNode the node to check
1917
- * @returns {boolean} node has children or not
2006
+ * Checks if a node has children. API function for TreeTable.
2007
+ *
2008
+ * @param {object} oNode The node to check
2009
+ * @returns {boolean} Whether the node has children or not
1918
2010
  * @protected
1919
2011
  */
1920
2012
  ODataTreeBindingFlat.prototype.nodeHasChildren = function (oNode) {
1921
2013
  return !(oNode && oNode.nodeState.isLeaf);
1922
2014
  };
1923
2015
 
1924
- /**
2016
+ /*
1925
2017
  * @see sap.ui.model.odata.v2.ODataTreeBinding
1926
2018
  */
1927
2019
  ODataTreeBindingFlat.prototype._hasChangedEntity = function (mChangedEntities) {
@@ -1943,8 +2035,9 @@ sap.ui.define([
1943
2035
 
1944
2036
  /**
1945
2037
  * Sets the selection state of the given node.
1946
- * @param {object} oNodeState the node state for which the selection should be changed
1947
- * @param {boolean} bIsSelected the selection state for the given node
2038
+ *
2039
+ * @param {object} oNode The node for which the selection should be changed
2040
+ * @param {boolean} bIsSelected The selection state for the given node
1948
2041
  */
1949
2042
  ODataTreeBindingFlat.prototype.setNodeSelection = function (oNode, bIsSelected) {
1950
2043
 
@@ -1969,7 +2062,9 @@ sap.ui.define([
1969
2062
 
1970
2063
  /**
1971
2064
  * Returns the selection state for the node at the given index.
1972
- * @param {int} iRowIndex the row index to check for selection state
2065
+ *
2066
+ * @param {number} iRowIndex the row index to check for selection state
2067
+ * @returns {boolean} Whether the given index is selected
1973
2068
  */
1974
2069
  ODataTreeBindingFlat.prototype.isIndexSelected = function (iRowIndex) {
1975
2070
  var oNode = this.findNode(iRowIndex);
@@ -1977,9 +2072,11 @@ sap.ui.define([
1977
2072
  };
1978
2073
 
1979
2074
  /**
1980
- * Returns if the node at the given index is selectable.
1981
- * Always true for TreeTable controls, except the node is not defined.
1982
- * @param {int} iRowIndex the row index which should be checked for "selectability"
2075
+ * Returns whether the node at the given index is selectable. Always true for TreeTable
2076
+ * controls, except when the node is not defined.
2077
+ *
2078
+ * @param {number} iRowIndex The row index which should be checked for "selectability"
2079
+ * @returns {boolean} Whether the row is selectable
1983
2080
  */
1984
2081
  ODataTreeBindingFlat.prototype.isIndexSelectable = function (iRowIndex) {
1985
2082
  var oNode = this.findNode(iRowIndex);
@@ -1987,7 +2084,9 @@ sap.ui.define([
1987
2084
  };
1988
2085
 
1989
2086
  /**
1990
- * Removes the selection from all nodes
2087
+ * Removes the selection from all nodes.
2088
+ *
2089
+ * @returns {object} An object with information about the selection status
1991
2090
  * @private
1992
2091
  */
1993
2092
  ODataTreeBindingFlat.prototype._clearSelection = function () {
@@ -2079,7 +2178,8 @@ sap.ui.define([
2079
2178
  if (iChangedIndex >= 0) {
2080
2179
  oChanges.rowIndices.splice(iChangedIndex, 1);
2081
2180
  } else {
2082
- // the newly selcted index is missing and also has to be propagated via the event params
2181
+ // the newly selected index is missing and also has to be propagated via the event
2182
+ // params
2083
2183
  oChanges.rowIndices.push(iRowIndex);
2084
2184
  }
2085
2185
 
@@ -2337,29 +2437,31 @@ sap.ui.define([
2337
2437
  };
2338
2438
 
2339
2439
  /**
2340
- * Sets the selection to the range from iFromIndex to iToIndex (including boundaries).
2341
- * e.g. setSelectionInterval(1,3) marks the rows 1,2 and 3.
2342
- * All currently selected rows will be deselected in the process.
2343
- * A selectionChanged event is fired
2440
+ * Sets the selection to the range from <code>iFromIndex</code> to <code>iToIndex</code>
2441
+ * (including boundaries). E.g. <code>setSelectionInterval(1,3)</code> marks the rows 1,2 and 3.
2442
+ * All currently selected rows will be deselected in the process. A
2443
+ * <code>selectionChanged</code> event is fired.
2444
+ *
2445
+ * @param {number} iFromIndex The first index to select
2446
+ * @param {number} iToIndex The last index to select
2344
2447
  */
2345
2448
  ODataTreeBindingFlat.prototype.setSelectionInterval = function (iFromIndex, iToIndex) {
2346
- // clears the selection but suppresses the selection change event
2347
- var mClearParams = this._clearSelection();
2348
- // the addSelectionInterval function takes care of the selection change event
2349
- var mSetParams = this._setSelectionInterval(iFromIndex, iToIndex, true);
2350
-
2351
- var mIndicesFound = {};
2352
- var aRowIndices = [];
2353
- var iIndex;
2449
+ var iIndex, i,
2450
+ // clears the selection but suppresses the selection change event
2451
+ mClearParams = this._clearSelection(),
2452
+ mIndicesFound = {},
2453
+ aRowIndices = [],
2454
+ mSetParams = this._setSelectionInterval(iFromIndex, iToIndex, true);
2354
2455
 
2355
2456
  // flag all cleared indices as changed
2356
- for (var i = 0; i < mClearParams.rowIndices.length; i++) {
2457
+ for (i = 0; i < mClearParams.rowIndices.length; i++) {
2357
2458
  iIndex = mClearParams.rowIndices[i];
2358
2459
  mIndicesFound[iIndex] = true;
2359
2460
  }
2360
2461
 
2361
2462
  // now merge the changed indices after clearing with the newly selected
2362
- // duplicate indices mean, that the index was previously selected and is now still selected -> remove it from the changes
2463
+ // duplicate indices mean, that the index was previously selected and is now still selected
2464
+ // -> remove it from the changes
2363
2465
  for (i = 0; i < mSetParams.rowIndices.length; i++) {
2364
2466
  iIndex = mSetParams.rowIndices[i];
2365
2467
  if (mIndicesFound[iIndex]) {
@@ -2385,14 +2487,23 @@ sap.ui.define([
2385
2487
  };
2386
2488
 
2387
2489
  /**
2388
- * Sets the value inside the given range to the value given with 'bSelectionValue'
2490
+ * Sets the value inside the given range to the value given with 'bSelectionValue'.
2491
+ *
2492
+ * @param {int} iFromIndex
2493
+ * The starting index of the selection range
2494
+ * @param {int} iToIndex
2495
+ * The end index of the selection range
2496
+ * @param {boolean} bSelectionValue
2497
+ * The selection state which should be applied to all indices between 'from' and 'to' index
2498
+ * @returns {object} An object containing information about the newly set selection
2499
+ *
2389
2500
  * @private
2390
- * @param {int} iFromIndex the starting index of the selection range
2391
- * @param {int} iToIndex the end index of the selection range
2392
- * @param {boolean} bSelectionValue the selection state which should be applied to all indices between 'from' and 'to' index
2393
2501
  */
2394
- ODataTreeBindingFlat.prototype._setSelectionInterval = function (iFromIndex, iToIndex, bSelectionValue) {
2395
- return this._bReadOnly ? this._indexSetSelectionInterval(iFromIndex, iToIndex, bSelectionValue) : this._mapSetSelectionInterval(iFromIndex, iToIndex, bSelectionValue);
2502
+ ODataTreeBindingFlat.prototype._setSelectionInterval
2503
+ = function (iFromIndex, iToIndex, bSelectionValue) {
2504
+ return this._bReadOnly
2505
+ ? this._indexSetSelectionInterval(iFromIndex, iToIndex, bSelectionValue)
2506
+ : this._mapSetSelectionInterval(iFromIndex, iToIndex, bSelectionValue);
2396
2507
  };
2397
2508
 
2398
2509
  ODataTreeBindingFlat.prototype._indexSetSelectionInterval = function (iFromIndex, iToIndex, bSelectionValue) {
@@ -2407,7 +2518,7 @@ sap.ui.define([
2407
2518
 
2408
2519
  bSelectionValue = !!bSelectionValue;
2409
2520
 
2410
- for (i = iNewFromIndex ; i <= iNewToIndex ; i++) {
2521
+ for (i = iNewFromIndex; i <= iNewToIndex; i++) {
2411
2522
  oNode = this.findNode(i);
2412
2523
 
2413
2524
  if (oNode) {
@@ -2511,10 +2622,13 @@ sap.ui.define([
2511
2622
  };
2512
2623
 
2513
2624
  /**
2514
- * Marks a range of tree nodes as selected/deselected, starting with iFromIndex going to iToIndex.
2515
- * The TreeNodes are referenced via their absolute row index.
2516
- * Please be aware, that the absolute row index only applies to the tree which is visualized by the TreeTable.
2517
- * Invisible nodes (collapsed child nodes) will not be regarded.
2625
+ * Marks a range of tree nodes as selected/deselected, starting with <code>iFromIndex</code>
2626
+ * going to <code>iToIndex</code>. The TreeNodes are referenced via their absolute row index.
2627
+ * Please be aware, that the absolute row index only applies to the tree which is visualized by
2628
+ * the TreeTable. Invisible nodes (collapsed child nodes) will not be regarded.
2629
+ *
2630
+ * @param {number} iFromIndex The first index to mark
2631
+ * @param {number} iToIndex The last index to mark
2518
2632
  */
2519
2633
  ODataTreeBindingFlat.prototype.addSelectionInterval = function (iFromIndex, iToIndex) {
2520
2634
  var mParams = this._setSelectionInterval(iFromIndex, iToIndex, true);
@@ -2522,7 +2636,10 @@ sap.ui.define([
2522
2636
  };
2523
2637
 
2524
2638
  /**
2525
- * Removes the selections inside the given range (including boundaries)
2639
+ * Removes the selections inside the given range (including boundaries).
2640
+ *
2641
+ * @param {number} iFromIndex The first index
2642
+ * @param {number} iToIndex The last index
2526
2643
  */
2527
2644
  ODataTreeBindingFlat.prototype.removeSelectionInterval = function (iFromIndex, iToIndex) {
2528
2645
  var mParams = this._setSelectionInterval(iFromIndex, iToIndex, false);
@@ -2530,10 +2647,14 @@ sap.ui.define([
2530
2647
  };
2531
2648
 
2532
2649
  /**
2533
- * Selects all avaliable nodes
2650
+ * Selects all available nodes
2534
2651
  */
2535
2652
  ODataTreeBindingFlat.prototype.selectAll = function () {
2536
- this._bReadOnly ? this._indexSelectAll() : this._mapSelectAll();
2653
+ if (this._bReadOnly) {
2654
+ this._indexSelectAll();
2655
+ } else {
2656
+ this._mapSelectAll();
2657
+ }
2537
2658
  };
2538
2659
 
2539
2660
  ODataTreeBindingFlat.prototype._indexSelectAll = function () {
@@ -2550,7 +2671,7 @@ sap.ui.define([
2550
2671
  var iLength = this.getLength(),
2551
2672
  i, oNode;
2552
2673
 
2553
- for (i = 0 ; i < iLength; i++) {
2674
+ for (i = 0; i < iLength; i++) {
2554
2675
  oNode = this.findNode(i);
2555
2676
  if (oNode && !oNode.isArtificial) {
2556
2677
  //if we find the old lead selection index -> keep it, safes some performance later on
@@ -2619,20 +2740,23 @@ sap.ui.define([
2619
2740
 
2620
2741
  /**
2621
2742
  * Removes the complete selection.
2622
- * @param {boolean} bSuppressSelectionChangeEvent if this is set to true, no selectionChange event will be fired
2743
+ * @param {boolean} bSuppressSelectionChangeEvent
2744
+ * Whether the <code>selectionChange</code> event should be suppressed
2623
2745
  */
2624
- ODataTreeBindingFlat.prototype.clearSelection = function (bSuppresSelectionChangeEvent) {
2746
+ ODataTreeBindingFlat.prototype.clearSelection = function (bSuppressSelectionChangeEvent) {
2625
2747
  var oChanges = this._clearSelection();
2626
2748
 
2627
2749
  // check if the selection change event should be suppressed
2628
- if (!bSuppresSelectionChangeEvent) {
2750
+ if (!bSuppressSelectionChangeEvent) {
2629
2751
  this._publishSelectionChanges(oChanges);
2630
2752
  }
2631
2753
  };
2632
2754
 
2633
2755
  /**
2634
- * Fires a "selectionChanged" event with the given parameters.
2635
- * Also performs a sanity check on the parameters.
2756
+ * Fires a <code>selectionChanged</code> event with the given parameters. Also performs a sanity
2757
+ * check on the parameters.
2758
+ *
2759
+ * @param {object} mParams Event parameters
2636
2760
  */
2637
2761
  ODataTreeBindingFlat.prototype._publishSelectionChanges = function (mParams) {
2638
2762
 
@@ -2664,8 +2788,10 @@ sap.ui.define([
2664
2788
  };
2665
2789
 
2666
2790
  /**
2667
- * Sets the node hierarchy to collapse recursive. When set to true, all child nodes will get collapsed as well.
2668
- * @param {boolean} bCollapseRecursive
2791
+ * Sets the node hierarchy to collapse recursive. When set to true, all child nodes will get
2792
+ * collapsed as well.
2793
+ *
2794
+ * @param {boolean} bCollapseRecursive Whether recursive collapse should be enabled
2669
2795
  */
2670
2796
  ODataTreeBindingFlat.prototype.setCollapseRecursive = function (bCollapseRecursive) {
2671
2797
  this.bCollapseRecursive = !!bCollapseRecursive;
@@ -2703,8 +2829,12 @@ sap.ui.define([
2703
2829
  };
2704
2830
 
2705
2831
  /**
2706
- * Finds a node for the given context object.
2707
- * First makes a cache search before traversing the tree
2832
+ * Finds a node for the given context object. First makes a cache search before traversing the
2833
+ * tree.
2834
+ *
2835
+ * @param {sap.ui.model.Context} oContext The context
2836
+ *
2837
+ * @returns {object} The found node
2708
2838
  */
2709
2839
  ODataTreeBindingFlat.prototype._findNodeByContext = function (oContext) {
2710
2840
  // First try to find the node in the cache.
@@ -2742,6 +2872,10 @@ sap.ui.define([
2742
2872
 
2743
2873
  /**
2744
2874
  * Resolves the correct change group for the given key/path.
2875
+ *
2876
+ * @param {string} [sKey] The key; leave empty to use the binding's resolved path
2877
+ * @returns {string} The change group's groupId
2878
+ *
2745
2879
  * @private
2746
2880
  */
2747
2881
  ODataTreeBindingFlat.prototype._getCorrectChangeGroup = function (sKey) {
@@ -2753,6 +2887,9 @@ sap.ui.define([
2753
2887
 
2754
2888
  /**
2755
2889
  * Creates a new entry, which can be added to this binding instance via addContexts(...).
2890
+ *
2891
+ * @param {object} [mParameters] Parameters for the new entry
2892
+ * @returns {object} The new entry
2756
2893
  */
2757
2894
  ODataTreeBindingFlat.prototype.createEntry = function (mParameters) {
2758
2895
  var sAbsolutePath = this.getResolvedPath();
@@ -2773,6 +2910,8 @@ sap.ui.define([
2773
2910
 
2774
2911
  /**
2775
2912
  * Submits the queued changes regarding this binding instance.
2913
+ *
2914
+ * @param {object} [mParameters] Additional parameters
2776
2915
  */
2777
2916
  ODataTreeBindingFlat.prototype.submitChanges = function (mParameters) {
2778
2917
  mParameters = mParameters || {};
@@ -2843,9 +2982,6 @@ sap.ui.define([
2843
2982
  }.bind(this);
2844
2983
 
2845
2984
  mParameters.error = function (oEvent) {
2846
- // TODO: How to handle errors?
2847
- // What kind of errors? Timeout? Authentication failed? General 50x error?
2848
-
2849
2985
  // call original error handler
2850
2986
  fnOrgError(oEvent);
2851
2987
  };
@@ -2861,10 +2997,16 @@ sap.ui.define([
2861
2997
  };
2862
2998
 
2863
2999
  /**
2864
- * Generates the request data for a submit request.
2865
- * Generates a minimal set of UPDATE & DELETE requests, in the correct order.
3000
+ * Generates the request data for a submit request. Generates a minimal set of UPDATE & DELETE
3001
+ * requests, in the correct order.
3002
+ *
3003
+ * @param {object} oOptimizedChanges
3004
+ * Information about done changes
3005
+ * @param {function} fnRestoreRequestErrorHandler
3006
+ * Error handler to be called when the request fails
2866
3007
  */
2867
- ODataTreeBindingFlat.prototype._generateSubmitData = function (oOptimizedChanges, restoreRequestErrorHandler) {
3008
+ ODataTreeBindingFlat.prototype._generateSubmitData
3009
+ = function (oOptimizedChanges, fnRestoreRequestErrorHandler) {
2868
3010
  var aRemoved = oOptimizedChanges.removed,
2869
3011
  aCreationCancelled = oOptimizedChanges.creationCancelled,
2870
3012
  aAdded = oOptimizedChanges.added,
@@ -2879,7 +3021,7 @@ sap.ui.define([
2879
3021
  }
2880
3022
  var mRestoreRequestParameters = {
2881
3023
  groupId: this._getCorrectChangeGroup(),
2882
- error: restoreRequestErrorHandler
3024
+ error: fnRestoreRequestErrorHandler
2883
3025
  };
2884
3026
 
2885
3027
  aAdded.forEach(setParent); // No extra requests for add. Everything we need should be in the POST response
@@ -3000,6 +3142,11 @@ sap.ui.define([
3000
3142
 
3001
3143
  /**
3002
3144
  * Checks if a node is on the top level of the hierarchy.
3145
+ *
3146
+ * @param {object} oNode
3147
+ * The node
3148
+ * @returns {boolean|undefined}
3149
+ * Whether the node is on the top level or <code>undefined</code> in error cases
3003
3150
  */
3004
3151
  ODataTreeBindingFlat.prototype._nodeIsOnTopLevel = function (oNode) {
3005
3152
  if (oNode && oNode.serverIndex >= 0) {
@@ -3014,18 +3161,27 @@ sap.ui.define([
3014
3161
  } else {
3015
3162
  Log.warning("ODataTreeBindingFlat.nodeIsOnTopLevel: Node is not defined or not a server-indexed node.");
3016
3163
  }
3164
+
3165
+ return undefined;
3017
3166
  };
3018
3167
 
3019
3168
  /**
3020
3169
  * Deletes a node. Two cases which have to be checked:
3021
3170
  * 1. Created node: it will NOT be created anymore.
3022
3171
  * 2. Existing server-node: it will be deleted.
3172
+ *
3173
+ * @param {object} oNode
3174
+ * The node
3175
+ * @returns {object|undefined}
3176
+ * The delete request's handle or <code>undefined</code> in case of a created node
3023
3177
  */
3024
3178
  ODataTreeBindingFlat.prototype._generateDeleteRequest = function (oNode) {
3025
3179
  var oContext = oNode.context;
3026
3180
 
3027
3181
  if (oNode.nodeState.added) {
3028
3182
  this.oModel.deleteCreatedEntry(oContext);
3183
+
3184
+ return undefined;
3029
3185
  } else {
3030
3186
  var oDeleteRequestHandle = this.oModel.remove(oContext.getPath(), {
3031
3187
  groupId: this._getCorrectChangeGroup(),
@@ -3121,7 +3277,6 @@ sap.ui.define([
3121
3277
  var aAddedNodes,
3122
3278
  that = this;
3123
3279
 
3124
- // TODO: Add unit test for this function
3125
3280
  aAddedNodes = oOptimizedChanges.added.slice();
3126
3281
 
3127
3282
  aAddedNodes.sort(function(a, b) {
@@ -3167,7 +3322,6 @@ sap.ui.define([
3167
3322
 
3168
3323
 
3169
3324
  ODataTreeBindingFlat.prototype._updateNodeInfoAfterSave = function(oNode) {
3170
- // TODO: check whether the binding updates the property if the server returns 404 for this sub request
3171
3325
  var bIsDeepOne = oNode.context.getProperty(this.oTreeProperties["hierarchy-preorder-rank-for"]) === undefined;
3172
3326
 
3173
3327
  if (oNode.isDeepOne === undefined) {
@@ -3223,7 +3377,7 @@ sap.ui.define([
3223
3377
  var iAborted = 0;
3224
3378
 
3225
3379
  aData.forEach(function(oData) {
3226
- if (oData.error) { // Error occured
3380
+ if (oData.error) { // Error occurred
3227
3381
  // The request is aborted if statusCode is set with 0
3228
3382
  if (oData.error.statusCode === 0) {
3229
3383
  iAborted++;
@@ -3266,21 +3420,31 @@ sap.ui.define([
3266
3420
  that.fireDataReceived({data: aData});
3267
3421
  return aData;
3268
3422
  }
3423
+
3424
+ return undefined;
3269
3425
  });
3270
3426
  }
3427
+
3428
+ return undefined;
3271
3429
  });
3272
3430
  };
3273
3431
 
3274
3432
  /**
3275
- * First collects all of the loaded server-index node and deep node sections. It then reloads all of them and merges
3276
- * them into the inner structure. It also takes care of expansion state and restore it after a node is reloaded.
3433
+ * First collects all of the loaded server-index node and deep node sections. It then reloads
3434
+ * all of them and merges them into the inner structure. It also takes care of expansion state
3435
+ * and restore it after a node is reloaded.
3277
3436
  *
3278
- * @return {Promise} The promise resolves if all reload requests succeed, otherwise it's rejected.
3279
- * The resolved and rejected parameter share the same structure. Both of them are an array of elements.
3280
- * Each of the element is an object which has either the responseData or the error property set. If the
3281
- * corresponding request succeeds, the responseData property is set with an object which has the
3282
- * calculated iSkip, iTop and the loaded content under property oData. Otherwise the error property is
3283
- * set with the error object which is returned from the server.
3437
+ * @param {object} oOptimizedChanges
3438
+ * Changes that happened since the last request
3439
+ *
3440
+ * @return {Promise}
3441
+ * The promise resolves if all reload requests succeed, otherwise it's rejected. The resolved
3442
+ * and rejected parameter share the same structure. Both of them are an array of elements.
3443
+ * Each of the element is an object which has either the responseData or the error property
3444
+ * set. If the corresponding request succeeds, the responseData property is set with an object
3445
+ * which has the calculated <code>iSkip</code>, <code>iTop</code> and the loaded content under
3446
+ * property <code>oData</code>. Otherwise the error property is set with the error object
3447
+ * which is returned from the server.
3284
3448
  */
3285
3449
  ODataTreeBindingFlat.prototype._executeRestoreTreeState = function (oOptimizedChanges) {
3286
3450
  var iCollapsedNodesCount,
@@ -3313,7 +3477,7 @@ sap.ui.define([
3313
3477
  }
3314
3478
 
3315
3479
  // Request children
3316
- // (for expanded nodes on intial-expand-level and expanded deep nodes)
3480
+ // (for expanded nodes on initial-expand-level and expanded deep nodes)
3317
3481
  var aDeepNodeSections = this._collectDeepNodes();
3318
3482
 
3319
3483
  mDeepChanges = this._filterChangesForDeepSections(oOptimizedChanges);
@@ -3378,7 +3542,7 @@ sap.ui.define([
3378
3542
  var iAborted = 0;
3379
3543
 
3380
3544
  aData.forEach(function(oData) {
3381
- if (oData.error) { // Error occured
3545
+ if (oData.error) { // Error occurred
3382
3546
  // The request is aborted if statusCode is set with 0
3383
3547
  if (oData.error.statusCode === 0) {
3384
3548
  iAborted++;
@@ -3395,6 +3559,8 @@ sap.ui.define([
3395
3559
  restoreCollapseState();
3396
3560
  return aData;
3397
3561
  }
3562
+
3563
+ return undefined;
3398
3564
  });
3399
3565
  };
3400
3566
 
@@ -3403,9 +3569,11 @@ sap.ui.define([
3403
3569
  * isn't undefined, it's counted as loaded and is collected in one loaded section.
3404
3570
  * Otherwise the element is treated as unloaded node.
3405
3571
  *
3406
- * @param {array} The nodes array where loaded sections are collected
3407
- * @return {array} The loaded sections. Each section is represented as an element in this array.
3408
- * The element has the following two properties: iSkip and iTop.
3572
+ * @param {array} aNodes
3573
+ * The nodes array where loaded sections are collected
3574
+ * @return {array}
3575
+ * The loaded sections. Each section is represented as an element in this array. The element
3576
+ * has the following two properties: <code>iSkip</code> and <code>iTop</code>.
3409
3577
  */
3410
3578
  ODataTreeBindingFlat.prototype._collectServerSections = function (aNodes) {
3411
3579
  var aSections = [];
@@ -3459,7 +3627,6 @@ sap.ui.define([
3459
3627
 
3460
3628
  iPosition = oNode.context.getProperty(sPositionAnnot);
3461
3629
  if (iPosition === undefined) {
3462
- // TODO: Throw error or compensate?
3463
3630
  Log.warning("ODataTreeBindingFlat", "Missing " + sPositionAnnot + " value for node " + oNode.key);
3464
3631
  break;
3465
3632
  }
@@ -3498,8 +3665,9 @@ sap.ui.define([
3498
3665
 
3499
3666
  // o---------> the node o is removed, the -------> means the children of node o
3500
3667
  // ----------------------------- oSection
3501
- // |--------| the length of this range is the iRestLenth
3502
- // The amount of nodes within the oSection which appear after the oRemovedNode and are still left after the removal of the oRemoveNode
3668
+ // |--------| the length of this range is the iRestLength
3669
+ // The amount of nodes within the oSection which appear after the oRemovedNode
3670
+ // and are still left after the removal of the oRemoveNode
3503
3671
  iRestLength = (oSection.iSkip + oSection.iTop) - iPosition - iRemovedLength;
3504
3672
 
3505
3673
  if (iRestLength > 0) {
@@ -3631,20 +3799,16 @@ sap.ui.define([
3631
3799
  // at least one of the parents of the node is removed
3632
3800
  if (bIsRemovedInParent) {
3633
3801
  fnTrackRemovedNodes(oNode);
3802
+ } else if (oNode.nodeState.removed && !oNode.nodeState.reinserted) {
3803
+ // Node is removed
3804
+ fnTrackRemovedNodes(oNode);
3805
+ } else if (oNode.nodeState.added) {
3806
+ // Node got added. Parent annotation still needs to be set
3807
+ aAdded.push(oNode);
3634
3808
  } else {
3635
- // if none of the parents are removed, but the node itself is removed,
3636
- // we probably have reached the top-level, in this case the node of course shall also be removed
3637
- if (oNode.nodeState.removed && !oNode.nodeState.reinserted) {
3638
- // Node is removed)
3639
- fnTrackRemovedNodes(oNode);
3640
- } else if (oNode.nodeState.added) {
3641
- // Node got added. Parent annotation still needs to be set
3642
- aAdded.push(oNode);
3643
- } else {
3644
- // Node is moved
3645
- // so we have to change the parent annotation value
3646
- aMoved.push(oNode);
3647
- }
3809
+ // Node is moved
3810
+ // so we have to change the parent annotation value
3811
+ aMoved.push(oNode);
3648
3812
  }
3649
3813
  }.bind(this));
3650
3814
 
@@ -3736,6 +3900,8 @@ sap.ui.define([
3736
3900
 
3737
3901
  /**
3738
3902
  * Makes sure that the changed node is only tracked once.
3903
+ *
3904
+ * @param {object} oNode The changed node
3739
3905
  */
3740
3906
  ODataTreeBindingFlat.prototype._trackChangedNode = function (oNode) {
3741
3907
  if (this._aAllChangedNodes.indexOf(oNode) == -1) {
@@ -3743,8 +3909,8 @@ sap.ui.define([
3743
3909
  }
3744
3910
  };
3745
3911
 
3746
- /**
3747
- * @see sap.ui.model.odata.v2.ODataTreebinding#addContexts
3912
+ /*
3913
+ * @see sap.ui.model.odata.v2.ODataTreeBinding#addContexts
3748
3914
  */
3749
3915
  ODataTreeBindingFlat.prototype.addContexts = function (oParentContext, vContextHandles) {
3750
3916
  var oNodeInfo = this._findNodeByContext(oParentContext),
@@ -3784,15 +3950,16 @@ sap.ui.define([
3784
3950
 
3785
3951
  // IMPORTANT:
3786
3952
  // We need to reverse the order of the input child vContextHandles array.
3787
- // The reason is, that we later always "unshift" the subtree-handles to the addedSubtree list of the parent node.
3953
+ // The reason is, that we later always "unshift" the subtree-handles to the addedSubtree
3954
+ // list of the parent node.
3788
3955
  // This is done so the newly added nodes are added to the top of the subtree.
3789
- // At this positon they are the most likely to be visible in the TreeTable.
3956
+ // At this position they are the most likely to be visible in the TreeTable.
3790
3957
  vContextHandles = vContextHandles.slice();
3791
3958
  vContextHandles.reverse();
3792
3959
 
3793
- // seperate existing nodes/subtress from the newly created ones
3960
+ // separate existing nodes/subtrees from the newly created ones
3794
3961
  for (var j = 0; j < vContextHandles.length; j++) {
3795
- var oContext = vContextHandles[j];
3962
+ oContext = vContextHandles[j];
3796
3963
 
3797
3964
  if (!oContext || !(oContext instanceof sap.ui.model.Context)) {
3798
3965
  Log.warning("ODataTreeBindingFlat.addContexts(): no valid child context given!");
@@ -3800,7 +3967,7 @@ sap.ui.define([
3800
3967
  }
3801
3968
 
3802
3969
  // look up the context for a cut out subtree handle
3803
- var oNewHandle = this._mSubtreeHandles[oContext.getPath()];
3970
+ oNewHandle = this._mSubtreeHandles[oContext.getPath()];
3804
3971
 
3805
3972
  // set unique node ID if the context was created and we did not assign an ID yet
3806
3973
  this._ensureHierarchyNodeIDForContext(oContext);
@@ -3824,18 +3991,12 @@ sap.ui.define([
3824
3991
  // --> used for removing the subtreeHandle from the addedSubtree collection of the new parent node (in #removeContexts())
3825
3992
  oNewHandle._oSubtreeRoot.containingSubtreeHandle = oNewHandle;
3826
3993
 
3827
- // update parent property
3828
- oContext = oNewHandle.getContext();
3829
-
3830
3994
  // track root node as changed
3831
3995
  this._trackChangedNode(oNewHandle._oSubtreeRoot);
3832
-
3833
- // clean cut out subtree handles, if the context is later removed from the binding again,
3834
- // we simply re-add it with updated subtree data
3835
- this._mSubtreeHandles[oContext.getPath()];
3836
3996
  } else {
3837
3997
  // Context is unknown to the binding --> new context
3838
- // TODO: What to do with contexts, which are not created by this binding?
3998
+ // This relates to the unsupported use case of moving a context from one tree
3999
+ // binding to another
3839
4000
  Log.info("ODataTreeBindingFlat.addContexts(): Newly created context added.");
3840
4001
 
3841
4002
  this._ensureHierarchyNodeIDForContext(oContext);
@@ -3870,10 +4031,6 @@ sap.ui.define([
3870
4031
  };
3871
4032
  }
3872
4033
 
3873
- // update containing-server index for the newly added subtree
3874
- // TODO: Check if this information can be used productively, right now it's only used for debugging
3875
- oNewHandle._iContainingServerIndex = oNewParentNode.serverIndex || oNewParentNode.containingServerIndex;
3876
-
3877
4034
  // finally add the new subtree handle to the existing parent node's addedSubtree list
3878
4035
  oNewParentNode.addedSubtrees.unshift(oNewHandle);
3879
4036
 
@@ -3897,6 +4054,8 @@ sap.ui.define([
3897
4054
  /**
3898
4055
  * Makes sure a newly created node gets a newly generated Hierarchy-Node ID.
3899
4056
  * This will only happen once per newly created node/context.
4057
+ *
4058
+ * @param {sap.ui.model.Context} oContext The new node's context
3900
4059
  */
3901
4060
  ODataTreeBindingFlat.prototype._ensureHierarchyNodeIDForContext = function (oContext) {
3902
4061
  if (oContext) {
@@ -3908,8 +4067,8 @@ sap.ui.define([
3908
4067
  }
3909
4068
  };
3910
4069
 
3911
- /**
3912
- * @see sap.ui.model.odata.v2.ODataTreebinding#removeContext
4070
+ /*
4071
+ * @see sap.ui.model.odata.v2.ODataTreeBinding#removeContext
3913
4072
  */
3914
4073
  ODataTreeBindingFlat.prototype.removeContext = function (oContext) {
3915
4074
  var that = this;
@@ -3938,7 +4097,7 @@ sap.ui.define([
3938
4097
  if (iNewParentIndex != -1) {
3939
4098
  oNodeForContext.parent.addedSubtrees.splice(iNewParentIndex, 1);
3940
4099
  oNodeForContext.nodeState.reinserted = false;
3941
- //TODO: Is reseting the parent a correct way to remove the node/subtree from the whole tree?
4100
+ // Reset the parent to remove the node/subtree from the whole tree
3942
4101
  oNodeForContext.parent = null;
3943
4102
  }
3944
4103
  }
@@ -3955,7 +4114,6 @@ sap.ui.define([
3955
4114
  this._fireChange({reason: ChangeReason.Remove});
3956
4115
 
3957
4116
  // Internal Subtree Handle API
3958
- // TODO: Use HierarchyNode ID instead of path? oContext.getProperty(this.oTreeProperties["hierarchy-node-for"])
3959
4117
  this._mSubtreeHandles[oContext.getPath()] = {
3960
4118
  _removedFromVisualIndex: iIndex,
3961
4119
  _isRemovedSubtree: true,
@@ -3972,7 +4130,6 @@ sap.ui.define([
3972
4130
  getContext: function () {
3973
4131
  return oContext;
3974
4132
  },
3975
- // TODO: Maybe remove this
3976
4133
  _restore: function () {
3977
4134
  oNodeForContext.nodeState.removed = false;
3978
4135
  var iNodeStateFound = that._aRemoved.indexOf(oNodeForContext);
@@ -3990,6 +4147,8 @@ sap.ui.define([
3990
4147
  } else {
3991
4148
  Log.warning("ODataTreeBinding.removeContexts(): The given context is not part of the tree. Was it removed already?");
3992
4149
  }
4150
+
4151
+ return undefined;
3993
4152
  };
3994
4153
 
3995
4154
  //*********************************************
@@ -3998,7 +4157,12 @@ sap.ui.define([
3998
4157
 
3999
4158
  /**
4000
4159
  * Gets the related server-index for the given node.
4001
- * Either the index of a server-indexed node or the server-index of a containing node (for deep noodes).
4160
+ *
4161
+ * @param {object} oNode
4162
+ * The node
4163
+ * @returns {number}
4164
+ * Either the index of a server-indexed node or the server-index of a containing node (for
4165
+ * deep noodes)
4002
4166
  */
4003
4167
  ODataTreeBindingFlat.prototype._getRelatedServerIndex = function(oNode) {
4004
4168
  if (oNode.serverIndex === undefined) {
@@ -4010,8 +4174,9 @@ sap.ui.define([
4010
4174
 
4011
4175
  /**
4012
4176
  * Gets the node info for the given row-index.
4013
- * @param {int} iRowIndex
4014
- * @returns {{index:int}} node info for the given row-index
4177
+ *
4178
+ * @param {int} iRowIndex The row-index
4179
+ * @returns {{index:int}} Node info for the given row-index
4015
4180
  */
4016
4181
  ODataTreeBindingFlat.prototype.getNodeInfoByRowIndex = function(iRowIndex) {
4017
4182
  var iCPointer = 0, iEPointer = 0, oNode, bTypeCollapse, iValidCollapseIndex = -1;
@@ -4042,24 +4207,23 @@ sap.ui.define([
4042
4207
  break;
4043
4208
  }
4044
4209
 
4210
+ // collapse
4045
4211
  if (bTypeCollapse) {
4046
- // collapse
4047
4212
  if (!oNode.isDeepOne && !oNode.initiallyCollapsed && oNode.serverIndex > iValidCollapseIndex) {
4048
4213
  iRowIndex += oNode.magnitude;
4049
4214
  iValidCollapseIndex = oNode.serverIndex + oNode.magnitude;
4050
4215
  }
4051
- } else {
4052
- // expand
4053
- if (oNode.serverIndex > iValidCollapseIndex) {
4054
- // only the expanded node on the defined expand level matters the index
4055
- if (!oNode.isDeepOne && oNode.initiallyCollapsed) {
4056
- iRowIndex -= oNode.magnitude;
4057
- }
4216
+ // expand
4217
+ } else if (oNode.serverIndex > iValidCollapseIndex) {
4218
+ // only the expanded node on the defined expand level matters the index
4219
+ if (!oNode.isDeepOne && oNode.initiallyCollapsed) {
4220
+ iRowIndex -= oNode.magnitude;
4221
+ }
4058
4222
 
4059
- if (iRowIndex <= oNode.serverIndex) {
4060
- // the searched node is under the current node
4061
- return this._calcDirectIndex(oNode, iRowIndex + oNode.magnitude - oNode.serverIndex - 1);
4062
- }
4223
+ if (iRowIndex <= oNode.serverIndex) {
4224
+ // the searched node is under the current node
4225
+ return this._calcDirectIndex(oNode,
4226
+ iRowIndex + oNode.magnitude - oNode.serverIndex - 1);
4063
4227
  }
4064
4228
  }
4065
4229
  }
@@ -4072,13 +4236,20 @@ sap.ui.define([
4072
4236
 
4073
4237
  /**
4074
4238
  * This method calculates the DIRECT parent and the child index of a node's nth descendant.
4239
+ *
4240
+ * @param {object} oNode
4241
+ * The node
4242
+ * @param {number} iIndex
4243
+ * The descendant's index
4244
+ * @returns {object|undefined}
4245
+ * An object containing the found parent and the child's index or <code>undefined</code>
4075
4246
  */
4076
- ODataTreeBindingFlat.prototype._calcDirectIndex = function (oNode, index) {
4077
- var i, iMagnitude, oChild;
4078
- for (i = 0 ; i < oNode.children.length ; i++) {
4247
+ ODataTreeBindingFlat.prototype._calcDirectIndex = function (oNode, iIndex) {
4248
+ var oChild, i, iMagnitude;
4249
+ for (i = 0; i < oNode.children.length; i++) {
4079
4250
  oChild = oNode.children[i];
4080
4251
 
4081
- if (index === 0) {
4252
+ if (iIndex === 0) {
4082
4253
  return {
4083
4254
  parent: oNode,
4084
4255
  childIndex: i
@@ -4086,24 +4257,27 @@ sap.ui.define([
4086
4257
  }
4087
4258
 
4088
4259
  iMagnitude = oChild ? oChild.magnitude : 0;
4089
- index--;
4260
+ iIndex--;
4090
4261
 
4091
4262
  if (!oChild || oChild.nodeState.collapsed) {
4092
4263
  continue;
4093
4264
  }
4094
4265
 
4095
- if (index < iMagnitude) {
4096
- return this._calcDirectIndex(oChild, index);
4266
+ if (iIndex < iMagnitude) {
4267
+ return this._calcDirectIndex(oChild, iIndex);
4097
4268
  } else {
4098
- index -= iMagnitude;
4269
+ iIndex -= iMagnitude;
4099
4270
  }
4100
4271
  }
4272
+
4273
+ return undefined;
4101
4274
  };
4102
4275
 
4103
4276
  /**
4104
4277
  * Retrieves the Row-Index for the given node.
4105
- * @param {Object} oNode
4106
- * @returns {int} Row-Index for the given node
4278
+ *
4279
+ * @param {object} oNode The node
4280
+ * @returns {number} Row-Index for the given node
4107
4281
  */
4108
4282
  ODataTreeBindingFlat.prototype.getRowIndexByNode = function (oNode) {
4109
4283
  var iDelta = 0;
@@ -4131,9 +4305,10 @@ sap.ui.define([
4131
4305
  };
4132
4306
 
4133
4307
  /**
4134
- * Gets an array of node-infos for all selected nodes.
4135
- * A node info contains the node itself and a the current row-index for said node.
4136
- * @returns {Array}
4308
+ * Gets an array of node infos for all selected nodes. A node info contains the node itself and
4309
+ * the current row-index for said node.
4310
+ *
4311
+ * @returns {object[]} The node infos
4137
4312
  */
4138
4313
  ODataTreeBindingFlat.prototype._getSelectedNodesInfo = function () {
4139
4314
  var aNodesInfo = [];
@@ -4184,11 +4359,18 @@ sap.ui.define([
4184
4359
  * An expanded node contributes to the delta when it meets the following conditions:
4185
4360
  * 1. it's not expanded with the initial call which means it's either initially collapsed or manually loaded
4186
4361
  * 2. none of its ancestor it's collapsed.
4362
+ *
4363
+ * @param {number} iEndServerIndex The server index
4364
+ * @returns {number} The index delta
4187
4365
  */
4188
4366
  ODataTreeBindingFlat.prototype._calcIndexDelta = function (iEndServerIndex) {
4367
+ var i, bIgnore,
4368
+ iCollapsedDelta = 0,
4369
+ mCollapsedServerIndices = {},
4370
+ iLastCollapsedIndex = 0;
4371
+
4189
4372
  // collect all collapsed server indices and magnitude as a look-up table
4190
4373
  // serverIndex + magnitude form a range for which we can check if there is a containment situation
4191
- var mCollapsedServerIndices = {};
4192
4374
  this._aCollapsed.forEach(function (oNode) {
4193
4375
  // only regard nodes with a server-index and not initially collapsed
4194
4376
  if (oNode.serverIndex >= 0 && oNode.serverIndex < iEndServerIndex && !oNode.isDeepOne && !oNode.initiallyCollapsed) {
@@ -4196,11 +4378,7 @@ sap.ui.define([
4196
4378
  }
4197
4379
  });
4198
4380
 
4199
- // collapsed delta
4200
- var iLastCollapsedIndex = 0;
4201
- var iCollapsedDelta = 0;
4202
-
4203
- for (var i = 0; i < this._aCollapsed.length; i++) {
4381
+ for (i = 0; i < this._aCollapsed.length; i++) {
4204
4382
  var oCollapsedNode = this._aCollapsed[i];
4205
4383
 
4206
4384
  if (this._getRelatedServerIndex(oCollapsedNode) >= iEndServerIndex) {
@@ -4256,7 +4434,7 @@ sap.ui.define([
4256
4434
  oParent = oParent.parent;
4257
4435
  }
4258
4436
 
4259
- var bIgnore = fnInCollapsedRange(oExpandedNode);
4437
+ bIgnore = fnInCollapsedRange(oExpandedNode);
4260
4438
 
4261
4439
  // if not then regard the children for the expanded delta
4262
4440
  if (!bYep && !bIgnore) {
@@ -4265,7 +4443,7 @@ sap.ui.define([
4265
4443
 
4266
4444
  } else if (oExpandedNode.initiallyCollapsed) {
4267
4445
  // see if the node on the last auto-expand level is contained in a sub-tree of a collapsed server-indexed node
4268
- var bIgnore = fnInCollapsedRange(oExpandedNode);
4446
+ bIgnore = fnInCollapsedRange(oExpandedNode);
4269
4447
  if (!bIgnore) {
4270
4448
  // still we have to check for a
4271
4449
  iExpandedDelta += oExpandedNode.children.length;
@@ -4278,6 +4456,8 @@ sap.ui.define([
4278
4456
 
4279
4457
  /**
4280
4458
  * Sorts the given nodes array based on the server-index or a containing server-index.
4459
+ *
4460
+ * @param {object[]} aNodes The nodes
4281
4461
  */
4282
4462
  ODataTreeBindingFlat.prototype._sortNodes = function(aNodes) {
4283
4463
  var fnSort = function (a, b) {