LCOV - code coverage report
Current view: top level - extensions/spellcheck/src - mozInlineSpellChecker.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 5 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 10 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13