From 5f26263c8cc14b2082dbac4408c4826bef7bb227 Mon Sep 17 00:00:00 2001 From: "edward.lee@engineering.uiuc.edu" Date: Wed, 23 Apr 2008 21:20:05 -0700 Subject: [PATCH] Bug 429531 - Location bar should show non-word-boundary matches below word-boundary matches. r=dietrich, ui-r=beltzner, b-ff3=beltzner, a1.9=beltzner --- browser/app/profile/firefox.js | 5 +++- .../components/places/src/nsNavHistory.cpp | 24 ++++++++++++---- toolkit/components/places/src/nsNavHistory.h | 14 +++++++++- .../places/src/nsNavHistoryAutoComplete.cpp | 28 +++++++++++++++---- .../autocomplete/test_word_boundary_search.js | 17 ++++++++++- 5 files changed, 74 insertions(+), 14 deletions(-) diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index c98af3db5d48..5c7cebb172b6 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -213,7 +213,10 @@ pref("browser.urlbar.doubleClickSelectsAll", false); #endif pref("browser.urlbar.autoFill", false); pref("browser.urlbar.matchOnlyTyped", false); -pref("browser.urlbar.matchOnWordBoundary", true); +// 0: Match anywhere (e.g., middle of words) +// 1: Match on word boundaries and then try matching anywhere +// 2: Match only on word boundaries (e.g., after / or .) +pref("browser.urlbar.matchBehavior", 1); pref("browser.urlbar.filter.javascript", true); // the maximum number of results to show in autocomplete when doing richResults diff --git a/toolkit/components/places/src/nsNavHistory.cpp b/toolkit/components/places/src/nsNavHistory.cpp index 68f86e9e03b0..67ca24894a4b 100644 --- a/toolkit/components/places/src/nsNavHistory.cpp +++ b/toolkit/components/places/src/nsNavHistory.cpp @@ -113,7 +113,7 @@ #define PREF_BROWSER_HISTORY_EXPIRE_DAYS_MAX "history_expire_days" #define PREF_BROWSER_HISTORY_EXPIRE_SITES "history_expire_sites" #define PREF_AUTOCOMPLETE_ONLY_TYPED "urlbar.matchOnlyTyped" -#define PREF_AUTOCOMPLETE_ON_WORD_BOUNDARY "urlbar.matchOnWordBoundary" +#define PREF_AUTOCOMPLETE_MATCH_BEHAVIOR "urlbar.matchBehavior" #define PREF_AUTOCOMPLETE_FILTER_JAVASCRIPT "urlbar.filter.javascript" #define PREF_AUTOCOMPLETE_ENABLED "urlbar.autocomplete.enabled" #define PREF_AUTOCOMPLETE_MAX_RICH_RESULTS "urlbar.maxRichResults" @@ -329,7 +329,7 @@ nsNavHistory::nsNavHistory() : mBatchLevel(0), mExpireNowTimer(nsnull), mExpire(this), mAutoCompleteOnlyTyped(PR_FALSE), - mAutoCompleteOnWordBoundary(PR_TRUE), + mAutoCompleteMatchBehavior(MATCH_BOUNDARY_ANYWHERE), mAutoCompleteMaxResults(25), mAutoCompleteSearchChunkSize(100), mAutoCompleteSearchTimeout(100), @@ -474,7 +474,7 @@ nsNavHistory::Init() nsCOMPtr pbi = do_QueryInterface(mPrefBranch); if (pbi) { pbi->AddObserver(PREF_AUTOCOMPLETE_ONLY_TYPED, this, PR_FALSE); - pbi->AddObserver(PREF_AUTOCOMPLETE_ON_WORD_BOUNDARY, this, PR_FALSE); + pbi->AddObserver(PREF_AUTOCOMPLETE_MATCH_BEHAVIOR, this, PR_FALSE); pbi->AddObserver(PREF_AUTOCOMPLETE_FILTER_JAVASCRIPT, this, PR_FALSE); pbi->AddObserver(PREF_AUTOCOMPLETE_MAX_RICH_RESULTS, this, PR_FALSE); pbi->AddObserver(PREF_AUTOCOMPLETE_SEARCH_CHUNK_SIZE, this, PR_FALSE); @@ -1876,8 +1876,22 @@ nsNavHistory::LoadPrefs(PRBool aInitializing) PRBool oldCompleteOnlyTyped = mAutoCompleteOnlyTyped; mPrefBranch->GetBoolPref(PREF_AUTOCOMPLETE_ONLY_TYPED, &mAutoCompleteOnlyTyped); - mPrefBranch->GetBoolPref(PREF_AUTOCOMPLETE_ON_WORD_BOUNDARY, - &mAutoCompleteOnWordBoundary); + + PRInt32 matchBehavior; + mPrefBranch->GetIntPref(PREF_AUTOCOMPLETE_MATCH_BEHAVIOR, + &matchBehavior); + switch (matchBehavior) { + case 0: + mAutoCompleteMatchBehavior = MATCH_ANYWHERE; + break; + case 2: + mAutoCompleteMatchBehavior = MATCH_BOUNDARY; + break; + default: + mAutoCompleteMatchBehavior = MATCH_BOUNDARY_ANYWHERE; + break; + } + mPrefBranch->GetBoolPref(PREF_AUTOCOMPLETE_FILTER_JAVASCRIPT, &mAutoCompleteFilterJavascript); mPrefBranch->GetIntPref(PREF_AUTOCOMPLETE_MAX_RICH_RESULTS, diff --git a/toolkit/components/places/src/nsNavHistory.h b/toolkit/components/places/src/nsNavHistory.h index 1e0ebab8d9c5..52eb5cf89f0f 100644 --- a/toolkit/components/places/src/nsNavHistory.h +++ b/toolkit/components/places/src/nsNavHistory.h @@ -663,10 +663,20 @@ protected: nsCOMPtr mDBAdaptiveQuery; // kAutoCompleteIndex_* results nsCOMPtr mDBFeedbackIncrease; + /** + * AutoComplete word matching behavior to determine if words should match on + * word boundaries or not or both. + */ + enum MatchType { + MATCH_ANYWHERE, + MATCH_BOUNDARY_ANYWHERE, + MATCH_BOUNDARY + }; + nsresult InitAutoComplete(); nsresult CreateAutoCompleteQueries(); PRBool mAutoCompleteOnlyTyped; - PRBool mAutoCompleteOnWordBoundary; + MatchType mAutoCompleteMatchBehavior; PRBool mAutoCompleteFilterJavascript; PRInt32 mAutoCompleteMaxResults; PRInt32 mAutoCompleteSearchChunkSize; @@ -687,6 +697,8 @@ protected: nsCOMPtr mCurrentResult; #endif + MatchType mCurrentMatchType; + MatchType mPreviousMatchType; nsDataHashtable mCurrentResultURLs; PRInt32 mCurrentChunkOffset; PRInt32 mPreviousChunkOffset; diff --git a/toolkit/components/places/src/nsNavHistoryAutoComplete.cpp b/toolkit/components/places/src/nsNavHistoryAutoComplete.cpp index 3ed8525729a5..3871d50a67b3 100644 --- a/toolkit/components/places/src/nsNavHistoryAutoComplete.cpp +++ b/toolkit/components/places/src/nsNavHistoryAutoComplete.cpp @@ -360,12 +360,22 @@ nsNavHistory::PerformAutoComplete() // If we ran out of pages to search, set offset to -1, so we can tell the // difference between completing and stopping because we have enough results - if (!moreChunksToSearch) - mCurrentChunkOffset = -1; + PRBool notEnoughResults = !AutoCompleteHasEnoughResults(); + if (!moreChunksToSearch) { + // But check first to see if we don't have enough results, and we're + // matching word boundaries, so try again without the match restriction + if (notEnoughResults && mCurrentMatchType == MATCH_BOUNDARY_ANYWHERE) { + mCurrentMatchType = MATCH_ANYWHERE; + mCurrentChunkOffset = -mAutoCompleteSearchChunkSize; + moreChunksToSearch = PR_TRUE; + } else { + mCurrentChunkOffset = -1; + } + } else { + // We know that we do have more chunks, so make sure we want more results + moreChunksToSearch = notEnoughResults; + } - // Only search more chunks if there are more and we need more results - moreChunksToSearch &= !AutoCompleteHasEnoughResults(); - // Determine the result of the search PRUint32 count; mCurrentResult->GetMatchCount(&count); @@ -402,6 +412,7 @@ nsNavHistory::PerformAutoComplete() void nsNavHistory::DoneSearching(PRBool aFinished) { + mPreviousMatchType = mCurrentMatchType; mPreviousChunkOffset = mCurrentChunkOffset; mAutoCompleteFinishedSearch = aFinished; mCurrentResult = nsnull; @@ -500,10 +511,15 @@ nsNavHistory::StartSearch(const nsAString & aSearchString, rv = mDBPreviousQuery->BindStringParameter(i + 1, *urls[i]); NS_ENSURE_SUCCESS(rv, rv); } + + // Use the same match behavior as the previous search + mCurrentMatchType = mPreviousMatchType; } } else { // Clear out any previous result queries mDBPreviousQuery = nsnull; + // Default to matching based on the user's preference + mCurrentMatchType = mAutoCompleteMatchBehavior; } mAutoCompleteFinishedSearch = PR_FALSE; @@ -670,7 +686,7 @@ nsNavHistory::AutoCompleteProcessSearch(mozIStorageStatement* aQuery, // Determine what type of search to try matching tokens against targets PRBool (*tokenMatchesTarget)(const nsAString &, const nsAString &) = - mAutoCompleteOnWordBoundary ? FindOnBoundary : FindAnywhere; + mCurrentMatchType != MATCH_ANYWHERE ? FindOnBoundary : FindAnywhere; PRBool hasMore = PR_FALSE; // Determine the result of the search diff --git a/toolkit/components/places/tests/autocomplete/test_word_boundary_search.js b/toolkit/components/places/tests/autocomplete/test_word_boundary_search.js index b226f882288e..22b582c8ed7e 100644 --- a/toolkit/components/places/tests/autocomplete/test_word_boundary_search.js +++ b/toolkit/components/places/tests/autocomplete/test_word_boundary_search.js @@ -40,6 +40,10 @@ * * Make sure we don't try matching one after a CamelCase because the upper-case * isn't really a word boundary. (bug 429498) + * + * Bug 429531 provides switching between "must match on word boundary" and "can + * match," so leverage "must match" pref for checking word boundary logic and + * make sure "can match" matches anywhere. */ let katakana = ["\u30a8", "\u30c9"]; // E, Do @@ -88,8 +92,10 @@ addPageBook(9, 0); // Provide for each test: description; search terms; array of gPages indices of // pages that should match; optional function to be run before the test let gTests = [ + // Tests after this one will match only on word boundaries ["0: Match 'match' at the beginning or after / or on a CamelCase", - "match", [0,2,4,9]], + "match", [0,2,4,9], + function() setBehavior(2)], ["1: Match 'dont' at the beginning or after /", "dont", [1,3,5]], ["2: Match '2' after the slash and after a word (in tags too)", @@ -119,4 +125,13 @@ let gTests = [ "ch", []], ["13: Don't match one character after a camel-case word boundary (bug 429498)", "atch", []], + + // Tests after this one will match against word boundaries and anywhere + ["14: Match on word boundaries as well as anywhere (bug 429531)", + "tch", [0,1,2,3,4,5,9], + function() setBehavior(1)], ]; + +function setBehavior(aType) { + prefs.setIntPref("browser.urlbar.matchBehavior", aType); +}