1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Daniel Glazman <glazman@netscape.com>
24 : * Sebastian Kromp <46b@gulli.com>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either of the GNU General Public License Version 2 or later (the "GPL"),
28 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #ifndef nsHTMLEditRules_h__
41 : #define nsHTMLEditRules_h__
42 :
43 : #include "nsTextEditRules.h"
44 : #include "nsIHTMLEditor.h"
45 : #include "nsIEditActionListener.h"
46 : #include "nsCOMArray.h"
47 : #include "nsCOMPtr.h"
48 : #include "nsString.h"
49 : #include "nsEditorUtils.h"
50 : #include "TypeInState.h"
51 : #include "nsReadableUtils.h"
52 : #include "nsTArray.h"
53 : #include "nsRange.h"
54 :
55 : class nsIDOMElement;
56 : class nsIEditor;
57 : class nsHTMLEditor;
58 :
59 : struct StyleCache : public PropItem
60 0 : {
61 : bool mPresent;
62 :
63 0 : StyleCache() : PropItem(), mPresent(false) {
64 0 : MOZ_COUNT_CTOR(StyleCache);
65 0 : }
66 :
67 0 : StyleCache(nsIAtom *aTag, const nsAString &aAttr, const nsAString &aValue) :
68 0 : PropItem(aTag, aAttr, aValue), mPresent(false) {
69 0 : MOZ_COUNT_CTOR(StyleCache);
70 0 : }
71 :
72 0 : ~StyleCache() {
73 0 : MOZ_COUNT_DTOR(StyleCache);
74 0 : }
75 : };
76 :
77 :
78 : #define SIZE_STYLE_TABLE 19
79 :
80 : class nsHTMLEditRules : public nsTextEditRules, public nsIEditActionListener
81 : {
82 : public:
83 :
84 : NS_DECL_ISUPPORTS_INHERITED
85 :
86 : nsHTMLEditRules();
87 : virtual ~nsHTMLEditRules();
88 :
89 :
90 : // nsIEditRules methods
91 : NS_IMETHOD Init(nsPlaintextEditor *aEditor);
92 : NS_IMETHOD DetachEditor();
93 : NS_IMETHOD BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection);
94 : NS_IMETHOD AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection);
95 : NS_IMETHOD WillDoAction(nsISelection *aSelection, nsRulesInfo *aInfo, bool *aCancel, bool *aHandled);
96 : NS_IMETHOD DidDoAction(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
97 : NS_IMETHOD DocumentModified();
98 :
99 : nsresult GetListState(bool *aMixed, bool *aOL, bool *aUL, bool *aDL);
100 : nsresult GetListItemState(bool *aMixed, bool *aLI, bool *aDT, bool *aDD);
101 : nsresult GetIndentState(bool *aCanIndent, bool *aCanOutdent);
102 : nsresult GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign);
103 : nsresult GetParagraphState(bool *aMixed, nsAString &outFormat);
104 : nsresult MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode);
105 :
106 : // nsIEditActionListener methods
107 :
108 : NS_IMETHOD WillCreateNode(const nsAString& aTag, nsIDOMNode *aParent, PRInt32 aPosition);
109 : NS_IMETHOD DidCreateNode(const nsAString& aTag, nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition, nsresult aResult);
110 : NS_IMETHOD WillInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition);
111 : NS_IMETHOD DidInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition, nsresult aResult);
112 : NS_IMETHOD WillDeleteNode(nsIDOMNode *aChild);
113 : NS_IMETHOD DidDeleteNode(nsIDOMNode *aChild, nsresult aResult);
114 : NS_IMETHOD WillSplitNode(nsIDOMNode *aExistingRightNode, PRInt32 aOffset);
115 : NS_IMETHOD DidSplitNode(nsIDOMNode *aExistingRightNode, PRInt32 aOffset, nsIDOMNode *aNewLeftNode, nsresult aResult);
116 : NS_IMETHOD WillJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent);
117 : NS_IMETHOD DidJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent, nsresult aResult);
118 : NS_IMETHOD WillInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsAString &aString);
119 : NS_IMETHOD DidInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsAString &aString, nsresult aResult);
120 : NS_IMETHOD WillDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength);
121 : NS_IMETHOD DidDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength, nsresult aResult);
122 : NS_IMETHOD WillDeleteSelection(nsISelection *aSelection);
123 : NS_IMETHOD DidDeleteSelection(nsISelection *aSelection);
124 :
125 : protected:
126 :
127 : enum RulesEndpoint
128 : {
129 : kStart,
130 : kEnd
131 : };
132 :
133 : enum BRLocation
134 : {
135 : kBeforeBlock,
136 : kBlockEnd
137 : };
138 :
139 : // nsHTMLEditRules implementation methods
140 : nsresult WillInsert(nsISelection *aSelection, bool *aCancel);
141 : #ifdef XXX_DEAD_CODE
142 : nsresult DidInsert(nsISelection *aSelection, nsresult aResult);
143 : #endif
144 : nsresult WillInsertText( PRInt32 aAction,
145 : nsISelection *aSelection,
146 : bool *aCancel,
147 : bool *aHandled,
148 : const nsAString *inString,
149 : nsAString *outString,
150 : PRInt32 aMaxLength);
151 : nsresult WillLoadHTML(nsISelection *aSelection, bool *aCancel);
152 : nsresult WillInsertBreak(nsISelection *aSelection, bool *aCancel, bool *aHandled);
153 : nsresult StandardBreakImpl(nsIDOMNode *aNode, PRInt32 aOffset, nsISelection *aSelection);
154 : nsresult DidInsertBreak(nsISelection *aSelection, nsresult aResult);
155 : nsresult SplitMailCites(nsISelection *aSelection, bool aPlaintext, bool *aHandled);
156 : nsresult WillDeleteSelection(nsISelection *aSelection, nsIEditor::EDirection aAction,
157 : bool *aCancel, bool *aHandled);
158 : nsresult DidDeleteSelection(nsISelection *aSelection,
159 : nsIEditor::EDirection aDir,
160 : nsresult aResult);
161 : nsresult InsertBRIfNeeded(nsISelection *aSelection);
162 : nsresult GetGoodSelPointForNode(nsIDOMNode *aNode, nsIEditor::EDirection aAction,
163 : nsCOMPtr<nsIDOMNode> *outSelNode, PRInt32 *outSelOffset);
164 : nsresult JoinBlocks(nsCOMPtr<nsIDOMNode> *aLeftBlock, nsCOMPtr<nsIDOMNode> *aRightBlock, bool *aCanceled);
165 : nsresult MoveBlock(nsIDOMNode *aLeft, nsIDOMNode *aRight, PRInt32 aLeftOffset, PRInt32 aRightOffset);
166 : nsresult MoveNodeSmart(nsIDOMNode *aSource, nsIDOMNode *aDest, PRInt32 *aOffset);
167 : nsresult MoveContents(nsIDOMNode *aSource, nsIDOMNode *aDest, PRInt32 *aOffset);
168 : nsresult DeleteNonTableElements(nsIDOMNode *aNode);
169 : nsresult WillMakeList(nsISelection *aSelection, const nsAString *aListType, bool aEntireList, const nsAString *aBulletType, bool *aCancel, bool *aHandled, const nsAString *aItemType=nsnull);
170 : nsresult WillRemoveList(nsISelection *aSelection, bool aOrderd, bool *aCancel, bool *aHandled);
171 : nsresult WillIndent(nsISelection *aSelection, bool *aCancel, bool *aHandled);
172 : nsresult WillCSSIndent(nsISelection *aSelection, bool *aCancel, bool *aHandled);
173 : nsresult WillHTMLIndent(nsISelection *aSelection, bool *aCancel, bool *aHandled);
174 : nsresult WillOutdent(nsISelection *aSelection, bool *aCancel, bool *aHandled);
175 : nsresult WillAlign(nsISelection *aSelection, const nsAString *alignType, bool *aCancel, bool *aHandled);
176 : nsresult WillAbsolutePosition(nsISelection *aSelection, bool *aCancel, bool * aHandled);
177 : nsresult WillRemoveAbsolutePosition(nsISelection *aSelection, bool *aCancel, bool * aHandled);
178 : nsresult WillRelativeChangeZIndex(nsISelection *aSelection, PRInt32 aChange, bool *aCancel, bool * aHandled);
179 : nsresult WillMakeDefListItem(nsISelection *aSelection, const nsAString *aBlockType, bool aEntireList, bool *aCancel, bool *aHandled);
180 : nsresult WillMakeBasicBlock(nsISelection *aSelection, const nsAString *aBlockType, bool *aCancel, bool *aHandled);
181 : nsresult DidMakeBasicBlock(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
182 : nsresult DidAbsolutePosition();
183 : nsresult AlignInnerBlocks(nsIDOMNode *aNode, const nsAString *alignType);
184 : nsresult AlignBlockContents(nsIDOMNode *aNode, const nsAString *alignType);
185 : nsresult AppendInnerFormatNodes(nsCOMArray<nsIDOMNode>& aArray,
186 : nsIDOMNode *aNode);
187 : nsresult GetFormatString(nsIDOMNode *aNode, nsAString &outFormat);
188 : nsresult GetInnerContent(nsIDOMNode *aNode, nsCOMArray<nsIDOMNode>& outArrayOfNodes, PRInt32 *aIndex, bool aList = true, bool aTble = true);
189 : already_AddRefed<nsIDOMNode> IsInListItem(nsIDOMNode* aNode);
190 : nsINode* IsInListItem(nsINode* aNode);
191 : nsresult ReturnInHeader(nsISelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset);
192 : nsresult ReturnInParagraph(nsISelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset, bool *aCancel, bool *aHandled);
193 : nsresult SplitParagraph(nsIDOMNode *aPara,
194 : nsIDOMNode *aBRNode,
195 : nsISelection *aSelection,
196 : nsCOMPtr<nsIDOMNode> *aSelNode,
197 : PRInt32 *aOffset);
198 : nsresult ReturnInListItem(nsISelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset);
199 : nsresult AfterEditInner(PRInt32 action, nsIEditor::EDirection aDirection);
200 : nsresult RemovePartOfBlock(nsIDOMNode *aBlock,
201 : nsIDOMNode *aStartChild,
202 : nsIDOMNode *aEndChild,
203 : nsCOMPtr<nsIDOMNode> *aLeftNode = 0,
204 : nsCOMPtr<nsIDOMNode> *aRightNode = 0);
205 : nsresult SplitBlock(nsIDOMNode *aBlock,
206 : nsIDOMNode *aStartChild,
207 : nsIDOMNode *aEndChild,
208 : nsCOMPtr<nsIDOMNode> *aLeftNode = 0,
209 : nsCOMPtr<nsIDOMNode> *aRightNode = 0,
210 : nsCOMPtr<nsIDOMNode> *aMiddleNode = 0);
211 : nsresult OutdentPartOfBlock(nsIDOMNode *aBlock,
212 : nsIDOMNode *aStartChild,
213 : nsIDOMNode *aEndChild,
214 : bool aIsBlockIndentedWithCSS,
215 : nsCOMPtr<nsIDOMNode> *aLeftNode = 0,
216 : nsCOMPtr<nsIDOMNode> *aRightNode = 0);
217 : nsresult ConvertListType(nsIDOMNode *aList, nsCOMPtr<nsIDOMNode> *outList, const nsAString& aListType, const nsAString& aItemType);
218 : nsresult CreateStyleForInsertText(nsISelection *aSelection, nsIDOMDocument *aDoc);
219 : nsresult IsEmptyBlock(nsIDOMNode *aNode,
220 : bool *outIsEmptyBlock,
221 : bool aMozBRDoesntCount = false,
222 : bool aListItemsNotEmpty = false);
223 : nsresult CheckForEmptyBlock(nsIDOMNode *aStartNode,
224 : nsIDOMNode *aBodyNode,
225 : nsISelection *aSelection,
226 : bool *aHandled);
227 : nsresult CheckForInvisibleBR(nsIDOMNode *aBlock, nsHTMLEditRules::BRLocation aWhere,
228 : nsCOMPtr<nsIDOMNode> *outBRNode, PRInt32 aOffset=0);
229 : nsresult ExpandSelectionForDeletion(nsISelection *aSelection);
230 : bool IsFirstNode(nsIDOMNode *aNode);
231 : bool IsLastNode(nsIDOMNode *aNode);
232 : #ifdef XXX_DEAD_CODE
233 : bool AtStartOfBlock(nsIDOMNode *aNode, PRInt32 aOffset, nsIDOMNode *aBlock);
234 : bool AtEndOfBlock(nsIDOMNode *aNode, PRInt32 aOffset, nsIDOMNode *aBlock);
235 : #endif
236 : nsresult NormalizeSelection(nsISelection *inSelection);
237 : nsresult GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode *aNode, PRInt32 aOffset,
238 : PRInt32 actionID, nsCOMPtr<nsIDOMNode> *outNode, PRInt32 *outOffset);
239 : nsresult GetPromotedRanges(nsISelection *inSelection,
240 : nsCOMArray<nsIDOMRange> &outArrayOfRanges,
241 : PRInt32 inOperationType);
242 : nsresult PromoteRange(nsIDOMRange *inRange, PRInt32 inOperationType);
243 : nsresult GetNodesForOperation(nsCOMArray<nsIDOMRange>& inArrayOfRanges,
244 : nsCOMArray<nsIDOMNode>& outArrayOfNodes,
245 : PRInt32 inOperationType,
246 : bool aDontTouchContent=false);
247 : nsresult GetChildNodesForOperation(nsIDOMNode *inNode,
248 : nsCOMArray<nsIDOMNode>& outArrayOfNodes);
249 : nsresult GetNodesFromPoint(DOMPoint point,
250 : PRInt32 operation,
251 : nsCOMArray<nsIDOMNode>& arrayOfNodes,
252 : bool dontTouchContent);
253 : nsresult GetNodesFromSelection(nsISelection *selection,
254 : PRInt32 operation,
255 : nsCOMArray<nsIDOMNode>& arrayOfNodes,
256 : bool aDontTouchContent=false);
257 : nsresult GetListActionNodes(nsCOMArray<nsIDOMNode> &outArrayOfNodes, bool aEntireList, bool aDontTouchContent=false);
258 : nsresult GetDefinitionListItemTypes(nsIDOMNode *aNode, bool &aDT, bool &aDD);
259 : nsresult GetParagraphFormatNodes(nsCOMArray<nsIDOMNode>& outArrayOfNodes, bool aDontTouchContent=false);
260 : nsresult LookInsideDivBQandList(nsCOMArray<nsIDOMNode>& aNodeArray);
261 : nsresult BustUpInlinesAtRangeEndpoints(nsRangeStore &inRange);
262 : nsresult BustUpInlinesAtBRs(nsIDOMNode *inNode,
263 : nsCOMArray<nsIDOMNode>& outArrayOfNodes);
264 : nsCOMPtr<nsIDOMNode> GetHighestInlineParent(nsIDOMNode* aNode);
265 : nsresult MakeTransitionList(nsCOMArray<nsIDOMNode>& inArrayOfNodes,
266 : nsTArray<bool> &inTransitionArray);
267 : nsresult RemoveBlockStyle(nsCOMArray<nsIDOMNode>& arrayOfNodes);
268 : nsresult ApplyBlockStyle(nsCOMArray<nsIDOMNode>& arrayOfNodes, const nsAString *aBlockTag);
269 : nsresult MakeBlockquote(nsCOMArray<nsIDOMNode>& arrayOfNodes);
270 : nsresult SplitAsNeeded(const nsAString *aTag, nsCOMPtr<nsIDOMNode> *inOutParent, PRInt32 *inOutOffset);
271 : nsresult AddTerminatingBR(nsIDOMNode *aBlock);
272 : nsresult JoinNodesSmart( nsIDOMNode *aNodeLeft,
273 : nsIDOMNode *aNodeRight,
274 : nsCOMPtr<nsIDOMNode> *aOutMergeParent,
275 : PRInt32 *aOutMergeOffset);
276 : nsresult GetTopEnclosingMailCite(nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutCiteNode, bool aPlaintext);
277 : nsresult PopListItem(nsIDOMNode *aListItem, bool *aOutOfList);
278 : nsresult RemoveListStructure(nsIDOMNode *aList);
279 : nsresult CacheInlineStyles(nsIDOMNode *aNode);
280 : nsresult ReapplyCachedStyles();
281 : nsresult ClearCachedStyles();
282 : nsresult AdjustSpecialBreaks(bool aSafeToAskFrames = false);
283 : nsresult AdjustWhitespace(nsISelection *aSelection);
284 : nsresult PinSelectionToNewBlock(nsISelection *aSelection);
285 : nsresult CheckInterlinePosition(nsISelection *aSelection);
286 : nsresult AdjustSelection(nsISelection *aSelection, nsIEditor::EDirection aAction);
287 : nsresult FindNearSelectableNode(nsIDOMNode *aSelNode,
288 : PRInt32 aSelOffset,
289 : nsIEditor::EDirection &aDirection,
290 : nsCOMPtr<nsIDOMNode> *outSelectableNode);
291 : nsresult InDifferentTableElements(nsIDOMNode *aNode1, nsIDOMNode *aNode2, bool *aResult);
292 : nsresult RemoveEmptyNodes();
293 : nsresult SelectionEndpointInNode(nsIDOMNode *aNode, bool *aResult);
294 : nsresult UpdateDocChangeRange(nsIDOMRange *aRange);
295 : nsresult ConfirmSelectionInBody();
296 : nsresult InsertMozBRIfNeeded(nsIDOMNode *aNode);
297 : bool IsEmptyInline(nsIDOMNode *aNode);
298 : bool ListIsEmptyLine(nsCOMArray<nsIDOMNode> &arrayOfNodes);
299 : nsresult RemoveAlignment(nsIDOMNode * aNode, const nsAString & aAlignType, bool aChildrenOnly);
300 : nsresult MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode, bool aStarts);
301 : nsresult AlignBlock(nsIDOMElement * aElement, const nsAString * aAlignType, bool aContentsOnly);
302 : nsresult RelativeChangeIndentationOfElementNode(nsIDOMNode *aNode, PRInt8 aRelativeChange);
303 : void DocumentModifiedWorker();
304 :
305 : // data members
306 : protected:
307 : nsHTMLEditor *mHTMLEditor;
308 : nsRefPtr<nsRange> mDocChangeRange;
309 : bool mListenerEnabled;
310 : bool mReturnInEmptyLIKillsList;
311 : bool mDidDeleteSelection;
312 : bool mDidRangedDelete;
313 : bool mRestoreContentEditableCount;
314 : nsRefPtr<nsRange> mUtilRange;
315 : PRUint32 mJoinOffset; // need to remember an int across willJoin/didJoin...
316 : nsCOMPtr<nsIDOMNode> mNewBlock;
317 : nsRangeStore mRangeItem;
318 : StyleCache mCachedStyles[SIZE_STYLE_TABLE];
319 : };
320 :
321 : #endif //nsHTMLEditRules_h__
322 :
|