Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
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/. */
6 #ifndef nsHTMLEditRules_h__
7 #define nsHTMLEditRules_h__
9 #include "TypeInState.h"
10 #include "nsAutoPtr.h"
11 #include "nsCOMPtr.h"
12 #include "nsEditor.h"
13 #include "nsIEditActionListener.h"
14 #include "nsIEditor.h"
15 #include "nsIHTMLEditor.h"
16 #include "nsISupportsImpl.h"
17 #include "nsSelectionState.h"
18 #include "nsTArray.h"
19 #include "nsTextEditRules.h"
20 #include "nscore.h"
22 class nsHTMLEditor;
23 class nsIAtom;
24 class nsIDOMCharacterData;
25 class nsIDOMDocument;
26 class nsIDOMElement;
27 class nsIDOMNode;
28 class nsIDOMRange;
29 class nsIEditor;
30 class nsINode;
31 class nsISelection;
32 class nsPlaintextEditor;
33 class nsRange;
34 class nsRulesInfo;
35 namespace mozilla {
36 namespace dom {
37 class Element;
38 class Selection;
39 } // namespace dom
40 } // namespace mozilla
41 struct DOMPoint;
42 template <class E> class nsCOMArray;
44 struct StyleCache : public PropItem
45 {
46 bool mPresent;
48 StyleCache() : PropItem(), mPresent(false) {
49 MOZ_COUNT_CTOR(StyleCache);
50 }
52 StyleCache(nsIAtom *aTag, const nsAString &aAttr, const nsAString &aValue) :
53 PropItem(aTag, aAttr, aValue), mPresent(false) {
54 MOZ_COUNT_CTOR(StyleCache);
55 }
57 ~StyleCache() {
58 MOZ_COUNT_DTOR(StyleCache);
59 }
60 };
63 #define SIZE_STYLE_TABLE 19
65 class nsHTMLEditRules : public nsTextEditRules, public nsIEditActionListener
66 {
67 public:
69 NS_DECL_ISUPPORTS_INHERITED
71 nsHTMLEditRules();
72 virtual ~nsHTMLEditRules();
75 // nsIEditRules methods
76 NS_IMETHOD Init(nsPlaintextEditor *aEditor);
77 NS_IMETHOD DetachEditor();
78 NS_IMETHOD BeforeEdit(EditAction action,
79 nsIEditor::EDirection aDirection);
80 NS_IMETHOD AfterEdit(EditAction action,
81 nsIEditor::EDirection aDirection);
82 NS_IMETHOD WillDoAction(mozilla::dom::Selection* aSelection, nsRulesInfo* aInfo,
83 bool* aCancel, bool* aHandled);
84 NS_IMETHOD DidDoAction(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
85 NS_IMETHOD DocumentModified();
87 nsresult GetListState(bool *aMixed, bool *aOL, bool *aUL, bool *aDL);
88 nsresult GetListItemState(bool *aMixed, bool *aLI, bool *aDT, bool *aDD);
89 nsresult GetIndentState(bool *aCanIndent, bool *aCanOutdent);
90 nsresult GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign);
91 nsresult GetParagraphState(bool *aMixed, nsAString &outFormat);
92 nsresult MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode);
94 // nsIEditActionListener methods
96 NS_IMETHOD WillCreateNode(const nsAString& aTag, nsIDOMNode *aParent, int32_t aPosition);
97 NS_IMETHOD DidCreateNode(const nsAString& aTag, nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t aPosition, nsresult aResult);
98 NS_IMETHOD WillInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t aPosition);
99 NS_IMETHOD DidInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t aPosition, nsresult aResult);
100 NS_IMETHOD WillDeleteNode(nsIDOMNode *aChild);
101 NS_IMETHOD DidDeleteNode(nsIDOMNode *aChild, nsresult aResult);
102 NS_IMETHOD WillSplitNode(nsIDOMNode *aExistingRightNode, int32_t aOffset);
103 NS_IMETHOD DidSplitNode(nsIDOMNode *aExistingRightNode, int32_t aOffset, nsIDOMNode *aNewLeftNode, nsresult aResult);
104 NS_IMETHOD WillJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent);
105 NS_IMETHOD DidJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent, nsresult aResult);
106 NS_IMETHOD WillInsertText(nsIDOMCharacterData *aTextNode, int32_t aOffset, const nsAString &aString);
107 NS_IMETHOD DidInsertText(nsIDOMCharacterData *aTextNode, int32_t aOffset, const nsAString &aString, nsresult aResult);
108 NS_IMETHOD WillDeleteText(nsIDOMCharacterData *aTextNode, int32_t aOffset, int32_t aLength);
109 NS_IMETHOD DidDeleteText(nsIDOMCharacterData *aTextNode, int32_t aOffset, int32_t aLength, nsresult aResult);
110 NS_IMETHOD WillDeleteSelection(nsISelection *aSelection);
111 NS_IMETHOD DidDeleteSelection(nsISelection *aSelection);
113 protected:
115 enum RulesEndpoint
116 {
117 kStart,
118 kEnd
119 };
121 enum BRLocation
122 {
123 kBeforeBlock,
124 kBlockEnd
125 };
127 void InitFields();
129 // nsHTMLEditRules implementation methods
130 nsresult WillInsert(nsISelection *aSelection, bool *aCancel);
131 nsresult WillInsertText( EditAction aAction,
132 mozilla::dom::Selection* aSelection,
133 bool *aCancel,
134 bool *aHandled,
135 const nsAString *inString,
136 nsAString *outString,
137 int32_t aMaxLength);
138 nsresult WillLoadHTML(nsISelection *aSelection, bool *aCancel);
139 nsresult WillInsertBreak(mozilla::dom::Selection* aSelection,
140 bool* aCancel, bool* aHandled);
141 nsresult StandardBreakImpl(nsIDOMNode *aNode, int32_t aOffset, nsISelection *aSelection);
142 nsresult DidInsertBreak(nsISelection *aSelection, nsresult aResult);
143 nsresult SplitMailCites(nsISelection *aSelection, bool aPlaintext, bool *aHandled);
144 nsresult WillDeleteSelection(mozilla::dom::Selection* aSelection,
145 nsIEditor::EDirection aAction,
146 nsIEditor::EStripWrappers aStripWrappers,
147 bool* aCancel, bool* aHandled);
148 nsresult DidDeleteSelection(nsISelection *aSelection,
149 nsIEditor::EDirection aDir,
150 nsresult aResult);
151 nsresult InsertBRIfNeeded(nsISelection *aSelection);
152 nsresult GetGoodSelPointForNode(nsIDOMNode *aNode, nsIEditor::EDirection aAction,
153 nsCOMPtr<nsIDOMNode> *outSelNode, int32_t *outSelOffset);
154 nsresult JoinBlocks(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, bool *aCanceled);
155 nsresult MoveBlock(nsIDOMNode *aLeft, nsIDOMNode *aRight, int32_t aLeftOffset, int32_t aRightOffset);
156 nsresult MoveNodeSmart(nsIDOMNode *aSource, nsIDOMNode *aDest, int32_t *aOffset);
157 nsresult MoveContents(nsIDOMNode *aSource, nsIDOMNode *aDest, int32_t *aOffset);
158 nsresult DeleteNonTableElements(nsINode* aNode);
159 nsresult WillMakeList(mozilla::dom::Selection* aSelection,
160 const nsAString* aListType,
161 bool aEntireList,
162 const nsAString* aBulletType,
163 bool* aCancel, bool* aHandled,
164 const nsAString* aItemType = nullptr);
165 nsresult WillRemoveList(mozilla::dom::Selection* aSelection,
166 bool aOrdered, bool* aCancel, bool* aHandled);
167 nsresult WillIndent(mozilla::dom::Selection* aSelection,
168 bool* aCancel, bool* aHandled);
169 nsresult WillCSSIndent(mozilla::dom::Selection* aSelection,
170 bool* aCancel, bool* aHandled);
171 nsresult WillHTMLIndent(mozilla::dom::Selection* aSelection,
172 bool* aCancel, bool* aHandled);
173 nsresult WillOutdent(mozilla::dom::Selection* aSelection,
174 bool* aCancel, bool* aHandled);
175 nsresult WillAlign(mozilla::dom::Selection* aSelection,
176 const nsAString* alignType,
177 bool* aCancel, bool* aHandled);
178 nsresult WillAbsolutePosition(mozilla::dom::Selection* aSelection,
179 bool* aCancel, bool* aHandled);
180 nsresult WillRemoveAbsolutePosition(mozilla::dom::Selection* aSelection,
181 bool* aCancel, bool* aHandled);
182 nsresult WillRelativeChangeZIndex(mozilla::dom::Selection* aSelection,
183 int32_t aChange,
184 bool* aCancel, bool* aHandled);
185 nsresult WillMakeDefListItem(mozilla::dom::Selection* aSelection,
186 const nsAString* aBlockType, bool aEntireList,
187 bool* aCancel, bool* aHandled);
188 nsresult WillMakeBasicBlock(mozilla::dom::Selection* aSelection,
189 const nsAString* aBlockType,
190 bool* aCancel, bool* aHandled);
191 nsresult DidMakeBasicBlock(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
192 nsresult DidAbsolutePosition();
193 nsresult AlignInnerBlocks(nsIDOMNode *aNode, const nsAString *alignType);
194 nsresult AlignBlockContents(nsIDOMNode *aNode, const nsAString *alignType);
195 nsresult AppendInnerFormatNodes(nsCOMArray<nsIDOMNode>& aArray,
196 nsINode* aNode);
197 nsresult AppendInnerFormatNodes(nsCOMArray<nsIDOMNode>& aArray,
198 nsIDOMNode *aNode);
199 nsresult GetFormatString(nsIDOMNode *aNode, nsAString &outFormat);
200 nsresult GetInnerContent(nsIDOMNode *aNode, nsCOMArray<nsIDOMNode>& outArrayOfNodes, int32_t *aIndex, bool aList = true, bool aTble = true);
201 already_AddRefed<nsIDOMNode> IsInListItem(nsIDOMNode* aNode);
202 nsINode* IsInListItem(nsINode* aNode);
203 nsresult ReturnInHeader(nsISelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, int32_t aOffset);
204 nsresult ReturnInParagraph(nsISelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, int32_t aOffset, bool *aCancel, bool *aHandled);
205 nsresult SplitParagraph(nsIDOMNode *aPara,
206 nsIDOMNode *aBRNode,
207 nsISelection *aSelection,
208 nsCOMPtr<nsIDOMNode> *aSelNode,
209 int32_t *aOffset);
210 nsresult ReturnInListItem(nsISelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, int32_t aOffset);
211 nsresult AfterEditInner(EditAction action,
212 nsIEditor::EDirection aDirection);
213 nsresult RemovePartOfBlock(nsIDOMNode *aBlock,
214 nsIDOMNode *aStartChild,
215 nsIDOMNode *aEndChild,
216 nsCOMPtr<nsIDOMNode> *aLeftNode = 0,
217 nsCOMPtr<nsIDOMNode> *aRightNode = 0);
218 nsresult SplitBlock(nsIDOMNode *aBlock,
219 nsIDOMNode *aStartChild,
220 nsIDOMNode *aEndChild,
221 nsCOMPtr<nsIDOMNode> *aLeftNode = 0,
222 nsCOMPtr<nsIDOMNode> *aRightNode = 0,
223 nsCOMPtr<nsIDOMNode> *aMiddleNode = 0);
224 nsresult OutdentPartOfBlock(nsIDOMNode *aBlock,
225 nsIDOMNode *aStartChild,
226 nsIDOMNode *aEndChild,
227 bool aIsBlockIndentedWithCSS,
228 nsCOMPtr<nsIDOMNode> *aLeftNode = 0,
229 nsCOMPtr<nsIDOMNode> *aRightNode = 0);
231 nsresult ConvertListType(nsIDOMNode* aList,
232 nsCOMPtr<nsIDOMNode>* outList,
233 nsIAtom* aListType,
234 nsIAtom* aItemType);
235 nsresult ConvertListType(nsINode* aList,
236 mozilla::dom::Element** aOutList,
237 nsIAtom* aListType,
238 nsIAtom* aItemType);
240 nsresult CreateStyleForInsertText(nsISelection *aSelection, nsIDOMDocument *aDoc);
241 nsresult IsEmptyBlock(nsIDOMNode *aNode,
242 bool *outIsEmptyBlock,
243 bool aMozBRDoesntCount = false,
244 bool aListItemsNotEmpty = false);
245 nsresult CheckForEmptyBlock(nsIDOMNode *aStartNode,
246 nsIDOMNode *aBodyNode,
247 nsISelection *aSelection,
248 bool *aHandled);
249 nsresult CheckForInvisibleBR(nsIDOMNode *aBlock, nsHTMLEditRules::BRLocation aWhere,
250 nsCOMPtr<nsIDOMNode> *outBRNode, int32_t aOffset=0);
251 nsresult ExpandSelectionForDeletion(nsISelection *aSelection);
252 bool IsFirstNode(nsIDOMNode *aNode);
253 bool IsLastNode(nsIDOMNode *aNode);
254 nsresult NormalizeSelection(nsISelection *inSelection);
255 void GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode* aNode,
256 int32_t aOffset, EditAction actionID,
257 nsCOMPtr<nsIDOMNode>* outNode, int32_t* outOffset);
258 nsresult GetPromotedRanges(nsISelection *inSelection,
259 nsCOMArray<nsIDOMRange> &outArrayOfRanges,
260 EditAction inOperationType);
261 nsresult PromoteRange(nsIDOMRange *inRange,
262 EditAction inOperationType);
263 nsresult GetNodesForOperation(nsCOMArray<nsIDOMRange>& inArrayOfRanges,
264 nsCOMArray<nsIDOMNode>& outArrayOfNodes,
265 EditAction inOperationType,
266 bool aDontTouchContent=false);
267 nsresult GetChildNodesForOperation(nsIDOMNode *inNode,
268 nsCOMArray<nsIDOMNode>& outArrayOfNodes);
269 nsresult GetNodesFromPoint(DOMPoint point,
270 EditAction operation,
271 nsCOMArray<nsIDOMNode>& arrayOfNodes,
272 bool dontTouchContent);
273 nsresult GetNodesFromSelection(nsISelection *selection,
274 EditAction operation,
275 nsCOMArray<nsIDOMNode>& arrayOfNodes,
276 bool aDontTouchContent=false);
277 nsresult GetListActionNodes(nsCOMArray<nsIDOMNode> &outArrayOfNodes, bool aEntireList, bool aDontTouchContent=false);
278 void GetDefinitionListItemTypes(mozilla::dom::Element* aElement, bool* aDT, bool* aDD);
279 nsresult GetParagraphFormatNodes(nsCOMArray<nsIDOMNode>& outArrayOfNodes, bool aDontTouchContent=false);
280 nsresult LookInsideDivBQandList(nsCOMArray<nsIDOMNode>& aNodeArray);
281 nsresult BustUpInlinesAtRangeEndpoints(nsRangeStore &inRange);
282 nsresult BustUpInlinesAtBRs(nsIDOMNode *inNode,
283 nsCOMArray<nsIDOMNode>& outArrayOfNodes);
284 nsCOMPtr<nsIDOMNode> GetHighestInlineParent(nsIDOMNode* aNode);
285 nsresult MakeTransitionList(nsCOMArray<nsIDOMNode>& inArrayOfNodes,
286 nsTArray<bool> &inTransitionArray);
287 nsresult RemoveBlockStyle(nsCOMArray<nsIDOMNode>& arrayOfNodes);
288 nsresult ApplyBlockStyle(nsCOMArray<nsIDOMNode>& arrayOfNodes, const nsAString *aBlockTag);
289 nsresult MakeBlockquote(nsCOMArray<nsIDOMNode>& arrayOfNodes);
290 nsresult SplitAsNeeded(const nsAString *aTag, nsCOMPtr<nsIDOMNode> *inOutParent, int32_t *inOutOffset);
291 nsresult AddTerminatingBR(nsIDOMNode *aBlock);
292 nsresult JoinNodesSmart( nsIDOMNode *aNodeLeft,
293 nsIDOMNode *aNodeRight,
294 nsCOMPtr<nsIDOMNode> *aOutMergeParent,
295 int32_t *aOutMergeOffset);
296 nsresult GetTopEnclosingMailCite(nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutCiteNode, bool aPlaintext);
297 nsresult PopListItem(nsIDOMNode *aListItem, bool *aOutOfList);
298 nsresult RemoveListStructure(nsIDOMNode *aList);
299 nsresult CacheInlineStyles(nsIDOMNode *aNode);
300 nsresult ReapplyCachedStyles();
301 void ClearCachedStyles();
302 nsresult AdjustSpecialBreaks(bool aSafeToAskFrames = false);
303 nsresult AdjustWhitespace(nsISelection *aSelection);
304 nsresult PinSelectionToNewBlock(nsISelection *aSelection);
305 nsresult CheckInterlinePosition(nsISelection *aSelection);
306 nsresult AdjustSelection(nsISelection *aSelection, nsIEditor::EDirection aAction);
307 nsresult FindNearSelectableNode(nsIDOMNode *aSelNode,
308 int32_t aSelOffset,
309 nsIEditor::EDirection &aDirection,
310 nsCOMPtr<nsIDOMNode> *outSelectableNode);
311 /**
312 * Returns true if aNode1 or aNode2 or both is the descendant of some type of
313 * table element, but their nearest table element ancestors differ. "Table
314 * element" here includes not just <table> but also <td>, <tbody>, <tr>, etc.
315 * The nodes count as being their own descendants for this purpose, so a
316 * table element is its own nearest table element ancestor.
317 */
318 bool InDifferentTableElements(nsIDOMNode* aNode1, nsIDOMNode* aNode2);
319 bool InDifferentTableElements(nsINode* aNode1, nsINode* aNode2);
320 nsresult RemoveEmptyNodes();
321 nsresult SelectionEndpointInNode(nsINode *aNode, bool *aResult);
322 nsresult UpdateDocChangeRange(nsIDOMRange *aRange);
323 nsresult ConfirmSelectionInBody();
324 nsresult InsertMozBRIfNeeded(nsIDOMNode *aNode);
325 bool IsEmptyInline(nsIDOMNode *aNode);
326 bool ListIsEmptyLine(nsCOMArray<nsIDOMNode> &arrayOfNodes);
327 nsresult RemoveAlignment(nsIDOMNode * aNode, const nsAString & aAlignType, bool aChildrenOnly);
328 nsresult MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode, bool aStarts);
329 nsresult AlignBlock(nsIDOMElement * aElement, const nsAString * aAlignType, bool aContentsOnly);
330 nsresult RelativeChangeIndentationOfElementNode(nsIDOMNode *aNode, int8_t aRelativeChange);
331 void DocumentModifiedWorker();
333 // data members
334 protected:
335 nsHTMLEditor *mHTMLEditor;
336 nsRefPtr<nsRange> mDocChangeRange;
337 bool mListenerEnabled;
338 bool mReturnInEmptyLIKillsList;
339 bool mDidDeleteSelection;
340 bool mDidRangedDelete;
341 bool mRestoreContentEditableCount;
342 nsRefPtr<nsRange> mUtilRange;
343 uint32_t mJoinOffset; // need to remember an int across willJoin/didJoin...
344 nsCOMPtr<nsIDOMNode> mNewBlock;
345 nsRefPtr<nsRangeStore> mRangeItem;
346 StyleCache mCachedStyles[SIZE_STYLE_TABLE];
347 };
349 #endif //nsHTMLEditRules_h__