summaryrefslogtreecommitdiffstats
path: root/mailnews/base/util/ABQueryUtils.jsm
diff options
context:
space:
mode:
authorMatt A. Tobin <email@mattatobin.com>2019-11-03 00:17:46 -0400
committerMatt A. Tobin <email@mattatobin.com>2019-11-03 00:17:46 -0400
commit302bf1b523012e11b60425d6eee1221ebc2724eb (patch)
treeb191a895f8716efcbe42f454f37597a545a6f421 /mailnews/base/util/ABQueryUtils.jsm
parent21b3f6247403c06f85e1f45d219f87549862198f (diff)
downloadUXP-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.jsm130
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");
+}