Back to index

lightning-sunbird  0.9+nobinonly
nsEditorUtils.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 
00039 #ifndef nsEditorUtils_h__
00040 #define nsEditorUtils_h__
00041 
00042 
00043 #include "nsCOMPtr.h"
00044 #include "nsIDOMNode.h"
00045 #include "nsISelection.h"
00046 #include "nsIEditor.h"
00047 #include "nsIAtom.h"
00048 #include "nsVoidArray.h"
00049 #include "nsEditor.h"
00050 #include "nsIContentIterator.h"
00051 #include "nsCOMArray.h"
00052 
00053 class nsPlaintextEditor;
00054 
00055 /***************************************************************************
00056  * stack based helper class for batching a collection of txns inside a 
00057  * placeholder txn.
00058  */
00059 class nsAutoPlaceHolderBatch
00060 {
00061   private:
00062     nsCOMPtr<nsIEditor> mEd;
00063   public:
00064     nsAutoPlaceHolderBatch( nsIEditor *aEd, nsIAtom *atom) : mEd(do_QueryInterface(aEd)) 
00065                    { if (mEd) mEd->BeginPlaceHolderTransaction(atom); }
00066     ~nsAutoPlaceHolderBatch() { if (mEd) mEd->EndPlaceHolderTransaction(); }
00067 };
00068 
00069 /***************************************************************************
00070  * stack based helper class for batching a collection of txns.  
00071  * Note: I changed this to use placeholder batching so that we get
00072  * proper selection save/restore across undo/redo.
00073  */
00074 class nsAutoEditBatch : public nsAutoPlaceHolderBatch
00075 {
00076   public:
00077     nsAutoEditBatch( nsIEditor *aEd) : nsAutoPlaceHolderBatch(aEd,nsnull)  {}
00078     ~nsAutoEditBatch() {}
00079 };
00080 
00081 /***************************************************************************
00082  * stack based helper class for saving/restoring selection.  Note that this
00083  * assumes that the nodes involved are still around afterwards!
00084  */
00085 class nsAutoSelectionReset
00086 {
00087   private:
00089     nsCOMPtr<nsISelection> mSel;
00090     nsEditor *mEd;  // non-owning ref to nsEditor
00091 
00092   public:
00094     nsAutoSelectionReset(nsISelection *aSel, nsEditor *aEd);
00095     
00097     ~nsAutoSelectionReset();
00098 
00100     void Abort();
00101 };
00102 
00103 /***************************************************************************
00104  * stack based helper class for StartOperation()/EndOperation() sandwich
00105  */
00106 class nsAutoRules
00107 {
00108   public:
00109   
00110   nsAutoRules(nsEditor *ed, PRInt32 action, nsIEditor::EDirection aDirection) : 
00111          mEd(ed), mDoNothing(PR_FALSE)
00112   { 
00113     if (mEd && !mEd->mAction) // mAction will already be set if this is nested call
00114     {
00115       mEd->StartOperation(action, aDirection);
00116     }
00117     else mDoNothing = PR_TRUE; // nested calls will end up here
00118   }
00119   ~nsAutoRules() 
00120   {
00121     if (mEd && !mDoNothing) 
00122     {
00123       mEd->EndOperation();
00124     }
00125   }
00126   
00127   protected:
00128   nsEditor *mEd;
00129   PRBool mDoNothing;
00130 };
00131 
00132 
00133 /***************************************************************************
00134  * stack based helper class for turning off active selection adjustment
00135  * by low level transactions
00136  */
00137 class nsAutoTxnsConserveSelection
00138 {
00139   public:
00140   
00141   nsAutoTxnsConserveSelection(nsEditor *ed) : mEd(ed), mOldState(PR_TRUE)
00142   {
00143     if (mEd) 
00144     {
00145       mOldState = mEd->GetShouldTxnSetSelection();
00146       mEd->SetShouldTxnSetSelection(PR_FALSE);
00147     }
00148   }
00149   
00150   ~nsAutoTxnsConserveSelection() 
00151   {
00152     if (mEd) 
00153     {
00154       mEd->SetShouldTxnSetSelection(mOldState);
00155     }
00156   }
00157   
00158   protected:
00159   nsEditor *mEd;
00160   PRBool mOldState;
00161 };
00162 
00163 /***************************************************************************
00164  * stack based helper class for batching reflow and paint requests.
00165  */
00166 class nsAutoUpdateViewBatch
00167 {
00168   public:
00169   
00170   nsAutoUpdateViewBatch(nsEditor *ed) : mEd(ed)
00171   {
00172     NS_ASSERTION(mEd, "null mEd pointer!");
00173 
00174     if (mEd) 
00175       mEd->BeginUpdateViewBatch();
00176   }
00177   
00178   ~nsAutoUpdateViewBatch() 
00179   {
00180     if (mEd) 
00181       mEd->EndUpdateViewBatch();
00182   }
00183   
00184   protected:
00185   nsEditor *mEd;
00186 };
00187 
00188 /******************************************************************************
00189  * some helper classes for iterating the dom tree
00190  *****************************************************************************/
00191 
00192 class nsDomIterFunctor 
00193 {
00194   public:
00195     virtual void* operator()(nsIDOMNode* aNode)=0;
00196 };
00197 
00198 class nsBoolDomIterFunctor 
00199 {
00200   public:
00201     virtual PRBool operator()(nsIDOMNode* aNode)=0;
00202 };
00203 
00204 class nsDOMIterator
00205 {
00206   public:
00207     nsDOMIterator();
00208     virtual ~nsDOMIterator();
00209     
00210     nsresult Init(nsIDOMRange* aRange);
00211     nsresult Init(nsIDOMNode* aNode);
00212     void ForEach(nsDomIterFunctor& functor) const;
00213     nsresult AppendList(nsBoolDomIterFunctor& functor,
00214                         nsCOMArray<nsIDOMNode>& arrayOfNodes) const;
00215   protected:
00216     nsCOMPtr<nsIContentIterator> mIter;
00217 };
00218 
00219 class nsDOMSubtreeIterator : public nsDOMIterator
00220 {
00221   public:
00222     nsDOMSubtreeIterator();
00223     virtual ~nsDOMSubtreeIterator();
00224 
00225     nsresult Init(nsIDOMRange* aRange);
00226     nsresult Init(nsIDOMNode* aNode);
00227 };
00228 
00229 class nsTrivialFunctor : public nsBoolDomIterFunctor
00230 {
00231   public:
00232     virtual PRBool operator()(nsIDOMNode* aNode)  // used to build list of all nodes iterator covers
00233     {
00234       return PR_TRUE;
00235     }
00236 };
00237 
00238 
00239 /******************************************************************************
00240  * general dom point utility struct
00241  *****************************************************************************/
00242 struct DOMPoint
00243 {
00244   nsCOMPtr<nsIDOMNode> node;
00245   PRInt32 offset;
00246   
00247   DOMPoint() : node(0),offset(0) {}
00248   DOMPoint(nsIDOMNode *aNode, PRInt32 aOffset) : 
00249                  node(aNode),offset(aOffset) {}
00250   void SetPoint(nsIDOMNode *aNode, PRInt32 aOffset)
00251   {
00252     node = aNode; offset = aOffset;
00253   }
00254   void GetPoint(nsCOMPtr<nsIDOMNode> &aNode, PRInt32 &aOffset)
00255   {
00256     aNode = node; aOffset = offset;
00257   }
00258 };
00259 
00260 
00261 class nsEditorUtils
00262 {
00263   public:
00264     static PRBool IsDescendantOf(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 *aOffset = 0);
00265     static PRBool IsLeafNode(nsIDOMNode *aNode);
00266 };
00267 
00268 
00269 class nsIDragSession;
00270 class nsITransferable;
00271 class nsIDOMEvent;
00272 class nsISimpleEnumerator;
00273 
00274 class nsEditorHookUtils
00275 {
00276   public:
00277     static PRBool   DoAllowDragHook(nsIDOMDocument *aDoc, nsIDOMEvent *aEvent);
00278     static PRBool   DoDragHook(nsIDOMDocument *aDoc, nsIDOMEvent *aEvent,
00279                                     nsITransferable *aTrans);
00280     static PRBool   DoAllowDropHook(nsIDOMDocument *aDoc, nsIDOMEvent *aEvent,
00281                                     nsIDragSession *aSession);
00282     static PRBool   DoInsertionHook(nsIDOMDocument *aDoc, nsIDOMEvent *aEvent,
00283                                     nsITransferable *aTrans);
00284   private:
00285     static nsresult GetHookEnumeratorFromDocument(nsIDOMDocument *aDoc,
00286                                                   nsISimpleEnumerator **aEnumerator);
00287 };
00288 
00289 #endif // nsEditorUtils_h__