1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #include "nsComponentManagerUtils.h" 7 #include "nsCycleCollectionParticipant.h" 8 #include "nsISelectionController.h" 9 #include "nsIController.h" 10 #include "nsIControllers.h" 11 #include "nsIObserver.h" 12 #include "nsUnicharUtils.h" 13 #include "nsIFind.h" 14 #include "nsIWebBrowserFind.h" 15 #include "nsWeakReference.h" 16 #include "nsISelection.h" 17 #include "nsIDOMRange.h" 18 #include "nsIDocShellTreeItem.h" 19 #include "nsITypeAheadFind.h" 20 #include "nsISound.h" 21 22 class nsPIDOMWindowInner; 23 class nsIPresShell; 24 class nsPresContext; 25 class nsRange; 26 27 #define TYPEAHEADFIND_NOTFOUND_WAV_URL "chrome://global/content/notfound.wav" 28 29 class nsTypeAheadFind : public nsITypeAheadFind, 30 public nsIObserver, 31 public nsSupportsWeakReference { 32 public: 33 nsTypeAheadFind(); 34 35 NS_DECL_CYCLE_COLLECTING_ISUPPORTS 36 NS_DECL_NSITYPEAHEADFIND 37 NS_DECL_NSIOBSERVER 38 39 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsTypeAheadFind, nsITypeAheadFind) 40 41 protected: 42 virtual ~nsTypeAheadFind(); 43 44 nsresult PrefsReset(); 45 46 void SaveFind(); 47 void PlayNotFoundSound(); 48 nsresult GetWebBrowserFind(nsIDocShell *aDocShell, 49 nsIWebBrowserFind **aWebBrowserFind); 50 51 void RangeStartsInsideLink(nsRange *aRange, nsIPresShell *aPresShell, 52 bool *aIsInsideLink, bool *aIsStartingLink); 53 54 void GetSelection(nsIPresShell *aPresShell, nsISelectionController **aSelCon, 55 nsISelection **aDomSel); 56 // *aNewRange may not be collapsed. If you want to collapse it in a 57 // particular way, you need to do it yourself. 58 bool IsRangeVisible(nsIPresShell *aPresShell, nsPresContext *aPresContext, 59 nsIDOMRange *aRange, bool aMustBeVisible, 60 bool aGetTopVisibleLeaf, nsIDOMRange **aNewRange, 61 bool *aUsesIndependentSelection); 62 bool IsRangeRendered(nsIPresShell *aPresShell, nsPresContext *aPresContext, 63 nsIDOMRange *aRange); 64 nsresult FindItNow(nsIPresShell *aPresShell, bool aIsLinksOnly, 65 bool aIsFirstVisiblePreferred, bool aFindPrev, 66 uint16_t *aResult); 67 nsresult GetSearchContainers(nsISupports *aContainer, 68 nsISelectionController *aSelectionController, 69 bool aIsFirstVisiblePreferred, bool aFindPrev, 70 nsIPresShell **aPresShell, 71 nsPresContext **aPresContext); 72 73 // Get the pres shell from mPresShell and return it only if it is still 74 // attached to the DOM window. 75 already_AddRefed<nsIPresShell> GetPresShell(); 76 77 void ReleaseStrongMemberVariables(); 78 79 // Current find state 80 nsString mTypeAheadBuffer; 81 nsCString mNotFoundSoundURL; 82 83 // PRBools are used instead of PRPackedBools because the address of the 84 // boolean variable is getting passed into a method. 85 bool mStartLinksOnlyPref; 86 bool mCaretBrowsingOn; 87 bool mDidAddObservers; 88 nsCOMPtr<nsIDOMElement> mFoundLink; // Most recent elem found, if a link 89 nsCOMPtr<nsIDOMElement> 90 mFoundEditable; // Most recent elem found, if editable 91 nsCOMPtr<nsIDOMRange> mFoundRange; // Most recent range found 92 nsCOMPtr<nsPIDOMWindowInner> mCurrentWindow; 93 // mLastFindLength is the character length of the last find string. It is 94 // used for disabling the "not found" sound when using backspace or delete 95 uint32_t mLastFindLength; 96 97 // Sound is played asynchronously on some platforms. 98 // If we destroy mSoundInterface before sound has played, it won't play 99 nsCOMPtr<nsISound> mSoundInterface; 100 bool mIsSoundInitialized; 101 102 // where selection was when user started the find 103 nsCOMPtr<nsIDOMRange> mStartFindRange; 104 nsCOMPtr<nsIDOMRange> mSearchRange; 105 nsCOMPtr<nsIDOMRange> mStartPointRange; 106 nsCOMPtr<nsIDOMRange> mEndPointRange; 107 108 // Cached useful interfaces 109 nsCOMPtr<nsIFind> mFind; 110 111 bool mCaseSensitive; 112 bool mEntireWord; 113 EnsureFind()114 bool EnsureFind() { 115 if (mFind) { 116 return true; 117 } 118 119 mFind = do_CreateInstance("@mozilla.org/embedcomp/rangefind;1"); 120 if (!mFind) { 121 return false; 122 } 123 124 mFind->SetCaseSensitive(mCaseSensitive); 125 mFind->SetEntireWord(mEntireWord); 126 127 return true; 128 } 129 130 nsCOMPtr<nsIWebBrowserFind> mWebBrowserFind; 131 132 // The focused content window that we're listening to and its cached objects 133 nsWeakPtr mDocShell; 134 nsWeakPtr mPresShell; 135 nsWeakPtr mSelectionController; 136 // Most recent match's controller 137 }; 138