LCOV - code coverage report
Current view: top level - editor/libeditor - EditorUtils.h (source / functions) Hit Total Coverage
Test: output.info Lines: 37 112 33.0 %
Date: 2017-07-14 16:53:18 Functions: 6 33 18.2 %
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             : 
       7             : #ifndef mozilla_EditorUtils_h
       8             : #define mozilla_EditorUtils_h
       9             : 
      10             : #include "mozilla/dom/Selection.h"
      11             : #include "mozilla/EditorBase.h"
      12             : #include "mozilla/GuardObjects.h"
      13             : #include "nsCOMPtr.h"
      14             : #include "nsDebug.h"
      15             : #include "nsIDOMNode.h"
      16             : #include "nsIEditor.h"
      17             : #include "nscore.h"
      18             : 
      19             : class nsIAtom;
      20             : class nsIContentIterator;
      21             : class nsIDOMDocument;
      22             : class nsIDOMEvent;
      23             : class nsISimpleEnumerator;
      24             : class nsITransferable;
      25             : class nsRange;
      26             : 
      27             : namespace mozilla {
      28             : template <class T> class OwningNonNull;
      29             : 
      30             : /***************************************************************************
      31             :  * EditActionResult is useful to return multiple results of an editor
      32             :  * action handler without out params.
      33             :  * Note that when you return an anonymous instance from a method, you should
      34             :  * use EditActionIgnored(), EditActionHandled() or EditActionCanceled() for
      35             :  * easier to read.  In other words, EditActionResult should be used when
      36             :  * declaring return type of a method, being an argument or defined as a local
      37             :  * variable.
      38             :  */
      39             : class MOZ_STACK_CLASS EditActionResult final
      40             : {
      41             : public:
      42             :   bool Succeeded() const { return NS_SUCCEEDED(mRv); }
      43           0 :   bool Failed() const { return NS_FAILED(mRv); }
      44           0 :   nsresult Rv() const { return mRv; }
      45           0 :   bool Canceled() const { return mCanceled; }
      46           0 :   bool Handled() const { return mHandled; }
      47             : 
      48           0 :   EditActionResult SetResult(nsresult aRv)
      49             :   {
      50           0 :     mRv = aRv;
      51           0 :     return *this;
      52             :   }
      53             :   EditActionResult MarkAsCanceled()
      54             :   {
      55             :     mCanceled = true;
      56             :     return *this;
      57             :   }
      58           0 :   EditActionResult MarkAsHandled()
      59             :   {
      60           0 :     mHandled = true;
      61           0 :     return *this;
      62             :   }
      63             : 
      64           0 :   explicit EditActionResult(nsresult aRv)
      65           0 :     : mRv(aRv)
      66             :     , mCanceled(false)
      67           0 :     , mHandled(false)
      68             :   {
      69           0 :   }
      70             : 
      71           0 :   EditActionResult& operator|=(const EditActionResult& aOther)
      72             :   {
      73           0 :     mCanceled |= aOther.mCanceled;
      74           0 :     mHandled |= aOther.mHandled;
      75             :     // When both result are same, keep the result.
      76           0 :     if (mRv == aOther.mRv) {
      77           0 :       return *this;
      78             :     }
      79             :     // If one of the results is error, use NS_ERROR_FAILURE.
      80           0 :     if (Failed() || aOther.Failed()) {
      81           0 :       mRv = NS_ERROR_FAILURE;
      82             :     } else {
      83             :       // Otherwise, use generic success code, NS_OK.
      84           0 :       mRv = NS_OK;
      85             :     }
      86           0 :     return *this;
      87             :   }
      88             : 
      89             : private:
      90             :   nsresult mRv;
      91             :   bool mCanceled;
      92             :   bool mHandled;
      93             : 
      94           0 :   EditActionResult(nsresult aRv, bool aCanceled, bool aHandled)
      95           0 :     : mRv(aRv)
      96             :     , mCanceled(aCanceled)
      97           0 :     , mHandled(aHandled)
      98             :   {
      99           0 :   }
     100             : 
     101             :   EditActionResult()
     102             :     : mRv(NS_ERROR_NOT_INITIALIZED)
     103             :     , mCanceled(false)
     104             :     , mHandled(false)
     105             :   {
     106             :   }
     107             : 
     108             :   friend EditActionResult EditActionIgnored(nsresult aRv);
     109             :   friend EditActionResult EditActionHandled(nsresult aRv);
     110             :   friend EditActionResult EditActionCanceled(nsresult aRv);
     111             : };
     112             : 
     113             : /***************************************************************************
     114             :  * When an edit action handler (or its helper) does nothing,
     115             :  * EditActionIgnored should be returned.
     116             :  */
     117             : inline EditActionResult
     118           0 : EditActionIgnored(nsresult aRv = NS_OK)
     119             : {
     120           0 :   return EditActionResult(aRv, false, false);
     121             : }
     122             : 
     123             : /***************************************************************************
     124             :  * When an edit action handler (or its helper) handled and not canceled,
     125             :  * EditActionHandled should be returned.
     126             :  */
     127             : inline EditActionResult
     128           0 : EditActionHandled(nsresult aRv = NS_OK)
     129             : {
     130           0 :   return EditActionResult(aRv, false, true);
     131             : }
     132             : 
     133             : /***************************************************************************
     134             :  * When an edit action handler (or its helper) handled and canceled,
     135             :  * EditActionHandled should be returned.
     136             :  */
     137             : inline EditActionResult
     138           0 : EditActionCanceled(nsresult aRv = NS_OK)
     139             : {
     140           0 :   return EditActionResult(aRv, true, true);
     141             : }
     142             : 
     143             : /***************************************************************************
     144             :  * stack based helper class for batching a collection of transactions inside a
     145             :  * placeholder transaction.
     146             :  * XXX This is used by mozInlineSpellChecker.  Therefore, cannot use concrete
     147             :  *     editor class.
     148             :  */
     149             : class MOZ_RAII AutoPlaceHolderBatch
     150             : {
     151             : private:
     152             :   nsCOMPtr<nsIEditor> mEditor;
     153             :   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     154             : 
     155             : public:
     156           1 :   AutoPlaceHolderBatch(nsIEditor* aEditor,
     157             :                        nsIAtom* aAtom
     158             :                        MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     159           1 :     : mEditor(aEditor)
     160             :   {
     161           1 :     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     162           1 :     if (mEditor) {
     163           1 :       mEditor->BeginPlaceHolderTransaction(aAtom);
     164             :     }
     165           1 :   }
     166           1 :   ~AutoPlaceHolderBatch()
     167           1 :   {
     168           1 :     if (mEditor) {
     169           1 :       mEditor->EndPlaceHolderTransaction();
     170             :     }
     171           1 :   }
     172             : };
     173             : 
     174             : /***************************************************************************
     175             :  * stack based helper class for batching a collection of txns.
     176             :  * Note: I changed this to use placeholder batching so that we get
     177             :  * proper selection save/restore across undo/redo.
     178             :  */
     179             : class MOZ_RAII AutoEditBatch final : public AutoPlaceHolderBatch
     180             : {
     181             : private:
     182             :   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     183             : 
     184             : public:
     185           0 :   explicit AutoEditBatch(nsIEditor* aEditor
     186             :                          MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     187           0 :     : AutoPlaceHolderBatch(aEditor, nullptr)
     188             :   {
     189           0 :     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     190           0 :   }
     191           0 :   ~AutoEditBatch() {}
     192             : };
     193             : 
     194             : /***************************************************************************
     195             :  * stack based helper class for saving/restoring selection.  Note that this
     196             :  * assumes that the nodes involved are still around afterwards!
     197             :  */
     198             : class MOZ_RAII AutoSelectionRestorer final
     199             : {
     200             : private:
     201             :   // Ref-counted reference to the selection that we are supposed to restore.
     202             :   RefPtr<dom::Selection> mSelection;
     203             :   EditorBase* mEditorBase;  // Non-owning ref to EditorBase.
     204             :   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     205             : 
     206             : public:
     207             :   /**
     208             :    * Constructor responsible for remembering all state needed to restore
     209             :    * aSelection.
     210             :    */
     211             :   AutoSelectionRestorer(dom::Selection* aSelection,
     212             :                         EditorBase* aEditorBase
     213             :                         MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
     214             : 
     215             :   /**
     216             :    * Destructor restores mSelection to its former state
     217             :    */
     218             :   ~AutoSelectionRestorer();
     219             : 
     220             :   /**
     221             :    * Abort() cancels to restore the selection.
     222             :    */
     223             :   void Abort();
     224             : };
     225             : 
     226             : /***************************************************************************
     227             :  * stack based helper class for StartOperation()/EndOperation() sandwich
     228             :  */
     229             : class MOZ_RAII AutoRules final
     230             : {
     231             : public:
     232           8 :   AutoRules(EditorBase* aEditorBase, EditAction aAction,
     233             :             nsIEditor::EDirection aDirection
     234             :             MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     235           8 :     : mEditorBase(aEditorBase)
     236           8 :     , mDoNothing(false)
     237             :   {
     238           8 :     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     239             :     // mAction will already be set if this is nested call
     240           8 :     if (mEditorBase && !mEditorBase->mAction) {
     241           3 :       mEditorBase->StartOperation(aAction, aDirection);
     242             :     } else {
     243           5 :       mDoNothing = true; // nested calls will end up here
     244             :     }
     245           8 :   }
     246             : 
     247           8 :   ~AutoRules()
     248           8 :   {
     249           8 :     if (mEditorBase && !mDoNothing) {
     250           3 :       mEditorBase->EndOperation();
     251             :     }
     252           8 :   }
     253             : 
     254             : protected:
     255             :   EditorBase* mEditorBase;
     256             :   bool mDoNothing;
     257             :   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     258             : };
     259             : 
     260             : /***************************************************************************
     261             :  * stack based helper class for turning off active selection adjustment
     262             :  * by low level transactions
     263             :  */
     264             : class MOZ_RAII AutoTransactionsConserveSelection final
     265             : {
     266             : public:
     267           1 :   explicit AutoTransactionsConserveSelection(EditorBase* aEditorBase
     268             :                                              MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     269           1 :     : mEditorBase(aEditorBase)
     270           1 :     , mOldState(true)
     271             :   {
     272           1 :     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     273           1 :     if (mEditorBase) {
     274           1 :       mOldState = mEditorBase->GetShouldTxnSetSelection();
     275           1 :       mEditorBase->SetShouldTxnSetSelection(false);
     276             :     }
     277           1 :   }
     278             : 
     279           1 :   ~AutoTransactionsConserveSelection()
     280           1 :   {
     281           1 :     if (mEditorBase) {
     282           1 :       mEditorBase->SetShouldTxnSetSelection(mOldState);
     283             :     }
     284           1 :   }
     285             : 
     286             : protected:
     287             :   EditorBase* mEditorBase;
     288             :   bool mOldState;
     289             :   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     290             : };
     291             : 
     292             : /***************************************************************************
     293             :  * stack based helper class for batching reflow and paint requests.
     294             :  */
     295             : class MOZ_RAII AutoUpdateViewBatch final
     296             : {
     297             : public:
     298           0 :   explicit AutoUpdateViewBatch(EditorBase* aEditorBase
     299             :                                MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     300           0 :     : mEditorBase(aEditorBase)
     301             :   {
     302           0 :     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     303           0 :     NS_ASSERTION(mEditorBase, "null mEditorBase pointer!");
     304             : 
     305           0 :     if (mEditorBase) {
     306           0 :       mEditorBase->BeginUpdateViewBatch();
     307             :     }
     308           0 :   }
     309             : 
     310           0 :   ~AutoUpdateViewBatch()
     311           0 :   {
     312           0 :     if (mEditorBase) {
     313           0 :       mEditorBase->EndUpdateViewBatch();
     314             :     }
     315           0 :   }
     316             : 
     317             : protected:
     318             :   EditorBase* mEditorBase;
     319             :   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     320             : };
     321             : 
     322           0 : class MOZ_STACK_CLASS AutoRangeArray final
     323             : {
     324             : public:
     325           0 :   explicit AutoRangeArray(dom::Selection* aSelection)
     326           0 :   {
     327           0 :     if (!aSelection) {
     328           0 :       return;
     329             :     }
     330           0 :     uint32_t rangeCount = aSelection->RangeCount();
     331           0 :     for (uint32_t i = 0; i < rangeCount; i++) {
     332           0 :       mRanges.AppendElement(*aSelection->GetRangeAt(i));
     333             :     }
     334             :   }
     335             : 
     336             :   AutoTArray<mozilla::OwningNonNull<nsRange>, 8> mRanges;
     337             : };
     338             : 
     339             : /******************************************************************************
     340             :  * some helper classes for iterating the dom tree
     341             :  *****************************************************************************/
     342             : 
     343           0 : class BoolDomIterFunctor
     344             : {
     345             : public:
     346             :   virtual bool operator()(nsINode* aNode) const = 0;
     347             : };
     348             : 
     349             : class MOZ_RAII DOMIterator
     350             : {
     351             : public:
     352             :   explicit DOMIterator(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
     353             : 
     354             :   explicit DOMIterator(nsINode& aNode MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
     355             :   virtual ~DOMIterator();
     356             : 
     357             :   nsresult Init(nsRange& aRange);
     358             : 
     359             :   void AppendList(
     360             :          const BoolDomIterFunctor& functor,
     361             :          nsTArray<mozilla::OwningNonNull<nsINode>>& arrayOfNodes) const;
     362             : 
     363             : protected:
     364             :   nsCOMPtr<nsIContentIterator> mIter;
     365             :   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     366             : };
     367             : 
     368             : class MOZ_RAII DOMSubtreeIterator final : public DOMIterator
     369             : {
     370             : public:
     371             :   explicit DOMSubtreeIterator(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
     372             :   virtual ~DOMSubtreeIterator();
     373             : 
     374             :   nsresult Init(nsRange& aRange);
     375             : };
     376             : 
     377           0 : class TrivialFunctor final : public BoolDomIterFunctor
     378             : {
     379             : public:
     380             :   // Used to build list of all nodes iterator covers
     381           0 :   virtual bool operator()(nsINode* aNode) const
     382             :   {
     383           0 :     return true;
     384             :   }
     385             : };
     386             : 
     387             : /******************************************************************************
     388             :  * general dom point utility struct
     389             :  *****************************************************************************/
     390           0 : struct MOZ_STACK_CLASS EditorDOMPoint final
     391             : {
     392             :   nsCOMPtr<nsINode> node;
     393             :   int32_t offset;
     394             : 
     395           0 :   EditorDOMPoint()
     396           0 :     : node(nullptr)
     397           0 :     , offset(-1)
     398           0 :   {}
     399           0 :   EditorDOMPoint(nsINode* aNode, int32_t aOffset)
     400           0 :     : node(aNode)
     401           0 :     , offset(aOffset)
     402           0 :   {}
     403             :   EditorDOMPoint(nsIDOMNode* aNode, int32_t aOffset)
     404             :     : node(do_QueryInterface(aNode))
     405             :     , offset(aOffset)
     406             :   {}
     407             : 
     408           0 :   void SetPoint(nsINode* aNode, int32_t aOffset)
     409             :   {
     410           0 :     node = aNode;
     411           0 :     offset = aOffset;
     412           0 :   }
     413             :   void SetPoint(nsIDOMNode* aNode, int32_t aOffset)
     414             :   {
     415             :     node = do_QueryInterface(aNode);
     416             :     offset = aOffset;
     417             :   }
     418             : };
     419             : 
     420             : class EditorUtils final
     421             : {
     422             : public:
     423             :   static bool IsDescendantOf(nsINode* aNode, nsINode* aParent,
     424             :                              int32_t* aOffset = 0);
     425             :   static bool IsDescendantOf(nsIDOMNode* aNode, nsIDOMNode* aParent,
     426             :                              int32_t* aOffset = 0);
     427             :   static bool IsLeafNode(nsIDOMNode* aNode);
     428             : };
     429             : 
     430             : class EditorHookUtils final
     431             : {
     432             : public:
     433             :   static bool DoInsertionHook(nsIDOMDocument* aDoc, nsIDOMEvent* aEvent,
     434             :                               nsITransferable* aTrans);
     435             : 
     436             : private:
     437             :   static nsresult GetHookEnumeratorFromDocument(
     438             :                     nsIDOMDocument*aDoc,
     439             :                     nsISimpleEnumerator** aEnumerator);
     440             : };
     441             : 
     442             : } // namespace mozilla
     443             : 
     444             : #endif // #ifndef mozilla_EditorUtils_h

Generated by: LCOV version 1.13