LCOV - code coverage report
Current view: top level - editor/libeditor - TextEditRules.h (source / functions) Hit Total Coverage
Test: output.info Lines: 16 28 57.1 %
Date: 2017-07-14 16:53:18 Functions: 6 14 42.9 %
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 mozilla_TextEditRules_h
       7             : #define mozilla_TextEditRules_h
       8             : 
       9             : #include "mozilla/EditorBase.h"
      10             : #include "nsCOMPtr.h"
      11             : #include "nsCycleCollectionParticipant.h"
      12             : #include "nsIEditRules.h"
      13             : #include "nsIEditor.h"
      14             : #include "nsISupportsImpl.h"
      15             : #include "nsITimer.h"
      16             : #include "nsString.h"
      17             : #include "nscore.h"
      18             : 
      19             : class nsIDOMNode;
      20             : 
      21             : namespace mozilla {
      22             : 
      23             : class AutoLockRulesSniffing;
      24             : class TextEditor;
      25             : namespace dom {
      26             : class Selection;
      27             : } // namespace dom
      28             : 
      29             : /**
      30             :  * Object that encapsulates HTML text-specific editing rules.
      31             :  *
      32             :  * To be a good citizen, edit rules must live by these restrictions:
      33             :  * 1. All data manipulation is through the editor.
      34             :  *    Content nodes in the document tree must <B>not</B> be manipulated
      35             :  *    directly.  Content nodes in document fragments that are not part of the
      36             :  *    document itself may be manipulated at will.  Operations on document
      37             :  *    fragments must <B>not</B> go through the editor.
      38             :  * 2. Selection must not be explicitly set by the rule method.
      39             :  *    Any manipulation of Selection must be done by the editor.
      40             :  */
      41             : class TextEditRules : public nsIEditRules
      42             :                     , public nsITimerCallback
      43             : {
      44             : public:
      45             :   typedef dom::Element Element;
      46             :   typedef dom::Selection Selection;
      47             :   typedef dom::Text Text;
      48             :   template<typename T> using OwningNonNull = OwningNonNull<T>;
      49             : 
      50             :   NS_DECL_NSITIMERCALLBACK
      51             :   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
      52          34 :   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(TextEditRules, nsIEditRules)
      53             : 
      54             :   TextEditRules();
      55             : 
      56             :   // nsIEditRules methods
      57             :   NS_IMETHOD Init(TextEditor* aTextEditor) override;
      58             :   NS_IMETHOD SetInitialValue(const nsAString& aValue) override;
      59             :   NS_IMETHOD DetachEditor() override;
      60             :   NS_IMETHOD BeforeEdit(EditAction action,
      61             :                         nsIEditor::EDirection aDirection) override;
      62             :   NS_IMETHOD AfterEdit(EditAction action,
      63             :                        nsIEditor::EDirection aDirection) override;
      64             :   NS_IMETHOD WillDoAction(Selection* aSelection, RulesInfo* aInfo,
      65             :                           bool* aCancel, bool* aHandled) override;
      66             :   NS_IMETHOD DidDoAction(Selection* aSelection, RulesInfo* aInfo,
      67             :                          nsresult aResult) override;
      68             :   NS_IMETHOD_(bool) DocumentIsEmpty() override;
      69             :   NS_IMETHOD DocumentModified() override;
      70             : 
      71             : protected:
      72             :   virtual ~TextEditRules();
      73             : 
      74             : public:
      75             :   void ResetIMETextPWBuf();
      76             : 
      77             :   /**
      78             :    * Handles the newline characters either according to aNewLineHandling
      79             :    * or to the default system prefs if aNewLineHandling is negative.
      80             :    *
      81             :    * @param aString the string to be modified in place.
      82             :    * @param aNewLineHandling determine the desired type of newline handling:
      83             :    *        * negative values:
      84             :    *          handle newlines according to platform defaults.
      85             :    *        * nsIPlaintextEditor::eNewlinesReplaceWithSpaces:
      86             :    *          replace newlines with spaces.
      87             :    *        * nsIPlaintextEditor::eNewlinesStrip:
      88             :    *          remove newlines from the string.
      89             :    *        * nsIPlaintextEditor::eNewlinesReplaceWithCommas:
      90             :    *          replace newlines with commas.
      91             :    *        * nsIPlaintextEditor::eNewlinesStripSurroundingWhitespace:
      92             :    *          collapse newlines and surrounding whitespace characters and
      93             :    *          remove them from the string.
      94             :    *        * nsIPlaintextEditor::eNewlinesPasteIntact:
      95             :    *          only remove the leading and trailing newlines.
      96             :    *        * nsIPlaintextEditor::eNewlinesPasteToFirst or any other value:
      97             :    *          remove the first newline and all characters following it.
      98             :    */
      99             :   static void HandleNewLines(nsString& aString, int32_t aNewLineHandling);
     100             : 
     101             :   /**
     102             :    * Prepare a string buffer for being displayed as the contents of a password
     103             :    * field.  This function uses the platform-specific character for representing
     104             :    * characters entered into password fields.
     105             :    *
     106             :    * @param aOutString the output string.  When this function returns,
     107             :    *        aOutString will contain aLength password characters.
     108             :    * @param aLength the number of password characters that aOutString should
     109             :    *        contain.
     110             :    */
     111             :   static void FillBufWithPWChars(nsAString* aOutString, int32_t aLength);
     112             : 
     113             : protected:
     114             : 
     115             :   void InitFields();
     116             : 
     117             :   // TextEditRules implementation methods
     118             :   nsresult WillInsertText(EditAction aAction,
     119             :                           Selection* aSelection,
     120             :                           bool* aCancel,
     121             :                           bool* aHandled,
     122             :                           const nsAString* inString,
     123             :                           nsAString* outString,
     124             :                           int32_t aMaxLength);
     125             :   nsresult DidInsertText(Selection* aSelection, nsresult aResult);
     126             : 
     127             :   nsresult WillInsertBreak(Selection* aSelection, bool* aCancel,
     128             :                            bool* aHandled, int32_t aMaxLength);
     129             :   nsresult DidInsertBreak(Selection* aSelection, nsresult aResult);
     130             : 
     131             :   nsresult WillSetText(Selection& aSelection,
     132             :                        bool* aCancel,
     133             :                        bool* aHandled,
     134             :                        const nsAString* inString,
     135             :                        int32_t aMaxLength);
     136             :   nsresult DidSetText(Selection& aSelection, nsresult aResult);
     137             : 
     138             :   void WillInsert(Selection& aSelection, bool* aCancel);
     139             :   nsresult DidInsert(Selection* aSelection, nsresult aResult);
     140             : 
     141             :   nsresult WillDeleteSelection(Selection* aSelection,
     142             :                                nsIEditor::EDirection aCollapsedAction,
     143             :                                bool* aCancel,
     144             :                                bool* aHandled);
     145             :   nsresult DidDeleteSelection(Selection* aSelection,
     146             :                               nsIEditor::EDirection aCollapsedAction,
     147             :                               nsresult aResult);
     148             : 
     149             :   nsresult WillSetTextProperty(Selection* aSelection, bool* aCancel,
     150             :                                bool* aHandled);
     151             :   nsresult DidSetTextProperty(Selection* aSelection, nsresult aResult);
     152             : 
     153             :   nsresult WillRemoveTextProperty(Selection* aSelection, bool* aCancel,
     154             :                                   bool* aHandled);
     155             :   nsresult DidRemoveTextProperty(Selection* aSelection, nsresult aResult);
     156             : 
     157             :   nsresult WillUndo(Selection* aSelection, bool* aCancel, bool* aHandled);
     158             :   nsresult DidUndo(Selection* aSelection, nsresult aResult);
     159             : 
     160             :   nsresult WillRedo(Selection* aSelection, bool* aCancel, bool* aHandled);
     161             :   nsresult DidRedo(Selection* aSelection, nsresult aResult);
     162             : 
     163             :   /**
     164             :    * Called prior to nsIEditor::OutputToString.
     165             :    * @param aSelection
     166             :    * @param aInFormat  The format requested for the output, a MIME type.
     167             :    * @param aOutText   The string to use for output, if aCancel is set to true.
     168             :    * @param aOutCancel If set to true, the caller should cancel the operation
     169             :    *                   and use aOutText as the result.
     170             :    */
     171             :   nsresult WillOutputText(Selection* aSelection,
     172             :                           const nsAString* aInFormat,
     173             :                           nsAString* aOutText,
     174             :                           uint32_t aFlags,
     175             :                           bool* aOutCancel,
     176             :                           bool* aHandled);
     177             : 
     178             :   nsresult DidOutputText(Selection* aSelection, nsresult aResult);
     179             : 
     180             :   /**
     181             :    * Check for and replace a redundant trailing break.
     182             :    */
     183             :   nsresult RemoveRedundantTrailingBR();
     184             : 
     185             :   /**
     186             :    * Creates a trailing break in the text doc if there is not one already.
     187             :    */
     188             :   nsresult CreateTrailingBRIfNeeded();
     189             : 
     190             :   /**
     191             :    * Creates a bogus text node if the document has no editable content.
     192             :    */
     193             :   nsresult CreateBogusNodeIfNeeded(Selection* aSelection);
     194             : 
     195             :   /**
     196             :    * Returns a truncated insertion string if insertion would place us over
     197             :    * aMaxLength
     198             :    */
     199             :   nsresult TruncateInsertionIfNeeded(Selection* aSelection,
     200             :                                      const nsAString* aInString,
     201             :                                      nsAString* aOutString,
     202             :                                      int32_t aMaxLength,
     203             :                                      bool* aTruncated);
     204             : 
     205             :   /**
     206             :    * Remove IME composition text from password buffer.
     207             :    */
     208             :   void RemoveIMETextFromPWBuf(uint32_t& aStart, nsAString* aIMEString);
     209             : 
     210             :   nsresult CreateMozBR(nsIDOMNode* inParent, int32_t inOffset,
     211             :                        nsIDOMNode** outBRNode = nullptr);
     212             : 
     213             :   void UndefineCaretBidiLevel(Selection* aSelection);
     214             : 
     215             :   nsresult CheckBidiLevelForDeletion(Selection* aSelection,
     216             :                                      nsIDOMNode* aSelNode,
     217             :                                      int32_t aSelOffset,
     218             :                                      nsIEditor::EDirection aAction,
     219             :                                      bool* aCancel);
     220             : 
     221             :   nsresult HideLastPWInput();
     222             : 
     223             :   nsresult CollapseSelectionToTrailingBRIfNeeded(Selection* aSelection);
     224             : 
     225             :   bool IsPasswordEditor() const;
     226             :   bool IsSingleLineEditor() const;
     227             :   bool IsPlaintextEditor() const;
     228             :   bool IsReadonly() const;
     229             :   bool IsDisabled() const;
     230             :   bool IsMailEditor() const;
     231             :   bool DontEchoPassword() const;
     232             : 
     233             : private:
     234             :   // Note that we do not refcount the editor.
     235             :   TextEditor* mTextEditor;
     236             : 
     237             : protected:
     238             :   // A buffer we use to store the real value of password editors.
     239             :   nsString mPasswordText;
     240             :   // A buffer we use to track the IME composition string.
     241             :   nsString mPasswordIMEText;
     242             :   uint32_t mPasswordIMEIndex;
     243             :   // Magic node acts as placeholder in empty doc.
     244             :   nsCOMPtr<nsIContent> mBogusNode;
     245             :   // Cached selected node.
     246             :   nsCOMPtr<nsINode> mCachedSelectionNode;
     247             :   // Cached selected offset.
     248             :   int32_t mCachedSelectionOffset;
     249             :   uint32_t mActionNesting;
     250             :   bool mLockRulesSniffing;
     251             :   bool mDidExplicitlySetInterline;
     252             :   // In bidirectional text, delete characters not visually adjacent to the
     253             :   // caret without moving the caret first.
     254             :   bool mDeleteBidiImmediately;
     255             :   // The top level editor action.
     256             :   EditAction mTheAction;
     257             :   nsCOMPtr<nsITimer> mTimer;
     258             :   uint32_t mLastStart;
     259             :   uint32_t mLastLength;
     260             : 
     261             :   // friends
     262             :   friend class AutoLockRulesSniffing;
     263             : };
     264             : 
     265             : // TODO: This class (almost struct, though) is ugly and its size isn't
     266             : //       optimized.  Should be refined later.
     267           5 : class TextRulesInfo final : public RulesInfo
     268             : {
     269             : public:
     270           5 :   explicit TextRulesInfo(EditAction aAction)
     271           5 :     : RulesInfo(aAction)
     272             :     , inString(nullptr)
     273             :     , outString(nullptr)
     274             :     , outputFormat(nullptr)
     275             :     , maxLength(-1)
     276             :     , flags(0)
     277             :     , collapsedAction(nsIEditor::eNext)
     278             :     , stripWrappers(nsIEditor::eStrip)
     279             :     , bOrdered(false)
     280             :     , entireList(false)
     281             :     , bulletType(nullptr)
     282             :     , alignType(nullptr)
     283           5 :     , blockType(nullptr)
     284           5 :   {}
     285             : 
     286             :   // EditAction::insertText / EditAction::insertIMEText
     287             :   const nsAString* inString;
     288             :   nsAString* outString;
     289             :   const nsAString* outputFormat;
     290             :   int32_t maxLength;
     291             : 
     292             :   // EditAction::outputText
     293             :   uint32_t flags;
     294             : 
     295             :   // EditAction::deleteSelection
     296             :   nsIEditor::EDirection collapsedAction;
     297             :   nsIEditor::EStripWrappers stripWrappers;
     298             : 
     299             :   // EditAction::removeList
     300             :   bool bOrdered;
     301             : 
     302             :   // EditAction::makeList
     303             :   bool entireList;
     304             :   const nsAString* bulletType;
     305             : 
     306             :   // EditAction::align
     307             :   const nsAString* alignType;
     308             : 
     309             :   // EditAction::makeBasicBlock
     310             :   const nsAString* blockType;
     311             : };
     312             : 
     313             : /**
     314             :  * Stack based helper class for StartOperation()/EndOperation() sandwich.
     315             :  * This class sets a bool letting us know to ignore any rules sniffing
     316             :  * that tries to occur reentrantly.
     317             :  */
     318             : class MOZ_STACK_CLASS AutoLockRulesSniffing final
     319             : {
     320             : public:
     321           6 :   explicit AutoLockRulesSniffing(TextEditRules* aRules)
     322           6 :     : mRules(aRules)
     323             :   {
     324           6 :     if (mRules) {
     325           6 :       mRules->mLockRulesSniffing = true;
     326             :     }
     327           6 :   }
     328             : 
     329           6 :   ~AutoLockRulesSniffing()
     330           6 :   {
     331           6 :     if (mRules) {
     332           6 :       mRules->mLockRulesSniffing = false;
     333             :     }
     334           6 :   }
     335             : 
     336             : protected:
     337             :   TextEditRules* mRules;
     338             : };
     339             : 
     340             : /**
     341             :  * Stack based helper class for turning on/off the edit listener.
     342             :  */
     343             : class MOZ_STACK_CLASS AutoLockListener final
     344             : {
     345             : public:
     346           0 :   explicit AutoLockListener(bool* aEnabled)
     347           0 :     : mEnabled(aEnabled)
     348           0 :     , mOldState(false)
     349             :   {
     350           0 :     if (mEnabled) {
     351           0 :       mOldState = *mEnabled;
     352           0 :       *mEnabled = false;
     353             :     }
     354           0 :   }
     355             : 
     356           0 :   ~AutoLockListener()
     357           0 :   {
     358           0 :     if (mEnabled) {
     359           0 :       *mEnabled = mOldState;
     360             :     }
     361           0 :   }
     362             : 
     363             : protected:
     364             :   bool* mEnabled;
     365             :   bool mOldState;
     366             : };
     367             : 
     368             : } // namespace mozilla
     369             : 
     370             : #endif // #ifndef mozilla_TextEditRules_h

Generated by: LCOV version 1.13