diff options
author | Matt A. Tobin <email@mattatobin.com> | 2019-11-03 00:17:46 -0400 |
---|---|---|
committer | Matt A. Tobin <email@mattatobin.com> | 2019-11-03 00:17:46 -0400 |
commit | 302bf1b523012e11b60425d6eee1221ebc2724eb (patch) | |
tree | b191a895f8716efcbe42f454f37597a545a6f421 /mailnews/base/util/ABQueryUtils.jsm | |
parent | 21b3f6247403c06f85e1f45d219f87549862198f (diff) | |
download | UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar.gz UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar.lz UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar.xz UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.zip |
Issue #1258 - Part 1: Import mailnews, ldap, and mork from comm-esr52.9.1
Diffstat (limited to 'mailnews/base/util/ABQueryUtils.jsm')
-rw-r--r-- | mailnews/base/util/ABQueryUtils.jsm | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/mailnews/base/util/ABQueryUtils.jsm b/mailnews/base/util/ABQueryUtils.jsm new file mode 100644 index 000000000..d4b694033 --- /dev/null +++ b/mailnews/base/util/ABQueryUtils.jsm @@ -0,0 +1,130 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * This file contains helper methods for dealing with addressbook search URIs. + */ + +this.EXPORTED_SYMBOLS = ["getSearchTokens", "getModelQuery", + "modelQueryHasUserValue", "generateQueryURI", + "encodeABTermValue"]; +Components.utils.import("resource://gre/modules/Services.jsm"); + +/** + * Parse the multiword search string to extract individual search terms + * (separated on the basis of spaces) or quoted exact phrases to search + * against multiple fields of the addressbook cards. + * + * @param aSearchString The full search string entered by the user. + * + * @return an array of separated search terms from the full search string. + */ +function getSearchTokens(aSearchString) { + let searchString = aSearchString.trim(); + if (searchString == "") + return []; + + let quotedTerms = []; + + // Split up multiple search words to create a *foo* and *bar* search against + // search fields, using the OR-search template from modelQuery for each word. + // If the search query has quoted terms as "foo bar", extract them as is. + let startIndex; + while ((startIndex = searchString.indexOf('"')) != -1) { + let endIndex = searchString.indexOf('"', startIndex + 1); + if (endIndex == -1) + endIndex = searchString.length; + + quotedTerms.push(searchString.substring(startIndex + 1, endIndex)); + let query = searchString.substring(0, startIndex); + if (endIndex < searchString.length) + query += searchString.substr(endIndex + 1); + + searchString = query.trim(); + } + + let searchWords = []; + if (searchString.length != 0) { + searchWords = quotedTerms.concat(searchString.split(/\s+/)); + } else { + searchWords = quotedTerms; + } + + return searchWords; +} + +/** + * For AB quicksearch or recipient autocomplete, get the normal or phonetic model + * query URL part from prefs, allowing users to customize these searches. + * @param aBasePrefName the full pref name of default, non-phonetic model query, + * e.g. mail.addr_book.quicksearchquery.format + * If phonetic search is used, corresponding pref must exist: + * e.g. mail.addr_book.quicksearchquery.format.phonetic + * @return depending on mail.addr_book.show_phonetic_fields pref, + * the value of aBasePrefName or aBasePrefName + ".phonetic" + */ +function getModelQuery(aBasePrefName) { + let modelQuery = ""; + if (Services.prefs.getComplexValue("mail.addr_book.show_phonetic_fields", + Components.interfaces.nsIPrefLocalizedString).data == "true") { + modelQuery = Services.prefs.getCharPref(aBasePrefName + ".phonetic"); + } else { + modelQuery = Services.prefs.getCharPref(aBasePrefName); + } + // remove leading "?" to migrate existing customized values for mail.addr_book.quicksearchquery.format + // todo: could this be done in a once-off migration at install time to avoid repetitive calls? + if (modelQuery.startsWith("?")) + modelQuery = modelQuery.slice(1); + return modelQuery; +} + +/** + * Check if the currently used pref with the model query was customized by user. + * @param aBasePrefName the full pref name of default, non-phonetic model query, + * e.g. mail.addr_book.quicksearchquery.format + * If phonetic search is used, corresponding pref must exist: + * e.g. mail.addr_book.quicksearchquery.format.phonetic + * @return true or false + */ +function modelQueryHasUserValue(aBasePrefName) { + if (Services.prefs.getComplexValue("mail.addr_book.show_phonetic_fields", + Components.interfaces.nsIPrefLocalizedString).data == "true") + return Services.prefs.prefHasUserValue(aBasePrefName + ".phonetic"); + return Services.prefs.prefHasUserValue(aBasePrefName); +} + +/* + * Given a database model query and a list of search tokens, + * return query URI. + * + * @param aModelQuery database model query + * @param aSearchWords an array of search tokens. + * + * @return query URI. + */ +function generateQueryURI(aModelQuery, aSearchWords) { + // If there are no search tokens, we simply return an empty string. + if (!aSearchWords || aSearchWords.length == 0) + return ""; + + let queryURI = ""; + aSearchWords.forEach(searchWord => + queryURI += aModelQuery.replace(/@V/g, encodeABTermValue(searchWord))); + + // queryURI has all the (or(...)) searches, link them up with (and(...)). + queryURI = "?(and" + queryURI + ")"; + + return queryURI; +} + + +/** + * 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"); +} |