diff --git a/apps/communications/contacts/test/unit/views/list_test.js b/apps/communications/contacts/test/unit/views/list_test.js
index 6b8d5eb3b194..df6bc9103684 100755
--- a/apps/communications/contacts/test/unit/views/list_test.js
+++ b/apps/communications/contacts/test/unit/views/list_test.js
@@ -1270,6 +1270,27 @@ suite('Render contacts list', function() {
});
});
+ test('Search for contacts with middle names', function(done) {
+ mockContacts = new MockContactsList();
+ var contactIndex = Math.floor(Math.random() * mockContacts.length);
+ var contact = mockContacts[contactIndex];
+ mockContacts[contactIndex].givenName[0] = contact.givenName[0] + ' Juan';
+
+ doLoad(subject, mockContacts, function() {
+ contacts.List.initSearch(function onInit() {
+ searchBox.value = contact.givenName[0][0] + ' ' +
+ contact.familyName[0][0];
+ contacts.Search.search(function search_finished() {
+ contacts.Search.invalidateCache();
+ done(function() {
+ assert.isTrue(noResults.classList.contains('hide'));
+ assertContactFound(contact);
+ });
+ });
+ });
+ });
+ });
+
test('Search phrase highlightded correctly for first letter',
function(done) {
mockContacts = new MockContactsList();
diff --git a/shared/js/contacts/search.js b/shared/js/contacts/search.js
index 48e412b33468..e73ae440c6f6 100644
--- a/shared/js/contacts/search.js
+++ b/shared/js/contacts/search.js
@@ -22,6 +22,7 @@ contacts.Search = (function() {
// On the steady state holds the list result of the current search
searchableNodes = null,
currentTextToSearch = '',
+ currentSearchTerms = [],
prevTextToSearch = '',
// Pointer to the nodes which are currently on the result list
currentSet = {},
@@ -153,11 +154,14 @@ contacts.Search = (function() {
// This regexp match against everything except HTML tags
// 'currentTextToSearch' should be relatively safe from
// regex symbols getting passed through since it was previously normalized
- var hRegEx = new RegExp('(' + currentTextToSearch + ')(?=[^>]*<)', 'gi');
- node.innerHTML = node.innerHTML.replace(
- hRegEx,
- '$1'
- );
+ for (var i=0, l=currentSearchTerms.length; i]*<)',
+ 'gi');
+ node.innerHTML = node.innerHTML.replace(
+ hRegEx,
+ '$1'
+ );
+ }
};
var updateSearchList = function updateSearchList(cb) {
@@ -216,6 +220,7 @@ contacts.Search = (function() {
function resetState() {
prevTextToSearch = '';
currentTextToSearch = '';
+ currentSearchTerms = [];
searchableNodes = null;
canReuseSearchables = false;
currentSet = {};
@@ -365,10 +370,11 @@ contacts.Search = (function() {
// Search the next chunk of contacts
var end = from + CHUNK_SIZE;
+ currentSearchTerms = pattern.source.split(/\s+/);
for (var c = from; c < end && c < contacts.length; c++) {
var contact = contacts[c].node || contacts[c];
var contactText = contacts[c].text || getSearchText(contacts[c]);
- if (!pattern.test(contactText)) {
+ if (!checkContactMatch(currentSearchTerms, contactText)) {
if (contact.dataset.uuid in currentSet) {
searchList.removeChild(currentSet[contact.dataset.uuid]);
delete currentSet[contact.dataset.uuid];
@@ -475,11 +481,10 @@ contacts.Search = (function() {
// If we have a current search then we need to determine whether the
// new nodes should show up in that search.
- var pattern = new RegExp(currentTextToSearch, 'i');
for (var i = 0, n = nodes.length; i < n; ++i) {
var node = nodes[i];
var nodeText = getSearchText(node);
- if (pattern.test(nodeText)) {
+ if (!checkContactMatch(currentSearchTerms, nodeText)) {
searchableNodes.push({
node: node,
text: nodeText
@@ -488,6 +493,15 @@ contacts.Search = (function() {
}
};
+ var checkContactMatch = function checkContactMatch(searchTerms, text) {
+ for (var i=0, m=searchTerms.length; i < m; i++){
+ if (!RegExp(searchTerms[i], 'i').test(text)) {
+ return false;
+ }
+ }
+ return true;
+ };
+
var search = function performSearch(searchDoneCb) {
prevTextToSearch = currentTextToSearch;