Bug 452317 - FeedConverter.js: QueryInterface should throw NS_ERROR_NO_INTERFACE...
[wine-gecko.git] / extensions / spellcheck / src / mozInlineSpellChecker.h
blob31e2e9d45d830c9c31c48673c029e42566318696
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is Inline Spellchecker
17 * The Initial Developer of the Original Code is Mozdev Group, Inc.
18 * Portions created by the Initial Developer are Copyright (C) 2004
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s): Neil Deakin (neil@mozdevgroup.com)
22 * Scott MacGregor (mscott@mozilla.org)
23 * Brett Wilson <brettw@gmail.com>
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 #ifndef __mozinlinespellchecker_h__
40 #define __mozinlinespellchecker_h__
42 #include "nsAutoPtr.h"
43 #include "nsIDOMRange.h"
44 #include "nsIEditorSpellCheck.h"
45 #include "nsIEditActionListener.h"
46 #include "nsIInlineSpellChecker.h"
47 #include "nsITextServicesDocument.h"
48 #include "nsIDOMTreeWalker.h"
49 #include "nsWeakReference.h"
50 #include "nsIEditor.h"
51 #include "nsIDOMFocusListener.h"
52 #include "nsIDOMMouseListener.h"
53 #include "nsIDOMKeyListener.h"
54 #include "nsWeakReference.h"
55 #include "mozISpellI18NUtil.h"
57 class nsIDOMDocumentRange;
58 class nsIDOMMouseEventListener;
59 class mozInlineSpellWordUtil;
60 class mozInlineSpellChecker;
61 class mozInlineSpellResume;
63 class mozInlineSpellStatus
65 public:
66 mozInlineSpellStatus(mozInlineSpellChecker* aSpellChecker);
68 nsresult InitForEditorChange(PRInt32 aAction,
69 nsIDOMNode* aAnchorNode, PRInt32 aAnchorOffset,
70 nsIDOMNode* aPreviousNode, PRInt32 aPreviousOffset,
71 nsIDOMNode* aStartNode, PRInt32 aStartOffset,
72 nsIDOMNode* aEndNode, PRInt32 aEndOffset);
73 nsresult InitForNavigation(PRBool aForceCheck, PRInt32 aNewPositionOffset,
74 nsIDOMNode* aOldAnchorNode, PRInt32 aOldAnchorOffset,
75 nsIDOMNode* aNewAnchorNode, PRInt32 aNewAnchorOffset,
76 PRBool* aContinue);
77 nsresult InitForSelection();
78 nsresult InitForRange(nsIDOMRange* aRange);
80 nsresult FinishInitOnEvent(mozInlineSpellWordUtil& aWordUtil);
82 nsRefPtr<mozInlineSpellChecker> mSpellChecker;
84 // The total number of words checked in this sequence, using this tally tells
85 // us when to stop. This count is preserved as we continue checking in new
86 // messages.
87 PRInt32 mWordCount;
89 // what happened?
90 enum Operation { eOpChange, // for SpellCheckAfterChange except kOpDeleteSelection
91 eOpChangeDelete, // for SpellCheckAfterChange kOpDeleteSelection
92 eOpNavigation, // for HandleNavigationEvent
93 eOpSelection, // re-check all misspelled words
94 eOpResume }; // for resuming a previously started check
95 Operation mOp;
97 // Used for events where we have already computed the range to use. It can
98 // also be NULL in these cases where we need to check the entire range.
99 nsCOMPtr<nsIDOMRange> mRange;
101 // If we happen to know something was inserted, this is that range.
102 // Can be NULL (this only allows an optimization, so not setting doesn't hurt)
103 nsCOMPtr<nsIDOMRange> mCreatedRange;
105 // Contains the range computed for the current word. Can be NULL.
106 nsCOMPtr<nsIDOMRange> mNoCheckRange;
108 // Indicates the position of the cursor for the event (so we can compute
109 // mNoCheckRange). It can be NULL if we don't care about the cursor position
110 // (such as for the intial check of everything).
112 // For mOp == eOpNavigation, this is the NEW position of the cursor
113 nsCOMPtr<nsIDOMRange> mAnchorRange;
115 // -----
116 // The following members are only for navigation events and are only
117 // stored for FinishNavigationEvent to initialize the other members.
118 // -----
120 // this is the OLD position of the cursor
121 nsCOMPtr<nsIDOMRange> mOldNavigationAnchorRange;
123 // Set when we should force checking the current word. See
124 // mozInlineSpellChecker::HandleNavigationEvent for a description of why we
125 // have this.
126 PRBool mForceNavigationWordCheck;
128 // Contains the offset passed in to HandleNavigationEvent
129 PRInt32 mNewNavigationPositionOffset;
131 protected:
132 nsresult FinishNavigationEvent(mozInlineSpellWordUtil& aWordUtil);
134 nsresult FillNoCheckRangeFromAnchor(mozInlineSpellWordUtil& aWordUtil);
136 nsresult GetDocumentRange(nsIDOMDocumentRange** aDocRange);
137 nsresult PositionToCollapsedRange(nsIDOMDocumentRange* aDocRange,
138 nsIDOMNode* aNode, PRInt32 aOffset,
139 nsIDOMRange** aRange);
142 class mozInlineSpellChecker : public nsIInlineSpellChecker, nsIEditActionListener, nsIDOMFocusListener, nsIDOMMouseListener, nsIDOMKeyListener,
143 nsSupportsWeakReference
145 private:
146 friend class mozInlineSpellStatus;
148 // Access with CanEnableInlineSpellChecking
149 enum SpellCheckingState { SpellCheck_Uninitialized = -1,
150 SpellCheck_NotAvailable = 0,
151 SpellCheck_Available = 1};
152 static SpellCheckingState gCanEnableSpellChecking;
154 nsWeakPtr mEditor;
155 nsCOMPtr<nsIEditorSpellCheck> mSpellCheck;
156 nsCOMPtr<nsITextServicesDocument> mTextServicesDocument;
157 nsCOMPtr<nsIDOMTreeWalker> mTreeWalker;
158 nsCOMPtr<mozISpellI18NUtil> mConverter;
160 PRInt32 mNumWordsInSpellSelection;
161 PRInt32 mMaxNumWordsInSpellSelection;
163 // How many misspellings we can add at once. This is often less than the max
164 // total number of misspellings. When you have a large textarea prepopulated
165 // with text with many misspellings, we can hit this limit. By making it
166 // lower than the total number of misspelled words, new text typed by the
167 // user can also have spellchecking in it.
168 PRInt32 mMaxMisspellingsPerCheck;
170 // we need to keep track of the current text position in the document
171 // so we can spell check the old word when the user clicks around the document.
172 nsCOMPtr<nsIDOMNode> mCurrentSelectionAnchorNode;
173 PRInt32 mCurrentSelectionOffset;
175 // Set when we have spellchecked after the last edit operation. See the
176 // commment at the top of the .cpp file for more info.
177 PRBool mNeedsCheckAfterNavigation;
179 // TODO: these should be defined somewhere so that they don't have to be copied
180 // from editor!
181 enum OperationID
183 kOpIgnore = -1,
184 kOpNone = 0,
185 kOpUndo,
186 kOpRedo,
187 kOpInsertNode,
188 kOpCreateNode,
189 kOpDeleteNode,
190 kOpSplitNode,
191 kOpJoinNode,
192 kOpDeleteSelection,
194 kOpInsertBreak = 1000,
195 kOpInsertText = 1001,
196 kOpInsertIMEText = 1002,
197 kOpDeleteText = 1003,
199 kOpMakeList = 3001,
200 kOpIndent = 3002,
201 kOpOutdent = 3003,
202 kOpAlign = 3004,
203 kOpMakeBasicBlock = 3005,
204 kOpRemoveList = 3006,
205 kOpMakeDefListItem = 3007,
206 kOpInsertElement = 3008,
207 kOpInsertQuotation = 3009,
208 kOpSetTextProperty = 3010,
209 kOpRemoveTextProperty = 3011,
210 kOpHTMLPaste = 3012,
211 kOpLoadHTML = 3013,
212 kOpResetTextProperties = 3014,
213 kOpSetAbsolutePosition = 3015,
214 kOpRemoveAbsolutePosition = 3016,
215 kOpDecreaseZIndex = 3017,
216 kOpIncreaseZIndex = 3018
219 public:
221 NS_DECL_ISUPPORTS
222 NS_DECL_NSIEDITACTIONLISTENER
223 NS_DECL_NSIINLINESPELLCHECKER
225 // returns true if it looks likely that we can enable real-time spell checking
226 static PRBool CanEnableInlineSpellChecking();
228 /*BEGIN implementations of focus event handler interface*/
229 NS_IMETHOD Focus(nsIDOMEvent* aEvent);
230 NS_IMETHOD Blur(nsIDOMEvent* aEvent);
231 /*END implementations of focus event handler interface*/
233 /*BEGIN implementations of mouseevent handler interface*/
234 NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
235 NS_IMETHOD MouseDown(nsIDOMEvent* aMouseEvent);
236 NS_IMETHOD MouseUp(nsIDOMEvent* aMouseEvent);
237 NS_IMETHOD MouseClick(nsIDOMEvent* aMouseEvent);
238 NS_IMETHOD MouseDblClick(nsIDOMEvent* aMouseEvent);
239 NS_IMETHOD MouseOver(nsIDOMEvent* aMouseEvent);
240 NS_IMETHOD MouseOut(nsIDOMEvent* aMouseEvent);
241 /*END implementations of mouseevent handler interface*/
243 /* BEGIN interfaces in to the keylistener interface. */
244 NS_IMETHOD KeyDown(nsIDOMEvent* aKeyEvent);
245 NS_IMETHOD KeyUp(nsIDOMEvent* aKeyEvent);
246 NS_IMETHOD KeyPress(nsIDOMEvent* aKeyEvent);
247 /* END interfaces from nsIDOMKeyListener */
249 mozInlineSpellChecker();
250 virtual ~mozInlineSpellChecker();
252 // spell checks all of the words between two nodes
253 nsresult SpellCheckBetweenNodes(nsIDOMNode *aStartNode,
254 PRInt32 aStartOffset,
255 nsIDOMNode *aEndNode,
256 PRInt32 aEndOffset);
258 // examines the dom node in question and returns true if the inline spell
259 // checker should skip the node (i.e. the text is inside of a block quote
260 // or an e-mail signature...)
261 nsresult SkipSpellCheckForNode(nsIEditor* aEditor,
262 nsIDOMNode *aNode, PRBool * aCheckSpelling);
264 nsresult SpellCheckAfterChange(nsIDOMNode* aCursorNode, PRInt32 aCursorOffset,
265 nsIDOMNode* aPreviousNode, PRInt32 aPreviousOffset,
266 nsISelection* aSpellCheckSelection);
268 // spell check the text contained within aRange, potentially scheduling
269 // another check in the future if the time threshold is reached
270 nsresult ScheduleSpellCheck(const mozInlineSpellStatus& aStatus);
272 nsresult DoSpellCheckSelection(mozInlineSpellWordUtil& aWordUtil,
273 nsISelection* aSpellCheckSelection,
274 mozInlineSpellStatus* aStatus);
275 nsresult DoSpellCheck(mozInlineSpellWordUtil& aWordUtil,
276 nsISelection *aSpellCheckSelection,
277 mozInlineSpellStatus* aStatus,
278 PRBool* aDoneChecking);
280 // helper routine to determine if a point is inside of a the passed in selection.
281 nsresult IsPointInSelection(nsISelection *aSelection,
282 nsIDOMNode *aNode,
283 PRInt32 aOffset,
284 nsIDOMRange **aRange);
286 nsresult CleanupRangesInSelection(nsISelection *aSelection);
288 nsresult RemoveRange(nsISelection *aSpellCheckSelection, nsIDOMRange * aRange);
289 nsresult AddRange(nsISelection *aSpellCheckSelection, nsIDOMRange * aRange);
290 PRBool SpellCheckSelectionIsFull() { return mNumWordsInSpellSelection >= mMaxNumWordsInSpellSelection; }
292 nsresult MakeSpellCheckRange(nsIDOMNode* aStartNode, PRInt32 aStartOffset,
293 nsIDOMNode* aEndNode, PRInt32 aEndOffset,
294 nsIDOMRange** aRange);
296 // DOM and editor event registration helper routines
297 nsresult RegisterEventListeners();
298 nsresult UnregisterEventListeners();
299 nsresult HandleNavigationEvent(nsIDOMEvent * aEvent, PRBool aForceWordSpellCheck, PRInt32 aNewPositionOffset = 0);
301 nsresult GetSpellCheckSelection(nsISelection ** aSpellCheckSelection);
302 nsresult SaveCurrentSelectionPosition();
304 nsresult ResumeCheck(mozInlineSpellStatus* aStatus);
307 #endif /* __mozinlinespellchecker_h__ */