Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit efbbd37

Browse files
devversionThomasBurleson
authored andcommitted
fix(tabs): avoid width calculation deviations.
* Currently when using centered tabs, the `updateInkBarStyles` method is getting executed infinitely (even without $$rAF, sync) This is impacting the performance significant, because we're calculating the styles on each function call. The problem is, that the pagination wrapper uses another rounding process than the `updateInkBarStyle` method. Now both calculations are using the same rounding process / logic and the width's are now correct. Fixes #8289. Closes #8293
1 parent e5dcbab commit efbbd37

File tree

1 file changed

+23
-10
lines changed

1 file changed

+23
-10
lines changed

src/components/tabs/js/tabsController.js

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,11 @@ function MdTabsController ($scope, $element, $window, $mdConstant, $mdTabInkRipp
505505
function shouldPaginate () {
506506
if (ctrl.noPagination || !loaded) return false;
507507
var canvasWidth = $element.prop('clientWidth');
508-
angular.forEach(getElements().dummies, function (tab) { canvasWidth -= tab.offsetWidth; });
508+
509+
angular.forEach(getElements().dummies, function (tab) {
510+
canvasWidth -= tab.offsetWidth;
511+
});
512+
509513
return canvasWidth < 0;
510514
}
511515

@@ -570,17 +574,22 @@ function MdTabsController ($scope, $element, $window, $mdConstant, $mdTabInkRipp
570574
}
571575

572576
/**
577+
* Calculates the width of the pagination wrapper by summing the widths of the dummy tabs.
573578
* @returns {number}
574579
*/
575580
function calcPagingWidth () {
576-
var width = 1;
581+
return calcTabsWidth(getElements().dummies);
582+
}
583+
584+
function calcTabsWidth(tabs) {
585+
var width = 0;
577586

578-
angular.forEach(getElements().dummies, function (element) {
587+
angular.forEach(tabs, function (tab) {
579588
//-- Uses the larger value between `getBoundingClientRect().width` and `offsetWidth`. This
580589
// prevents `offsetWidth` value from being rounded down and causing wrapping issues, but
581590
// also handles scenarios where `getBoundingClientRect()` is inaccurate (ie. tabs inside
582591
// of a dialog)
583-
width += Math.max(element.offsetWidth, element.getBoundingClientRect().width);
592+
width += Math.max(tab.offsetWidth, tab.getBoundingClientRect().width);
584593
});
585594

586595
return Math.ceil(width);
@@ -746,21 +755,25 @@ function MdTabsController ($scope, $element, $window, $mdConstant, $mdTabInkRipp
746755
angular.element(elements.inkBar).css({ left: 'auto', right: 'auto' });
747756
return;
748757
}
758+
749759
if (!ctrl.tabs.length) return queue.push(ctrl.updateInkBarStyles);
750760
// if the element is not visible, we will not be able to calculate sizes until it is
751761
// we should treat that as a resize event rather than just updating the ink bar
752762
if (!$element.prop('offsetParent')) return handleResizeWhenVisible();
763+
753764
var index = ctrl.selectedIndex,
754765
totalWidth = elements.paging.offsetWidth,
755766
tab = elements.tabs[ index ],
756767
left = tab.offsetLeft,
757-
right = totalWidth - left - tab.offsetWidth,
758-
tabWidth;
768+
right = totalWidth - left - tab.offsetWidth;
769+
759770
if (ctrl.shouldCenterTabs) {
760-
tabWidth = Array.prototype.slice.call(elements.tabs).reduce(function (value, element) {
761-
return value + element.offsetWidth;
762-
}, 0);
763-
if (totalWidth > tabWidth) $mdUtil.nextTick(updateInkBarStyles, false);
771+
// We need to use the same calculate process as in the pagination wrapper, to avoid rounding deviations.
772+
var tabWidth = calcTabsWidth(elements.tabs);
773+
774+
if (totalWidth > tabWidth) {
775+
$mdUtil.nextTick(updateInkBarStyles, false);
776+
}
764777
}
765778
updateInkBarClassName();
766779
angular.element(elements.inkBar).css({ left: left + 'px', right: right + 'px' });

0 commit comments

Comments
 (0)