Thu, 15 Jan 2015 21:03:48 +0100
Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)
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 /*
7 * Implementation of the |attributes| property of DOM Core's Element object.
8 */
10 #ifndef nsDOMAttributeMap_h
11 #define nsDOMAttributeMap_h
13 #include "mozilla/MemoryReporting.h"
14 #include "mozilla/dom/Attr.h"
15 #include "mozilla/ErrorResult.h"
16 #include "nsCycleCollectionParticipant.h"
17 #include "nsIDOMMozNamedAttrMap.h"
18 #include "nsRefPtrHashtable.h"
19 #include "nsString.h"
20 #include "nsWrapperCache.h"
22 class nsIAtom;
23 class nsINodeInfo;
24 class nsIDocument;
26 /**
27 * Structure used as a key for caching Attrs in nsDOMAttributeMap's mAttributeCache.
28 */
29 class nsAttrKey
30 {
31 public:
32 /**
33 * The namespace of the attribute
34 */
35 int32_t mNamespaceID;
37 /**
38 * The atom for attribute, weak ref. is fine as we only use it for the
39 * hashcode, we never dereference it.
40 */
41 nsIAtom* mLocalName;
43 nsAttrKey(int32_t aNs, nsIAtom* aName)
44 : mNamespaceID(aNs), mLocalName(aName) {}
46 nsAttrKey(const nsAttrKey& aAttr)
47 : mNamespaceID(aAttr.mNamespaceID), mLocalName(aAttr.mLocalName) {}
48 };
50 /**
51 * PLDHashEntryHdr implementation for nsAttrKey.
52 */
53 class nsAttrHashKey : public PLDHashEntryHdr
54 {
55 public:
56 typedef const nsAttrKey& KeyType;
57 typedef const nsAttrKey* KeyTypePointer;
59 nsAttrHashKey(KeyTypePointer aKey) : mKey(*aKey) {}
60 nsAttrHashKey(const nsAttrHashKey& aCopy) : mKey(aCopy.mKey) {}
61 ~nsAttrHashKey() {}
63 KeyType GetKey() const { return mKey; }
64 bool KeyEquals(KeyTypePointer aKey) const
65 {
66 return mKey.mLocalName == aKey->mLocalName &&
67 mKey.mNamespaceID == aKey->mNamespaceID;
68 }
70 static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
71 static PLDHashNumber HashKey(KeyTypePointer aKey)
72 {
73 if (!aKey)
74 return 0;
76 return mozilla::HashGeneric(aKey->mNamespaceID, aKey->mLocalName);
77 }
78 enum { ALLOW_MEMMOVE = true };
80 private:
81 nsAttrKey mKey;
82 };
84 // Helper class that implements the nsIDOMMozNamedAttrMap interface.
85 class nsDOMAttributeMap : public nsIDOMMozNamedAttrMap
86 , public nsWrapperCache
87 {
88 public:
89 typedef mozilla::dom::Attr Attr;
90 typedef mozilla::dom::Element Element;
91 typedef mozilla::ErrorResult ErrorResult;
93 nsDOMAttributeMap(Element *aContent);
94 virtual ~nsDOMAttributeMap();
96 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
97 NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsDOMAttributeMap)
99 // nsIDOMMozNamedAttrMap interface
100 NS_DECL_NSIDOMMOZNAMEDATTRMAP
102 void DropReference();
104 Element* GetContent()
105 {
106 return mContent;
107 }
109 /**
110 * Called when mContent is moved into a new document.
111 * Updates the nodeinfos of all owned nodes.
112 */
113 nsresult SetOwnerDocument(nsIDocument* aDocument);
115 /**
116 * Drop an attribute from the map's cache (does not remove the attribute
117 * from the node!)
118 */
119 void DropAttribute(int32_t aNamespaceID, nsIAtom* aLocalName);
121 /**
122 * Returns the number of attribute nodes currently in the map.
123 * Note: this is just the number of cached attribute nodes, not the number of
124 * attributes in mContent.
125 *
126 * @return The number of attribute nodes in the map.
127 */
128 uint32_t Count() const;
130 typedef nsRefPtrHashtable<nsAttrHashKey, Attr> AttrCache;
132 /**
133 * Enumerates over the attribute nodess in the map and calls aFunc for each
134 * one. If aFunc returns PL_DHASH_STOP we'll stop enumerating at that point.
135 *
136 * @return The number of attribute nodes that aFunc was called for.
137 */
138 uint32_t Enumerate(AttrCache::EnumReadFunction aFunc, void *aUserArg) const;
140 Element* GetParentObject() const
141 {
142 return mContent;
143 }
144 virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
146 // WebIDL
147 Attr* GetNamedItem(const nsAString& aAttrName);
148 Attr* NamedGetter(const nsAString& aAttrName, bool& aFound);
149 bool NameIsEnumerable(const nsAString& aName);
150 already_AddRefed<Attr>
151 SetNamedItem(Attr& aAttr, ErrorResult& aError)
152 {
153 return SetNamedItemInternal(aAttr, false, aError);
154 }
155 already_AddRefed<Attr>
156 RemoveNamedItem(const nsAString& aName, ErrorResult& aError);
158 Attr* Item(uint32_t aIndex);
159 Attr* IndexedGetter(uint32_t aIndex, bool& aFound);
160 uint32_t Length() const;
162 Attr*
163 GetNamedItemNS(const nsAString& aNamespaceURI,
164 const nsAString& aLocalName);
165 already_AddRefed<Attr>
166 SetNamedItemNS(Attr& aNode, ErrorResult& aError)
167 {
168 return SetNamedItemInternal(aNode, true, aError);
169 }
170 already_AddRefed<Attr>
171 RemoveNamedItemNS(const nsAString& aNamespaceURI, const nsAString& aLocalName,
172 ErrorResult& aError);
174 void GetSupportedNames(unsigned, nsTArray<nsString>& aNames)
175 {
176 // No supported names we want to show up in iteration.
177 }
179 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
181 private:
182 nsCOMPtr<Element> mContent;
184 /**
185 * Cache of Attrs.
186 */
187 AttrCache mAttributeCache;
189 /**
190 * SetNamedItem() (aWithNS = false) and SetNamedItemNS() (aWithNS =
191 * true) implementation.
192 */
193 already_AddRefed<Attr>
194 SetNamedItemInternal(Attr& aNode, bool aWithNS, ErrorResult& aError);
196 already_AddRefed<nsINodeInfo>
197 GetAttrNodeInfo(const nsAString& aNamespaceURI,
198 const nsAString& aLocalName);
200 Attr* GetAttribute(nsINodeInfo* aNodeInfo, bool aNsAware);
202 /**
203 * Remove an attribute, returns the removed node.
204 */
205 already_AddRefed<Attr> RemoveAttribute(nsINodeInfo* aNodeInfo);
206 };
208 // XXX khuey yes this is crazy. The bindings code needs to see this include,
209 // but if we pull it in at the top of the file we get a circular include
210 // problem.
211 #include "mozilla/dom/Element.h"
213 #endif /* nsDOMAttributeMap_h */