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

Commit e85a115

Browse files
crisbetoThomasBurleson
authored andcommitted
fix(autocomplete): fix a couple of js errors and log a warning if the display value isn't a string
* Fixes a couple of JS errors in the autocomplete that were caused by assumptions that the input would always be a string. * Adds a warning for cases where the display value doesn't evaluate to a string. * Cleans up a few redundant expressions. **Note:** There's still a JS error when clearing the value, but it should be fixed with #9221. Fixes #9242. Closes #9251
1 parent 9c7f95e commit e85a115

File tree

3 files changed

+45
-12
lines changed

3 files changed

+45
-12
lines changed

src/components/autocomplete/autocomplete.spec.js

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describe('<md-autocomplete>', function() {
3535

3636
scope.asyncMatch = function(term) {
3737
return $timeout(function() {
38-
return scope.match(term)
38+
return scope.match(term);
3939
}, 1000);
4040
};
4141

@@ -702,7 +702,7 @@ describe('<md-autocomplete>', function() {
702702
return {display: item};
703703
});
704704
var scope = createScope(myItems);
705-
705+
706706
var template = '\
707707
<md-autocomplete\
708708
md-selected-item="selectedItem"\
@@ -740,7 +740,7 @@ describe('<md-autocomplete>', function() {
740740

741741
expect(scope.searchText).toBe('foo ');
742742
expect(scope.selectedItem).toBe(scope.match(scope.searchText)[0]);
743-
743+
744744
ctrl.clear();
745745
$timeout.flush();
746746

@@ -1125,6 +1125,32 @@ describe('<md-autocomplete>', function() {
11251125
element.remove();
11261126
}));
11271127

1128+
it('should log a warning if the display text does not evaluate to a string',
1129+
inject(function($log) {
1130+
spyOn($log, 'warn');
1131+
1132+
var scope = createScope();
1133+
1134+
var template =
1135+
'<md-autocomplete ' +
1136+
'md-selected-item="selectedItem" ' +
1137+
'md-search-text="searchText"' +
1138+
'md-items="item in match(searchText)"> ' +
1139+
'</md-autocomplete>';
1140+
1141+
var element = compile(template, scope);
1142+
1143+
scope.$apply(function() {
1144+
scope.selectedItem = { display: 'foo' };
1145+
});
1146+
1147+
expect($log.warn).toHaveBeenCalled();
1148+
expect($log.warn.calls.mostRecent().args[0]).toMatch(/md-item-text/);
1149+
1150+
element.remove();
1151+
})
1152+
);
1153+
11281154
});
11291155

11301156
describe('xss prevention', function() {

src/components/autocomplete/js/autocompleteController.js

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ var ITEM_HEIGHT = 41,
88
INPUT_PADDING = 2; // Padding provided by `md-input-container`
99

1010
function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming, $window,
11-
$animate, $rootElement, $attrs, $q) {
11+
$animate, $rootElement, $attrs, $q, $log) {
1212

1313
// Internal Variables.
1414
var ctrl = this,
@@ -194,7 +194,7 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
194194

195195
angular.element($window).off('resize', positionDropdown);
196196
if ( elements ){
197-
var items = 'ul scroller scrollContainer input'.split(' ');
197+
var items = ['ul', 'scroller', 'scrollContainer', 'input'];
198198
angular.forEach(items, function(key){
199199
elements.$[key].remove();
200200
});
@@ -207,8 +207,8 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
207207
function gatherElements () {
208208
elements = {
209209
main: $element[0],
210-
scrollContainer: $element[0].getElementsByClassName('md-virtual-repeat-container')[0],
211-
scroller: $element[0].getElementsByClassName('md-virtual-repeat-scroller')[0],
210+
scrollContainer: $element[0].querySelector('.md-virtual-repeat-container'),
211+
scroller: $element[0].querySelector('.md-virtual-repeat-scroller'),
212212
ul: $element.find('ul')[0],
213213
input: $element.find('input')[0],
214214
wrap: $element.find('md-autocomplete-wrap')[0],
@@ -290,7 +290,7 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
290290
return function() {
291291
element.off('wheel', preventDefault);
292292
element.off('touchmove', preventDefault);
293-
}
293+
};
294294
}
295295

296296
/**
@@ -335,7 +335,7 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
335335
// Clear the searchText, when the selectedItem is set to null.
336336
// Do not clear the searchText, when the searchText isn't matching with the previous
337337
// selected item.
338-
if (displayValue.toLowerCase() === $scope.searchText.toLowerCase()) {
338+
if (displayValue.toString().toLowerCase() === $scope.searchText.toLowerCase()) {
339339
$scope.searchText = '';
340340
}
341341
});
@@ -531,7 +531,14 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
531531
* @returns {*}
532532
*/
533533
function getDisplayValue (item) {
534-
return $q.when(getItemText(item) || item);
534+
return $q.when(getItemText(item) || item).then(function(itemText) {
535+
if (itemText && !angular.isString(itemText)) {
536+
$log.warn('md-autocomplete: Could not resolve display value to a string. ' +
537+
'Please check the `md-item-text` attribute.');
538+
}
539+
540+
return itemText;
541+
});
535542

536543
/**
537544
* Getter function to invoke user-defined expression (in the directive)

src/components/autocomplete/js/highlightController.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ function MdHighlightCtrl ($scope, $element, $attrs) {
1616
};
1717
}, function (state, prevState) {
1818
if (text === null || state.unsafeText !== prevState.unsafeText) {
19-
text = angular.element('<div>').text(state.unsafeText).html()
19+
text = angular.element('<div>').text(state.unsafeText).html();
2020
}
2121
if (regex === null || state.term !== prevState.term) {
2222
regex = getRegExp(state.term, flags);
@@ -28,7 +28,7 @@ function MdHighlightCtrl ($scope, $element, $attrs) {
2828
}
2929

3030
function sanitize (term) {
31-
return term && term.replace(/[\\\^\$\*\+\?\.\(\)\|\{}\[\]]/g, '\\$&');
31+
return term && term.toString().replace(/[\\\^\$\*\+\?\.\(\)\|\{}\[\]]/g, '\\$&');
3232
}
3333

3434
function getRegExp (text, flags) {

0 commit comments

Comments
 (0)