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 Communicator client 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 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either of the GNU General Public License Version 2 or later (the "GPL"),
26 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : /*
39 : * Base class for DOM Core's nsIDOMComment, nsIDOMDocumentType, nsIDOMText,
40 : * nsIDOMCDATASection, and nsIDOMProcessingInstruction nodes.
41 : */
42 :
43 : #ifndef nsGenericDOMDataNode_h___
44 : #define nsGenericDOMDataNode_h___
45 :
46 : #include "nsIContent.h"
47 :
48 : #include "nsTextFragment.h"
49 : #include "nsDOMError.h"
50 : #include "nsEventListenerManager.h"
51 : #include "nsGenericElement.h"
52 : #include "nsCycleCollectionParticipant.h"
53 :
54 : #include "nsISMILAttr.h"
55 :
56 : // This bit is set to indicate that if the text node changes to
57 : // non-whitespace, we may need to create a frame for it. This bit must
58 : // not be set on nodes that already have a frame.
59 : #define NS_CREATE_FRAME_IF_NON_WHITESPACE (1 << NODE_TYPE_SPECIFIC_BITS_OFFSET)
60 :
61 : // This bit is set to indicate that if the text node changes to
62 : // whitespace, we may need to reframe it (or its ancestors).
63 : #define NS_REFRAME_IF_WHITESPACE (1 << (NODE_TYPE_SPECIFIC_BITS_OFFSET + 1))
64 :
65 : // Make sure we have enough space for those bits
66 : PR_STATIC_ASSERT(NODE_TYPE_SPECIFIC_BITS_OFFSET + 1 < 32);
67 :
68 : class nsIDOMAttr;
69 : class nsIDOMEventListener;
70 : class nsIDOMNodeList;
71 : class nsIFrame;
72 : class nsIDOMText;
73 : class nsINodeInfo;
74 : class nsURI;
75 :
76 : class nsGenericDOMDataNode : public nsIContent
77 : {
78 : public:
79 76040 : NS_DECL_CYCLE_COLLECTING_ISUPPORTS
80 :
81 : NS_DECL_SIZEOF_EXCLUDING_THIS
82 :
83 : nsGenericDOMDataNode(already_AddRefed<nsINodeInfo> aNodeInfo);
84 : virtual ~nsGenericDOMDataNode();
85 :
86 : // Implementation for nsIDOMNode
87 0 : nsresult GetNodeName(nsAString& aNodeName)
88 : {
89 0 : aNodeName = NodeName();
90 0 : return NS_OK;
91 : }
92 141 : nsresult GetNodeType(PRUint16* aNodeType)
93 : {
94 141 : *aNodeType = NodeType();
95 141 : return NS_OK;
96 : }
97 : nsresult GetNodeValue(nsAString& aNodeValue);
98 : nsresult SetNodeValue(const nsAString& aNodeValue);
99 0 : nsresult GetAttributes(nsIDOMNamedNodeMap** aAttributes)
100 : {
101 0 : NS_ENSURE_ARG_POINTER(aAttributes);
102 0 : *aAttributes = nsnull;
103 0 : return NS_OK;
104 : }
105 0 : nsresult HasChildNodes(bool* aHasChildNodes)
106 : {
107 0 : NS_ENSURE_ARG_POINTER(aHasChildNodes);
108 0 : *aHasChildNodes = false;
109 0 : return NS_OK;
110 : }
111 0 : nsresult HasAttributes(bool* aHasAttributes)
112 : {
113 0 : NS_ENSURE_ARG_POINTER(aHasAttributes);
114 0 : *aHasAttributes = false;
115 0 : return NS_OK;
116 : }
117 0 : nsresult InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
118 : nsIDOMNode** aReturn)
119 : {
120 0 : return ReplaceOrInsertBefore(false, aNewChild, aRefChild, aReturn);
121 : }
122 0 : nsresult ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
123 : nsIDOMNode** aReturn)
124 : {
125 0 : return ReplaceOrInsertBefore(true, aNewChild, aOldChild, aReturn);
126 : }
127 0 : nsresult RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
128 : {
129 0 : return nsINode::RemoveChild(aOldChild, aReturn);
130 : }
131 0 : nsresult AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
132 : {
133 0 : return InsertBefore(aNewChild, nsnull, aReturn);
134 : }
135 : nsresult GetNamespaceURI(nsAString& aNamespaceURI);
136 170 : nsresult GetLocalName(nsAString& aLocalName)
137 : {
138 170 : aLocalName = LocalName();
139 170 : return NS_OK;
140 : }
141 : nsresult GetPrefix(nsAString& aPrefix);
142 : nsresult IsSupported(const nsAString& aFeature,
143 : const nsAString& aVersion,
144 : bool* aReturn);
145 98 : nsresult CloneNode(bool aDeep, PRUint8 aOptionalArgc, nsIDOMNode** aReturn)
146 : {
147 98 : if (!aOptionalArgc) {
148 0 : aDeep = true;
149 : }
150 :
151 98 : return nsNodeUtils::CloneNodeImpl(this, aDeep, true, aReturn);
152 : }
153 :
154 : // Implementation for nsIDOMCharacterData
155 : nsresult GetData(nsAString& aData) const;
156 : nsresult SetData(const nsAString& aData);
157 : nsresult GetLength(PRUint32* aLength);
158 : nsresult SubstringData(PRUint32 aOffset, PRUint32 aCount,
159 : nsAString& aReturn);
160 : nsresult AppendData(const nsAString& aArg);
161 : nsresult InsertData(PRUint32 aOffset, const nsAString& aArg);
162 : nsresult DeleteData(PRUint32 aOffset, PRUint32 aCount);
163 : nsresult ReplaceData(PRUint32 aOffset, PRUint32 aCount,
164 : const nsAString& aArg);
165 :
166 : // nsINode methods
167 : virtual PRUint32 GetChildCount() const;
168 : virtual nsIContent *GetChildAt(PRUint32 aIndex) const;
169 : virtual nsIContent * const * GetChildArray(PRUint32* aChildCount) const;
170 : virtual PRInt32 IndexOf(nsINode* aPossibleChild) const;
171 : virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
172 : bool aNotify);
173 : virtual nsresult RemoveChildAt(PRUint32 aIndex, bool aNotify);
174 0 : NS_IMETHOD GetTextContent(nsAString &aTextContent)
175 : {
176 0 : nsresult rv = GetNodeValue(aTextContent);
177 0 : NS_ASSERTION(NS_SUCCEEDED(rv), "GetNodeValue() failed?");
178 0 : return rv;
179 : }
180 0 : NS_IMETHOD SetTextContent(const nsAString& aTextContent)
181 : {
182 : // Batch possible DOMSubtreeModified events.
183 0 : mozAutoSubtreeModified subtree(OwnerDoc(), nsnull);
184 0 : return SetNodeValue(aTextContent);
185 : }
186 :
187 : // Implementation for nsIContent
188 : virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
189 : nsIContent* aBindingParent,
190 : bool aCompileEventHandlers);
191 : virtual void UnbindFromTree(bool aDeep = true,
192 : bool aNullParent = true);
193 :
194 : virtual already_AddRefed<nsINodeList> GetChildren(PRUint32 aFilter);
195 :
196 : virtual nsIAtom *GetIDAttributeName() const;
197 : virtual already_AddRefed<nsINodeInfo> GetExistingAttrNameFromQName(const nsAString& aStr) const;
198 : nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
199 : const nsAString& aValue, bool aNotify)
200 : {
201 : return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
202 : }
203 : virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
204 : nsIAtom* aPrefix, const nsAString& aValue,
205 : bool aNotify);
206 : virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
207 : bool aNotify);
208 : virtual bool GetAttr(PRInt32 aNameSpaceID, nsIAtom *aAttribute,
209 : nsAString& aResult) const;
210 : virtual bool HasAttr(PRInt32 aNameSpaceID, nsIAtom *aAttribute) const;
211 : virtual const nsAttrName* GetAttrNameAt(PRUint32 aIndex) const;
212 : virtual PRUint32 GetAttrCount() const;
213 : virtual const nsTextFragment *GetText();
214 : virtual PRUint32 TextLength();
215 : virtual nsresult SetText(const PRUnichar* aBuffer, PRUint32 aLength,
216 : bool aNotify);
217 : // Need to implement this here too to avoid hiding.
218 0 : nsresult SetText(const nsAString& aStr, bool aNotify)
219 : {
220 0 : return SetText(aStr.BeginReading(), aStr.Length(), aNotify);
221 : }
222 : virtual nsresult AppendText(const PRUnichar* aBuffer, PRUint32 aLength,
223 : bool aNotify);
224 : virtual bool TextIsOnlyWhitespace();
225 : virtual void AppendTextTo(nsAString& aResult);
226 : virtual void DestroyContent();
227 : virtual void SaveSubtreeState();
228 :
229 0 : virtual nsISMILAttr* GetAnimatedAttr(PRInt32 /*aNamespaceID*/, nsIAtom* /*aName*/)
230 : {
231 0 : return nsnull;
232 : }
233 : virtual nsIDOMCSSStyleDeclaration* GetSMILOverrideStyle();
234 : virtual mozilla::css::StyleRule* GetSMILOverrideStyleRule();
235 : virtual nsresult SetSMILOverrideStyleRule(mozilla::css::StyleRule* aStyleRule,
236 : bool aNotify);
237 :
238 : #ifdef DEBUG
239 : virtual void List(FILE* out, PRInt32 aIndent) const;
240 : virtual void DumpContent(FILE* out, PRInt32 aIndent, bool aDumpAll) const;
241 : #endif
242 :
243 : virtual nsIContent *GetBindingParent() const;
244 : virtual bool IsNodeOfType(PRUint32 aFlags) const;
245 : virtual bool IsLink(nsIURI** aURI) const;
246 :
247 : virtual nsIAtom* DoGetID() const;
248 : virtual const nsAttrValue* DoGetClasses() const;
249 : NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
250 : virtual mozilla::css::StyleRule* GetInlineStyleRule();
251 : NS_IMETHOD SetInlineStyleRule(mozilla::css::StyleRule* aStyleRule, bool aNotify);
252 : NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
253 : virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
254 : PRInt32 aModType) const;
255 : virtual nsIAtom *GetClassAttributeName() const;
256 :
257 517 : virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
258 : {
259 517 : *aResult = CloneDataNode(aNodeInfo, true);
260 517 : if (!*aResult) {
261 0 : return NS_ERROR_OUT_OF_MEMORY;
262 : }
263 :
264 517 : NS_ADDREF(*aResult);
265 :
266 517 : return NS_OK;
267 : }
268 :
269 : nsresult SplitData(PRUint32 aOffset, nsIContent** aReturn,
270 : bool aCloneAfterOriginal = true);
271 :
272 : //----------------------------------------
273 :
274 : #ifdef DEBUG
275 : void ToCString(nsAString& aBuf, PRInt32 aOffset, PRInt32 aLen) const;
276 : #endif
277 :
278 2622382 : NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsGenericDOMDataNode)
279 :
280 : protected:
281 0 : virtual mozilla::dom::Element* GetNameSpaceElement()
282 : {
283 0 : nsINode *parent = GetNodeParent();
284 :
285 0 : return parent && parent->IsElement() ? parent->AsElement() : nsnull;
286 : }
287 :
288 : /**
289 : * There are a set of DOM- and scripting-specific instance variables
290 : * that may only be instantiated when a content object is accessed
291 : * through the DOM. Rather than burn actual slots in the content
292 : * objects for each of these instance variables, we put them off
293 : * in a side structure that's only allocated when the content is
294 : * accessed through the DOM.
295 : */
296 : class nsDataSlots : public nsINode::nsSlots
297 92 : {
298 : public:
299 23 : nsDataSlots()
300 : : nsINode::nsSlots(),
301 23 : mBindingParent(nsnull)
302 : {
303 23 : }
304 :
305 : /**
306 : * The nearest enclosing content node with a binding that created us.
307 : * @see nsIContent::GetBindingParent
308 : */
309 : nsIContent* mBindingParent; // [Weak]
310 : };
311 :
312 : // Override from nsINode
313 : virtual nsINode::nsSlots* CreateSlots();
314 :
315 0 : nsDataSlots *GetDataSlots()
316 : {
317 0 : return static_cast<nsDataSlots*>(GetSlots());
318 : }
319 :
320 405543 : nsDataSlots *GetExistingDataSlots() const
321 : {
322 405543 : return static_cast<nsDataSlots*>(GetExistingSlots());
323 : }
324 :
325 : nsresult SplitText(PRUint32 aOffset, nsIDOMText** aReturn);
326 :
327 : nsresult GetWholeText(nsAString& aWholeText);
328 :
329 : static PRInt32 FirstLogicallyAdjacentTextNode(nsIContent* aParent,
330 : PRInt32 aIndex);
331 :
332 : static PRInt32 LastLogicallyAdjacentTextNode(nsIContent* aParent,
333 : PRInt32 aIndex,
334 : PRUint32 aCount);
335 :
336 : nsresult SetTextInternal(PRUint32 aOffset, PRUint32 aCount,
337 : const PRUnichar* aBuffer, PRUint32 aLength,
338 : bool aNotify,
339 : CharacterDataChangeInfo::Details* aDetails = nsnull);
340 :
341 : /**
342 : * Method to clone this node. This needs to be overriden by all derived
343 : * classes. If aCloneText is true the text content will be cloned too.
344 : *
345 : * @param aOwnerDocument the ownerDocument of the clone
346 : * @param aCloneText if true the text content will be cloned too
347 : * @return the clone
348 : */
349 : virtual nsGenericDOMDataNode *CloneDataNode(nsINodeInfo *aNodeInfo,
350 : bool aCloneText) const = 0;
351 :
352 : nsTextFragment mText;
353 :
354 : public:
355 212339 : virtual bool IsPurple()
356 : {
357 212339 : return mRefCnt.IsPurple();
358 : }
359 0 : virtual void RemovePurple()
360 : {
361 0 : mRefCnt.RemovePurple();
362 0 : }
363 :
364 : private:
365 : already_AddRefed<nsIAtom> GetCurrentValueAtom();
366 : };
367 :
368 : #endif /* nsGenericDOMDataNode_h___ */
|