Back to index

lightning-sunbird  0.9+nobinonly
nsHTMLEditRules.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  *   Daniel Glazman <glazman@netscape.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #ifndef nsHTMLEditRules_h__
00040 #define nsHTMLEditRules_h__
00041 
00042 #include "nsTextEditRules.h"
00043 #include "nsIHTMLEditRules.h"
00044 #include "nsIEditActionListener.h"
00045 #include "nsCOMArray.h"
00046 #include "nsCOMPtr.h"
00047 #include "nsString.h"
00048 #include "nsEditorUtils.h"
00049 #include "TypeInState.h"
00050 #include "nsReadableUtils.h"
00051 
00052 class nsVoidArray;
00053 class nsIDOMElement;
00054 class nsIEditor;
00055 class nsHTMLEditor;
00056 
00057 struct StyleCache : public PropItem
00058 {
00059   PRBool mPresent;
00060   
00061   StyleCache() : PropItem(nsnull, EmptyString(), EmptyString()), mPresent(PR_FALSE){};
00062   StyleCache(nsIAtom *aTag, const nsAString &aAttr, const nsAString &aValue) : 
00063              PropItem(aTag, aAttr, aValue), mPresent(PR_FALSE) {};
00064   ~StyleCache() {};
00065 };
00066 
00067 
00068 #define SIZE_STYLE_TABLE 19
00069 
00070 class nsHTMLEditRules : public nsIHTMLEditRules, public nsTextEditRules, public nsIEditActionListener
00071 {
00072 public:
00073 
00074   NS_DECL_ISUPPORTS_INHERITED
00075   
00076             nsHTMLEditRules();
00077   virtual   ~nsHTMLEditRules();
00078 
00079 
00080   // nsIEditRules methods
00081   NS_IMETHOD Init(nsPlaintextEditor *aEditor, PRUint32 aFlags);
00082   NS_IMETHOD BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection);
00083   NS_IMETHOD AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection);
00084   NS_IMETHOD WillDoAction(nsISelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled);
00085   NS_IMETHOD DidDoAction(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
00086 
00087   // nsIHTMLEditRules methods
00088   
00089   NS_IMETHOD GetListState(PRBool *aMixed, PRBool *aOL, PRBool *aUL, PRBool *aDL);
00090   NS_IMETHOD GetListItemState(PRBool *aMixed, PRBool *aLI, PRBool *aDT, PRBool *aDD);
00091   NS_IMETHOD GetIndentState(PRBool *aCanIndent, PRBool *aCanOutdent);
00092   NS_IMETHOD GetAlignment(PRBool *aMixed, nsIHTMLEditor::EAlignment *aAlign);
00093   NS_IMETHOD GetParagraphState(PRBool *aMixed, nsAString &outFormat);
00094   NS_IMETHOD MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode);
00095 
00096   // nsIEditActionListener methods
00097   
00098   NS_IMETHOD WillCreateNode(const nsAString& aTag, nsIDOMNode *aParent, PRInt32 aPosition);
00099   NS_IMETHOD DidCreateNode(const nsAString& aTag, nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition, nsresult aResult);
00100   NS_IMETHOD WillInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition);
00101   NS_IMETHOD DidInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition, nsresult aResult);
00102   NS_IMETHOD WillDeleteNode(nsIDOMNode *aChild);
00103   NS_IMETHOD DidDeleteNode(nsIDOMNode *aChild, nsresult aResult);
00104   NS_IMETHOD WillSplitNode(nsIDOMNode *aExistingRightNode, PRInt32 aOffset);
00105   NS_IMETHOD DidSplitNode(nsIDOMNode *aExistingRightNode, PRInt32 aOffset, nsIDOMNode *aNewLeftNode, nsresult aResult);
00106   NS_IMETHOD WillJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent);
00107   NS_IMETHOD DidJoinNodes(nsIDOMNode  *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent, nsresult aResult);
00108   NS_IMETHOD WillInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsAString &aString);
00109   NS_IMETHOD DidInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsAString &aString, nsresult aResult);
00110   NS_IMETHOD WillDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength);
00111   NS_IMETHOD DidDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength, nsresult aResult);
00112   NS_IMETHOD WillDeleteRange(nsIDOMRange *aRange);
00113   NS_IMETHOD DidDeleteRange(nsIDOMRange *aRange);
00114   NS_IMETHOD WillDeleteSelection(nsISelection *aSelection);
00115   NS_IMETHOD DidDeleteSelection(nsISelection *aSelection);
00116 
00117 protected:
00118 
00119   enum RulesEndpoint
00120   {
00121     kStart,
00122     kEnd
00123   };
00124 
00125   enum BRLocation
00126   {
00127     kBeforeBlock,
00128     kBlockEnd
00129   };
00130 
00131   // nsHTMLEditRules implementation methods
00132   nsresult WillInsert(nsISelection *aSelection, PRBool *aCancel);
00133 #ifdef XXX_DEAD_CODE
00134   nsresult DidInsert(nsISelection *aSelection, nsresult aResult);
00135 #endif
00136   nsresult WillInsertText(  PRInt32          aAction,
00137                             nsISelection *aSelection, 
00138                             PRBool          *aCancel,
00139                             PRBool          *aHandled,
00140                             const nsAString *inString,
00141                             nsAString       *outString,
00142                             PRInt32          aMaxLength);
00143   nsresult WillLoadHTML(nsISelection *aSelection, PRBool *aCancel);
00144   nsresult WillInsertBreak(nsISelection *aSelection, PRBool *aCancel, PRBool *aHandled);
00145   nsresult StandardBreakImpl(nsIDOMNode *aNode, PRInt32 aOffset, nsISelection *aSelection);
00146   nsresult DidInsertBreak(nsISelection *aSelection, nsresult aResult);
00147   nsresult SplitMailCites(nsISelection *aSelection, PRBool aPlaintext, PRBool *aHandled);
00148   nsresult WillDeleteSelection(nsISelection *aSelection, nsIEditor::EDirection aAction, 
00149                                PRBool *aCancel, PRBool *aHandled);
00150   nsresult DidDeleteSelection(nsISelection *aSelection, 
00151                               nsIEditor::EDirection aDir, 
00152                               nsresult aResult);
00153   nsresult InsertBRIfNeeded(nsISelection *aSelection);
00154   nsresult GetGoodSelPointForNode(nsIDOMNode *aNode, nsIEditor::EDirection aAction, 
00155                                   nsCOMPtr<nsIDOMNode> *outSelNode, PRInt32 *outSelOffset);
00156   nsresult JoinBlocks(nsCOMPtr<nsIDOMNode> *aLeftBlock, nsCOMPtr<nsIDOMNode> *aRightBlock, PRBool *aCanceled);
00157   nsresult MoveBlock(nsIDOMNode *aLeft, nsIDOMNode *aRight, PRInt32 aLeftOffset, PRInt32 aRightOffset);
00158   nsresult MoveNodeSmart(nsIDOMNode *aSource, nsIDOMNode *aDest, PRInt32 *aOffset);
00159   nsresult MoveContents(nsIDOMNode *aSource, nsIDOMNode *aDest, PRInt32 *aOffset);
00160   nsresult DeleteNonTableElements(nsIDOMNode *aNode);
00161   nsresult WillMakeList(nsISelection *aSelection, const nsAString *aListType, PRBool aEntireList, const nsAString *aBulletType, PRBool *aCancel, PRBool *aHandled, const nsAString *aItemType=nsnull);
00162   nsresult WillRemoveList(nsISelection *aSelection, PRBool aOrderd, PRBool *aCancel, PRBool *aHandled);
00163   nsresult WillIndent(nsISelection *aSelection, PRBool *aCancel, PRBool *aHandled);
00164   nsresult WillCSSIndent(nsISelection *aSelection, PRBool *aCancel, PRBool *aHandled);
00165   nsresult WillHTMLIndent(nsISelection *aSelection, PRBool *aCancel, PRBool *aHandled);
00166   nsresult WillOutdent(nsISelection *aSelection, PRBool *aCancel, PRBool *aHandled);
00167   nsresult WillAlign(nsISelection *aSelection, const nsAString *alignType, PRBool *aCancel, PRBool *aHandled);
00168   nsresult WillAbsolutePosition(nsISelection *aSelection, PRBool *aCancel, PRBool * aHandled);
00169   nsresult WillRemoveAbsolutePosition(nsISelection *aSelection, PRBool *aCancel, PRBool * aHandled);
00170   nsresult WillRelativeChangeZIndex(nsISelection *aSelection, PRInt32 aChange, PRBool *aCancel, PRBool * aHandled);
00171   nsresult WillMakeDefListItem(nsISelection *aSelection, const nsAString *aBlockType, PRBool aEntireList, PRBool *aCancel, PRBool *aHandled);
00172   nsresult WillMakeBasicBlock(nsISelection *aSelection, const nsAString *aBlockType, PRBool *aCancel, PRBool *aHandled);
00173   nsresult DidMakeBasicBlock(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
00174   nsresult DidAbsolutePosition();
00175   nsresult AlignInnerBlocks(nsIDOMNode *aNode, const nsAString *alignType);
00176   nsresult AlignBlockContents(nsIDOMNode *aNode, const nsAString *alignType);
00177   nsresult AppendInnerFormatNodes(nsCOMArray<nsIDOMNode>& aArray,
00178                                   nsIDOMNode *aNode);
00179   nsresult GetFormatString(nsIDOMNode *aNode, nsAString &outFormat);
00180   nsresult GetInnerContent(nsIDOMNode *aNode, nsCOMArray<nsIDOMNode>& outArrayOfNodes, PRInt32 *aIndex, PRBool aList = PR_TRUE, PRBool aTble = PR_TRUE);
00181   nsCOMPtr<nsIDOMNode> IsInListItem(nsIDOMNode *aNode);
00182   nsresult ReturnInHeader(nsISelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset);
00183   nsresult ReturnInParagraph(nsISelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset, PRBool *aCancel, PRBool *aHandled);
00184   nsresult SplitParagraph(nsIDOMNode *aPara,
00185                           nsIDOMNode *aBRNode, 
00186                           nsISelection *aSelection,
00187                           nsCOMPtr<nsIDOMNode> *aSelNode, 
00188                           PRInt32 *aOffset);
00189   nsresult ReturnInListItem(nsISelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset);
00190   nsresult AfterEditInner(PRInt32 action, nsIEditor::EDirection aDirection);
00191   nsresult RemovePartOfBlock(nsIDOMNode *aBlock, 
00192                              nsIDOMNode *aStartChild, 
00193                              nsIDOMNode *aEndChild,
00194                              nsCOMPtr<nsIDOMNode> *aLeftNode = 0,
00195                              nsCOMPtr<nsIDOMNode> *aRightNode = 0);
00196   nsresult SplitBlock(nsIDOMNode *aBlock, 
00197                       nsIDOMNode *aStartChild, 
00198                       nsIDOMNode *aEndChild,
00199                       nsCOMPtr<nsIDOMNode> *aLeftNode = 0,
00200                       nsCOMPtr<nsIDOMNode> *aRightNode = 0,
00201                       nsCOMPtr<nsIDOMNode> *aMiddleNode = 0);
00202   nsresult OutdentPartOfBlock(nsIDOMNode *aBlock, 
00203                               nsIDOMNode *aStartChild, 
00204                               nsIDOMNode *aEndChild,
00205                               PRBool aIsBlockIndentedWithCSS,
00206                               nsCOMPtr<nsIDOMNode> *aLeftNode = 0,
00207                               nsCOMPtr<nsIDOMNode> *aRightNode = 0);
00208   nsresult ConvertListType(nsIDOMNode *aList, nsCOMPtr<nsIDOMNode> *outList, const nsAString& aListType, const nsAString& aItemType);
00209   nsresult CreateStyleForInsertText(nsISelection *aSelection, nsIDOMDocument *aDoc);
00210   nsresult IsEmptyBlock(nsIDOMNode *aNode, 
00211                         PRBool *outIsEmptyBlock, 
00212                         PRBool aMozBRDoesntCount = PR_FALSE,
00213                         PRBool aListItemsNotEmpty = PR_FALSE);
00214   nsresult CheckForEmptyBlock(nsIDOMNode *aStartNode, 
00215                               nsIDOMNode *aBodyNode,
00216                               nsISelection *aSelection,
00217                               PRBool *aHandled);
00218   nsresult CheckForInvisibleBR(nsIDOMNode *aBlock, nsHTMLEditRules::BRLocation aWhere, 
00219                                nsCOMPtr<nsIDOMNode> *outBRNode, PRInt32 aOffset=0);
00220   PRBool ExpandSelectionForDeletion(nsISelection *aSelection);
00221   PRBool IsFirstNode(nsIDOMNode *aNode);
00222   PRBool IsLastNode(nsIDOMNode *aNode);
00223 #ifdef XXX_DEAD_CODE
00224   PRBool AtStartOfBlock(nsIDOMNode *aNode, PRInt32 aOffset, nsIDOMNode *aBlock);
00225   PRBool AtEndOfBlock(nsIDOMNode *aNode, PRInt32 aOffset, nsIDOMNode *aBlock);
00226 #endif
00227   nsresult NormalizeSelection(nsISelection *inSelection);
00228   nsresult GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode *aNode, PRInt32 aOffset, 
00229                             PRInt32 actionID, nsCOMPtr<nsIDOMNode> *outNode, PRInt32 *outOffset);
00230   nsresult GetPromotedRanges(nsISelection *inSelection, 
00231                              nsCOMArray<nsIDOMRange> &outArrayOfRanges, 
00232                              PRInt32 inOperationType);
00233   nsresult PromoteRange(nsIDOMRange *inRange, PRInt32 inOperationType);
00234   nsresult GetNodesForOperation(nsCOMArray<nsIDOMRange>& inArrayOfRanges, 
00235                                 nsCOMArray<nsIDOMNode>& outArrayOfNodes, 
00236                                 PRInt32 inOperationType,
00237                                 PRBool aDontTouchContent=PR_FALSE);
00238   nsresult GetChildNodesForOperation(nsIDOMNode *inNode, 
00239                                      nsCOMArray<nsIDOMNode>& outArrayOfNodes);
00240   nsresult GetNodesFromPoint(DOMPoint point,
00241                              PRInt32 operation,
00242                              nsCOMArray<nsIDOMNode>& arrayOfNodes,
00243                              PRBool dontTouchContent);
00244   nsresult GetNodesFromSelection(nsISelection *selection,
00245                                  PRInt32 operation,
00246                                  nsCOMArray<nsIDOMNode>& arrayOfNodes,
00247                                  PRBool aDontTouchContent=PR_FALSE);
00248   nsresult GetListActionNodes(nsCOMArray<nsIDOMNode> &outArrayOfNodes, PRBool aEntireList, PRBool aDontTouchContent=PR_FALSE);
00249   nsresult GetDefinitionListItemTypes(nsIDOMNode *aNode, PRBool &aDT, PRBool &aDD);
00250   nsresult GetParagraphFormatNodes(nsCOMArray<nsIDOMNode>& outArrayOfNodes, PRBool aDontTouchContent=PR_FALSE);
00251   nsresult LookInsideDivBQandList(nsCOMArray<nsIDOMNode>& aNodeArray);
00252   nsresult BustUpInlinesAtRangeEndpoints(nsRangeStore &inRange);
00253   nsresult BustUpInlinesAtBRs(nsIDOMNode *inNode, 
00254                               nsCOMArray<nsIDOMNode>& outArrayOfNodes);
00255   nsCOMPtr<nsIDOMNode> GetHighestInlineParent(nsIDOMNode* aNode);
00256   nsresult MakeTransitionList(nsCOMArray<nsIDOMNode>& inArrayOfNodes, 
00257                               nsVoidArray &inTransitionArray);
00258   nsresult RemoveBlockStyle(nsCOMArray<nsIDOMNode>& arrayOfNodes);
00259   nsresult ApplyBlockStyle(nsCOMArray<nsIDOMNode>& arrayOfNodes, const nsAString *aBlockTag);
00260   nsresult MakeBlockquote(nsCOMArray<nsIDOMNode>& arrayOfNodes);
00261   nsresult SplitAsNeeded(const nsAString *aTag, nsCOMPtr<nsIDOMNode> *inOutParent, PRInt32 *inOutOffset);
00262   nsresult AddTerminatingBR(nsIDOMNode *aBlock);
00263   nsresult JoinNodesSmart( nsIDOMNode *aNodeLeft, 
00264                            nsIDOMNode *aNodeRight, 
00265                            nsCOMPtr<nsIDOMNode> *aOutMergeParent, 
00266                            PRInt32 *aOutMergeOffset);
00267   nsresult GetTopEnclosingMailCite(nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutCiteNode, PRBool aPlaintext);
00268   nsresult PopListItem(nsIDOMNode *aListItem, PRBool *aOutOfList);
00269   nsresult RemoveListStructure(nsIDOMNode *aList);
00270   nsresult CacheInlineStyles(nsIDOMNode *aNode);
00271   nsresult ReapplyCachedStyles(); 
00272   nsresult ClearCachedStyles();
00273   nsresult AdjustSpecialBreaks(PRBool aSafeToAskFrames = PR_FALSE);
00274   nsresult AdjustWhitespace(nsISelection *aSelection);
00275   nsresult PinSelectionToNewBlock(nsISelection *aSelection);
00276   nsresult CheckInterlinePosition(nsISelection *aSelection);
00277   nsresult AdjustSelection(nsISelection *aSelection, nsIEditor::EDirection aAction);
00278   nsresult FindNearSelectableNode(nsIDOMNode *aSelNode, 
00279                                   PRInt32 aSelOffset, 
00280                                   nsIEditor::EDirection &aDirection,
00281                                   nsCOMPtr<nsIDOMNode> *outSelectableNode);
00282   nsresult InDifferentTableElements(nsIDOMNode *aNode1, nsIDOMNode *aNode2, PRBool *aResult);
00283   nsresult RemoveEmptyNodes();
00284   nsresult SelectionEndpointInNode(nsIDOMNode *aNode, PRBool *aResult);
00285   nsresult UpdateDocChangeRange(nsIDOMRange *aRange);
00286   nsresult ConfirmSelectionInBody();
00287   nsresult InsertMozBRIfNeeded(nsIDOMNode *aNode);
00288   PRBool   IsEmptyInline(nsIDOMNode *aNode);
00289   PRBool   ListIsEmptyLine(nsCOMArray<nsIDOMNode> &arrayOfNodes);
00290   nsresult RemoveAlignment(nsIDOMNode * aNode, const nsAString & aAlignType, PRBool aChildrenOnly);
00291   nsresult MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode, PRBool aStarts);
00292   nsresult AlignBlock(nsIDOMElement * aElement, const nsAString * aAlignType, PRBool aContentsOnly);
00293   nsresult RelativeChangeIndentationOfElementNode(nsIDOMNode *aNode, PRInt8 aRelativeChange);
00294 
00295 // data members
00296 protected:
00297   nsHTMLEditor           *mHTMLEditor;
00298   nsCOMPtr<nsIDOMRange>   mDocChangeRange;
00299   PRPackedBool            mListenerEnabled;
00300   PRPackedBool            mReturnInEmptyLIKillsList;
00301   PRPackedBool            mDidDeleteSelection;
00302   PRPackedBool            mDidRangedDelete;
00303   nsCOMPtr<nsIDOMRange>   mUtilRange;
00304   PRUint32                mJoinOffset;  // need to remember an int across willJoin/didJoin...
00305   nsCOMPtr<nsIDOMNode>    mNewBlock;
00306   nsRangeStore            mRangeItem;
00307   StyleCache              mCachedStyles[SIZE_STYLE_TABLE];
00308 };
00309 
00310 nsresult NS_NewHTMLEditRules(nsIEditRules** aInstancePtrResult);
00311 
00312 #endif //nsHTMLEditRules_h__
00313