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
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
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
,
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
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
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
;
116 // The following members are only for navigation events and are only
117 // stored for FinishNavigationEvent to initialize the other members.
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
126 PRBool mForceNavigationWordCheck
;
128 // Contains the offset passed in to HandleNavigationEvent
129 PRInt32 mNewNavigationPositionOffset
;
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
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
;
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
194 kOpInsertBreak
= 1000,
195 kOpInsertText
= 1001,
196 kOpInsertIMEText
= 1002,
197 kOpDeleteText
= 1003,
203 kOpMakeBasicBlock
= 3005,
204 kOpRemoveList
= 3006,
205 kOpMakeDefListItem
= 3007,
206 kOpInsertElement
= 3008,
207 kOpInsertQuotation
= 3009,
208 kOpSetTextProperty
= 3010,
209 kOpRemoveTextProperty
= 3011,
212 kOpResetTextProperties
= 3014,
213 kOpSetAbsolutePosition
= 3015,
214 kOpRemoveAbsolutePosition
= 3016,
215 kOpDecreaseZIndex
= 3017,
216 kOpIncreaseZIndex
= 3018
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
,
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
,
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__ */