From c8f0ae083f01145cfba6c8e4f846bd8799453519 Mon Sep 17 00:00:00 2001 From: Marco Bonardo Date: Thu, 19 Apr 2012 22:17:04 +0200 Subject: [PATCH] Bug 742776 - Use a case sensitive match for the URI path in inline autocomplete query. r=gavin a=desktop-only --- toolkit/components/places/SQLFunctions.cpp | 13 ++++++ toolkit/components/places/SQLFunctions.h | 12 +++++ .../places/mozIPlacesAutoComplete.idl | 6 +++ .../components/places/nsPlacesAutoComplete.js | 12 ++++- .../places/tests/inline/test_casing.js | 44 +++++++++++++++++-- 5 files changed, 82 insertions(+), 5 deletions(-) diff --git a/toolkit/components/places/SQLFunctions.cpp b/toolkit/components/places/SQLFunctions.cpp index 7b143d29dece..27e59e6db8cd 100644 --- a/toolkit/components/places/SQLFunctions.cpp +++ b/toolkit/components/places/SQLFunctions.cpp @@ -319,6 +319,17 @@ namespace places { return false; } + /* static */ + bool + MatchAutoCompleteFunction::findBeginningCaseSensitive( + const nsDependentCSubstring &aToken, + const nsACString &aSourceString) + { + NS_PRECONDITION(!aToken.IsEmpty(), "Don't search for an empty token!"); + + return StringBeginsWith(aSourceString, aToken); + } + /* static */ MatchAutoCompleteFunction::searchFunctionPtr MatchAutoCompleteFunction::getSearchFunction(PRInt32 aBehavior) @@ -329,6 +340,8 @@ namespace places { return findAnywhere; case mozIPlacesAutoComplete::MATCH_BEGINNING: return findBeginning; + case mozIPlacesAutoComplete::MATCH_BEGINNING_CASE_SENSITIVE: + return findBeginningCaseSensitive; case mozIPlacesAutoComplete::MATCH_BOUNDARY: default: return findOnBoundary; diff --git a/toolkit/components/places/SQLFunctions.h b/toolkit/components/places/SQLFunctions.h index 9711616f2ff5..71a94dc10dea 100644 --- a/toolkit/components/places/SQLFunctions.h +++ b/toolkit/components/places/SQLFunctions.h @@ -146,6 +146,18 @@ private: static bool findBeginning(const nsDependentCSubstring &aToken, const nsACString &aSourceString); + /** + * Tests if aSourceString starts with aToken in a case sensitive way. + * + * @param aToken + * The string to search for. + * @param aSourceString + * The string to search. + * @return true if found, false otherwise. + */ + static bool findBeginningCaseSensitive(const nsDependentCSubstring &aToken, + const nsACString &aSourceString); + /** * Searches aSourceString for aToken anywhere in the string in a case- * insensitive way. diff --git a/toolkit/components/places/mozIPlacesAutoComplete.idl b/toolkit/components/places/mozIPlacesAutoComplete.idl index 046b14cfb28a..4941996e8d82 100644 --- a/toolkit/components/places/mozIPlacesAutoComplete.idl +++ b/toolkit/components/places/mozIPlacesAutoComplete.idl @@ -79,6 +79,12 @@ interface mozIPlacesAutoComplete : nsISupports */ const long MATCH_ANYWHERE_UNMODIFIED = 4; + /** + * Match only the beginning of each search term using a case sensitive + * comparator. + */ + const long MATCH_BEGINNING_CASE_SENSITIVE = 5; + ////////////////////////////////////////////////////////////////////////////// //// Search Behavior Constants diff --git a/toolkit/components/places/nsPlacesAutoComplete.js b/toolkit/components/places/nsPlacesAutoComplete.js index c5520cad4324..1aa359fb8818 100644 --- a/toolkit/components/places/nsPlacesAutoComplete.js +++ b/toolkit/components/places/nsPlacesAutoComplete.js @@ -76,6 +76,7 @@ const MATCH_ANYWHERE = Ci.mozIPlacesAutoComplete.MATCH_ANYWHERE; const MATCH_BOUNDARY_ANYWHERE = Ci.mozIPlacesAutoComplete.MATCH_BOUNDARY_ANYWHERE; const MATCH_BOUNDARY = Ci.mozIPlacesAutoComplete.MATCH_BOUNDARY; const MATCH_BEGINNING = Ci.mozIPlacesAutoComplete.MATCH_BEGINNING; +const MATCH_BEGINNING_CASE_SENSITIVE = Ci.mozIPlacesAutoComplete.MATCH_BEGINNING_CASE_SENSITIVE; // AutoComplete index constants. All AutoComplete queries will provide these // columns in this order. @@ -1439,11 +1440,20 @@ urlInlineComplete.prototype = { return; } + // The URIs in the database are fixed up, so we can match on a lowercased + // host, but the path must be matched in a case sensitive way. + let pathIndex = + this._originalSearchString.indexOf("/", this._strippedPrefix.length); + this._currentSearchString = fixupSearchText( + this._originalSearchString.slice(0, pathIndex).toLowerCase() + + this._originalSearchString.slice(pathIndex) + ); + // Within the standard autocomplete query, we only search the beginning // of URLs for 1 result. let query = this._asyncQuery; let (params = query.params) { - params.matchBehavior = MATCH_BEGINNING; + params.matchBehavior = MATCH_BEGINNING_CASE_SENSITIVE; params.searchBehavior = Ci.mozIPlacesAutoComplete["BEHAVIOR_URL"]; params.searchString = this._currentSearchString; } diff --git a/toolkit/components/places/tests/inline/test_casing.js b/toolkit/components/places/tests/inline/test_casing.js index b49198d0d5c7..cd255b642416 100644 --- a/toolkit/components/places/tests/inline/test_casing.js +++ b/toolkit/components/places/tests/inline/test_casing.js @@ -14,7 +14,7 @@ add_autocomplete_test([ add_autocomplete_test([ "Searching for cased entry 2", "mozilla.org/T", - { autoFilled: "mozilla.org/Test/", completed: "mozilla.org/test/" }, + { autoFilled: "mozilla.org/T", completed: "mozilla.org/T" }, function () { addBookmark({ url: "http://mozilla.org/test/" }); } @@ -22,8 +22,26 @@ add_autocomplete_test([ add_autocomplete_test([ "Searching for cased entry 3", + "mozilla.org/T", + { autoFilled: "mozilla.org/Test/", completed: "mozilla.org/Test/" }, + function () { + addBookmark({ url: "http://mozilla.org/Test/" }); + } +]); + +add_autocomplete_test([ + "Searching for cased entry 4", "mOzilla.org/t", - { autoFilled: "mOzilla.org/test/", completed: "mozilla.org/Test/" }, + { autoFilled: "mOzilla.org/t", completed: "mOzilla.org/t" }, + function () { + addBookmark({ url: "http://mozilla.org/Test/" }); + }, +]); + +add_autocomplete_test([ + "Searching for cased entry 5", + "mOzilla.org/T", + { autoFilled: "mOzilla.org/Test/", completed: "mozilla.org/Test/" }, function () { addBookmark({ url: "http://mozilla.org/Test/" }); }, @@ -50,7 +68,16 @@ add_autocomplete_test([ add_autocomplete_test([ "Searching for untrimmed cased entry with path", "http://mOzilla.org/t", - { autoFilled: "http://mOzilla.org/test/", completed: "http://mozilla.org/Test/" }, + { autoFilled: "http://mOzilla.org/t", completed: "http://mOzilla.org/t" }, + function () { + addBookmark({ url: "http://mozilla.org/Test/" }); + }, +]); + +add_autocomplete_test([ + "Searching for untrimmed cased entry with path 2", + "http://mOzilla.org/T", + { autoFilled: "http://mOzilla.org/Test/", completed: "http://mozilla.org/Test/" }, function () { addBookmark({ url: "http://mozilla.org/Test/" }); }, @@ -59,7 +86,16 @@ add_autocomplete_test([ add_autocomplete_test([ "Searching for untrimmed cased entry with www and path", "http://www.mOzilla.org/t", - { autoFilled: "http://www.mOzilla.org/test/", completed: "http://www.mozilla.org/Test/" }, + { autoFilled: "http://www.mOzilla.org/t", completed: "http://www.mOzilla.org/t" }, + function () { + addBookmark({ url: "http://www.mozilla.org/Test/" }); + }, +]); + +add_autocomplete_test([ + "Searching for untrimmed cased entry with www and path 2", + "http://www.mOzilla.org/T", + { autoFilled: "http://www.mOzilla.org/Test/", completed: "http://www.mozilla.org/Test/" }, function () { addBookmark({ url: "http://www.mozilla.org/Test/" }); },