@openui5/sap.ui.table 1.93.3 → 1.96.2

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 (53) hide show
  1. package/.reuse/dep5 +6 -11
  2. package/THIRDPARTY.txt +10 -16
  3. package/package.json +3 -3
  4. package/src/sap/ui/table/.library +1 -1
  5. package/src/sap/ui/table/AnalyticalColumn.js +1 -1
  6. package/src/sap/ui/table/AnalyticalColumnMenu.js +1 -1
  7. package/src/sap/ui/table/AnalyticalTable.js +51 -12
  8. package/src/sap/ui/table/Column.js +29 -6
  9. package/src/sap/ui/table/ColumnMenu.js +3 -1
  10. package/src/sap/ui/table/CreationRow.js +1 -1
  11. package/src/sap/ui/table/Row.js +1 -1
  12. package/src/sap/ui/table/RowAction.js +1 -1
  13. package/src/sap/ui/table/RowActionItem.js +1 -1
  14. package/src/sap/ui/table/RowSettings.js +3 -2
  15. package/src/sap/ui/table/Table.js +79 -98
  16. package/src/sap/ui/table/TablePersoController.js +1 -1
  17. package/src/sap/ui/table/TableRenderer.js +9 -3
  18. package/src/sap/ui/table/TreeTable.js +27 -2
  19. package/src/sap/ui/table/extensions/Accessibility.js +45 -26
  20. package/src/sap/ui/table/extensions/AccessibilityRender.js +1 -1
  21. package/src/sap/ui/table/extensions/DragAndDrop.js +1 -1
  22. package/src/sap/ui/table/extensions/ExtensionBase.js +1 -1
  23. package/src/sap/ui/table/extensions/Keyboard.js +25 -45
  24. package/src/sap/ui/table/extensions/KeyboardDelegate.js +67 -46
  25. package/src/sap/ui/table/extensions/Pointer.js +1 -14
  26. package/src/sap/ui/table/extensions/Scrolling.js +133 -126
  27. package/src/sap/ui/table/extensions/ScrollingIOS.js +369 -0
  28. package/src/sap/ui/table/extensions/Synchronization.js +1 -1
  29. package/src/sap/ui/table/library.js +10 -10
  30. package/src/sap/ui/table/messagebundle_fr.properties +1 -1
  31. package/src/sap/ui/table/messagebundle_it.properties +3 -3
  32. package/src/sap/ui/table/plugins/BindingSelection.js +1 -1
  33. package/src/sap/ui/table/plugins/PluginBase.js +1 -1
  34. package/src/sap/ui/table/plugins/SelectionModelSelection.js +17 -28
  35. package/src/sap/ui/table/plugins/SelectionPlugin.js +1 -1
  36. package/src/sap/ui/table/plugins/V4Aggregation.js +9 -2
  37. package/src/sap/ui/table/rowmodes/AutoRowMode.js +16 -1
  38. package/src/sap/ui/table/rowmodes/FixedRowMode.js +16 -1
  39. package/src/sap/ui/table/rowmodes/InteractiveRowMode.js +23 -9
  40. package/src/sap/ui/table/rowmodes/RowMode.js +10 -28
  41. package/src/sap/ui/table/rowmodes/VariableRowMode.js +1 -1
  42. package/src/sap/ui/table/themes/base/Cell.less +1 -10
  43. package/src/sap/ui/table/themes/base/Grouping.less +4 -1
  44. package/src/sap/ui/table/themes/base/ScrollingIOS.less +26 -0
  45. package/src/sap/ui/table/themes/base/Table.less +1 -1
  46. package/src/sap/ui/table/themes/base/library.source.less +1 -0
  47. package/src/sap/ui/table/utils/TableUtils.js +25 -60
  48. package/src/sap/ui/table/utils/_BindingUtils.js +1 -1
  49. package/src/sap/ui/table/utils/_ColumnUtils.js +1 -1
  50. package/src/sap/ui/table/utils/_GroupingUtils.js +5 -1
  51. package/src/sap/ui/table/utils/_HookUtils.js +1 -1
  52. package/src/sap/ui/table/utils/_MenuUtils.js +1 -1
  53. package/ui5.yaml +4 -1
