1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/base/src/nsGenericDOMDataNode.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,332 @@ 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 +/* 1.10 + * Base class for DOM Core's nsIDOMComment, nsIDOMDocumentType, nsIDOMText, 1.11 + * nsIDOMCDATASection, and nsIDOMProcessingInstruction nodes. 1.12 + */ 1.13 + 1.14 +#ifndef nsGenericDOMDataNode_h___ 1.15 +#define nsGenericDOMDataNode_h___ 1.16 + 1.17 +#include "mozilla/Attributes.h" 1.18 +#include "nsIContent.h" 1.19 + 1.20 +#include "nsTextFragment.h" 1.21 +#include "nsError.h" 1.22 +#include "mozilla/dom/Element.h" 1.23 +#include "nsCycleCollectionParticipant.h" 1.24 + 1.25 +#include "nsISMILAttr.h" 1.26 +#include "nsIDocument.h" 1.27 + 1.28 +class nsIDOMAttr; 1.29 +class nsIDOMEventListener; 1.30 +class nsIDOMNodeList; 1.31 +class nsIFrame; 1.32 +class nsIDOMText; 1.33 +class nsINodeInfo; 1.34 +class nsURI; 1.35 + 1.36 +#define DATA_NODE_FLAG_BIT(n_) NODE_FLAG_BIT(NODE_TYPE_SPECIFIC_BITS_OFFSET + (n_)) 1.37 + 1.38 +// Data node specific flags 1.39 +enum { 1.40 + // This bit is set to indicate that if the text node changes to 1.41 + // non-whitespace, we may need to create a frame for it. This bit must 1.42 + // not be set on nodes that already have a frame. 1.43 + NS_CREATE_FRAME_IF_NON_WHITESPACE = DATA_NODE_FLAG_BIT(0), 1.44 + 1.45 + // This bit is set to indicate that if the text node changes to 1.46 + // whitespace, we may need to reframe it (or its ancestors). 1.47 + NS_REFRAME_IF_WHITESPACE = DATA_NODE_FLAG_BIT(1), 1.48 + 1.49 + // This bit is set to indicate that we have a cached 1.50 + // TextIsOnlyWhitespace value 1.51 + NS_CACHED_TEXT_IS_ONLY_WHITESPACE = DATA_NODE_FLAG_BIT(2), 1.52 + 1.53 + // This bit is only meaningful if the NS_CACHED_TEXT_IS_ONLY_WHITESPACE 1.54 + // bit is set, and if so it indicates whether we're only whitespace or 1.55 + // not. 1.56 + NS_TEXT_IS_ONLY_WHITESPACE = DATA_NODE_FLAG_BIT(3), 1.57 +}; 1.58 + 1.59 +// Make sure we have enough space for those bits 1.60 +ASSERT_NODE_FLAGS_SPACE(NODE_TYPE_SPECIFIC_BITS_OFFSET + 4); 1.61 + 1.62 +#undef DATA_NODE_FLAG_BIT 1.63 + 1.64 +class nsGenericDOMDataNode : public nsIContent 1.65 +{ 1.66 +public: 1.67 + NS_DECL_CYCLE_COLLECTING_ISUPPORTS 1.68 + 1.69 + NS_DECL_SIZEOF_EXCLUDING_THIS 1.70 + 1.71 + nsGenericDOMDataNode(already_AddRefed<nsINodeInfo>& aNodeInfo); 1.72 + nsGenericDOMDataNode(already_AddRefed<nsINodeInfo>&& aNodeInfo); 1.73 + virtual ~nsGenericDOMDataNode(); 1.74 + 1.75 + virtual void GetNodeValueInternal(nsAString& aNodeValue) MOZ_OVERRIDE; 1.76 + virtual void SetNodeValueInternal(const nsAString& aNodeValue, 1.77 + mozilla::ErrorResult& aError) MOZ_OVERRIDE; 1.78 + 1.79 + // Implementation for nsIDOMCharacterData 1.80 + nsresult GetData(nsAString& aData) const; 1.81 + nsresult SetData(const nsAString& aData); 1.82 + nsresult GetLength(uint32_t* aLength); 1.83 + nsresult SubstringData(uint32_t aOffset, uint32_t aCount, 1.84 + nsAString& aReturn); 1.85 + nsresult AppendData(const nsAString& aArg); 1.86 + nsresult InsertData(uint32_t aOffset, const nsAString& aArg); 1.87 + nsresult DeleteData(uint32_t aOffset, uint32_t aCount); 1.88 + nsresult ReplaceData(uint32_t aOffset, uint32_t aCount, 1.89 + const nsAString& aArg); 1.90 + NS_IMETHOD MozRemove(); 1.91 + 1.92 + // nsINode methods 1.93 + virtual uint32_t GetChildCount() const MOZ_OVERRIDE; 1.94 + virtual nsIContent *GetChildAt(uint32_t aIndex) const MOZ_OVERRIDE; 1.95 + virtual nsIContent * const * GetChildArray(uint32_t* aChildCount) const MOZ_OVERRIDE; 1.96 + virtual int32_t IndexOf(const nsINode* aPossibleChild) const MOZ_OVERRIDE; 1.97 + virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex, 1.98 + bool aNotify) MOZ_OVERRIDE; 1.99 + virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) MOZ_OVERRIDE; 1.100 + virtual void GetTextContentInternal(nsAString& aTextContent) MOZ_OVERRIDE 1.101 + { 1.102 + GetNodeValue(aTextContent); 1.103 + } 1.104 + virtual void SetTextContentInternal(const nsAString& aTextContent, 1.105 + mozilla::ErrorResult& aError) MOZ_OVERRIDE 1.106 + { 1.107 + // Batch possible DOMSubtreeModified events. 1.108 + mozAutoSubtreeModified subtree(OwnerDoc(), nullptr); 1.109 + return SetNodeValue(aTextContent, aError); 1.110 + } 1.111 + 1.112 + // Implementation for nsIContent 1.113 + virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, 1.114 + nsIContent* aBindingParent, 1.115 + bool aCompileEventHandlers) MOZ_OVERRIDE; 1.116 + virtual void UnbindFromTree(bool aDeep = true, 1.117 + bool aNullParent = true) MOZ_OVERRIDE; 1.118 + 1.119 + virtual already_AddRefed<nsINodeList> GetChildren(uint32_t aFilter) MOZ_OVERRIDE; 1.120 + 1.121 + virtual nsIAtom *GetIDAttributeName() const MOZ_OVERRIDE; 1.122 + 1.123 + nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName, 1.124 + const nsAString& aValue, bool aNotify) 1.125 + { 1.126 + return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify); 1.127 + } 1.128 + virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute, 1.129 + nsIAtom* aPrefix, const nsAString& aValue, 1.130 + bool aNotify) MOZ_OVERRIDE; 1.131 + virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute, 1.132 + bool aNotify) MOZ_OVERRIDE; 1.133 + virtual const nsAttrName* GetAttrNameAt(uint32_t aIndex) const MOZ_OVERRIDE; 1.134 + virtual uint32_t GetAttrCount() const MOZ_OVERRIDE; 1.135 + virtual const nsTextFragment *GetText() MOZ_OVERRIDE; 1.136 + virtual uint32_t TextLength() const MOZ_OVERRIDE; 1.137 + virtual nsresult SetText(const char16_t* aBuffer, uint32_t aLength, 1.138 + bool aNotify) MOZ_OVERRIDE; 1.139 + // Need to implement this here too to avoid hiding. 1.140 + nsresult SetText(const nsAString& aStr, bool aNotify) 1.141 + { 1.142 + return SetText(aStr.BeginReading(), aStr.Length(), aNotify); 1.143 + } 1.144 + virtual nsresult AppendText(const char16_t* aBuffer, uint32_t aLength, 1.145 + bool aNotify) MOZ_OVERRIDE; 1.146 + virtual bool TextIsOnlyWhitespace() MOZ_OVERRIDE; 1.147 + virtual bool HasTextForTranslation() MOZ_OVERRIDE; 1.148 + virtual void AppendTextTo(nsAString& aResult) MOZ_OVERRIDE; 1.149 + virtual bool AppendTextTo(nsAString& aResult, 1.150 + const mozilla::fallible_t&) MOZ_OVERRIDE NS_WARN_UNUSED_RESULT; 1.151 + virtual void DestroyContent() MOZ_OVERRIDE; 1.152 + virtual void SaveSubtreeState() MOZ_OVERRIDE; 1.153 + 1.154 +#ifdef DEBUG 1.155 + virtual void List(FILE* out, int32_t aIndent) const MOZ_OVERRIDE; 1.156 + virtual void DumpContent(FILE* out, int32_t aIndent, bool aDumpAll) const MOZ_OVERRIDE; 1.157 +#endif 1.158 + 1.159 + virtual nsIContent *GetBindingParent() const MOZ_OVERRIDE; 1.160 + virtual nsXBLBinding *GetXBLBinding() const MOZ_OVERRIDE; 1.161 + virtual void SetXBLBinding(nsXBLBinding* aBinding, 1.162 + nsBindingManager* aOldBindingManager = nullptr) MOZ_OVERRIDE; 1.163 + virtual mozilla::dom::ShadowRoot *GetContainingShadow() const MOZ_OVERRIDE; 1.164 + virtual mozilla::dom::ShadowRoot *GetShadowRoot() const MOZ_OVERRIDE; 1.165 + virtual void SetShadowRoot(mozilla::dom::ShadowRoot* aShadowRoot) MOZ_OVERRIDE; 1.166 + virtual nsIContent *GetXBLInsertionParent() const MOZ_OVERRIDE; 1.167 + virtual void SetXBLInsertionParent(nsIContent* aContent) MOZ_OVERRIDE; 1.168 + virtual bool IsNodeOfType(uint32_t aFlags) const MOZ_OVERRIDE; 1.169 + virtual bool IsLink(nsIURI** aURI) const MOZ_OVERRIDE; 1.170 + 1.171 + virtual mozilla::dom::CustomElementData* GetCustomElementData() const MOZ_OVERRIDE; 1.172 + virtual void SetCustomElementData(mozilla::dom::CustomElementData* aData) MOZ_OVERRIDE; 1.173 + 1.174 + virtual nsIAtom* DoGetID() const MOZ_OVERRIDE; 1.175 + virtual const nsAttrValue* DoGetClasses() const MOZ_OVERRIDE; 1.176 + NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) MOZ_OVERRIDE; 1.177 + NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const; 1.178 + virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute, 1.179 + int32_t aModType) const; 1.180 + virtual nsIAtom *GetClassAttributeName() const; 1.181 + 1.182 + virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE 1.183 + { 1.184 + *aResult = CloneDataNode(aNodeInfo, true); 1.185 + if (!*aResult) { 1.186 + return NS_ERROR_OUT_OF_MEMORY; 1.187 + } 1.188 + 1.189 + NS_ADDREF(*aResult); 1.190 + 1.191 + return NS_OK; 1.192 + } 1.193 + 1.194 + nsresult SplitData(uint32_t aOffset, nsIContent** aReturn, 1.195 + bool aCloneAfterOriginal = true); 1.196 + 1.197 + // WebIDL API 1.198 + // Our XPCOM GetData is just fine for WebIDL 1.199 + virtual void SetData(const nsAString& aData, mozilla::ErrorResult& rv) 1.200 + { 1.201 + rv = SetData(aData); 1.202 + } 1.203 + // nsINode::Length() returns the right thing for our length attribute 1.204 + void SubstringData(uint32_t aStart, uint32_t aCount, nsAString& aReturn, 1.205 + mozilla::ErrorResult& rv); 1.206 + void AppendData(const nsAString& aData, mozilla::ErrorResult& rv) 1.207 + { 1.208 + rv = AppendData(aData); 1.209 + } 1.210 + void InsertData(uint32_t aOffset, const nsAString& aData, 1.211 + mozilla::ErrorResult& rv) 1.212 + { 1.213 + rv = InsertData(aOffset, aData); 1.214 + } 1.215 + void DeleteData(uint32_t aOffset, uint32_t aCount, mozilla::ErrorResult& rv) 1.216 + { 1.217 + rv = DeleteData(aOffset, aCount); 1.218 + } 1.219 + void ReplaceData(uint32_t aOffset, uint32_t aCount, const nsAString& aData, 1.220 + mozilla::ErrorResult& rv) 1.221 + { 1.222 + rv = ReplaceData(aOffset, aCount, aData); 1.223 + } 1.224 + 1.225 + //---------------------------------------- 1.226 + 1.227 +#ifdef DEBUG 1.228 + void ToCString(nsAString& aBuf, int32_t aOffset, int32_t aLen) const; 1.229 +#endif 1.230 + 1.231 + NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsGenericDOMDataNode) 1.232 + 1.233 +protected: 1.234 + virtual mozilla::dom::Element* GetNameSpaceElement() 1.235 + { 1.236 + nsINode *parent = GetParentNode(); 1.237 + 1.238 + return parent && parent->IsElement() ? parent->AsElement() : nullptr; 1.239 + } 1.240 + 1.241 + /** 1.242 + * There are a set of DOM- and scripting-specific instance variables 1.243 + * that may only be instantiated when a content object is accessed 1.244 + * through the DOM. Rather than burn actual slots in the content 1.245 + * objects for each of these instance variables, we put them off 1.246 + * in a side structure that's only allocated when the content is 1.247 + * accessed through the DOM. 1.248 + */ 1.249 + class nsDataSlots : public nsINode::nsSlots 1.250 + { 1.251 + public: 1.252 + nsDataSlots(); 1.253 + 1.254 + void Traverse(nsCycleCollectionTraversalCallback &cb); 1.255 + void Unlink(); 1.256 + 1.257 + /** 1.258 + * The nearest enclosing content node with a binding that created us. 1.259 + * @see nsIContent::GetBindingParent 1.260 + */ 1.261 + nsIContent* mBindingParent; // [Weak] 1.262 + 1.263 + /** 1.264 + * @see nsIContent::GetXBLInsertionParent 1.265 + */ 1.266 + nsCOMPtr<nsIContent> mXBLInsertionParent; 1.267 + 1.268 + /** 1.269 + * @see nsIContent::GetContainingShadow 1.270 + */ 1.271 + nsRefPtr<mozilla::dom::ShadowRoot> mContainingShadow; 1.272 + }; 1.273 + 1.274 + // Override from nsINode 1.275 + virtual nsINode::nsSlots* CreateSlots() MOZ_OVERRIDE; 1.276 + 1.277 + nsDataSlots* DataSlots() 1.278 + { 1.279 + return static_cast<nsDataSlots*>(Slots()); 1.280 + } 1.281 + 1.282 + nsDataSlots *GetExistingDataSlots() const 1.283 + { 1.284 + return static_cast<nsDataSlots*>(GetExistingSlots()); 1.285 + } 1.286 + 1.287 + nsresult SplitText(uint32_t aOffset, nsIDOMText** aReturn); 1.288 + 1.289 + nsresult GetWholeText(nsAString& aWholeText); 1.290 + 1.291 + static int32_t FirstLogicallyAdjacentTextNode(nsIContent* aParent, 1.292 + int32_t aIndex); 1.293 + 1.294 + static int32_t LastLogicallyAdjacentTextNode(nsIContent* aParent, 1.295 + int32_t aIndex, 1.296 + uint32_t aCount); 1.297 + 1.298 + nsresult SetTextInternal(uint32_t aOffset, uint32_t aCount, 1.299 + const char16_t* aBuffer, uint32_t aLength, 1.300 + bool aNotify, 1.301 + CharacterDataChangeInfo::Details* aDetails = nullptr); 1.302 + 1.303 + /** 1.304 + * Method to clone this node. This needs to be overriden by all derived 1.305 + * classes. If aCloneText is true the text content will be cloned too. 1.306 + * 1.307 + * @param aOwnerDocument the ownerDocument of the clone 1.308 + * @param aCloneText if true the text content will be cloned too 1.309 + * @return the clone 1.310 + */ 1.311 + virtual nsGenericDOMDataNode *CloneDataNode(nsINodeInfo *aNodeInfo, 1.312 + bool aCloneText) const = 0; 1.313 + 1.314 + nsTextFragment mText; 1.315 + 1.316 +public: 1.317 + virtual bool OwnedOnlyByTheDOMTree() MOZ_OVERRIDE 1.318 + { 1.319 + return GetParent() && mRefCnt.get() == 1; 1.320 + } 1.321 + 1.322 + virtual bool IsPurple() MOZ_OVERRIDE 1.323 + { 1.324 + return mRefCnt.IsPurple(); 1.325 + } 1.326 + virtual void RemovePurple() MOZ_OVERRIDE 1.327 + { 1.328 + mRefCnt.RemovePurple(); 1.329 + } 1.330 + 1.331 +private: 1.332 + already_AddRefed<nsIAtom> GetCurrentValueAtom(); 1.333 +}; 1.334 + 1.335 +#endif /* nsGenericDOMDataNode_h___ */