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/. */
7 * Implementation of the |attributes| property of DOM Core's Element object.
10 #ifndef nsDOMAttributeMap_h
11 #define nsDOMAttributeMap_h
13 #include "mozilla/MemoryReporting.h"
14 #include "mozilla/UniquePtr.h"
15 #include "mozilla/dom/Attr.h"
16 #include "mozilla/ErrorResult.h"
17 #include "nsCycleCollectionParticipant.h"
18 #include "nsIDOMMozNamedAttrMap.h"
19 #include "nsRefPtrHashtable.h"
21 #include "nsWrapperCache.h"
27 * Structure used as a key for caching Attrs in nsDOMAttributeMap's mAttributeCache.
33 * The namespace of the attribute
38 * The atom for attribute, weak ref. is fine as we only use it for the
39 * hashcode, we never dereference it.
43 nsAttrKey(int32_t aNs
, nsIAtom
* aName
)
44 : mNamespaceID(aNs
), mLocalName(aName
) {}
46 nsAttrKey(const nsAttrKey
& aAttr
)
47 : mNamespaceID(aAttr
.mNamespaceID
), mLocalName(aAttr
.mLocalName
) {}
51 * PLDHashEntryHdr implementation for nsAttrKey.
53 class nsAttrHashKey
: public PLDHashEntryHdr
56 typedef const nsAttrKey
& KeyType
;
57 typedef const nsAttrKey
* KeyTypePointer
;
59 explicit nsAttrHashKey(KeyTypePointer aKey
) : mKey(*aKey
) {}
60 nsAttrHashKey(const nsAttrHashKey
& aCopy
) : mKey(aCopy
.mKey
) {}
63 KeyType
GetKey() const { return mKey
; }
64 bool KeyEquals(KeyTypePointer aKey
) const
66 return mKey
.mLocalName
== aKey
->mLocalName
&&
67 mKey
.mNamespaceID
== aKey
->mNamespaceID
;
70 static KeyTypePointer
KeyToPointer(KeyType aKey
) { return &aKey
; }
71 static PLDHashNumber
HashKey(KeyTypePointer aKey
)
76 return mozilla::HashGeneric(aKey
->mNamespaceID
, aKey
->mLocalName
);
78 enum { ALLOW_MEMMOVE
= true };
84 // Helper class that implements the nsIDOMMozNamedAttrMap interface.
85 class nsDOMAttributeMap
: public nsIDOMMozNamedAttrMap
86 , public nsWrapperCache
89 typedef mozilla::dom::Attr Attr
;
90 typedef mozilla::dom::Element Element
;
91 typedef mozilla::ErrorResult ErrorResult
;
93 explicit nsDOMAttributeMap(Element
*aContent
);
95 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
96 NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsDOMAttributeMap
)
98 // nsIDOMMozNamedAttrMap interface
99 NS_DECL_NSIDOMMOZNAMEDATTRMAP
101 void DropReference();
103 Element
* GetContent()
109 * Called when mContent is moved into a new document.
110 * Updates the nodeinfos of all owned nodes.
112 nsresult
SetOwnerDocument(nsIDocument
* aDocument
);
115 * Drop an attribute from the map's cache (does not remove the attribute
118 void DropAttribute(int32_t aNamespaceID
, nsIAtom
* aLocalName
);
121 * Returns the number of attribute nodes currently in the map.
122 * Note: this is just the number of cached attribute nodes, not the number of
123 * attributes in mContent.
125 * @return The number of attribute nodes in the map.
127 uint32_t Count() const;
129 typedef nsRefPtrHashtable
<nsAttrHashKey
, Attr
> AttrCache
;
132 * Enumerates over the attribute nodess in the map and calls aFunc for each
133 * one. If aFunc returns PL_DHASH_STOP we'll stop enumerating at that point.
135 * @return The number of attribute nodes that aFunc was called for.
137 uint32_t Enumerate(AttrCache::EnumReadFunction aFunc
, void *aUserArg
) const;
139 Element
* GetParentObject() const
143 virtual JSObject
* WrapObject(JSContext
* aCx
) MOZ_OVERRIDE
;
146 Attr
* GetNamedItem(const nsAString
& aAttrName
);
147 Attr
* NamedGetter(const nsAString
& aAttrName
, bool& aFound
);
148 bool NameIsEnumerable(const nsAString
& aName
);
149 already_AddRefed
<Attr
>
150 SetNamedItem(Attr
& aAttr
, ErrorResult
& aError
)
152 return SetNamedItemInternal(aAttr
, false, aError
);
154 already_AddRefed
<Attr
>
155 RemoveNamedItem(const nsAString
& aName
, ErrorResult
& aError
);
157 Attr
* Item(uint32_t aIndex
);
158 Attr
* IndexedGetter(uint32_t aIndex
, bool& aFound
);
159 uint32_t Length() const;
162 GetNamedItemNS(const nsAString
& aNamespaceURI
,
163 const nsAString
& aLocalName
);
164 already_AddRefed
<Attr
>
165 SetNamedItemNS(Attr
& aNode
, ErrorResult
& aError
)
167 return SetNamedItemInternal(aNode
, true, aError
);
169 already_AddRefed
<Attr
>
170 RemoveNamedItemNS(const nsAString
& aNamespaceURI
, const nsAString
& aLocalName
,
171 ErrorResult
& aError
);
173 void GetSupportedNames(unsigned, nsTArray
<nsString
>& aNames
)
175 // No supported names we want to show up in iteration.
178 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf
) const;
181 virtual ~nsDOMAttributeMap();
184 nsCOMPtr
<Element
> mContent
;
187 * Cache of Attrs. It's usually empty, and thus initialized lazily.
189 mozilla::UniquePtr
<AttrCache
> mAttributeCache
;
191 void EnsureAttributeCache();
194 * SetNamedItem() (aWithNS = false) and SetNamedItemNS() (aWithNS =
195 * true) implementation.
197 already_AddRefed
<Attr
>
198 SetNamedItemInternal(Attr
& aNode
, bool aWithNS
, ErrorResult
& aError
);
200 already_AddRefed
<mozilla::dom::NodeInfo
>
201 GetAttrNodeInfo(const nsAString
& aNamespaceURI
,
202 const nsAString
& aLocalName
);
204 Attr
* GetAttribute(mozilla::dom::NodeInfo
* aNodeInfo
, bool aNsAware
);
207 * Remove an attribute, returns the removed node.
209 already_AddRefed
<Attr
> RemoveAttribute(mozilla::dom::NodeInfo
* aNodeInfo
);
212 // XXX khuey yes this is crazy. The bindings code needs to see this include,
213 // but if we pull it in at the top of the file we get a circular include
215 #include "mozilla/dom/Element.h"
217 #endif /* nsDOMAttributeMap_h */