From b577d1f18d07779c8b25e91f61201e07ef364ea9 Mon Sep 17 00:00:00 2001 From: "pamg.bugs%gmail.com" Date: Fri, 21 Jul 2006 00:11:47 +0000 Subject: [PATCH] Bug 345095: FAYT doesn't search for pasted strings properly ('findfast only search for the first character if searchstring is copied...'). Patch by pkasting@google.com, r=masayuki --- .../typeaheadfind/src/nsTypeAheadFind.cpp | 157 +++++------------- .../typeaheadfind/src/nsTypeAheadFind.h | 30 +--- 2 files changed, 42 insertions(+), 145 deletions(-) diff --git a/toolkit/components/typeaheadfind/src/nsTypeAheadFind.cpp b/toolkit/components/typeaheadfind/src/nsTypeAheadFind.cpp index ef568b0049b..1f5b3318c32 100755 --- a/toolkit/components/typeaheadfind/src/nsTypeAheadFind.cpp +++ b/toolkit/components/typeaheadfind/src/nsTypeAheadFind.cpp @@ -114,17 +114,13 @@ static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID); nsTypeAheadFind::nsTypeAheadFind(): mLinksOnlyPref(PR_FALSE), mStartLinksOnlyPref(PR_FALSE), - mLinksOnly(PR_FALSE), mCaretBrowsingOn(PR_FALSE), - mLiteralTextSearchOnly(PR_FALSE), mDontTryExactMatch(PR_FALSE), - mAllTheSameChar(PR_TRUE), mRepeatingMode(eRepeatingNone), - mLastFindLength(0), mIsSoundInitialized(PR_FALSE) + mLinksOnly(PR_FALSE), mCaretBrowsingOn(PR_FALSE), mLastFindLength(0), + mIsSoundInitialized(PR_FALSE) { } nsTypeAheadFind::~nsTypeAheadFind() { - Cancel(); - nsCOMPtr prefInternal(do_GetService(NS_PREFSERVICE_CONTRACTID)); if (prefInternal) { prefInternal->RemoveObserver("accessibility.typeaheadfind", this); @@ -272,7 +268,7 @@ void nsTypeAheadFind::SaveFind() { if (mWebBrowserFind) - mWebBrowserFind->SetSearchString(PromiseFlatString(mTypeAheadBuffer).get()); + mWebBrowserFind->SetSearchString(mTypeAheadBuffer.get()); // save the length of this find for "not found" sound mLastFindLength = mTypeAheadBuffer.Length(); @@ -308,9 +304,8 @@ nsTypeAheadFind::PlayNotFoundSound() } nsresult -nsTypeAheadFind::FindItNow(nsIPresShell *aPresShell, - PRBool aIsRepeatingSameChar, PRBool aIsLinksOnly, - PRBool aIsFirstVisiblePreferred, PRBool aFindNext, +nsTypeAheadFind::FindItNow(nsIPresShell *aPresShell, PRBool aIsLinksOnly, + PRBool aIsFirstVisiblePreferred, PRBool aFindPrev, PRBool aHasFocus, PRUint16* aResult) { *aResult = FIND_NOTFOUND; @@ -396,8 +391,7 @@ nsTypeAheadFind::FindItNow(nsIPresShell *aPresShell, (!aIsFirstVisiblePreferred || mStartFindRange) ? selectionController : nsnull, - aIsRepeatingSameChar, - aIsFirstVisiblePreferred, + aIsFirstVisiblePreferred, aFindPrev, getter_AddRefs(presShell), getter_AddRefs(presContext)))) { return NS_ERROR_FAILURE; @@ -408,21 +402,15 @@ nsTypeAheadFind::FindItNow(nsIPresShell *aPresShell, // No need to wrap find in doc if starting at beginning PRBool hasWrapped = (rangeCompareResult < 0); - nsAutoString findBuffer; - if (aIsRepeatingSameChar) - findBuffer = mTypeAheadBuffer.First(); - else - findBuffer = PromiseFlatString(mTypeAheadBuffer); - - if (findBuffer.IsEmpty()) + if (mTypeAheadBuffer.IsEmpty()) return NS_ERROR_FAILURE; - mFind->SetFindBackwards(mRepeatingMode == eRepeatingCharReverse || mRepeatingMode == eRepeatingReverse); + mFind->SetFindBackwards(aFindPrev); while (PR_TRUE) { // ----- Outer while loop: go through all docs ----- while (PR_TRUE) { // === Inner while loop: go through a single doc === - mFind->Find(findBuffer.get(), mSearchRange, mStartPointRange, - mEndPointRange, getter_AddRefs(returnRange)); + mFind->Find(mTypeAheadBuffer.get(), mSearchRange, mStartPointRange, + mEndPointRange, getter_AddRefs(returnRange)); if (!returnRange) break; // Nothing found in this doc, go to outer loop (try next doc) @@ -441,7 +429,6 @@ nsTypeAheadFind::FindItNow(nsIPresShell *aPresShell, aIsFirstVisiblePreferred, PR_FALSE, getter_AddRefs(mStartPointRange), &usesIndependentSelection) || - (aIsRepeatingSameChar && !isStartingLink) || (aIsLinksOnly && !isInsideLink) || (mStartLinksOnlyPref && aIsLinksOnly && !isStartingLink)) { // ------ Failure ------ @@ -449,7 +436,7 @@ nsTypeAheadFind::FindItNow(nsIPresShell *aPresShell, returnRange->CloneRange(getter_AddRefs(mStartPointRange)); // Collapse to end - mStartPointRange->Collapse(mRepeatingMode == eRepeatingReverse || mRepeatingMode == eRepeatingCharReverse); + mStartPointRange->Collapse(aFindPrev); continue; } @@ -615,16 +602,14 @@ nsTypeAheadFind::FindItNow(nsIPresShell *aPresShell, } if (continueLoop) { - if (NS_FAILED(GetSearchContainers(currentContainer, - nsnull, - aIsRepeatingSameChar, - aIsFirstVisiblePreferred, + if (NS_FAILED(GetSearchContainers(currentContainer, nsnull, + aIsFirstVisiblePreferred, aFindPrev, getter_AddRefs(presShell), getter_AddRefs(presContext)))) { continue; } - if (mRepeatingMode == eRepeatingCharReverse || mRepeatingMode == eRepeatingReverse) { + if (aFindPrev) { // Reverse mode: swap start and end points, so that we start // at end of document and go to beginning nsCOMPtr tempRange; @@ -680,8 +665,8 @@ nsTypeAheadFind::GetCurrentWindow(nsIDOMWindow** aCurrentWindow) nsresult nsTypeAheadFind::GetSearchContainers(nsISupports *aContainer, nsISelectionController *aSelectionController, - PRBool aIsRepeatingSameChar, PRBool aIsFirstVisiblePreferred, + PRBool aFindPrev, nsIPresShell **aPresShell, nsPresContext **aPresContext) { @@ -756,14 +741,12 @@ nsTypeAheadFind::GetSearchContainers(nsISupports *aContainer, else { PRInt32 startOffset; nsCOMPtr startNode; - if ((aIsRepeatingSameChar && mRepeatingMode != eRepeatingCharReverse) || - mRepeatingMode == eRepeatingForward) { - currentSelectionRange->GetEndContainer(getter_AddRefs(startNode)); - currentSelectionRange->GetEndOffset(&startOffset); - } - else { + if (aFindPrev) { currentSelectionRange->GetStartContainer(getter_AddRefs(startNode)); currentSelectionRange->GetStartOffset(&startOffset); + } else { + currentSelectionRange->GetEndContainer(getter_AddRefs(startNode)); + currentSelectionRange->GetEndOffset(&startOffset); } if (!startNode) startNode = rootNode; @@ -888,58 +871,21 @@ nsTypeAheadFind::RangeStartsInsideLink(nsIDOMRange *aRange, NS_IMETHODIMP nsTypeAheadFind::FindPrevious(PRBool aHasFocus, PRUint16* aResult) { - return FindInternal(PR_TRUE, aHasFocus, aResult); + *aResult = FIND_NOTFOUND; + + if (!mTypeAheadBuffer.IsEmpty()) + FindItNow(nsnull, mLinksOnly, PR_FALSE, PR_TRUE, aHasFocus, aResult); + + return NS_OK; } NS_IMETHODIMP nsTypeAheadFind::FindNext(PRBool aHasFocus, PRUint16* aResult) -{ - return FindInternal(PR_FALSE, aHasFocus, aResult); -} - -nsresult -nsTypeAheadFind::FindInternal(PRBool aFindBackwards, PRBool aHasFocus, - PRUint16* aResult) { *aResult = FIND_NOTFOUND; - if (mTypeAheadBuffer.IsEmpty()) - return NS_OK; - - PRBool repeatingSameChar = PR_FALSE; - - if (mRepeatingMode == eRepeatingChar || - mRepeatingMode == eRepeatingCharReverse) { - mRepeatingMode = aFindBackwards? eRepeatingCharReverse: eRepeatingChar; - repeatingSameChar = PR_TRUE; - } - else { - mRepeatingMode = aFindBackwards? eRepeatingReverse: eRepeatingForward; - } - mLiteralTextSearchOnly = PR_TRUE; - - if (NS_FAILED(FindItNow(nsnull, repeatingSameChar, mLinksOnly, PR_FALSE, - !aFindBackwards, aHasFocus, aResult))) - mRepeatingMode = eRepeatingNone; - - return NS_OK; -} - -nsresult -nsTypeAheadFind::Cancel() -{ - if (mRepeatingMode != eRepeatingNone) - mTypeAheadBuffer.Truncate(); - - // These will be initialized to their true values after - // the first character is typed - mCaretBrowsingOn = PR_FALSE; - mLiteralTextSearchOnly = PR_FALSE; - mDontTryExactMatch = PR_FALSE; - mStartFindRange = nsnull; - mAllTheSameChar = PR_TRUE; // Until at least 2 different chars are typed - - mSelectionController = nsnull; + if (!mTypeAheadBuffer.IsEmpty()) + FindItNow(nsnull, mLinksOnly, PR_FALSE, PR_FALSE, aHasFocus, aResult); return NS_OK; } @@ -974,9 +920,15 @@ nsTypeAheadFind::Find(const nsAString& aSearchString, PRBool aLinksOnly, selection->CollapseToStart(); if (aSearchString.IsEmpty()) { - mTypeAheadBuffer = aSearchString; + mTypeAheadBuffer.Truncate(); + + // These will be initialized to their true values after the first character + // is typed + mStartFindRange = nsnull; + mSelectionController = nsnull; + *aResult = FIND_FOUND; - return Cancel(); + return NS_OK; } PRBool atEnd = PR_FALSE; @@ -1017,20 +969,6 @@ nsTypeAheadFind::Find(const nsAString& aSearchString, PRBool aLinksOnly, PRInt32 bufferLength = mTypeAheadBuffer.Length(); - // --------- New char in repeated char mode --------- - if ((mRepeatingMode == eRepeatingChar || - mRepeatingMode == eRepeatingCharReverse) && - bufferLength > 1/* && aChar != mTypeAheadBuffer.First()*/) { - // If they repeat the same character and then change, such as aaaab - // start over with new char as a repeated char find - //mTypeAheadBuffer = aChar; - } - // ------- Set repeating mode --------- - else if (bufferLength > 0) /*mTypeAheadBuffer.First() != aChar*/ { - mRepeatingMode = eRepeatingNone; - mAllTheSameChar = PR_FALSE; - } - mTypeAheadBuffer = aSearchString; PRBool isFirstVisiblePreferred = PR_FALSE; @@ -1042,8 +980,6 @@ nsTypeAheadFind::Find(const nsAString& aSearchString, PRBool aLinksOnly, if (!mLinksOnly) mLinksOnly = mLinksOnlyPref; - mRepeatingMode = eRepeatingNone; - // If you can see the selection (not collapsed or thru caret browsing), // or if already focused on a page element, start there. // Otherwise we're going to start at the first visible element @@ -1072,25 +1008,8 @@ nsTypeAheadFind::Find(const nsAString& aSearchString, PRBool aLinksOnly, } // ----------- Find the text! --------------------- - nsresult rv = NS_ERROR_FAILURE; - - if (!mDontTryExactMatch) { - // Regular find, not repeated char find - - // Prefer to find exact match - rv = FindItNow(nsnull, PR_FALSE, mLinksOnly, isFirstVisiblePreferred, - PR_FALSE, aHasFocus, aResult); - } - -#ifndef NO_LINK_CYCLE_ON_SAME_CHAR - if (NS_FAILED(rv) && !mLiteralTextSearchOnly && mAllTheSameChar && - mTypeAheadBuffer.Length() > 1) { - mRepeatingMode = eRepeatingChar; - mDontTryExactMatch = PR_TRUE; // Repeated character find mode - rv = FindItNow(nsnull, PR_TRUE, PR_TRUE, isFirstVisiblePreferred, PR_FALSE, - aHasFocus, aResult); - } -#endif + nsresult rv = FindItNow(nsnull, mLinksOnly, isFirstVisiblePreferred, + PR_FALSE, aHasFocus, aResult); // ---------Handle success or failure --------------- if (NS_SUCCEEDED(rv)) { @@ -1108,8 +1027,6 @@ nsTypeAheadFind::Find(const nsAString& aSearchString, PRBool aLinksOnly, } } else { - mRepeatingMode = eRepeatingNone; - // Error sound if (mTypeAheadBuffer.Length() > mLastFindLength) PlayNotFoundSound(); diff --git a/toolkit/components/typeaheadfind/src/nsTypeAheadFind.h b/toolkit/components/typeaheadfind/src/nsTypeAheadFind.h index 194f3f5e258..0fc9ef59eb0 100755 --- a/toolkit/components/typeaheadfind/src/nsTypeAheadFind.h +++ b/toolkit/components/typeaheadfind/src/nsTypeAheadFind.h @@ -58,16 +58,6 @@ #define TYPEAHEADFIND_NOTFOUND_WAV_URL \ "chrome://global/content/notfound.wav" -enum { - eRepeatingNone, - eRepeatingChar, - eRepeatingCharReverse, - eRepeatingForward, - eRepeatingReverse -}; - -const int kMaxBadCharsBeforeCancel = 3; - class nsTypeAheadFind : public nsITypeAheadFind, public nsIObserver, public nsSupportsWeakReference @@ -85,7 +75,6 @@ protected: void SaveFind(); void PlayNotFoundSound(); - nsresult FindInternal(PRBool aFindBackwards, PRBool aHasFocus, PRUint16* aResult); nsresult GetWebBrowserFind(nsIDocShell *aDocShell, nsIWebBrowserFind **aWebBrowserFind); @@ -98,18 +87,15 @@ protected: nsIDOMRange *aRange, PRBool aMustBeVisible, PRBool aGetTopVisibleLeaf, nsIDOMRange **aNewRange, PRBool *aUsesIndependentSelection); - nsresult FindItNow(nsIPresShell *aPresShell, PRBool aIsRepeatingSameChar, - PRBool aIsLinksOnly, PRBool aIsFirstVisiblePreferred, - PRBool aFindNext, PRBool aHasFocus, PRUint16* aResult); + nsresult FindItNow(nsIPresShell *aPresShell, PRBool aIsLinksOnly, + PRBool aIsFirstVisiblePreferred, PRBool aFindPrev, + PRBool aHasFocus, PRUint16* aResult); nsresult GetSearchContainers(nsISupports *aContainer, nsISelectionController *aSelectionController, - PRBool aIsRepeatingSameChar, - PRBool aIsFirstVisiblePreferred, - nsIPresShell **aPresShell, + PRBool aIsFirstVisiblePreferred, + PRBool aFindPrev, nsIPresShell **aPresShell, nsPresContext **aPresContext); - nsresult Cancel(); - // Get the pres shell from mPresShell and return it only if it is still // attached to the DOM window. NS_HIDDEN_(already_AddRefed) GetPresShell(); @@ -128,12 +114,6 @@ protected: nsCOMPtr mFoundLink; // Most recent elem found, if a link nsCOMPtr mFoundEditable; // Most recent elem found, if editable nsCOMPtr mCurrentWindow; - PRPackedBool mLiteralTextSearchOnly; - PRPackedBool mDontTryExactMatch; - // mAllTheSame Char starts out PR_TRUE, becomes false when - // at least 2 different chars typed - PRPackedBool mAllTheSameChar; - PRInt32 mRepeatingMode; // mLastFindLength is the character length of the last find string. It is used for // disabling the "not found" sound when using backspace or delete PRUint32 mLastFindLength;