Back to index

lightning-sunbird  0.9+nobinonly
nsTypeAheadFind.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is 
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Original Author: Aaron Leventhal <aaronl@netscape.com>    
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsIDOMEventListener.h"
00040 #include "nsIDOMKeyListener.h"
00041 #include "nsIDOMTextListener.h"
00042 #include "nsIDOMCompositionListener.h"
00043 #include "nsIScrollPositionListener.h"
00044 #include "nsISelectionListener.h"
00045 #include "nsISelectionController.h"
00046 #include "nsIController.h"
00047 #include "nsIControllers.h"
00048 #include "nsIFocusController.h"
00049 #include "nsIObserver.h"
00050 #include "nsITimer.h"
00051 #include "nsUnicharUtils.h"
00052 #include "nsIFindService.h"
00053 #include "nsIFind.h"
00054 #include "nsIWebBrowserFind.h"
00055 #include "nsWeakReference.h"
00056 #include "nsIAppStartupNotifier.h"
00057 #include "nsIPresShell.h"
00058 #include "nsPresContext.h"
00059 #include "nsISelection.h"
00060 #include "nsIDOMRange.h"
00061 #include "nsIDOMWindow.h"
00062 #include "nsIDocShellTreeItem.h"
00063 #include "nsITypeAheadFind.h"
00064 #include "nsIStringBundle.h"
00065 #include "nsISupportsArray.h"
00066 #include "nsISound.h"
00067 
00068 #define TYPEAHEADFIND_BUNDLE_URL \
00069         "chrome://global/locale/typeaheadfind.properties"
00070 #define TYPEAHEADFIND_NOTFOUND_WAV_URL \
00071         "chrome://global/content/notfound.wav"
00072 
00073 enum {
00074   eRepeatingNone,
00075   eRepeatingChar,
00076   eRepeatingCharReverse,
00077   eRepeatingForward,
00078   eRepeatingReverse
00079 }; 
00080 
00081 const int kMaxBadCharsBeforeCancel = 3;
00082 
00083 class nsTypeAheadFind : public nsITypeAheadFind,
00084                         public nsIDOMKeyListener,
00085                         public nsIDOMTextListener,
00086                         public nsIDOMCompositionListener,
00087                         public nsIObserver,
00088                         public nsIScrollPositionListener,
00089                         public nsISelectionListener,
00090                         public nsITimerCallback,
00091                         public nsSupportsWeakReference
00092 {
00093 public:
00094   nsTypeAheadFind();
00095   virtual ~nsTypeAheadFind();
00096 
00097   NS_DEFINE_STATIC_CID_ACCESSOR(NS_TYPEAHEADFIND_CID);
00098 
00099   NS_DECL_ISUPPORTS
00100   NS_DECL_NSITYPEAHEADFIND
00101   NS_DECL_NSIOBSERVER
00102   NS_DECL_NSIDOMEVENTLISTENER
00103   NS_DECL_NSISELECTIONLISTENER
00104 
00105   // ----- nsIDOMKeyListener ----------------------------
00106   NS_IMETHOD KeyDown(nsIDOMEvent* aKeyEvent);
00107   NS_IMETHOD KeyUp(nsIDOMEvent* aKeyEvent);
00108   NS_IMETHOD KeyPress(nsIDOMEvent* aKeyEvent);
00109 
00110   // ----- nsIDOMTextListener ----------------------------
00111   NS_IMETHOD HandleText(nsIDOMEvent* aTextEvent);
00112 
00113   // ----- nsIDOMCompositionListener ----------------------------
00114   NS_IMETHOD HandleStartComposition(nsIDOMEvent* aCompositionEvent);
00115   NS_IMETHOD HandleEndComposition(nsIDOMEvent* aCompositionEvent);
00116   NS_IMETHOD HandleQueryComposition(nsIDOMEvent* aCompositionEvent);
00117   NS_IMETHOD HandleQueryReconversion(nsIDOMEvent* aCompositionEvent);
00118   NS_IMETHOD HandleQueryCaretRect(nsIDOMEvent* aCompositionEvent);
00119 
00120   // ----- nsIScrollPositionListener --------------------
00121   NS_IMETHOD ScrollPositionWillChange(nsIScrollableView *aView, 
00122                                       nscoord aX, nscoord aY);
00123   NS_IMETHOD ScrollPositionDidChange(nsIScrollableView *aView, 
00124                                      nscoord aX, nscoord aY);
00125 
00126   // ----- nsITimerCallback -----------------------------
00127   NS_DECL_NSITIMERCALLBACK
00128 
00129   static nsTypeAheadFind *GetInstance();
00130   static void ReleaseInstance(void);
00131   static PRBool IsTargetContentOkay(nsIContent *aContent);
00132 
00133 protected:
00134   nsresult PrefsReset();
00135 
00136   // Helper methods
00137   nsresult HandleChar(PRUnichar aChar);
00138   PRBool HandleBackspace();
00139   void SaveFind();
00140   void PlayNotFoundSound();
00141   void GetTopContentPresShell(nsIDocShellTreeItem *aTreeItem, 
00142                               nsIPresShell **aPresShell);
00143   void GetStartWindow(nsIDOMWindow *aWindow, nsIDOMWindow **aStartWindow);
00144   nsresult GetWebBrowserFind(nsIDOMWindow *aDOMWin,
00145                              nsIWebBrowserFind **aWebBrowserFind);
00146   void StartTimeout();
00147   nsresult Init();
00148   void Shutdown();
00149   nsresult UseInWindow(nsIDOMWindow *aDomWin);
00150   void SetSelectionLook(nsIPresShell *aPresShell, PRBool aChangeColor, 
00151                         PRBool aEnabled);
00152   void ResetGlobalAutoStart(PRBool aAutoStart);
00153   void AttachDocListeners(nsIPresShell *aPresShell);
00154   void RemoveDocListeners();
00155   void AttachWindowListeners(nsIDOMWindow *aDOMWin);
00156   void RemoveWindowListeners(nsIDOMWindow *aDOMWin);
00157   void GetChromeEventHandler(nsIDOMWindow *aDOMWin, 
00158                              nsIDOMEventTarget **aChromeTarget);
00159 
00160   void RangeStartsInsideLink(nsIDOMRange *aRange, nsIPresShell *aPresShell, 
00161                              PRBool *aIsInsideLink, PRBool *aIsStartingLink);
00162 
00163   nsresult GetTargetIfTypeAheadOkay(nsIDOMEvent *aEvent, 
00164                                     nsIContent **aTargetContent, 
00165                                     nsIPresShell **aTargetPresShell);
00166 
00167   // Get selection and selection controller for current pres shell
00168   void GetSelection(nsIPresShell *aPresShell, nsISelectionController **aSelCon, 
00169                     nsISelection **aDomSel);
00170   PRBool IsRangeVisible(nsIPresShell *aPresShell, nsPresContext *aPresContext,
00171                          nsIDOMRange *aRange, PRBool aMustBeVisible, 
00172                          PRBool aGetTopVisibleLeaf,
00173                          nsIDOMRange **aNewRange);
00174   nsresult FindItNow(nsIPresShell *aPresShell, PRBool aIsRepeatingSameChar, 
00175                      PRBool aIsLinksOnly, PRBool aIsFirstVisiblePreferred);
00176   nsresult GetSearchContainers(nsISupports *aContainer, 
00177                                PRBool aIsRepeatingSameChar,
00178                                PRBool aIsFirstVisiblePreferred, 
00179                                PRBool aCanUseDocSelection,
00180                                nsIPresShell **aPresShell, 
00181                                nsPresContext **aPresContext);
00182   void DisplayStatus(PRBool aSuccess, nsIContent *aFocusedContent, 
00183                      PRBool aClearStatus, const PRUnichar *aText = nsnull);
00184   nsresult GetTranslatedString(const nsAString& aKey, nsAString& aStringOut);
00185 
00186   // Get the pres shell from mFocusedWeakShell and return it only if it is
00187   // still attached to the DOM window.
00188   NS_HIDDEN_(already_AddRefed<nsIPresShell>) GetPresShell();
00189 
00190   // Used by GetInstance and ReleaseInstance
00191   static nsTypeAheadFind *sInstance;
00192 
00193   // Current find state
00194   nsString mTypeAheadBuffer;
00195   nsString mFindNextBuffer;
00196   nsString mIMEString;
00197 
00198   nsCString mNotFoundSoundURL;
00199 
00200   // PRBool's are used instead of PRPackedBool's where the address of the
00201   // boolean variable is getting passed into a method. For example:
00202   // GetBoolPref("accessibility.typeaheadfind.linksonly", &mLinksOnlyPref);
00203   PRBool mIsFindAllowedInWindow;
00204   PRBool mAutoStartPref;
00205   PRBool mLinksOnlyPref;
00206   PRBool mStartLinksOnlyPref;
00207   PRPackedBool mLinksOnly;
00208   PRBool mIsTypeAheadOn;
00209   PRBool mCaretBrowsingOn;
00210   PRPackedBool mLiteralTextSearchOnly;
00211   PRPackedBool mDontTryExactMatch;
00212   // mAllTheSame Char starts out PR_TRUE, becomes false when 
00213   // at least 2 different chars typed
00214   PRPackedBool mAllTheSameChar;
00215   // mLinksOnlyManuallySet = PR_TRUE when the user has already 
00216   // typed / or '. This allows the next / or ' to get searched for.
00217   PRPackedBool mLinksOnlyManuallySet;
00218   // mIsFindingText = PR_TRUE when we need to prevent listener callbacks 
00219   // from resetting us during typeahead find processing
00220   PRPackedBool mIsFindingText; 
00221   PRPackedBool mIsMenuBarActive;
00222   PRPackedBool mIsMenuPopupActive;
00223   PRPackedBool mIsFirstVisiblePreferred;
00224   PRPackedBool mIsIMETypeAheadActive;
00225   PRPackedBool mIsBackspaceProtectOn; // from accidentally going back in history
00226   PRInt32 mBadKeysSinceMatch;
00227   PRUnichar mLastBadChar; // if taf automatically overwrites an unfound character
00228   PRInt32 mRepeatingMode;
00229   PRInt32 mTimeoutLength; // time in ms before find is automatically cancelled
00230 
00231   // Sound is played asynchronously on some platforms.
00232   // If we destroy mSoundInterface before sound has played, it won't play
00233   nsCOMPtr<nsISound> mSoundInterface;
00234   PRBool mIsSoundInitialized;
00235   
00236   static PRInt32 sAccelKey;  // magic value of -1 indicates unitialized state
00237 
00238   // where selection was when user started the find
00239   nsCOMPtr<nsIDOMRange> mStartFindRange;
00240   nsCOMPtr<nsIDOMRange> mSearchRange;
00241   nsCOMPtr<nsIDOMRange> mStartPointRange;
00242   nsCOMPtr<nsIDOMRange> mEndPointRange;
00243 
00244   // Cached useful interfaces
00245   nsCOMPtr<nsIFind> mFind;
00246   nsCOMPtr<nsIFindService> mFindService;
00247   nsCOMPtr<nsIStringBundle> mStringBundle;
00248   nsCOMPtr<nsITimer> mTimer;
00249   nsCOMPtr<nsIFocusController> mFocusController;
00250 
00251   // The focused content window that we're listening to and it's cached objects
00252   nsCOMPtr<nsISelection> mFocusedDocSelection;
00253   nsCOMPtr<nsISelectionController> mFocusedDocSelCon;
00254   nsCOMPtr<nsIDOMWindow> mFocusedWindow;
00255   nsCOMPtr<nsIWeakReference> mFocusedWeakShell;
00256 
00257   // Windows where typeaheadfind doesn't auto start as the user types
00258   nsCOMPtr<nsISupportsArray> mManualFindWindows;
00259 };
00260 
00261 
00262 class nsTypeAheadController : public nsIController
00263 {
00264 public:
00265   nsTypeAheadController(nsIFocusController *aFocusController);
00266   virtual ~nsTypeAheadController();
00267   NS_DECL_ISUPPORTS
00268   NS_DECL_NSICONTROLLER
00269 
00270 private:
00271   nsCOMPtr<nsIFocusController> mFocusController;
00272   nsresult EnsureContentWindow(nsIDOMWindowInternal *aFocusedWin,
00273                                nsIDOMWindow **aStartContentWin);
00274 };