From 1063a92ec60f8e2941195c5e22ef82a4dba1c8dc Mon Sep 17 00:00:00 2001 From: Michael Prentice Date: Tue, 23 Apr 2019 17:21:33 -0500 Subject: [PATCH] fix(tabs): new tab animation broken by code to support IE11 (#11711) ## PR Checklist Please check that your PR fulfills the following requirements: - [x] The commit message follows [our guidelines](https://github.com/angular/material/blob/master/.github/CONTRIBUTING.md#-commit-message-format) - [ ] Tests for the changes have been added or this is not a bug fix / enhancement - [x] Docs have been added, updated, or were not required ## PR Type What kind of change does this PR introduce? ``` [x] Bugfix [ ] Enhancement [ ] Documentation content changes [ ] Code style update (formatting, local variables) [ ] Refactoring (no functional changes, no api changes) [ ] Build related changes [ ] CI related changes [ ] Infrastructure changes [ ] Other... Please describe: ``` ## What is the current behavior? The scroll to new tab animation is broken. Issue Number: Fixes #11689 ## What is the new behavior? The scroll to new tab animation is fixed for browsers other than IE. ## Does this PR introduce a breaking change? ``` [ ] Yes [x] No ``` ## Other information --- package-lock.json | 43 ++++++------------- package.json | 2 +- src/components/tabs/demoDynamicTabs/script.js | 13 +++--- src/components/tabs/js/tabDirective.js | 6 ++- src/components/tabs/js/tabsController.js | 38 +++++++++------- src/core/util/util.js | 9 +++- 6 files changed, 53 insertions(+), 58 deletions(-) diff --git a/package-lock.json b/package-lock.json index ac0706cc30b..0ffeae61ceb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "angular-material-source", - "version": "1.1.17", + "version": "1.1.18", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -3470,8 +3470,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -3492,14 +3491,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3514,20 +3511,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -3644,8 +3638,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -3657,7 +3650,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3672,7 +3664,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3680,14 +3671,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -3706,7 +3695,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -3787,8 +3775,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -3800,7 +3787,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -3886,8 +3872,7 @@ "safe-buffer": { "version": "5.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -3923,7 +3908,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3943,7 +3927,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3987,14 +3970,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, diff --git a/package.json b/package.json index 445e2e7c6e5..d21f4c6f1b4 100644 --- a/package.json +++ b/package.json @@ -115,4 +115,4 @@ "not bb <= 10", "not op_mob <= 12.1" ] -} \ No newline at end of file +} diff --git a/src/components/tabs/demoDynamicTabs/script.js b/src/components/tabs/demoDynamicTabs/script.js index 5efe5524961..2853c0437f8 100644 --- a/src/components/tabs/demoDynamicTabs/script.js +++ b/src/components/tabs/demoDynamicTabs/script.js @@ -32,14 +32,14 @@ previous = null; $scope.tabs = tabs; $scope.selectedIndex = 0; - $scope.$watch('selectedIndex', function(current, old) { + $scope.$watch('selectedIndex', function(newVal, oldVal) { previous = selected; - selected = tabs[current]; - if (old + 1 && (old !== current)) { - $log.debug('Goodbye ' + previous.title + '!'); + selected = tabs[newVal]; + if (oldVal + 1 && !angular.equals(oldVal, newVal)) { + $log.log('Goodbye ' + previous.title + '!'); } - if (current + 1) { - $log.debug('Hello ' + selected.title + '!'); + if (newVal + 1 > 0) { + $log.log('Hello ' + selected.title + '!'); } }); $scope.addTab = function(title, view) { @@ -52,4 +52,3 @@ }; } })(); - diff --git a/src/components/tabs/js/tabDirective.js b/src/components/tabs/js/tabDirective.js index fba407f3d42..8ec1aa48d4f 100644 --- a/src/components/tabs/js/tabDirective.js +++ b/src/components/tabs/js/tabDirective.js @@ -25,7 +25,8 @@ * @param {string=} label Optional attribute to specify a simple string as the tab label * @param {boolean=} ng-disabled If present and expression evaluates to truthy, disabled tab * selection. - * @param {string=} md-tab-class Optional attribute to specify a class that will be applied to the tab's button + * @param {string=} md-tab-class Optional attribute to specify a class that will be applied to the + * tab's button * @param {expression=} md-on-deselect Expression to be evaluated after the tab has been * de-selected. * @param {expression=} md-on-select Expression to be evaluated after the tab has been selected. @@ -36,7 +37,8 @@ * @usage * * - * + * *

My Tab content

*
* diff --git a/src/components/tabs/js/tabsController.js b/src/components/tabs/js/tabsController.js index 3624d93da97..ba12bd02d27 100644 --- a/src/components/tabs/js/tabsController.js +++ b/src/components/tabs/js/tabsController.js @@ -230,13 +230,13 @@ function MdTabsController ($scope, $element, $window, $mdConstant, $mdTabInkRipp * @param {string|number} left */ function handleOffsetChange (left) { - var elements = getElements(); var newValue = ((ctrl.shouldCenterTabs || isRtl() ? '' : '-') + left + 'px'); // Fix double-negative which can happen with RTL support newValue = newValue.replace('--', ''); - angular.element(elements.paging).css($mdConstant.CSS.TRANSFORM, 'translate(' + newValue + ', 0)'); + angular.element(getElements().paging).css($mdConstant.CSS.TRANSFORM, + 'translate(' + newValue + ', 0)'); $scope.$broadcast('$mdTabsPaginationChanged'); } @@ -439,11 +439,11 @@ function MdTabsController ($scope, $element, $window, $mdConstant, $mdTabInkRipp * Create an entry in the tabs array for a new tab at the specified index. * @param {Object} tabData tab to insert * @param {number} index location to insert the new tab - * @returns {*} + * @returns {Object} the inserted tab */ function insertTab (tabData, index) { var hasLoaded = loaded; - var proto = { + var proto = { getIndex: function () { return ctrl.tabs.indexOf(tab); }, isActive: function () { return this.getIndex() === ctrl.selectedIndex; }, isLeft: function () { return this.getIndex() < ctrl.selectedIndex; }, @@ -455,24 +455,27 @@ function MdTabsController ($scope, $element, $window, $mdConstant, $mdTabInkRipp }, id: $mdUtil.nextUid(), hasContent: !!(tabData.template && tabData.template.trim()) - }, - tab = angular.extend(proto, tabData); + }; + var tab = angular.extend(proto, tabData); + if (angular.isDefined(index)) { ctrl.tabs.splice(index, 0, tab); } else { ctrl.tabs.push(tab); } - processQueue(); updateHasContent(); + $mdUtil.nextTick(function () { updatePagination(); setAriaControls(tab); // if autoselect is enabled, select the newly added tab - if (hasLoaded && ctrl.autoselect) $mdUtil.nextTick(function () { - $mdUtil.nextTick(function () { select(ctrl.tabs.indexOf(tab)); }); - }); + if (hasLoaded && ctrl.autoselect) { + $mdUtil.nextTick(function () { + $mdUtil.nextTick(function () { select(ctrl.tabs.indexOf(tab)); }); + }); + } }); return tab; } @@ -576,17 +579,20 @@ function MdTabsController ($scope, $element, $window, $mdConstant, $mdTabInkRipp }); shouldPaginate = canvasWidth < 0; - // Work around width calculation issues on IE11 when pagination is enabled - if (shouldPaginate) { - getElements().paging.style.width = '999999px'; - } else { - getElements().paging.style.width = undefined; + // Work around width calculation issues on IE11 when pagination is enabled. + // Don't do this on other browsers because it breaks scroll to new tab animation. + if ($mdUtil.msie) { + if (shouldPaginate) { + getElements().paging.style.width = '999999px'; + } else { + getElements().paging.style.width = undefined; + } } return shouldPaginate; } /** - * Finds the nearest tab index that is available. This is primarily used for when the active + * Finds the nearest tab index that is available. This is primarily used for when the active * tab is removed. * @param newIndex * @returns {*} diff --git a/src/core/util/util.js b/src/core/util/util.js index 06774146932..c517ee804c5 100644 --- a/src/core/util/util.js +++ b/src/core/util/util.js @@ -901,7 +901,14 @@ function UtilFactory($document, $timeout, $compile, $rootScope, $$mdAnimate, $in // The XMLSerializer API is supported on IE11 and is the recommended workaround. var serializer = new XMLSerializer(); return serializer.serializeToString(element); - } + }, + + /** + * Support: IE 9-11 only + * documentMode is an IE-only property + * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx + */ + msie: window.document.documentMode }; // Instantiate other namespace utility methods