Bug 749097 - Allow to search for ( and ) characters in addressbook cards by urlencoding them in the search query. r=Neil, r=mconley
This commit is contained in:
Родитель
cd429d1f6f
Коммит
97b13bc33c
|
@ -283,7 +283,7 @@ function onSearch()
|
|||
|
||||
for (var j=0;j<max_attrs;j++) {
|
||||
// append the term(s) to the searchUri
|
||||
searchUri += "(" + attrs[j] + "," + opStr + "," + encodeURIComponent(searchTerm.value.str) + ")";
|
||||
searchUri += "(" + attrs[j] + "," + opStr + "," + encodeABTermValue(searchTerm.value.str) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -754,3 +754,13 @@ function makePhotoFile(aDir, aExtension) {
|
|||
} while (newFile.exists());
|
||||
return newFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the string passed as value into an addressbook search term.
|
||||
* The '(' and ')' characters are special for the addressbook
|
||||
* search query language, but are not escaped in encodeURIComponent()
|
||||
* so must be done manually on top of it.
|
||||
*/
|
||||
function encodeABTermValue(aString) {
|
||||
return encodeURIComponent(aString).replace(/\(/g, "%28").replace(/\)/g, "%29");
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ function onEnterInSearchBar()
|
|||
var searchInput = document.getElementById("peopleSearchInput");
|
||||
|
||||
if (searchInput.value != "")
|
||||
searchURI += gQueryURIFormat.replace(/@V/g, encodeURIComponent(searchInput.value));
|
||||
searchURI += gQueryURIFormat.replace(/@V/g, encodeABTermValue(searchInput.value));
|
||||
|
||||
SetAbView(searchURI);
|
||||
}
|
||||
|
|
|
@ -500,7 +500,7 @@ function onEnterInSearchBar()
|
|||
if (searchInput && searchInput.value != "") {
|
||||
// replace all instances of @V with the escaped version
|
||||
// of what the user typed in the quick search text input
|
||||
searchURI += gQueryURIFormat.replace(/@V/g, encodeURIComponent(searchInput.value));
|
||||
searchURI += gQueryURIFormat.replace(/@V/g, encodeABTermValue(searchInput.value));
|
||||
}
|
||||
|
||||
SetAbView(searchURI);
|
||||
|
|
|
@ -129,8 +129,13 @@ nsAbAutoCompleteSearch.prototype = {
|
|||
* @param result The result element to append results to.
|
||||
*/
|
||||
_searchCards: function _searchCards(searchQuery, directory, result) {
|
||||
var childCards =
|
||||
this._abManager.getDirectory(directory.URI + searchQuery).childCards;
|
||||
let childCards;
|
||||
try {
|
||||
childCards = this._abManager.getDirectory(directory.URI + searchQuery).childCards;
|
||||
} catch (e) {
|
||||
Components.utils.reportError("Error running addressbook query '" + searchQuery + "': " + e);
|
||||
return;
|
||||
}
|
||||
|
||||
// Cache this values to save going through xpconnect each time
|
||||
var commentColumn = this._commentColumn == 1 ? directory.dirName : "";
|
||||
|
@ -350,7 +355,7 @@ nsAbAutoCompleteSearch.prototype = {
|
|||
"(NickName,c,@V)(PrimaryEmail,c,@V)(SecondEmail,c,@V)" +
|
||||
"(and(IsMailList,=,TRUE)(Notes,c,@V)))";
|
||||
for (let searchWord of searchWords) {
|
||||
searchQuery += modelQuery.replace(/@V/g, encodeURIComponent(searchWord));
|
||||
searchQuery += modelQuery.replace(/@V/g, encodeABTermValue(searchWord));
|
||||
}
|
||||
searchQuery = "?(and" + searchQuery + ")";
|
||||
// Now do the searching
|
||||
|
@ -386,6 +391,16 @@ nsAbAutoCompleteSearch.prototype = {
|
|||
.nsIAutoCompleteSearch])
|
||||
};
|
||||
|
||||
/**
|
||||
* Encode the string passed as value into an addressbook search term.
|
||||
* The '(' and ')' characters are special for the addressbook
|
||||
* search query language, but are not escaped in encodeURIComponent()
|
||||
* so it must be done manually on top of it.
|
||||
*/
|
||||
function encodeABTermValue(aString) {
|
||||
return encodeURIComponent(aString).replace(/\(/g, "%28").replace(/\)/g, "%29");
|
||||
}
|
||||
|
||||
// Module
|
||||
|
||||
var components = [nsAbAutoCompleteSearch];
|
||||
|
|
|
@ -15,6 +15,20 @@
|
|||
#include "plstr.h"
|
||||
#include "nsIMutableArray.h"
|
||||
|
||||
/**
|
||||
* This code parses the query expression passed in as an addressbook URI.
|
||||
* The expression takes the form:
|
||||
* (BOOL1(FIELD1,OP1,VALUE1)..(FIELDn,OPn,VALUEn)(BOOL2(FIELD1,OP1,VALUE1)...)...)
|
||||
*
|
||||
* BOOLn A boolean operator joining subsequent terms delimited by ().
|
||||
* For possible values see CreateBooleanExpression().
|
||||
* FIELDn An addressbook card data field.
|
||||
* OPn An operator for the search term.
|
||||
* For possible values see CreateBooleanConditionString().
|
||||
* VALUEn The value to be matched in the FIELDn via the OPn operator.
|
||||
* The value must be URL encoded by the caller, if it contains any special
|
||||
* characters including '(' and ')'.
|
||||
*/
|
||||
nsresult nsAbQueryStringToExpression::Convert (
|
||||
const nsACString &aQueryString,
|
||||
nsIAbBooleanExpression** expression)
|
||||
|
|
|
@ -19,12 +19,20 @@ const cards = [
|
|||
{ email: "foo3@foo.invalid", displayName: "dis",
|
||||
popularityIndex: 2, firstName: "first2", value: "dis <foo3@foo.invalid>" },
|
||||
{ email: "foo2@foo.invalid", displayName: "di",
|
||||
popularityIndex: 3, firstName: "first2", value: "di <foo2@foo.invalid>" }
|
||||
popularityIndex: 3, firstName: "first2", value: "di <foo2@foo.invalid>" },
|
||||
// this just tests we can search for the special chars '(' and ')', bug 749097
|
||||
{ email: "bracket@not.invalid", secondEmail: "h@not.invalid", firstName: "Mr.",
|
||||
displayName: "Mr. (Bracket)", value: "Mr. (Bracket) <bracket@not.invalid>",
|
||||
popularityIndex: 2 },
|
||||
{ email: "mr@(bracket).not.invalid", secondEmail: "bracket@not.invalid", firstName: "Mr.",
|
||||
displayName: "Mr. Bracket", value: "Mr. Bracket <mr@(bracket).not.invalid>",
|
||||
popularityIndex: 1 }
|
||||
];
|
||||
|
||||
const duplicates = [
|
||||
{ search: "test", expected: [2, 1] },
|
||||
{ search: "first", expected: [6, 5, 3] }
|
||||
{ search: "first", expected: [6, 5, 3] },
|
||||
{ search: "(bracket)", expected: [7, 8] }
|
||||
];
|
||||
|
||||
|
||||
|
|
|
@ -756,3 +756,13 @@ function makePhotoFile(aDir, aExtension) {
|
|||
} while (newFile.exists());
|
||||
return newFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the string passed as value into an addressbook search term.
|
||||
* The '(' and ')' characters are special for the addressbook
|
||||
* search query language, but are not escaped in encodeURIComponent()
|
||||
* so must be done manually on top of it.
|
||||
*/
|
||||
function encodeABTermValue(aString) {
|
||||
return encodeURIComponent(aString).replace(/\(/g, "%28").replace(/\)/g, "%29");
|
||||
}
|
||||
|
|
|
@ -366,7 +366,7 @@ function onEnterInSearchBar()
|
|||
var searchURI = selectedNode.value;
|
||||
|
||||
if (gSearchInput.value != "") {
|
||||
searchURI += gQueryURIFormat.replace(/@V/g, encodeURIComponent(gSearchInput.value));
|
||||
searchURI += gQueryURIFormat.replace(/@V/g, encodeABTermValue(gSearchInput.value));
|
||||
}
|
||||
|
||||
SetAbView(searchURI);
|
||||
|
|
|
@ -364,7 +364,7 @@ function onEnterInSearchBar()
|
|||
if (gSearchInput.value != "") {
|
||||
// replace all instances of @V with the escaped version
|
||||
// of what the user typed in the quick search text input
|
||||
searchURI += gQueryURIFormat.replace(/@V/g, encodeURIComponent(gSearchInput.value));
|
||||
searchURI += gQueryURIFormat.replace(/@V/g, encodeABTermValue(gSearchInput.value));
|
||||
}
|
||||
|
||||
SetAbView(searchURI);
|
||||
|
|
|
@ -277,7 +277,7 @@ function onSearch()
|
|||
|
||||
for (var j=0;j<max_attrs;j++) {
|
||||
// append the term(s) to the searchUri
|
||||
searchUri += "(" + attrs[j] + "," + opStr + "," + encodeURIComponent(searchTerm.value.str) + ")";
|
||||
searchUri += "(" + attrs[j] + "," + opStr + "," + encodeABTermValue(searchTerm.value.str) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче