diff --git a/src/components/button/button.js b/src/components/button/button.js index 4f199895cf3..8bc32094b74 100644 --- a/src/components/button/button.js +++ b/src/components/button/button.js @@ -38,7 +38,7 @@ angular.module('material.components.button', [ * * I'm a link * - * + * * I'm a disabled button * * @@ -58,12 +58,11 @@ function MdButtonDirective($mdInkRipple, $mdTheming, $mdAria) { } function getTemplate(element, attr) { - var tag = isAnchor(attr) ? 'a' : 'button'; - //We need to manually pass disabled to the replaced element because - //of a bug where it isn't always passed. - var disabled = element[0].hasAttribute('disabled') ? ' disabled ' : ' '; - - return '<' + tag + disabled + 'class="md-button" ng-transclude>'; + if (isAnchor(attr)) { + return ''; + } else { + return ''; + } } function postLink(scope, element, attr) { @@ -79,9 +78,7 @@ function MdButtonDirective($mdInkRipple, $mdTheming, $mdAria) { // For anchor elements, we have to set tabindex manually when the // element is disabled if (isAnchor(attr)) { - scope.$watch(function() { - return node.hasAttribute('disabled'); - }, function(isDisabled) { + scope.$watch(attr.ngDisabled, function(isDisabled) { element.attr('tabindex', isDisabled ? -1 : 0); }); } diff --git a/src/components/button/button.spec.js b/src/components/button/button.spec.js index 2b610171e4b..c58020d9d7e 100644 --- a/src/components/button/button.spec.js +++ b/src/components/button/button.spec.js @@ -21,12 +21,6 @@ describe('md-button', function() { expect(button[0].tagName.toLowerCase()).toEqual('button'); })); - it('should pass in disabled attribute (testing our DOM bug-fix)', inject(function($compile, $rootScope) { - var button = $compile('')($rootScope.$new()); - $rootScope.$apply(); - expect(button[0].hasAttribute('disabled')).toBe(true); - })); - it('should expect an aria-label if element has no text', inject(function($compile, $rootScope, $log) { spyOn($log, 'warn'); var button = $compile('')($rootScope); diff --git a/src/components/button/demoBasicUsage/index.html b/src/components/button/demoBasicUsage/index.html index 5ba8bc35876..70a26eb74c1 100644 --- a/src/components/button/demoBasicUsage/index.html +++ b/src/components/button/demoBasicUsage/index.html @@ -13,7 +13,7 @@
Button Primary - Disabled + Disabled Warn
raised
@@ -27,7 +27,7 @@
- + diff --git a/src/components/checkbox/checkbox.js b/src/components/checkbox/checkbox.js index d6e7e976f9d..68d2e92f871 100644 --- a/src/components/checkbox/checkbox.js +++ b/src/components/checkbox/checkbox.js @@ -26,7 +26,6 @@ angular.module('material.components.checkbox', [ * @param {expression=} ngFalseValue The value to which the expression should be set when not selected. * @param {string=} ngChange Angular expression to be executed when input changes due to user interaction with the input element. * @param {boolean=} mdNoInk Use of attribute indicates use of ripple ink effects - * @param {boolean=} disabled Use of attribute indicates the switch is disabled: no ink effects and not selectable * @param {string=} ariaLabel Publish the button label used by screen-readers for accessibility. Defaults to the checkbox's text. * * @usage @@ -39,7 +38,7 @@ angular.module('material.components.checkbox', [ * No Ink Effects * * - * + * * Disabled * * diff --git a/src/components/checkbox/checkbox.spec.js b/src/components/checkbox/checkbox.spec.js index c875a2a1dbc..bb1947ec62e 100644 --- a/src/components/checkbox/checkbox.spec.js +++ b/src/components/checkbox/checkbox.spec.js @@ -52,18 +52,19 @@ describe('mdCheckbox', function() { it('should be disabled with disabled attr', inject(function($compile, $rootScope) { var element = $compile('
' + - '' + + '' + '' + '
')($rootScope); var checkbox = element.find('md-checkbox'); + $rootScope.$apply('isDisabled = true'); $rootScope.$apply('blue = false'); checkbox.triggerHandler('click'); expect($rootScope.blue).toBe(false); - checkbox.removeAttr('disabled'); + $rootScope.$apply('isDisabled = false'); checkbox.triggerHandler('click'); expect($rootScope.blue).toBe(true); diff --git a/src/components/checkbox/demoBasicUsage/index.html b/src/components/checkbox/demoBasicUsage/index.html index f0620ecda6a..259f77f77af 100644 --- a/src/components/checkbox/demoBasicUsage/index.html +++ b/src/components/checkbox/demoBasicUsage/index.html @@ -9,11 +9,11 @@ Checkbox 2: {{ data.cb2 }}
- + Checkbox (Disabled) - + Checkbox (Disabled, Checked) diff --git a/src/components/radioButton/radioButton.spec.js b/src/components/radioButton/radioButton.spec.js index cda14db073f..ea2e4763272 100644 --- a/src/components/radioButton/radioButton.spec.js +++ b/src/components/radioButton/radioButton.spec.js @@ -132,15 +132,16 @@ describe('radioButton', function() { it('should be disabled', inject(function($compile, $rootScope) { var element = $compile('' + - '' + + '' + '')($rootScope); var radio = element.find('md-radio-button'); + $rootScope.$apply('isDisabled = true'); $rootScope.$apply('color = null'); radio.triggerHandler('click'); expect($rootScope.color).toBe(null); - radio.removeAttr('disabled'); + $rootScope.$apply('isDisabled = false'); radio.triggerHandler('click'); expect($rootScope.color).toBe('white'); })); diff --git a/src/components/slider/demoBasicUsage/index.html b/src/components/slider/demoBasicUsage/index.html index 11d351f6f2a..474611732e0 100644 --- a/src/components/slider/demoBasicUsage/index.html +++ b/src/components/slider/demoBasicUsage/index.html @@ -44,12 +44,12 @@

Rating: {{rating}}/5

Disabled

- - + +

Disabled, Discrete

- - + + diff --git a/src/components/slider/slider.js b/src/components/slider/slider.js index 6b3528422d4..9454f2a2291 100644 --- a/src/components/slider/slider.js +++ b/src/components/slider/slider.js @@ -112,8 +112,6 @@ function SliderController($scope, $element, $attrs, $$rAF, $window, $mdAria, $md var stopDisabledWatch = angular.noop; if ($attrs.ngDisabled) { stopDisabledWatch = $scope.$parent.$watch($attrs.ngDisabled, updateAriaDisabled); - } else { - updateAriaDisabled(!!$attrs.disabled); } $mdAria.expect($element, 'aria-label'); diff --git a/src/components/sticky/sticky.js b/src/components/sticky/sticky.js index 62aeaa7895a..128f68eed0b 100644 --- a/src/components/sticky/sticky.js +++ b/src/components/sticky/sticky.js @@ -112,9 +112,6 @@ function MdSticky($document, $mdConstant, $compile, $$rAF, $mdUtil) { } function refreshElements() { - var contentRect = contentEl[0].getBoundingClientRect(); - - // Sort our collection of elements by their current position in the DOM. // We need to do this because our elements' order of being added may not // be the same as their order of display. diff --git a/src/components/switch/demoBasicUsage/index.html b/src/components/switch/demoBasicUsage/index.html index fe3c2f9463d..c400d520568 100644 --- a/src/components/switch/demoBasicUsage/index.html +++ b/src/components/switch/demoBasicUsage/index.html @@ -7,11 +7,11 @@ Switch 2: {{ data.cb2 }} - + Switch (Disabled) - + Switch (Disabled, Active) diff --git a/src/components/switch/switch.js b/src/components/switch/switch.js index f296fe13cbb..74d955ff1d9 100644 --- a/src/components/switch/switch.js +++ b/src/components/switch/switch.js @@ -29,7 +29,6 @@ angular.module('material.components.switch', [ * @param {expression=} ngFalseValue The value to which the expression should be set when not selected. * @param {string=} ngChange Angular expression to be executed when input changes due to user interaction with the input element. * @param {boolean=} mdNoInk Use of attribute indicates use of ripple ink effects. - * @param {boolean=} disabled Use of attribute indicates the switch is disabled: no ink effects and not selectable * @param {string=} ariaLabel Publish the button label used by screen-readers for accessibility. Defaults to the switch's text. * * @usage @@ -42,7 +41,7 @@ angular.module('material.components.switch', [ * No Ink Effects * * - * + * * Disabled * * @@ -65,17 +64,11 @@ function MdSwitch(mdCheckboxDirective, mdRadioButtonDirective, $mdTheming) { }; function compile(element, attr) { - var thumb = angular.element(element[0].querySelector('.md-switch-thumb')); - //Copy down disabled attributes for checkboxDirective to use - thumb.attr('disabled', attr.disabled); - thumb.attr('ngDisabled', attr.ngDisabled); - var checkboxLink = checkboxDirective.compile(thumb, attr); return function (scope, element, attr, ngModelCtrl) { $mdTheming(element); - var thumb = angular.element(element[0].querySelector('.md-switch-thumb')); return checkboxLink(scope, thumb, attr, ngModelCtrl); }; } diff --git a/src/components/tabs/demoStaticTabs/index.html b/src/components/tabs/demoStaticTabs/index.html index 792e4ee938e..ed8316bf1f1 100644 --- a/src/components/tabs/demoStaticTabs/index.html +++ b/src/components/tabs/demoStaticTabs/index.html @@ -1,6 +1,6 @@
- + Item One diff --git a/src/components/tabs/js/tabItemController.js b/src/components/tabs/js/tabItemController.js index 14f0a6ea35a..6c9c75e9b34 100644 --- a/src/components/tabs/js/tabItemController.js +++ b/src/components/tabs/js/tabItemController.js @@ -5,7 +5,7 @@ angular.module('material.components.tabs') .controller('$mdTab', TabItemController); -function TabItemController($scope, $element, $compile, $animate, $mdUtil) { +function TabItemController($scope, $element, $attrs, $compile, $animate, $mdUtil, $parse) { var self = this; // Properties @@ -20,8 +20,9 @@ function TabItemController($scope, $element, $compile, $animate, $mdUtil) { self.onSelect = onSelect; self.onDeselect = onDeselect; + var disabledParsed = $parse($attrs.ngDisabled); function isDisabled() { - return $element[0].hasAttribute('disabled'); + return disabledParsed($scope.$parent); } /** diff --git a/src/components/tabs/tabs.spec.js b/src/components/tabs/tabs.spec.js index d4c8df504d6..3fd761b6401 100644 --- a/src/components/tabs/tabs.spec.js +++ b/src/components/tabs/tabs.spec.js @@ -175,11 +175,11 @@ describe('', function() { tabs.scope().$apply('disabled0 = true'); expect(tabItems.eq(1)).toBeActiveTab(); expect(tabItems.eq(0).attr('aria-disabled')).toBe('true'); - expect(tabItems.eq(1).attr('aria-disabled')).toBe('false'); + expect(tabItems.eq(1).attr('aria-disabled')).not.toBe('true'); tabs.scope().$apply('disabled0 = false; disabled1 = true'); expect(tabItems.eq(0)).toBeActiveTab(); - expect(tabItems.eq(0).attr('aria-disabled')).toBe('false'); + expect(tabItems.eq(0).attr('aria-disabled')).not.toBe('true'); expect(tabItems.eq(1).attr('aria-disabled')).toBe('true'); }); diff --git a/src/components/textField/textField.js b/src/components/textField/textField.js index 39e04a9b5ec..2d62eb5ae06 100644 --- a/src/components/textField/textField.js +++ b/src/components/textField/textField.js @@ -36,13 +36,13 @@ angular.module('material.components.textField', [ * * * - * + * * * * * */ -function mdTextFloatDirective($mdTheming, $mdUtil) { +function mdTextFloatDirective($mdTheming, $mdUtil, $parse) { return { restrict: 'E', replace: true, @@ -59,26 +59,20 @@ function mdTextFloatDirective($mdTheming, $mdUtil) { return { pre : function(scope, element, attrs) { - // transpose `disabled` flag - if ( angular.isDefined(attrs.disabled) ) { - element.attr('disabled', true); - scope.isDisabled = true; - } + var disabledParsed = $parse(attrs.ngDisabled); + scope.isDisabled = function() { + return disabledParsed(scope.$parent); + }; scope.inputType = attrs.type || "text"; - element.removeAttr('type'); - - // transpose optional `class` settings - element.attr('class', attrs.class ); - }, post: $mdTheming }; }, template: - '' + + '' + ' ' + - ' ' + + ' ' + '' }; } @@ -148,15 +142,11 @@ function mdInputDirective($mdUtil) { var inputGroupCtrl = ctrls[0]; var ngModelCtrl = ctrls[1]; - // scan for disabled and transpose the `type` value to the element - var parent = element[0].parentNode; - var isDisabled = parent && parent.hasAttribute('disabled'); - - element.attr({ - 'tabindex': isDisabled ? -1 : 0, - 'aria-disabled': isDisabled ? 'true' : 'false', - 'type': attr.type || element.parent().attr('type') || "text" + scope.$watch(scope.isDisabled, function(isDisabled) { + element.attr('aria-disabled', !!isDisabled); + element.attr('tabindex', !!isDisabled); }); + element.attr('type', attr.type || element.parent().attr('type') || "text"); // When the input value changes, check if it "has" a value, and // set the appropriate class on the input group @@ -191,7 +181,7 @@ function mdInputDirective($mdUtil) { function isNotEmpty(value) { value = angular.isUndefined(value) ? element.val() : value; return (angular.isDefined(value) && (value!==null) && - (value.toString().trim() != "")); + (value.toString().trim() !== "")); } } }; diff --git a/src/components/textField/textField.spec.js b/src/components/textField/textField.spec.js index 2ced9a8c079..e39b914568a 100644 --- a/src/components/textField/textField.spec.js +++ b/src/components/textField/textField.spec.js @@ -215,7 +215,7 @@ describe('Text Field directives', function() { }); it('should add an ARIA attribute for disabled inputs', function() { - var markup ='' + ''; diff --git a/src/core/services/ripple/ripple.js b/src/core/services/ripple/ripple.js index 4b1468f4f72..7c259d8b959 100644 --- a/src/core/services/ripple/ripple.js +++ b/src/core/services/ripple/ripple.js @@ -67,8 +67,9 @@ function InkRippleService($window, $timeout) { }; function rippleIsAllowed() { + var parent; return !element[0].hasAttribute('disabled') && - !(element[0].parentNode && element[0].parentNode.hasAttribute('disabled')); + !((parent = element[0].parentNode) && parent.hasAttribute('disabled')); } function removeElement(element, wait) {