extensions/spellcheck/src/mozInlineSpellChecker.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     6 #ifndef __mozinlinespellchecker_h__
     7 #define __mozinlinespellchecker_h__
     9 #include "nsAutoPtr.h"
    10 #include "nsRange.h"
    11 #include "nsIEditorSpellCheck.h"
    12 #include "nsIEditActionListener.h"
    13 #include "nsIInlineSpellChecker.h"
    14 #include "nsIDOMTreeWalker.h"
    15 #include "nsWeakReference.h"
    16 #include "nsEditor.h"
    17 #include "nsIDOMEventListener.h"
    18 #include "nsWeakReference.h"
    19 #include "mozISpellI18NUtil.h"
    20 #include "nsCycleCollectionParticipant.h"
    22 // X.h defines KeyPress
    23 #ifdef KeyPress
    24 #undef KeyPress
    25 #endif
    27 class nsIDOMMouseEventListener;
    28 class mozInlineSpellWordUtil;
    29 class mozInlineSpellChecker;
    30 class mozInlineSpellResume;
    31 class InitEditorSpellCheckCallback;
    32 class UpdateCurrentDictionaryCallback;
    33 class mozInlineSpellResume;
    35 class mozInlineSpellStatus
    36 {
    37 public:
    38   mozInlineSpellStatus(mozInlineSpellChecker* aSpellChecker);
    40   nsresult InitForEditorChange(EditAction aAction,
    41                                nsIDOMNode* aAnchorNode, int32_t aAnchorOffset,
    42                                nsIDOMNode* aPreviousNode, int32_t aPreviousOffset,
    43                                nsIDOMNode* aStartNode, int32_t aStartOffset,
    44                                nsIDOMNode* aEndNode, int32_t aEndOffset);
    45   nsresult InitForNavigation(bool aForceCheck, int32_t aNewPositionOffset,
    46                              nsIDOMNode* aOldAnchorNode, int32_t aOldAnchorOffset,
    47                              nsIDOMNode* aNewAnchorNode, int32_t aNewAnchorOffset,
    48                              bool* aContinue);
    49   nsresult InitForSelection();
    50   nsresult InitForRange(nsRange* aRange);
    52   nsresult FinishInitOnEvent(mozInlineSpellWordUtil& aWordUtil);
    54   // Return true if we plan to spell-check everything
    55   bool IsFullSpellCheck() const {
    56     return mOp == eOpChange && !mRange;
    57   }
    59   nsRefPtr<mozInlineSpellChecker> mSpellChecker;
    61   // The total number of words checked in this sequence, using this tally tells
    62   // us when to stop. This count is preserved as we continue checking in new
    63   // messages.
    64   int32_t mWordCount;
    66   // what happened?
    67   enum Operation { eOpChange,       // for SpellCheckAfterChange except deleteSelection
    68                    eOpChangeDelete, // for SpellCheckAfterChange deleteSelection
    69                    eOpNavigation,   // for HandleNavigationEvent
    70                    eOpSelection,    // re-check all misspelled words
    71                    eOpResume };     // for resuming a previously started check
    72   Operation mOp;
    74   // Used for events where we have already computed the range to use. It can
    75   // also be nullptr in these cases where we need to check the entire range.
    76   nsRefPtr<nsRange> mRange;
    78   // If we happen to know something was inserted, this is that range.
    79   // Can be nullptr (this only allows an optimization, so not setting doesn't hurt)
    80   nsCOMPtr<nsIDOMRange> mCreatedRange;
    82   // Contains the range computed for the current word. Can be nullptr.
    83   nsRefPtr<nsRange> mNoCheckRange;
    85   // Indicates the position of the cursor for the event (so we can compute
    86   // mNoCheckRange). It can be nullptr if we don't care about the cursor position
    87   // (such as for the intial check of everything).
    88   //
    89   // For mOp == eOpNavigation, this is the NEW position of the cursor
    90   nsCOMPtr<nsIDOMRange> mAnchorRange;
    92   // -----
    93   // The following members are only for navigation events and are only
    94   // stored for FinishNavigationEvent to initialize the other members.
    95   // -----
    97   // this is the OLD position of the cursor
    98   nsCOMPtr<nsIDOMRange> mOldNavigationAnchorRange;
   100   // Set when we should force checking the current word. See
   101   // mozInlineSpellChecker::HandleNavigationEvent for a description of why we
   102   // have this.
   103   bool mForceNavigationWordCheck;
   105   // Contains the offset passed in to HandleNavigationEvent
   106   int32_t mNewNavigationPositionOffset;
   108 protected:
   109   nsresult FinishNavigationEvent(mozInlineSpellWordUtil& aWordUtil);
   111   nsresult FillNoCheckRangeFromAnchor(mozInlineSpellWordUtil& aWordUtil);
   113   nsresult GetDocument(nsIDOMDocument** aDocument);
   114   nsresult PositionToCollapsedRange(nsIDOMDocument* aDocument,
   115                                     nsIDOMNode* aNode, int32_t aOffset,
   116                                     nsIDOMRange** aRange);
   117 };
   119 class mozInlineSpellChecker : public nsIInlineSpellChecker,
   120                               public nsIEditActionListener,
   121                               public nsIDOMEventListener,
   122                               public nsSupportsWeakReference
   123 {
   124 private:
   125   friend class mozInlineSpellStatus;
   126   friend class InitEditorSpellCheckCallback;
   127   friend class UpdateCurrentDictionaryCallback;
   128   friend class AutoChangeNumPendingSpellChecks;
   129   friend class mozInlineSpellResume;
   131   // Access with CanEnableInlineSpellChecking
   132   enum SpellCheckingState { SpellCheck_Uninitialized = -1,
   133                             SpellCheck_NotAvailable = 0,
   134                             SpellCheck_Available = 1};
   135   static SpellCheckingState gCanEnableSpellChecking;
   137   nsWeakPtr mEditor; 
   138   nsCOMPtr<nsIEditorSpellCheck> mSpellCheck;
   139   nsCOMPtr<nsIEditorSpellCheck> mPendingSpellCheck;
   140   nsCOMPtr<nsIDOMTreeWalker> mTreeWalker;
   141   nsCOMPtr<mozISpellI18NUtil> mConverter;
   143   int32_t mNumWordsInSpellSelection;
   144   int32_t mMaxNumWordsInSpellSelection;
   146   // How many misspellings we can add at once. This is often less than the max
   147   // total number of misspellings. When you have a large textarea prepopulated
   148   // with text with many misspellings, we can hit this limit. By making it
   149   // lower than the total number of misspelled words, new text typed by the
   150   // user can also have spellchecking in it.
   151   int32_t mMaxMisspellingsPerCheck;
   153   // we need to keep track of the current text position in the document
   154   // so we can spell check the old word when the user clicks around the document.
   155   nsCOMPtr<nsIDOMNode> mCurrentSelectionAnchorNode;
   156   int32_t              mCurrentSelectionOffset;
   158   // Tracks the number of pending spell checks *and* async operations that may
   159   // lead to spell checks, like updating the current dictionary.  This is
   160   // necessary so that observers can know when to wait for spell check to
   161   // complete.
   162   int32_t mNumPendingSpellChecks;
   164   // The number of calls to UpdateCurrentDictionary that haven't finished yet.
   165   int32_t mNumPendingUpdateCurrentDictionary;
   167   // This number is incremented each time the spell checker is disabled so that
   168   // pending scheduled spell checks and UpdateCurrentDictionary calls can be
   169   // ignored when they finish.
   170   uint32_t mDisabledAsyncToken;
   172   // When mPendingSpellCheck is non-null, this is the callback passed when
   173   // it was initialized.
   174   nsRefPtr<InitEditorSpellCheckCallback> mPendingInitEditorSpellCheckCallback;
   176   // Set when we have spellchecked after the last edit operation. See the
   177   // commment at the top of the .cpp file for more info.
   178   bool mNeedsCheckAfterNavigation;
   180   // Set when we have a pending mozInlineSpellResume which will check
   181   // the whole document.
   182   bool mFullSpellCheckScheduled;
   184   // Maintains state during the asynchronous UpdateCurrentDictionary call.
   185   nsString mPreviousDictionary;
   187 public:
   189   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   190   NS_DECL_NSIEDITACTIONLISTENER
   191   NS_DECL_NSIINLINESPELLCHECKER
   192   NS_DECL_NSIDOMEVENTLISTENER
   193   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(mozInlineSpellChecker, nsIDOMEventListener)
   195   // returns true if there are any spell checking dictionaries available
   196   static bool CanEnableInlineSpellChecking();
   197   // update the cached value whenever the list of available dictionaries changes
   198   static void UpdateCanEnableInlineSpellChecking();
   200   nsresult Blur(nsIDOMEvent* aEvent);
   201   nsresult MouseClick(nsIDOMEvent* aMouseEvent);
   202   nsresult KeyPress(nsIDOMEvent* aKeyEvent);
   204   mozInlineSpellChecker();
   205   virtual ~mozInlineSpellChecker();
   207   // spell checks all of the words between two nodes
   208   nsresult SpellCheckBetweenNodes(nsIDOMNode *aStartNode,
   209                                   int32_t aStartOffset,
   210                                   nsIDOMNode *aEndNode,
   211                                   int32_t aEndOffset);
   213   // examines the dom node in question and returns true if the inline spell
   214   // checker should skip the node (i.e. the text is inside of a block quote
   215   // or an e-mail signature...)
   216   nsresult SkipSpellCheckForNode(nsIEditor* aEditor,
   217                                  nsIDOMNode *aNode, bool * aCheckSpelling);
   219   nsresult SpellCheckAfterChange(nsIDOMNode* aCursorNode, int32_t aCursorOffset,
   220                                  nsIDOMNode* aPreviousNode, int32_t aPreviousOffset,
   221                                  nsISelection* aSpellCheckSelection);
   223   // spell check the text contained within aRange, potentially scheduling
   224   // another check in the future if the time threshold is reached
   225   nsresult ScheduleSpellCheck(const mozInlineSpellStatus& aStatus);
   227   nsresult DoSpellCheckSelection(mozInlineSpellWordUtil& aWordUtil,
   228                                  nsISelection* aSpellCheckSelection,
   229                                  mozInlineSpellStatus* aStatus);
   230   nsresult DoSpellCheck(mozInlineSpellWordUtil& aWordUtil,
   231                         nsISelection *aSpellCheckSelection,
   232                         mozInlineSpellStatus* aStatus,
   233                         bool* aDoneChecking);
   235   // helper routine to determine if a point is inside of the passed in selection.
   236   nsresult IsPointInSelection(nsISelection *aSelection,
   237                               nsIDOMNode *aNode,
   238                               int32_t aOffset,
   239                               nsIDOMRange **aRange);
   241   nsresult CleanupRangesInSelection(nsISelection *aSelection);
   243   nsresult RemoveRange(nsISelection *aSpellCheckSelection, nsIDOMRange * aRange);
   244   nsresult AddRange(nsISelection *aSpellCheckSelection, nsIDOMRange * aRange);
   245   bool     SpellCheckSelectionIsFull() { return mNumWordsInSpellSelection >= mMaxNumWordsInSpellSelection; }
   247   nsresult MakeSpellCheckRange(nsIDOMNode* aStartNode, int32_t aStartOffset,
   248                                nsIDOMNode* aEndNode, int32_t aEndOffset,
   249                                nsRange** aRange);
   251   // DOM and editor event registration helper routines
   252   nsresult RegisterEventListeners();
   253   nsresult UnregisterEventListeners();
   254   nsresult HandleNavigationEvent(bool aForceWordSpellCheck, int32_t aNewPositionOffset = 0);
   256   nsresult GetSpellCheckSelection(nsISelection ** aSpellCheckSelection);
   257   nsresult SaveCurrentSelectionPosition();
   259   nsresult ResumeCheck(mozInlineSpellStatus* aStatus);
   261 protected:
   263   // called when async nsIEditorSpellCheck methods complete
   264   nsresult EditorSpellCheckInited();
   265   nsresult CurrentDictionaryUpdated();
   267   // track the number of pending spell checks and async operations that may lead
   268   // to spell checks, notifying observers accordingly
   269   void ChangeNumPendingSpellChecks(int32_t aDelta,
   270                                    nsIEditor* aEditor = nullptr);
   271   void NotifyObservers(const char* aTopic, nsIEditor* aEditor);
   272 };
   274 #endif /* __mozinlinespellchecker_h__ */

mercurial