|
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 #ifndef nsHTMLEditRules_h__ |
|
7 #define nsHTMLEditRules_h__ |
|
8 |
|
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" |
|
21 |
|
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; |
|
43 |
|
44 struct StyleCache : public PropItem |
|
45 { |
|
46 bool mPresent; |
|
47 |
|
48 StyleCache() : PropItem(), mPresent(false) { |
|
49 MOZ_COUNT_CTOR(StyleCache); |
|
50 } |
|
51 |
|
52 StyleCache(nsIAtom *aTag, const nsAString &aAttr, const nsAString &aValue) : |
|
53 PropItem(aTag, aAttr, aValue), mPresent(false) { |
|
54 MOZ_COUNT_CTOR(StyleCache); |
|
55 } |
|
56 |
|
57 ~StyleCache() { |
|
58 MOZ_COUNT_DTOR(StyleCache); |
|
59 } |
|
60 }; |
|
61 |
|
62 |
|
63 #define SIZE_STYLE_TABLE 19 |
|
64 |
|
65 class nsHTMLEditRules : public nsTextEditRules, public nsIEditActionListener |
|
66 { |
|
67 public: |
|
68 |
|
69 NS_DECL_ISUPPORTS_INHERITED |
|
70 |
|
71 nsHTMLEditRules(); |
|
72 virtual ~nsHTMLEditRules(); |
|
73 |
|
74 |
|
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(); |
|
86 |
|
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); |
|
93 |
|
94 // nsIEditActionListener methods |
|
95 |
|
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); |
|
112 |
|
113 protected: |
|
114 |
|
115 enum RulesEndpoint |
|
116 { |
|
117 kStart, |
|
118 kEnd |
|
119 }; |
|
120 |
|
121 enum BRLocation |
|
122 { |
|
123 kBeforeBlock, |
|
124 kBlockEnd |
|
125 }; |
|
126 |
|
127 void InitFields(); |
|
128 |
|
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); |
|
230 |
|
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); |
|
239 |
|
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(); |
|
332 |
|
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 }; |
|
348 |
|
349 #endif //nsHTMLEditRules_h__ |
|
350 |