diff --git a/src/components/autocomplete/autocomplete.spec.js b/src/components/autocomplete/autocomplete.spec.js index a5df54bc3fa..b01ccc32480 100644 --- a/src/components/autocomplete/autocomplete.spec.js +++ b/src/components/autocomplete/autocomplete.spec.js @@ -194,7 +194,6 @@ describe('', function() { var element = compile(template, scope); var ctrl = element.controller('mdAutocomplete'); - var input = element.find('input'); var ul = element.find('ul'); $material.flushInterimElement(); @@ -523,7 +522,7 @@ describe('', function() { 'md-items="item in match(searchText)" ' + 'md-item-text="item.display" ' + 'md-select-on-focus="" ' + - 'tabindex="3"' + + 'tabindex="3" ' + 'placeholder="placeholder">' + '{{item.display}}' + ''; @@ -628,7 +627,7 @@ describe('', function() { 'md-search-text="searchText" ' + 'md-items="item in match(searchText)" ' + 'md-item-text="item.display" ' + - 'tabindex="3"' + + 'tabindex="3" ' + 'placeholder="placeholder">' + '{{item.display}}' + ''; @@ -650,7 +649,7 @@ describe('', function() { 'md-search-text="searchText" ' + 'md-items="item in match(searchText)" ' + 'md-item-text="item.display" ' + - 'tabindex="3"' + + 'tabindex="3" ' + 'placeholder="placeholder">' + '{{item.display}}' + ''; @@ -726,7 +725,7 @@ describe('', function() { var scope = createScope(null, { match: function() { // Return an invalid object, which is not an array, neither a promise. - return {} + return {}; } }); @@ -737,7 +736,7 @@ describe('', function() { 'md-search-text="searchText" ' + 'md-items="item in match(searchText)" ' + 'md-item-text="item.display" ' + - 'tabindex="3"' + + 'tabindex="3" ' + 'placeholder="placeholder">' + '{{item.display}}' + ''; @@ -763,7 +762,6 @@ describe('', function() { {{item.display}}\ '; var element = compile(template, scope); - var input = element.find('input'); var ctrl = element.controller('mdAutocomplete'); expect(scope.searchText).toBe(''); @@ -784,7 +782,7 @@ describe('', function() { describe('md-input-maxlength', function() { - it('should correctly set the form to invalid if floating label is present', inject(function($timeout) { + it('should correctly set the form to invalid if floating label is present', function() { var scope = createScope(null, {inputId: 'custom-input-id'}); var template = '
' + @@ -796,14 +794,13 @@ describe('', function() { 'md-search-text="searchText" ' + 'md-items="item in match(searchText)" ' + 'md-item-text="item.display" ' + - 'tabindex="3"' + + 'tabindex="3" ' + 'md-floating-label="Favorite state">' + '{{item.display}}' + '' + '
'; var element = compile(template, scope); - var input = element.find('input'); expect(scope.searchText).toBe(''); expect(scope.testForm.$valid).toBe(true); @@ -813,9 +810,9 @@ describe('', function() { expect(scope.testForm.$valid).toBe(false); element.remove(); - })); + }); - it('should correctly set the form to invalid when no floating label is present', inject(function($timeout) { + it('should correctly set the form to invalid when no floating label is present', function() { var scope = createScope(null, {inputId: 'custom-input-id'}); var template = '
' + @@ -832,7 +829,6 @@ describe('', function() { ''; var element = compile(template, scope); - var input = element.find('input'); expect(scope.searchText).toBe(''); expect(scope.testForm.$valid).toBe(true); @@ -842,9 +838,9 @@ describe('', function() { expect(scope.testForm.$valid).toBe(false); element.remove(); - })); + }); - it('should not clear the view value if the input is invalid', inject(function($timeout) { + it('should not clear the view value if the input is invalid', function() { var scope = createScope(null, {inputId: 'custom-input-id'}); var template = '
' + @@ -856,7 +852,7 @@ describe('', function() { 'md-search-text="searchText" ' + 'md-items="item in match(searchText)" ' + 'md-item-text="item.display" ' + - 'tabindex="3"' + + 'tabindex="3" ' + 'md-floating-label="Favorite state">' + '{{item.display}}' + '' + @@ -876,13 +872,12 @@ describe('', function() { expect(scope.searchText).toBe('Exceeded'); element.remove(); - })); - + }); }); describe('md-input-minlength', function() { - it('should correctly set the form to invalid when floating label is present', inject(function($timeout) { + it('should correctly set the form to invalid when floating label is present', function() { var scope = createScope(null, {inputId: 'custom-input-id'}); var template = '' + @@ -894,14 +889,13 @@ describe('', function() { 'md-search-text="searchText" ' + 'md-items="item in match(searchText)" ' + 'md-item-text="item.display" ' + - 'tabindex="3"' + + 'tabindex="3" ' + 'md-floating-label="Favorite state">' + '{{item.display}}' + '' + ''; var element = compile(template, scope); - var input = element.find('input'); scope.$apply('searchText = "abc"'); @@ -912,9 +906,9 @@ describe('', function() { expect(scope.testForm.$valid).toBe(true); element.remove(); - })); + }); - it('should correctly set the form to invalid when no floating label is present', inject(function($timeout) { + it('should correctly set the form to invalid when no floating label is present', function() { var scope = createScope(null, {inputId: 'custom-input-id'}); var template = '
' + @@ -931,7 +925,6 @@ describe('', function() { ''; var element = compile(template, scope); - var input = element.find('input'); scope.$apply('searchText = "abc"'); @@ -942,8 +935,7 @@ describe('', function() { expect(scope.testForm.$valid).toBe(true); element.remove(); - })); - + }); }); describe('md-escape-options checks', function() { @@ -981,7 +973,7 @@ describe('', function() { expect(ctrl.hidden).toBe(false); })); - afterEach(function() { element.remove() }); + afterEach(function() { element.remove(); }); it('does not clear the value nor blur when hitting escape', inject(function($mdConstant, $document, $timeout) { scope.$apply('escapeOptions = "none"'); scope.$apply(function() { @@ -1059,7 +1051,6 @@ describe('', function() { '; var element = compile(template, scope); var ctrl = element.controller('mdAutocomplete'); - var ul = element.find('ul'); $material.flushInterimElement(); @@ -1325,7 +1316,6 @@ describe('', function() { ' Sorry, not found...' + ''; var element = compile(template, scope); - var ctrl = element.controller('mdAutocomplete'); $material.flushOutstandingAnimations(); @@ -1491,7 +1481,7 @@ describe('', function() { expect(ctrl.hasNotFound).toBe(true); })); - it('properly sets hasNotFound with multiple autocompletes', inject(function($timeout, $material) { + it('properly sets hasNotFound with multiple autocompletes', function() { var scope = createScope(); var template1 = '', function() { // The first autocomplete has a template, the second one does not expect(ctrl1.hasNotFound).toBe(true); expect(ctrl2.hasNotFound).toBe(false); - })); + }); it('shows the md-not-found template even if we have lost focus', inject(function($timeout) { var scope = createScope(); @@ -1601,7 +1591,7 @@ describe('', function() { var template = ' ' + ''; @@ -1617,7 +1607,6 @@ describe('', function() { element.remove(); }) ); - }); describe('clear button', function() { @@ -1691,13 +1680,12 @@ describe('', function() { expect(ctrl.scope.clearButton).toBe(true); expect(wrapEl).toHaveClass('md-show-clear-button'); }); - }); describe('xss prevention', function() { it('should not allow html to slip through', inject(function($timeout, $material) { - var html = 'foo '; + var html = 'foo test'; var scope = createScope([{ display: html }]); var template = '\ @@ -1750,7 +1738,6 @@ describe('', function() { ' {{item.display}}' + ''; var element = compile(template, scope); - var input = element.find('input'); var ctrl = element.controller('mdAutocomplete'); $material.flushInterimElement(); @@ -1765,7 +1752,6 @@ describe('', function() { expect(ctrl.loading).toBe(false); })); - }); describe('Accessibility', function() { @@ -1915,7 +1901,6 @@ describe('', function() { var scope = createScope(items); var element = compile(template, scope); var ctrl = element.controller('mdAutocomplete'); - var input = element.find('input'); // Run our initial flush $timeout.flush(); @@ -1986,7 +1971,6 @@ describe('', function() { var scope = createScope(); var element = compile(template, scope); var ctrl = element.controller('mdAutocomplete'); - var input = element.find('input'); // Run our initial flush $timeout.flush(); @@ -2034,7 +2018,6 @@ describe('', function() { var scope = createScope(); var element = compile(template, scope); var ctrl = element.controller('mdAutocomplete'); - var input = element.find('input'); // Run our initial flush $timeout.flush(); @@ -2297,7 +2280,6 @@ describe('', function() { ''; var scope = createScope(); var element = compile(template, scope); - var ctrl = element.controller('mdAutocomplete'); var input = element.find('input'); // Run our initial flush $timeout.flush(); @@ -2321,7 +2303,6 @@ describe('', function() { ''; var scope = createScope(); var element = compile(template, scope); - var ctrl = element.controller('mdAutocomplete'); var input = element.find('input'); // Run our initial flush $timeout.flush(); @@ -2905,6 +2886,7 @@ describe('', function() { describe('when required', function() { it('properly handles md-min-length="0" and undefined searchText', function() { var scope = createScope(); + var element; var template = '\ ', function() { var error; try { - var element = compile(template, scope); + element = compile(template, scope); scope.searchText = undefined; scope.$digest(); @@ -3187,7 +3169,7 @@ describe('', function() { document.body.removeChild(parent[0]); })); - it('should show standard-mode lists on focus when min-length is met', inject(function($timeout) { + it('should show standard-mode lists on focus when min-length is met', function() { var scope = createScope(); // Overwrite the match function to always show some results. @@ -3228,9 +3210,9 @@ describe('', function() { expect(scrollContainer.offsetParent).toBeTruthy(); document.body.removeChild(parent[0]); - })); + }); - it('should show virtual lists on focus when min-length is met', inject(function($timeout) { + it('should show virtual lists on focus when min-length is met', function() { var scope = createScope(); // Overwrite the match function to always show some results. @@ -3270,9 +3252,9 @@ describe('', function() { expect(scrollContainer.offsetParent).toBeTruthy(); document.body.removeChild(parent[0]); - })); + }); - it('should not show virtual lists on focus when min-length is not met', inject(function($timeout) { + it('should not show virtual lists on focus when min-length is not met', function() { var scope = createScope(); // Overwrite the match function to always show some results. @@ -3322,9 +3304,9 @@ describe('', function() { expect(scrollContainer.offsetParent).toBeTruthy(); document.body.removeChild(parent[0]); - })); + }); - it('should not show standard-mode lists on focus when min-length is not met', inject(function($timeout) { + it('should not show standard-mode lists on focus when min-length is not met', function() { var scope = createScope(); // Overwrite the match function to always show some results. @@ -3375,7 +3357,7 @@ describe('', function() { expect(scrollContainer.offsetParent).toBeTruthy(); document.body.removeChild(parent[0]); - })); + }); it('should calculate the height of a virtual list from the default max items', inject(function($timeout) { var scope = createScope(); @@ -3487,7 +3469,7 @@ describe('', function() { 'md-items="item in match(searchText)" ' + 'md-item-text="item" ' + 'md-min-length="0" ' + - 'md-dropdown-items="' + maxDropdownItems +'"' + + 'md-dropdown-items="' + maxDropdownItems +'" ' + 'placeholder="placeholder">' + '{{item}}' + '' + @@ -3538,7 +3520,7 @@ describe('', function() { 'md-items="item in match(searchText)" ' + 'md-item-text="item" ' + 'md-min-length="0" ' + - 'md-dropdown-items="' + maxDropdownItems +'"' + + 'md-dropdown-items="' + maxDropdownItems +'" ' + 'placeholder="placeholder" ' + 'md-mode="standard">' + '{{item}}' + @@ -4037,7 +4019,7 @@ describe('', function() { var scope = createScope(null, { message: 'AngularJS Material', - query: '' + query: 'test' }); var element = compile(template, scope); @@ -4047,7 +4029,6 @@ describe('', function() { element.remove(); }); - }); it('should prevent XSS attacks from the content text', function() { @@ -4057,14 +4038,14 @@ describe('', function() { var template = '
{{message}}
'; var scope = createScope(null, { - message: '', + message: 'test', query: '' }); var element = compile(template, scope); // Expect the image to be escaped due to XSS protection. - expect(element.html()).toBe('<img src="img" onerror="alert(1)">'); + expect(element.html()).toBe('<img src="img" onerror="alert(1)" alt="test">'); expect(window.alert).not.toHaveBeenCalled(); element.remove(); diff --git a/src/components/autocomplete/demoBasicUsage/index.html b/src/components/autocomplete/demoBasicUsage/index.html index 4e337f298bc..55087fa6f7e 100644 --- a/src/components/autocomplete/demoBasicUsage/index.html +++ b/src/components/autocomplete/demoBasicUsage/index.html @@ -15,7 +15,6 @@ md-items="item in ctrl.querySearch(ctrl.searchText)" md-item-text="item.display" md-min-length="0" - md-escape-options="clear" placeholder="Ex. Alaska" input-aria-labelledby="favoriteStateLabel"> diff --git a/src/components/autocomplete/js/autocompleteController.js b/src/components/autocomplete/js/autocompleteController.js index 1e7ba6edd99..a3b8ffd2b05 100644 --- a/src/components/autocomplete/js/autocompleteController.js +++ b/src/components/autocomplete/js/autocompleteController.js @@ -54,6 +54,7 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming, ctrl.isReadonly = null; ctrl.hasNotFound = false; ctrl.selectedMessage = $scope.selectedMessage || 'selected'; + ctrl.defaultEscapeOptions = 'clear'; // Public Exported Methods ctrl.keydown = keydown; @@ -804,7 +805,11 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming, * @returns {boolean} if the specified escape option is set, return true. Return false otherwise. */ function hasEscapeOption(option) { - return !$scope.escapeOptions || $scope.escapeOptions.toLowerCase().indexOf(option) !== -1; + if (!angular.isString($scope.escapeOptions)) { + return ctrl.defaultEscapeOptions.indexOf(option) !== -1; + } else { + return $scope.escapeOptions.toLowerCase().indexOf(option) !== -1; + } } /** diff --git a/src/components/autocomplete/js/autocompleteDirective.js b/src/components/autocomplete/js/autocompleteDirective.js index 489b70f0024..f2b5dd50d00 100644 --- a/src/components/autocomplete/js/autocompleteDirective.js +++ b/src/components/autocomplete/js/autocompleteDirective.js @@ -126,7 +126,7 @@ angular * An exact match is when only one match is displayed. * @param {boolean=} md-match-case-insensitive When set and using `md-select-on-match`, autocomplete * will select on case-insensitive match. - * @param {string=} md-escape-options Override escape key logic. Default is `blur clear`.
+ * @param {string=} md-escape-options Override escape key logic. Default is `clear`.
* Options: `blur`, `clear`, `none`. * @param {string=} md-dropdown-items Specifies the maximum amount of items to be shown in * the dropdown.