@@ -94,7 +94,7 @@ sap.ui.define([
94
94
  * the data model and binding being used.
95
95
  * </p>
96
96
  * @extends sap.ui.core.Control
97
- * @version 1.93.3
97
+ * @version 1.96.2
98
98
  *
99
99
  * @constructor
100
100
  * @public
@@ -899,7 +899,7 @@ sap.ui.define([
899
899
  * </ul>
900
900
  *
901
901
  * @name sap.ui.table.Table#getDragDropConfig
902
- * @returns sap.ui.core.dnd.DragDropBase[]
902
+ * @returns {sap.ui.core.dnd.DragDropBase[]}
903
903
  * @function
904
904
  * @public
905
905
  * @since 1.52
@@ -971,8 +971,7 @@ sap.ui.define([
971
971
  // text selection for column headers?
972
972
  this._bAllowColumnHeaderTextSelection = false;
973
973
 
974
- this._iPendingRequests = 0;
975
- this._bPendingRequest = false; // Fallback in case a counter is not applicable.
974
+ _private(this).iPendingRequests = 0;
976
975
  this._iBindingLength = null;
977
976
 
978
977
  this._bFirstRendering = true;
@@ -1024,11 +1023,21 @@ sap.ui.define([
1024
1023
  if (this._bExtensionsInitialized) {
1025
1024
  return;
1026
1025
  }
1026
+
1027
1027
  ExtensionBase.enrich(this, PointerExtension);
1028
1028
  ExtensionBase.enrich(this, ScrollExtension);
1029
1029
  ExtensionBase.enrich(this, KeyboardExtension);
1030
1030
  ExtensionBase.enrich(this, AccExtension); // Must be registered after keyboard to reach correct delegate order
1031
1031
  ExtensionBase.enrich(this, DragAndDropExtension);
1032
+
1033
+ if (Device.os.ios) {
1034
+ sap.ui.require(["sap/ui/table/extensions/ScrollingIOS"], function(ScrollingIOSExtension) {
1035
+ if (!this.bIsDestroyed) {
1036
+ ExtensionBase.enrich(this, ScrollingIOSExtension);
1037
+ }
1038
+ }.bind(this));
1039
+ }
1040
+
1032
1041
  this._bExtensionsInitialized = true;
1033
1042
  };
1034
1043
 
@@ -1043,8 +1052,7 @@ sap.ui.define([
1043
1052
  this._cleanUpTimers();
1044
1053
  this._detachEvents();
1045
1054
  TableUtils.Menu.cleanupDefaultContentCellContextMenu(this);
1046
- clearTimeout(this._dataReceivedHandlerId);
1047
- delete this._dataReceivedHandlerId;
1055
+ clearHideBusyIndicatorTimeout(this);
1048
1056
  delete this._aTableHeaders;
1049
1057
  };
1050
1058
 
@@ -1101,7 +1109,7 @@ sap.ui.define([
1101
1109
  var bLangChanged = oChanges.hasOwnProperty("language");
1102
1110
  this._adaptLocalization(bRtlChanged, bLangChanged).then(function() {
1103
1111
  this.invalidate();
1104
- }.bind(this));
1112
+ }.bind(this)).catch(function() {});
1105
1113
  };
1106
1114
 
1107
1115
  /**
@@ -1543,11 +1551,6 @@ sap.ui.define([
1543
1551
  });
1544
1552
  }, this);
1545
1553
 
1546
- var oScrollExtension = this._getScrollExtension();
1547
- oScrollExtension.updateHorizontalScrollbar(oTableSizes);
1548
- oScrollExtension.updateVerticalScrollbarPosition();
1549
- oScrollExtension.updateVerticalScrollbarVisibility();
1550
-
1551
1554
  var $this = this.$();
1552
1555
 
1553
1556
  if (TableUtils.hasRowActions(this) || TableUtils.hasRowNavigationIndicators(this)) {
@@ -1564,7 +1567,10 @@ sap.ui.define([
1564
1567
  }
1565
1568
  return iColumnsWidth;
1566
1569
  }.bind(this), 0);
1567
- var bDummyColumnHasWidth = iTableWidth > iColumnsWidth;
1570
+ var bDummyColumnHasWidth = iTableWidth > iColumnsWidth + 1;
1571
+ // when the column widths contain subpixels, iTableWidth might be higher than iColumnsWidth
1572
+ // for just a fraction of a pixel even though no dummy column is needed. To avoid left positioning
1573
+ // of the row actions instead of absolute right, the calculation is adjusted with +1 pixel.
1568
1574
 
1569
1575
  if (!bHasFlexibleRowActions && bDummyColumnHasWidth) {
1570
1576
  var iRowActionPos = iColumnsWidth + oTableSizes.tableRowHdrScrWidth + oTableSizes.tableCtrlFixedWidth;
@@ -1589,12 +1595,14 @@ sap.ui.define([
1589
1595
  TableUtils.Hook.call(this, Hook.UpdateSizes, sReason);
1590
1596
  };
1591
1597
 
1598
+ /*
1599
+ * @see JSDoc generated by SAPUI5 control
1600
+ */
1592
1601
  Table.prototype.setShowOverlay = function(bShow) {
1593
- bShow = !!bShow;
1594
1602
  this.setProperty("showOverlay", bShow, true);
1595
1603
 
1596
1604
  if (this.getDomRef()) {
1597
- this.$().toggleClass("sapUiTableOverlay", bShow);
1605
+ this.$().toggleClass("sapUiTableOverlay", this.getShowOverlay());
1598
1606
  this._getAccExtension().updateAriaStateForOverlayAndNoData();
1599
1607
  this._getKeyboardExtension().updateNoDataAndOverlayFocus();
1600
1608
  }
@@ -1908,6 +1916,7 @@ sap.ui.define([
1908
1916
  resetBindingFlags(this);
1909
1917
  this._bRowsBeingBound = true;
1910
1918
  destroyVirtualRow(this);
1919
+ updateAutomaticBusyIndicator(this);
1911
1920
 
1912
1921
  // Temporary fix for the Support Assistant hacks. Support Assistant should implement a selection plugin.
1913
1922
  // TODO: Before we recommend to implement a selection plugin -> Complete BLI CPOUIFTEAMB-1464
@@ -1924,10 +1933,6 @@ sap.ui.define([
1924
1933
  //Table._addBindingListener(oBindingInfo, "dataRequested", this._onBindingDataRequested, this);
1925
1934
  //Table._addBindingListener(oBindingInfo, "dataReceived", this._onBindingDataReceived, this);
1926
1935
 
1927
- if (this.getEnableBusyIndicator()) {
1928
- this.setBusy(false);
1929
- }
1930
-
1931
1936
  TableUtils.Hook.call(this, Hook.BindRows, oBindingInfo);
1932
1937
  Control.prototype.bindAggregation.call(this, "rows", oBindingInfo);
1933
1938
  this._bRowsBeingBound = false;
@@ -2007,13 +2012,13 @@ sap.ui.define([
2007
2012
  }
2008
2013
 
2009
2014
  resetBindingFlags(this);
2015
+ updateAutomaticBusyIndicator(this);
2010
2016
  };
2011
2017
 
2012
2018
  function resetBindingFlags(oTable) {
2013
2019
  oTable._bRowsBeingBound = false;
2014
2020
  oTable._bContextsAvailable = false;
2015
- oTable._iPendingRequests = 0;
2016
- oTable._bPendingRequest = false;
2021
+ _private(oTable).iPendingRequests = 0;
2017
2022
  oTable._iBindingLength = null;
2018
2023
  }
2019
2024
 
@@ -2347,8 +2352,13 @@ sap.ui.define([
2347
2352
  Table.prototype._getRowContexts = function(iRequestLength, bSuppressAdjustToBindingLength, bSecondCall) {
2348
2353
  var oBinding = this.getBinding();
2349
2354
  var iRowCount = this.getRows().length;
2355
+ var iThreshold = this.getThreshold();
2350
2356
 
2351
2357
  iRequestLength = iRequestLength == null ? iRowCount : iRequestLength;
2358
+
2359
+ // If the threshold is not explicitly disabled by setting it to 0, the default threshold should be the number of rows.
2360
+ iThreshold = iThreshold > 0 ? Math.max(iRequestLength, iThreshold) : 0;
2361
+
2352
2362
  iRequestLength = Math.max(iRequestLength, this._getRowMode().getMinRequestLength());
2353
2363
 
2354
2364
  if (!oBinding || iRequestLength <= 0) {
@@ -2370,10 +2380,6 @@ sap.ui.define([
2370
2380
  var iMergeOffsetScrollRows = 0;
2371
2381
  var iMergeOffsetBottomRow = iLength;
2372
2382
 
2373
- // If the threshold is not explicitly disabled by setting it to 0, the default threshold should be the number of rows.
2374
- var iThreshold = this.getThreshold();
2375
- iThreshold = iThreshold ? Math.max(iRowCount, iThreshold) : 0;
2376
-
2377
2383
  // data can be requested with a single getContexts call if the fixed rows and the scrollable rows overlap.
2378
2384
  var iStartIndex = iFirstRenderedRowIndex;
2379
2385
 
@@ -2444,20 +2450,12 @@ sap.ui.define([
2444
2450
  * @private
2445
2451
  */
2446
2452
  Table.prototype._adjustToTotalRowCount = function() {
2447
- var oBinding = this.getBinding();
2448
2453
  var iTotalRowCount = this._getTotalRowCount();
2449
2454
 
2450
2455
  if (this._iBindingLength !== iTotalRowCount) {
2451
2456
  this._iBindingLength = iTotalRowCount;
2452
2457
  this._updateFixedBottomRows();
2453
2458
  TableUtils.Hook.call(this, Hook.TotalRowCountChanged);
2454
-
2455
- if (!oBinding || !TableUtils.hasPendingRequests(this)) {
2456
- // A client binding -or- an $expand filled list binding does not fire dataReceived events. Therefore we need to update the no data area here.
2457
- // When the binding has been removed, the table might not be completely re-rendered (just the content). But the cached binding
2458
- // length changes. In this case the no data area needs to be updated.
2459
- this._updateNoData();
2460
- }
2461
2459
  }
2462
2460
  };
2463
2461
 
@@ -2685,18 +2683,20 @@ sap.ui.define([
2685
2683
  // =============================================================================
2686
2684
 
2687
2685
  /**
2688
- * Show or hide the no data container.
2686
+ * Show or hide the NoData container.
2687
+ *
2688
+ * @param {sap.ui.table.Table} oTable Instance of the table.
2689
2689
  * @private
2690
2690
  */
2691
- Table.prototype._updateNoData = function() {
2692
- if (!this.getDomRef()) {
2693
- return;
2694
- }
2691
+ function updateNoData(oTable) {
2692
+ var oDomRef = oTable.getDomRef();
2695
2693
 
2696
- this.$().toggleClass("sapUiTableEmpty", TableUtils.isNoDataVisible(this));
2697
- this._getAccExtension().updateAriaStateForOverlayAndNoData();
2698
- this._getKeyboardExtension().updateNoDataAndOverlayFocus();
2699
- };
2694
+ if (oDomRef) {
2695
+ oTable.getDomRef().classList.toggle("sapUiTableEmpty", TableUtils.isNoDataVisible(oTable));
2696
+ oTable._getAccExtension().updateAriaStateForOverlayAndNoData();
2697
+ oTable._getKeyboardExtension().updateNoDataAndOverlayFocus();
2698
+ }
2699
+ }
2700
2700
 
2701
2701
  /*
2702
2702
  * @see JSDoc generated by SAPUI5 control API generator
@@ -3782,23 +3782,6 @@ sap.ui.define([
3782
3782
  return TableUtils.BaseSize[sContentDensity];
3783
3783
  };
3784
3784
 
3785
- /*
3786
- * @see JSDoc generated by SAPUI5 control API generator
3787
- */
3788
- Table.prototype.setShowNoData = function(bShowNoData) {
3789
- var bSuppressInvalidate = true;
3790
-
3791
- if (this.getShowNoData() && bShowNoData === false && this.getRows().length === 0) {
3792
- // If the NoData text is disabled, but there is no data, the table needs to be invalidated to make sure that empty rows are rendered.
3793
- bSuppressInvalidate = false;
3794
- }
3795
-
3796
- this.setProperty("showNoData", bShowNoData, bSuppressInvalidate);
3797
- this._updateNoData();
3798
-
3799
- return this;
3800
- };
3801
-
3802
3785
  /*
3803
3786
  * @see JSDoc generated by SAPUI5 control API generator
3804
3787
  */
@@ -3961,66 +3944,63 @@ sap.ui.define([
3961
3944
  */
3962
3945
  Table.prototype.setEnableBusyIndicator = function(bValue) {
3963
3946
  this.setProperty("enableBusyIndicator", bValue, true);
3964
- if (!bValue) {
3947
+
3948
+ if (this.getEnableBusyIndicator()) {
3949
+ updateAutomaticBusyIndicator(this);
3950
+ } else {
3965
3951
  this.setBusy(false);
3952
+ clearHideBusyIndicatorTimeout(this);
3966
3953
  }
3954
+
3967
3955
  return this;
3968
3956
  };
3969
3957
 
3970
3958
  /**
3971
- *
3972
3959
  * @private
3973
3960
  */
3974
- Table.prototype._onBindingDataRequested = function(oEvent) {
3975
- if (oEvent.getSource() != this.getBinding() || oEvent.getParameter("__simulateAsyncAnalyticalBinding")) {
3976
- return;
3977
- }
3978
-
3979
- this._iPendingRequests++;
3980
- this._bPendingRequest = true;
3981
-
3982
- var bCanUsePendingRequestsCounter = TableUtils.canUsePendingRequestsCounter(this);
3983
-
3984
- if (this.getEnableBusyIndicator()
3985
- && (bCanUsePendingRequestsCounter && this._iPendingRequests === 1
3986
- || !bCanUsePendingRequestsCounter)) {
3987
- this.setBusy(true);
3988
- }
3961
+ Table.prototype._onBindingDataRequested = function() {
3962
+ _private(this).iPendingRequests++;
3963
+ updateAutomaticBusyIndicator(this);
3964
+ };
3989
3965
 
3990
- clearTimeout(this._dataReceivedHandlerId);
3991
- delete this._dataReceivedHandlerId;
3966
+ /**
3967
+ * @private
3968
+ */
3969
+ Table.prototype._onBindingDataReceived = function() {
3970
+ _private(this).iPendingRequests--;
3971
+ updateAutomaticBusyIndicator(this);
3992
3972
  };
3993
3973
 
3994
3974
  /**
3995
- *
3996
3975
  * @private
3997
3976
  */
3998
- Table.prototype._onBindingDataReceived = function(oEvent) {
3999
- if (oEvent.getSource() != this.getBinding() || oEvent.getParameter("__simulateAsyncAnalyticalBinding")) {
3977
+ Table.prototype._hasPendingRequests = function() {
3978
+ return _private(this).iPendingRequests > 0;
3979
+ };
3980
+
3981
+ function updateAutomaticBusyIndicator(oTable) {
3982
+ if (!oTable.getEnableBusyIndicator()) {
4000
3983
  return;
4001
3984
  }
4002
3985
 
4003
- this._iPendingRequests--;
4004
- this._bPendingRequest = false;
3986
+ clearHideBusyIndicatorTimeout(oTable);
4005
3987
 
4006
- // The AnalyticalBinding updates the length after it fires dataReceived, therefore the total row count will not change here. Later,
4007
- // when the contexts are retrieved in Table#_getRowContexts, the AnalyticalBinding updates the length and Table#_adjustToTotalRowCount
4008
- // will be called again and actually perform the update.
4009
- this._adjustToTotalRowCount();
4010
-
4011
- if (!TableUtils.hasPendingRequests(this)) {
3988
+ if (oTable._hasPendingRequests()) {
3989
+ oTable.setBusy(true);
3990
+ } else {
4012
3991
  // This timer should avoid flickering of the busy indicator and unnecessary updates of NoData in case a request will be sent
4013
3992
  // (dataRequested) immediately after the last response was received (dataReceived).
4014
- clearTimeout(this._dataReceivedHandlerId);
4015
- this._dataReceivedHandlerId = setTimeout(function() {
4016
- if (this.getEnableBusyIndicator()) {
4017
- this.setBusy(false);
4018
- }
4019
- this._updateNoData();
4020
- delete this._dataReceivedHandlerId;
4021
- }.bind(this), 0);
3993
+ _private(oTable).hideBusyIndicatorTimeoutId = setTimeout(function() {
3994
+ oTable.setBusy(false);
3995
+ clearHideBusyIndicatorTimeout(oTable);
3996
+ }, 0);
4022
3997
  }
4023
- };
3998
+ }
3999
+
4000
+ function clearHideBusyIndicatorTimeout(oTable) {
4001
+ clearTimeout(_private(oTable).hideBusyIndicatorTimeoutId);
4002
+ delete _private(oTable).hideBusyIndicatorTimeoutId;
4003
+ }
4024
4004
 
4025
4005
  /**
4026
4006
  * Lets you control in which situation the <code>Scrollbar</code> fires scroll events.
@@ -4366,6 +4346,7 @@ sap.ui.define([
4366
4346
  TableUtils.Grouping.updateGroups(this);
4367
4347
  this._getAccExtension()._updateAriaRowIndices();
4368
4348
  this._updateSelection();
4349
+ updateNoData(this);
4369
4350
 
4370
4351
  // TODO: Move somewhere else. Row or GroupingUtils
4371
4352
  this.getRows().forEach(function(oRow) {
@@ -30,7 +30,7 @@ sap.ui.define([
30
30
  * @extends sap.ui.base.ManagedObject
31
31
  *
32
32
  * @author SAP SE
33
- * @version 1.93.3
33
+ * @version 1.96.2
34
34
  * @since 1.21.1
35
35
  *
36
36
  * @constructor
@@ -5,9 +5,9 @@
5
5
  */
6
6
 
7
7
  //Provides default renderer for control sap.ui.table.Table
8
- sap.ui.define(['sap/ui/core/Control', 'sap/ui/core/theming/Parameters', 'sap/ui/Device', './library', "./Column", './utils/TableUtils', "./extensions/ExtensionBase",
8
+ sap.ui.define(['sap/ui/core/Control', 'sap/ui/Device', './library', "./Column", './utils/TableUtils', "./extensions/ExtensionBase",
9
9
  'sap/ui/core/Renderer', 'sap/ui/core/IconPool', "sap/base/Log"],
10
- function(Control, Parameters, Device, library, Column, TableUtils, ExtensionBase, Renderer, IconPool, Log) {
10
+ function(Control, Device, library, Column, TableUtils, ExtensionBase, Renderer, IconPool, Log) {
11
11
  "use strict";
12
12
 
13
13
 
@@ -95,7 +95,7 @@ sap.ui.define(['sap/ui/core/Control', 'sap/ui/core/theming/Parameters', 'sap/ui/
95
95
  rm.class("sapUiTableRowNavIndicator");
96
96
  }
97
97
 
98
- if (TableUtils.isNoDataVisible(oTable) && !TableUtils.hasPendingRequests(oTable)) {
98
+ if (TableUtils.isNoDataVisible(oTable) && !oTable._hasPendingRequests()) {
99
99
  rm.class("sapUiTableEmpty"); // no data!
100
100
  }
101
101
 
@@ -1242,10 +1242,16 @@ sap.ui.define(['sap/ui/core/Control', 'sap/ui/core/theming/Parameters', 'sap/ui/
1242
1242
 
1243
1243
  TableRenderer.renderVSbExternal = function(rm, oTable) {
1244
1244
  if (ExtensionBase.isEnrichedWith(oTable, "sap.ui.table.extensions.Synchronization")) {
1245
+ rm.openStart("div");
1246
+ rm.style("position", "relative");
1247
+ rm.openEnd();
1248
+
1245
1249
  this.renderVSb(rm, oTable, {
1246
1250
  cssClass: "sapUiTableVSbExternal",
1247
1251
  tabIndex: false
1248
1252
  });
1253
+
1254
+ rm.close("div");
1249
1255
  } else {
1250
1256
  Log.error("This method can only be used with synchronization enabled.", oTable, "TableRenderer.renderVSbExternal");
1251
1257
  }
@@ -29,6 +29,8 @@ sap.ui.define([
29
29
  ) {
30
30
  "use strict";
31
31
 
32
+ var _private = TableUtils.createWeakMapFacade();
33
+
32
34
  /**
33
35
  * Constructor for a new TreeTable.
34
36
  *
@@ -38,7 +40,7 @@ sap.ui.define([
38
40
  * @class
39
41
  * The TreeTable control provides a comprehensive set of features to display hierarchical data.
40
42
  * @extends sap.ui.table.Table
41
- * @version 1.93.3
43
+ * @version 1.96.2
42
44
  *
43
45
  * @constructor
44
46
  * @public
@@ -159,6 +161,9 @@ sap.ui.define([
159
161
  */
160
162
  TreeTable.prototype.init = function() {
161
163
  Table.prototype.init.apply(this, arguments);
164
+
165
+ _private(this).bPendingRequest = false;
166
+
162
167
  TableUtils.Grouping.setToDefaultTreeMode(this);
163
168
  TableUtils.Hook.register(this, TableUtils.Hook.Keys.Row.UpdateState, updateRowState, this);
164
169
  TableUtils.Hook.register(this, TableUtils.Hook.Keys.Row.Expand, expandRow, this);
@@ -166,6 +171,8 @@ sap.ui.define([
166
171
  };
167
172
 
168
173
  TreeTable.prototype._bindRows = function(oBindingInfo) {
174
+ _private(this).bPendingRequest = false;
175
+
169
176
  if (!oBindingInfo.parameters) {
170
177
  oBindingInfo.parameters = {};
171
178
  }
@@ -690,6 +697,24 @@ sap.ui.define([
690
697
  return new BindingSelectionPlugin();
691
698
  };
692
699
 
693
- return TreeTable;
700
+ // If the ODataTreeBindingFlat adapter is applied to the TreeBinding, the adapter fires a dataRequested event on every call of getNodes,
701
+ // even if no request is sent. This can happen if the adapter ignores the request, because it finds out there is a pending request which
702
+ // covers it. When a request is ignored, no dataReceived event is fired.
703
+ // Therefore, a more limited method using a flag has to be used instead of a counter.
704
+
705
+ TreeTable.prototype._onBindingDataRequested = function(oEvent) {
706
+ _private(this).bPendingRequest = true;
707
+ Table.prototype._onBindingDataRequested.apply(this, arguments);
708
+ };
709
+
710
+ TreeTable.prototype._onBindingDataReceived = function(oEvent) {
711
+ _private(this).bPendingRequest = false;
712
+ Table.prototype._onBindingDataReceived.apply(this, arguments);
713
+ };
694
714
 
715
+ TreeTable.prototype._hasPendingRequests = function() {
716
+ return _private(this).bPendingRequest;
717
+ };
718
+
719
+ return TreeTable;
695
720
  });
@@ -239,6 +239,33 @@ sap.ui.define([
239
239
  return null;
240
240
  },
241
241
 
242
+ /**
243
+ * Gets the aria-relevant numbers of columns and rows in the table, taking into account virtualization and internal columns like the row
244
+ * action column.
245
+ *
246
+ * @returns {{columnCount: int, rowCount: int}}
247
+ */
248
+ getGridSize: function(oTable) {
249
+ var bHasRowHeader = TableUtils.hasRowHeader(oTable);
250
+ var bHasRowActions = TableUtils.hasRowActions(oTable);
251
+ var iColumnCount = TableUtils.getVisibleColumnCount(oTable) + (bHasRowHeader ? 1 : 0) + (bHasRowActions ? 1 : 0);
252
+ var iContentRowCount = TableUtils.isNoDataVisible(oTable) ? 0 : Math.max(oTable._getTotalRowCount(), oTable._getRowCounts().count);
253
+
254
+ return {
255
+ columnCount: iColumnCount,
256
+ rowCount: TableUtils.getHeaderRowCount(oTable) + iContentRowCount
257
+ };
258
+ },
259
+
260
+ /**
261
+ * Gets the aria-relevant index of a row, taking into account virtualization and the number of header rows.
262
+ *
263
+ * @returns {int}
264
+ */
265
+ getRowIndex: function(oRow) {
266
+ return oRow.getIndex() + 1 + TableUtils.getHeaderRowCount(oRow.getTable());
267
+ },
268
+
242
269
  /*
243
270
  * Determines the current row and column and updates the hidden description texts of the table accordingly.
244
271
  */
@@ -248,25 +275,21 @@ sap.ui.define([
248
275
  bIsRowChanged = false,
249
276
  bIsColChanged = false,
250
277
  bIsInitial = false,
251
- bHasRowHeader = TableUtils.hasRowHeader(oTable),
252
- bHasRowActions = TableUtils.hasRowActions(oTable);
278
+ bHasRowHeader = TableUtils.hasRowHeader(oTable);
253
279
 
254
280
  if (oIN) {
255
281
  // +1 -> we want to announce a count and not the index, the action column is handled like a normal column
256
282
  var iColumnNumber = ExtensionHelper.getColumnIndexOfFocusedCell(oExtension) + 1 + (bHasRowHeader ? 1 : 0);
257
- // same here + take virtualization into account
258
- var iRowNumber = TableUtils.getRowIndexOfFocusedCell(oTable) + oTable._getFirstRenderedRowIndex() + 1;
259
- var iColCount = TableUtils.getVisibleColumnCount(oTable) + (bHasRowHeader ? 1 : 0) + (bHasRowActions ? 1 : 0);
260
- var iRowCount = TableUtils.isNoDataVisible(oTable) ? 0 : Math.max(oTable._getTotalRowCount(), oTable._getRowCounts().count);
283
+ var oRow = oTable.getRows()[TableUtils.getRowIndexOfFocusedCell(oTable)];
284
+ var iRowNumber = oRow ? ExtensionHelper.getRowIndex(oRow) : 0;
285
+ var mGridSize = ExtensionHelper.getGridSize(oTable);
261
286
 
262
- bIsRowChanged = oExtension._iLastRowNumber != iRowNumber || (oExtension._iLastRowNumber == iRowNumber
263
- && oExtension._iLastColumnNumber == iColumnNumber);
287
+ bIsRowChanged = oExtension._iLastRowNumber != iRowNumber || (oExtension._iLastRowNumber == iRowNumber && oExtension._iLastColumnNumber == iColumnNumber);
264
288
  bIsColChanged = oExtension._iLastColumnNumber != iColumnNumber;
265
289
  bIsInitial = oExtension._iLastRowNumber == null && oExtension._iLastColumnNumber == null;
266
-
267
- oTable.$("rownumberofrows").text(bIsRowChanged && iRowNumber > 0 ? TableUtils.getResourceText("TBL_ROW_ROWCOUNT", [iRowNumber, iRowCount]) : " ");
268
- oTable.$("colnumberofcols").text(bIsColChanged ? TableUtils.getResourceText("TBL_COL_COLCOUNT", [iColumnNumber, iColCount]) : " ");
269
- oTable.$("ariacount").text(bIsInitial ? TableUtils.getResourceText("TBL_DATA_ROWS_COLS", [iRowCount, iColCount]) : " ");
290
+ oTable.$("rownumberofrows").text(bIsRowChanged && iRowNumber > 0 ? TableUtils.getResourceText("TBL_ROW_ROWCOUNT", [iRowNumber, mGridSize.rowCount]) : " ");
291
+ oTable.$("colnumberofcols").text(bIsColChanged ? TableUtils.getResourceText("TBL_COL_COLCOUNT", [iColumnNumber, mGridSize.columnCount]) : " ");
292
+ oTable.$("ariacount").text(bIsInitial ? TableUtils.getResourceText("TBL_DATA_ROWS_COLS", [mGridSize.rowCount, mGridSize.columnCount]) : " ");
270
293
 
271
294
  oExtension._iLastRowNumber = iRowNumber;
272
295
  oExtension._iLastColumnNumber = iColumnNumber;
@@ -689,12 +712,8 @@ sap.ui.define([
689
712
  mAttributes["role"] = "gridcell";
690
713
  mAttributes["aria-colindex"] = mParams.index + 1 + (TableUtils.hasRowHeader(oTable) ? 1 : 0);
691
714
 
692
- var aLabels = [],
693
- oColumn = mParams && mParams.column ? mParams.column : null;
694
-
695
- if (oColumn) {
696
- aLabels = ExtensionHelper.getRelevantColumnHeaders(oTable, oColumn);
697
- mAttributes["headers"] = aLabels.join(" ");
715
+ if (mParams.column) {
716
+ var aLabels = ExtensionHelper.getRelevantColumnHeaders(oTable, mParams.column);
698
717
 
699
718
  for (var i = 0; i < aLabels.length; i++) {
700
719
  aLabels[i] = aLabels[i] + "-inner";
@@ -703,9 +722,9 @@ sap.ui.define([
703
722
  if (mParams && mParams.fixed) {
704
723
  aLabels.push(sTableId + "-ariafixedcolumn");
705
724
  }
706
- }
707
725
 
708
- mAttributes["aria-labelledby"] = aLabels;
726
+ mAttributes["aria-labelledby"] = aLabels;
727
+ }
709
728
  break;
710
729
 
711
730
  case AccExtension.ELEMENTTYPES.ROOT: //The tables root dom element
@@ -717,7 +736,6 @@ sap.ui.define([
717
736
  break;
718
737
 
719
738
  case AccExtension.ELEMENTTYPES.CONTAINER: //The table container
720
- mAttributes["role"] = "application";
721
739
  break;
722
740
 
723
741
  case AccExtension.ELEMENTTYPES.CONTENT: //The content area of the table which contains all the table elements, rowheaders, columnheaders, etc
@@ -738,6 +756,7 @@ sap.ui.define([
738
756
  var bHasFixedBottomRows = mRowCounts.fixedBottom > 0;
739
757
  var bHasRowHeader = TableUtils.hasRowHeader(oTable);
740
758
  var bHasRowActions = TableUtils.hasRowActions(oTable);
759
+ var mGridSize = ExtensionHelper.getGridSize(oTable);
741
760
 
742
761
  mAttributes["aria-owns"] = [sTableId + "-table"];
743
762
  if (bHasFixedColumns) {
@@ -762,8 +781,8 @@ sap.ui.define([
762
781
  mAttributes["aria-owns"].push(sTableId + "-sapUiTableRowActionScr");
763
782
  }
764
783
 
765
- mAttributes["aria-rowcount"] = oTable._getTotalRowCount();
766
- mAttributes["aria-colcount"] = oTable._getVisibleColumns().length + (bHasRowHeader ? 1 : 0) + (bHasRowActions ? 1 : 0);
784
+ mAttributes["aria-rowcount"] = mGridSize.rowCount;
785
+ mAttributes["aria-colcount"] = mGridSize.columnCount;
767
786
 
768
787
  if (oTable.isA("sap.ui.table.AnalyticalTable")) {
769
788
  mAttributes["aria-roledescription"] = TableUtils.getResourceText("TBL_ANALYTICAL_TABLE_ROLE_DESCRIPTION");
@@ -883,7 +902,7 @@ sap.ui.define([
883
902
  * @class Extension for sap.ui.table.Table which handles ACC related things.
884
903
  * @extends sap.ui.table.extensions.ExtensionBase
885
904
  * @author SAP SE
886
- * @version 1.93.3
905
+ * @version 1.96.2
887
906
  * @constructor
888
907
  * @private
889
908
  * @alias sap.ui.table.extensions.Accessibility
@@ -1060,7 +1079,7 @@ sap.ui.define([
1060
1079
 
1061
1080
  for (i = 0; i < aRows.length; i++) {
1062
1081
  oRow = aRows[i];
1063
- oRow.getDomRefs(true).row.attr("aria-rowindex", oRow.getIndex() + 1);
1082
+ oRow.getDomRefs(true).row.attr("aria-rowindex", ExtensionHelper.getRowIndex(oRow));
1064
1083
  }
1065
1084
  };
1066
1085
 
@@ -1073,7 +1092,7 @@ sap.ui.define([
1073
1092
  var $Table = oTable.$("sapUiTableGridCnt");
1074
1093
 
1075
1094
  if ($Table) {
1076
- $Table.attr("aria-rowcount", oTable._getTotalRowCount());
1095
+ $Table.attr("aria-rowcount", ExtensionHelper.getGridSize(oTable).rowCount);
1077
1096
  }
1078
1097
  };
1079
1098
 
@@ -42,7 +42,7 @@ sap.ui.define([
42
42
  * @class Extension for sap.ui.table.TableRenderer which handles ACC related things.
43
43
  * @extends sap.ui.table.extensions.ExtensionBase
44
44
  * @author SAP SE
45
- * @version 1.93.3
45
+ * @version 1.96.2
46
46
  * @constructor
47
47
  * @private
48
48
  * @alias sap.ui.table.extensions.AccessibilityRender
@@ -244,7 +244,7 @@ sap.ui.define([
244
244
  *
245
245
  * @extends sap.ui.table.extensions.ExtensionBase
246
246
  * @author SAP SE
247
- * @version 1.93.3
247
+ * @version 1.96.2
248
248
  * @constructor
249
249
  * @private
250
250
  * @alias sap.ui.table.extensions.DragAndDrop
@@ -19,7 +19,7 @@ sap.ui.define([
19
19
  * @abstract
20
20
  * @extends sap.ui.base.Object
21
21
  * @author SAP SE
22
- * @version 1.93.3
22
+ * @version 1.96.2
23
23
  * @constructor
24
24
  * @private
25
25
  * @alias sap.ui.table.extensions.ExtensionBase