1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/editor/libeditor/html/nsHTMLEditRules.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,350 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef nsHTMLEditRules_h__ 1.10 +#define nsHTMLEditRules_h__ 1.11 + 1.12 +#include "TypeInState.h" 1.13 +#include "nsAutoPtr.h" 1.14 +#include "nsCOMPtr.h" 1.15 +#include "nsEditor.h" 1.16 +#include "nsIEditActionListener.h" 1.17 +#include "nsIEditor.h" 1.18 +#include "nsIHTMLEditor.h" 1.19 +#include "nsISupportsImpl.h" 1.20 +#include "nsSelectionState.h" 1.21 +#include "nsTArray.h" 1.22 +#include "nsTextEditRules.h" 1.23 +#include "nscore.h" 1.24 + 1.25 +class nsHTMLEditor; 1.26 +class nsIAtom; 1.27 +class nsIDOMCharacterData; 1.28 +class nsIDOMDocument; 1.29 +class nsIDOMElement; 1.30 +class nsIDOMNode; 1.31 +class nsIDOMRange; 1.32 +class nsIEditor; 1.33 +class nsINode; 1.34 +class nsISelection; 1.35 +class nsPlaintextEditor; 1.36 +class nsRange; 1.37 +class nsRulesInfo; 1.38 +namespace mozilla { 1.39 +namespace dom { 1.40 +class Element; 1.41 +class Selection; 1.42 +} // namespace dom 1.43 +} // namespace mozilla 1.44 +struct DOMPoint; 1.45 +template <class E> class nsCOMArray; 1.46 + 1.47 +struct StyleCache : public PropItem 1.48 +{ 1.49 + bool mPresent; 1.50 + 1.51 + StyleCache() : PropItem(), mPresent(false) { 1.52 + MOZ_COUNT_CTOR(StyleCache); 1.53 + } 1.54 + 1.55 + StyleCache(nsIAtom *aTag, const nsAString &aAttr, const nsAString &aValue) : 1.56 + PropItem(aTag, aAttr, aValue), mPresent(false) { 1.57 + MOZ_COUNT_CTOR(StyleCache); 1.58 + } 1.59 + 1.60 + ~StyleCache() { 1.61 + MOZ_COUNT_DTOR(StyleCache); 1.62 + } 1.63 +}; 1.64 + 1.65 + 1.66 +#define SIZE_STYLE_TABLE 19 1.67 + 1.68 +class nsHTMLEditRules : public nsTextEditRules, public nsIEditActionListener 1.69 +{ 1.70 +public: 1.71 + 1.72 + NS_DECL_ISUPPORTS_INHERITED 1.73 + 1.74 + nsHTMLEditRules(); 1.75 + virtual ~nsHTMLEditRules(); 1.76 + 1.77 + 1.78 + // nsIEditRules methods 1.79 + NS_IMETHOD Init(nsPlaintextEditor *aEditor); 1.80 + NS_IMETHOD DetachEditor(); 1.81 + NS_IMETHOD BeforeEdit(EditAction action, 1.82 + nsIEditor::EDirection aDirection); 1.83 + NS_IMETHOD AfterEdit(EditAction action, 1.84 + nsIEditor::EDirection aDirection); 1.85 + NS_IMETHOD WillDoAction(mozilla::dom::Selection* aSelection, nsRulesInfo* aInfo, 1.86 + bool* aCancel, bool* aHandled); 1.87 + NS_IMETHOD DidDoAction(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult); 1.88 + NS_IMETHOD DocumentModified(); 1.89 + 1.90 + nsresult GetListState(bool *aMixed, bool *aOL, bool *aUL, bool *aDL); 1.91 + nsresult GetListItemState(bool *aMixed, bool *aLI, bool *aDT, bool *aDD); 1.92 + nsresult GetIndentState(bool *aCanIndent, bool *aCanOutdent); 1.93 + nsresult GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign); 1.94 + nsresult GetParagraphState(bool *aMixed, nsAString &outFormat); 1.95 + nsresult MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode); 1.96 + 1.97 + // nsIEditActionListener methods 1.98 + 1.99 + NS_IMETHOD WillCreateNode(const nsAString& aTag, nsIDOMNode *aParent, int32_t aPosition); 1.100 + NS_IMETHOD DidCreateNode(const nsAString& aTag, nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t aPosition, nsresult aResult); 1.101 + NS_IMETHOD WillInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t aPosition); 1.102 + NS_IMETHOD DidInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t aPosition, nsresult aResult); 1.103 + NS_IMETHOD WillDeleteNode(nsIDOMNode *aChild); 1.104 + NS_IMETHOD DidDeleteNode(nsIDOMNode *aChild, nsresult aResult); 1.105 + NS_IMETHOD WillSplitNode(nsIDOMNode *aExistingRightNode, int32_t aOffset); 1.106 + NS_IMETHOD DidSplitNode(nsIDOMNode *aExistingRightNode, int32_t aOffset, nsIDOMNode *aNewLeftNode, nsresult aResult); 1.107 + NS_IMETHOD WillJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent); 1.108 + NS_IMETHOD DidJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent, nsresult aResult); 1.109 + NS_IMETHOD WillInsertText(nsIDOMCharacterData *aTextNode, int32_t aOffset, const nsAString &aString); 1.110 + NS_IMETHOD DidInsertText(nsIDOMCharacterData *aTextNode, int32_t aOffset, const nsAString &aString, nsresult aResult); 1.111 + NS_IMETHOD WillDeleteText(nsIDOMCharacterData *aTextNode, int32_t aOffset, int32_t aLength); 1.112 + NS_IMETHOD DidDeleteText(nsIDOMCharacterData *aTextNode, int32_t aOffset, int32_t aLength, nsresult aResult); 1.113 + NS_IMETHOD WillDeleteSelection(nsISelection *aSelection); 1.114 + NS_IMETHOD DidDeleteSelection(nsISelection *aSelection); 1.115 + 1.116 +protected: 1.117 + 1.118 + enum RulesEndpoint 1.119 + { 1.120 + kStart, 1.121 + kEnd 1.122 + }; 1.123 + 1.124 + enum BRLocation 1.125 + { 1.126 + kBeforeBlock, 1.127 + kBlockEnd 1.128 + }; 1.129 + 1.130 + void InitFields(); 1.131 + 1.132 + // nsHTMLEditRules implementation methods 1.133 + nsresult WillInsert(nsISelection *aSelection, bool *aCancel); 1.134 + nsresult WillInsertText( EditAction aAction, 1.135 + mozilla::dom::Selection* aSelection, 1.136 + bool *aCancel, 1.137 + bool *aHandled, 1.138 + const nsAString *inString, 1.139 + nsAString *outString, 1.140 + int32_t aMaxLength); 1.141 + nsresult WillLoadHTML(nsISelection *aSelection, bool *aCancel); 1.142 + nsresult WillInsertBreak(mozilla::dom::Selection* aSelection, 1.143 + bool* aCancel, bool* aHandled); 1.144 + nsresult StandardBreakImpl(nsIDOMNode *aNode, int32_t aOffset, nsISelection *aSelection); 1.145 + nsresult DidInsertBreak(nsISelection *aSelection, nsresult aResult); 1.146 + nsresult SplitMailCites(nsISelection *aSelection, bool aPlaintext, bool *aHandled); 1.147 + nsresult WillDeleteSelection(mozilla::dom::Selection* aSelection, 1.148 + nsIEditor::EDirection aAction, 1.149 + nsIEditor::EStripWrappers aStripWrappers, 1.150 + bool* aCancel, bool* aHandled); 1.151 + nsresult DidDeleteSelection(nsISelection *aSelection, 1.152 + nsIEditor::EDirection aDir, 1.153 + nsresult aResult); 1.154 + nsresult InsertBRIfNeeded(nsISelection *aSelection); 1.155 + nsresult GetGoodSelPointForNode(nsIDOMNode *aNode, nsIEditor::EDirection aAction, 1.156 + nsCOMPtr<nsIDOMNode> *outSelNode, int32_t *outSelOffset); 1.157 + nsresult JoinBlocks(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, bool *aCanceled); 1.158 + nsresult MoveBlock(nsIDOMNode *aLeft, nsIDOMNode *aRight, int32_t aLeftOffset, int32_t aRightOffset); 1.159 + nsresult MoveNodeSmart(nsIDOMNode *aSource, nsIDOMNode *aDest, int32_t *aOffset); 1.160 + nsresult MoveContents(nsIDOMNode *aSource, nsIDOMNode *aDest, int32_t *aOffset); 1.161 + nsresult DeleteNonTableElements(nsINode* aNode); 1.162 + nsresult WillMakeList(mozilla::dom::Selection* aSelection, 1.163 + const nsAString* aListType, 1.164 + bool aEntireList, 1.165 + const nsAString* aBulletType, 1.166 + bool* aCancel, bool* aHandled, 1.167 + const nsAString* aItemType = nullptr); 1.168 + nsresult WillRemoveList(mozilla::dom::Selection* aSelection, 1.169 + bool aOrdered, bool* aCancel, bool* aHandled); 1.170 + nsresult WillIndent(mozilla::dom::Selection* aSelection, 1.171 + bool* aCancel, bool* aHandled); 1.172 + nsresult WillCSSIndent(mozilla::dom::Selection* aSelection, 1.173 + bool* aCancel, bool* aHandled); 1.174 + nsresult WillHTMLIndent(mozilla::dom::Selection* aSelection, 1.175 + bool* aCancel, bool* aHandled); 1.176 + nsresult WillOutdent(mozilla::dom::Selection* aSelection, 1.177 + bool* aCancel, bool* aHandled); 1.178 + nsresult WillAlign(mozilla::dom::Selection* aSelection, 1.179 + const nsAString* alignType, 1.180 + bool* aCancel, bool* aHandled); 1.181 + nsresult WillAbsolutePosition(mozilla::dom::Selection* aSelection, 1.182 + bool* aCancel, bool* aHandled); 1.183 + nsresult WillRemoveAbsolutePosition(mozilla::dom::Selection* aSelection, 1.184 + bool* aCancel, bool* aHandled); 1.185 + nsresult WillRelativeChangeZIndex(mozilla::dom::Selection* aSelection, 1.186 + int32_t aChange, 1.187 + bool* aCancel, bool* aHandled); 1.188 + nsresult WillMakeDefListItem(mozilla::dom::Selection* aSelection, 1.189 + const nsAString* aBlockType, bool aEntireList, 1.190 + bool* aCancel, bool* aHandled); 1.191 + nsresult WillMakeBasicBlock(mozilla::dom::Selection* aSelection, 1.192 + const nsAString* aBlockType, 1.193 + bool* aCancel, bool* aHandled); 1.194 + nsresult DidMakeBasicBlock(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult); 1.195 + nsresult DidAbsolutePosition(); 1.196 + nsresult AlignInnerBlocks(nsIDOMNode *aNode, const nsAString *alignType); 1.197 + nsresult AlignBlockContents(nsIDOMNode *aNode, const nsAString *alignType); 1.198 + nsresult AppendInnerFormatNodes(nsCOMArray<nsIDOMNode>& aArray, 1.199 + nsINode* aNode); 1.200 + nsresult AppendInnerFormatNodes(nsCOMArray<nsIDOMNode>& aArray, 1.201 + nsIDOMNode *aNode); 1.202 + nsresult GetFormatString(nsIDOMNode *aNode, nsAString &outFormat); 1.203 + nsresult GetInnerContent(nsIDOMNode *aNode, nsCOMArray<nsIDOMNode>& outArrayOfNodes, int32_t *aIndex, bool aList = true, bool aTble = true); 1.204 + already_AddRefed<nsIDOMNode> IsInListItem(nsIDOMNode* aNode); 1.205 + nsINode* IsInListItem(nsINode* aNode); 1.206 + nsresult ReturnInHeader(nsISelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, int32_t aOffset); 1.207 + nsresult ReturnInParagraph(nsISelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, int32_t aOffset, bool *aCancel, bool *aHandled); 1.208 + nsresult SplitParagraph(nsIDOMNode *aPara, 1.209 + nsIDOMNode *aBRNode, 1.210 + nsISelection *aSelection, 1.211 + nsCOMPtr<nsIDOMNode> *aSelNode, 1.212 + int32_t *aOffset); 1.213 + nsresult ReturnInListItem(nsISelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, int32_t aOffset); 1.214 + nsresult AfterEditInner(EditAction action, 1.215 + nsIEditor::EDirection aDirection); 1.216 + nsresult RemovePartOfBlock(nsIDOMNode *aBlock, 1.217 + nsIDOMNode *aStartChild, 1.218 + nsIDOMNode *aEndChild, 1.219 + nsCOMPtr<nsIDOMNode> *aLeftNode = 0, 1.220 + nsCOMPtr<nsIDOMNode> *aRightNode = 0); 1.221 + nsresult SplitBlock(nsIDOMNode *aBlock, 1.222 + nsIDOMNode *aStartChild, 1.223 + nsIDOMNode *aEndChild, 1.224 + nsCOMPtr<nsIDOMNode> *aLeftNode = 0, 1.225 + nsCOMPtr<nsIDOMNode> *aRightNode = 0, 1.226 + nsCOMPtr<nsIDOMNode> *aMiddleNode = 0); 1.227 + nsresult OutdentPartOfBlock(nsIDOMNode *aBlock, 1.228 + nsIDOMNode *aStartChild, 1.229 + nsIDOMNode *aEndChild, 1.230 + bool aIsBlockIndentedWithCSS, 1.231 + nsCOMPtr<nsIDOMNode> *aLeftNode = 0, 1.232 + nsCOMPtr<nsIDOMNode> *aRightNode = 0); 1.233 + 1.234 + nsresult ConvertListType(nsIDOMNode* aList, 1.235 + nsCOMPtr<nsIDOMNode>* outList, 1.236 + nsIAtom* aListType, 1.237 + nsIAtom* aItemType); 1.238 + nsresult ConvertListType(nsINode* aList, 1.239 + mozilla::dom::Element** aOutList, 1.240 + nsIAtom* aListType, 1.241 + nsIAtom* aItemType); 1.242 + 1.243 + nsresult CreateStyleForInsertText(nsISelection *aSelection, nsIDOMDocument *aDoc); 1.244 + nsresult IsEmptyBlock(nsIDOMNode *aNode, 1.245 + bool *outIsEmptyBlock, 1.246 + bool aMozBRDoesntCount = false, 1.247 + bool aListItemsNotEmpty = false); 1.248 + nsresult CheckForEmptyBlock(nsIDOMNode *aStartNode, 1.249 + nsIDOMNode *aBodyNode, 1.250 + nsISelection *aSelection, 1.251 + bool *aHandled); 1.252 + nsresult CheckForInvisibleBR(nsIDOMNode *aBlock, nsHTMLEditRules::BRLocation aWhere, 1.253 + nsCOMPtr<nsIDOMNode> *outBRNode, int32_t aOffset=0); 1.254 + nsresult ExpandSelectionForDeletion(nsISelection *aSelection); 1.255 + bool IsFirstNode(nsIDOMNode *aNode); 1.256 + bool IsLastNode(nsIDOMNode *aNode); 1.257 + nsresult NormalizeSelection(nsISelection *inSelection); 1.258 + void GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode* aNode, 1.259 + int32_t aOffset, EditAction actionID, 1.260 + nsCOMPtr<nsIDOMNode>* outNode, int32_t* outOffset); 1.261 + nsresult GetPromotedRanges(nsISelection *inSelection, 1.262 + nsCOMArray<nsIDOMRange> &outArrayOfRanges, 1.263 + EditAction inOperationType); 1.264 + nsresult PromoteRange(nsIDOMRange *inRange, 1.265 + EditAction inOperationType); 1.266 + nsresult GetNodesForOperation(nsCOMArray<nsIDOMRange>& inArrayOfRanges, 1.267 + nsCOMArray<nsIDOMNode>& outArrayOfNodes, 1.268 + EditAction inOperationType, 1.269 + bool aDontTouchContent=false); 1.270 + nsresult GetChildNodesForOperation(nsIDOMNode *inNode, 1.271 + nsCOMArray<nsIDOMNode>& outArrayOfNodes); 1.272 + nsresult GetNodesFromPoint(DOMPoint point, 1.273 + EditAction operation, 1.274 + nsCOMArray<nsIDOMNode>& arrayOfNodes, 1.275 + bool dontTouchContent); 1.276 + nsresult GetNodesFromSelection(nsISelection *selection, 1.277 + EditAction operation, 1.278 + nsCOMArray<nsIDOMNode>& arrayOfNodes, 1.279 + bool aDontTouchContent=false); 1.280 + nsresult GetListActionNodes(nsCOMArray<nsIDOMNode> &outArrayOfNodes, bool aEntireList, bool aDontTouchContent=false); 1.281 + void GetDefinitionListItemTypes(mozilla::dom::Element* aElement, bool* aDT, bool* aDD); 1.282 + nsresult GetParagraphFormatNodes(nsCOMArray<nsIDOMNode>& outArrayOfNodes, bool aDontTouchContent=false); 1.283 + nsresult LookInsideDivBQandList(nsCOMArray<nsIDOMNode>& aNodeArray); 1.284 + nsresult BustUpInlinesAtRangeEndpoints(nsRangeStore &inRange); 1.285 + nsresult BustUpInlinesAtBRs(nsIDOMNode *inNode, 1.286 + nsCOMArray<nsIDOMNode>& outArrayOfNodes); 1.287 + nsCOMPtr<nsIDOMNode> GetHighestInlineParent(nsIDOMNode* aNode); 1.288 + nsresult MakeTransitionList(nsCOMArray<nsIDOMNode>& inArrayOfNodes, 1.289 + nsTArray<bool> &inTransitionArray); 1.290 + nsresult RemoveBlockStyle(nsCOMArray<nsIDOMNode>& arrayOfNodes); 1.291 + nsresult ApplyBlockStyle(nsCOMArray<nsIDOMNode>& arrayOfNodes, const nsAString *aBlockTag); 1.292 + nsresult MakeBlockquote(nsCOMArray<nsIDOMNode>& arrayOfNodes); 1.293 + nsresult SplitAsNeeded(const nsAString *aTag, nsCOMPtr<nsIDOMNode> *inOutParent, int32_t *inOutOffset); 1.294 + nsresult AddTerminatingBR(nsIDOMNode *aBlock); 1.295 + nsresult JoinNodesSmart( nsIDOMNode *aNodeLeft, 1.296 + nsIDOMNode *aNodeRight, 1.297 + nsCOMPtr<nsIDOMNode> *aOutMergeParent, 1.298 + int32_t *aOutMergeOffset); 1.299 + nsresult GetTopEnclosingMailCite(nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutCiteNode, bool aPlaintext); 1.300 + nsresult PopListItem(nsIDOMNode *aListItem, bool *aOutOfList); 1.301 + nsresult RemoveListStructure(nsIDOMNode *aList); 1.302 + nsresult CacheInlineStyles(nsIDOMNode *aNode); 1.303 + nsresult ReapplyCachedStyles(); 1.304 + void ClearCachedStyles(); 1.305 + nsresult AdjustSpecialBreaks(bool aSafeToAskFrames = false); 1.306 + nsresult AdjustWhitespace(nsISelection *aSelection); 1.307 + nsresult PinSelectionToNewBlock(nsISelection *aSelection); 1.308 + nsresult CheckInterlinePosition(nsISelection *aSelection); 1.309 + nsresult AdjustSelection(nsISelection *aSelection, nsIEditor::EDirection aAction); 1.310 + nsresult FindNearSelectableNode(nsIDOMNode *aSelNode, 1.311 + int32_t aSelOffset, 1.312 + nsIEditor::EDirection &aDirection, 1.313 + nsCOMPtr<nsIDOMNode> *outSelectableNode); 1.314 + /** 1.315 + * Returns true if aNode1 or aNode2 or both is the descendant of some type of 1.316 + * table element, but their nearest table element ancestors differ. "Table 1.317 + * element" here includes not just <table> but also <td>, <tbody>, <tr>, etc. 1.318 + * The nodes count as being their own descendants for this purpose, so a 1.319 + * table element is its own nearest table element ancestor. 1.320 + */ 1.321 + bool InDifferentTableElements(nsIDOMNode* aNode1, nsIDOMNode* aNode2); 1.322 + bool InDifferentTableElements(nsINode* aNode1, nsINode* aNode2); 1.323 + nsresult RemoveEmptyNodes(); 1.324 + nsresult SelectionEndpointInNode(nsINode *aNode, bool *aResult); 1.325 + nsresult UpdateDocChangeRange(nsIDOMRange *aRange); 1.326 + nsresult ConfirmSelectionInBody(); 1.327 + nsresult InsertMozBRIfNeeded(nsIDOMNode *aNode); 1.328 + bool IsEmptyInline(nsIDOMNode *aNode); 1.329 + bool ListIsEmptyLine(nsCOMArray<nsIDOMNode> &arrayOfNodes); 1.330 + nsresult RemoveAlignment(nsIDOMNode * aNode, const nsAString & aAlignType, bool aChildrenOnly); 1.331 + nsresult MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode, bool aStarts); 1.332 + nsresult AlignBlock(nsIDOMElement * aElement, const nsAString * aAlignType, bool aContentsOnly); 1.333 + nsresult RelativeChangeIndentationOfElementNode(nsIDOMNode *aNode, int8_t aRelativeChange); 1.334 + void DocumentModifiedWorker(); 1.335 + 1.336 +// data members 1.337 +protected: 1.338 + nsHTMLEditor *mHTMLEditor; 1.339 + nsRefPtr<nsRange> mDocChangeRange; 1.340 + bool mListenerEnabled; 1.341 + bool mReturnInEmptyLIKillsList; 1.342 + bool mDidDeleteSelection; 1.343 + bool mDidRangedDelete; 1.344 + bool mRestoreContentEditableCount; 1.345 + nsRefPtr<nsRange> mUtilRange; 1.346 + uint32_t mJoinOffset; // need to remember an int across willJoin/didJoin... 1.347 + nsCOMPtr<nsIDOMNode> mNewBlock; 1.348 + nsRefPtr<nsRangeStore> mRangeItem; 1.349 + StyleCache mCachedStyles[SIZE_STYLE_TABLE]; 1.350 +}; 1.351 + 1.352 +#endif //nsHTMLEditRules_h__ 1.353 +