Bug 852135 - Part c: Implement the remainder of the WebIDL API on nsDOMAttributeMap; r=bz

This commit is contained in:
Ms2ger 2013-04-26 08:48:23 +02:00
Родитель 6b81c09a4a
Коммит 1d29441b12
5 изменённых файлов: 132 добавлений и 104 удалений

Просмотреть файл

@ -382,5 +382,11 @@ Attr::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
return AttrBinding::Wrap(aCx, aScope, this);
}
Element*
Attr::GetContentInternal() const
{
return mAttrMap ? mAttrMap->GetContent() : nullptr;
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -17,7 +17,6 @@
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsINodeInfo.h"
#include "nsDOMAttributeMap.h"
#include "nsCycleCollectionParticipant.h"
#include "nsStubMutationObserver.h"
@ -107,10 +106,7 @@ protected:
private:
already_AddRefed<nsIAtom> GetNameAtom(nsIContent* aContent);
mozilla::dom::Element *GetContentInternal() const
{
return mAttrMap ? mAttrMap->GetContent() : nullptr;
}
mozilla::dom::Element* GetContentInternal() const;
nsString mValue;
};

Просмотреть файл

@ -790,14 +790,7 @@ Element::SetAttributeNode(Attr& aNewAttr, ErrorResult& aError)
{
OwnerDoc()->WarnOnceAbout(nsIDocument::eSetAttributeNode);
nsCOMPtr<nsIDOMAttr> attr;
aError = Attributes()->SetNamedItem(&aNewAttr, getter_AddRefs(attr));
if (aError.Failed()) {
return nullptr;
}
nsRefPtr<Attr> returnAttr = static_cast<Attr*>(attr.get());
return returnAttr.forget();
return Attributes()->SetNamedItem(aNewAttr, aError);
}
already_AddRefed<Attr>
@ -805,22 +798,7 @@ Element::RemoveAttributeNode(Attr& aAttribute,
ErrorResult& aError)
{
OwnerDoc()->WarnOnceAbout(nsIDocument::eRemoveAttributeNode);
nsAutoString name;
aError = aAttribute.GetName(name);
if (aError.Failed()) {
return nullptr;
}
nsCOMPtr<nsIDOMAttr> attr;
aError = Attributes()->RemoveNamedItem(name, getter_AddRefs(attr));
if (aError.Failed()) {
return nullptr;
}
nsRefPtr<Attr> returnAttr = static_cast<Attr*>(attr.get());
return returnAttr.forget();
return Attributes()->RemoveNamedItem(aAttribute.NodeName(), aError);
}
void
@ -904,7 +882,7 @@ Element::SetAttributeNodeNS(Attr& aNewAttr,
ErrorResult& aError)
{
OwnerDoc()->WarnOnceAbout(nsIDocument::eSetAttributeNodeNS);
return Attributes()->SetNamedItemNS(&aNewAttr, aError);
return Attributes()->SetNamedItemNS(aNewAttr, aError);
}
already_AddRefed<nsIHTMLCollection>

Просмотреть файл

@ -8,15 +8,16 @@
*/
#include "nsDOMAttributeMap.h"
#include "mozilla/dom/Attr.h"
#include "nsIDOMDocument.h"
#include "mozilla/dom/Element.h"
#include "nsIDocument.h"
#include "nsINameSpaceManager.h"
#include "nsError.h"
#include "nsContentUtils.h"
#include "nsNodeInfoManager.h"
#include "nsAttrName.h"
#include "nsContentUtils.h"
#include "nsError.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsINameSpaceManager.h"
#include "nsNodeInfoManager.h"
#include "nsUnicharUtils.h"
using namespace mozilla;
@ -172,8 +173,9 @@ nsDOMAttributeMap::GetAttribute(nsINodeInfo* aNodeInfo, bool aNsAware)
}
Attr*
nsDOMAttributeMap::GetNamedItem(const nsAString& aAttrName)
nsDOMAttributeMap::NamedGetter(const nsAString& aAttrName, bool& aFound)
{
aFound = false;
NS_ENSURE_TRUE(mContent, nullptr);
nsCOMPtr<nsINodeInfo> ni = mContent->GetExistingAttrNameFromQName(aAttrName);
@ -181,9 +183,17 @@ nsDOMAttributeMap::GetNamedItem(const nsAString& aAttrName)
return nullptr;
}
aFound = true;
return GetAttribute(ni, false);
}
Attr*
nsDOMAttributeMap::GetNamedItem(const nsAString& aAttrName)
{
bool dummy;
return NamedGetter(aAttrName, dummy);
}
NS_IMETHODIMP
nsDOMAttributeMap::GetNamedItem(const nsAString& aAttrName,
nsIDOMAttr** aAttribute)
@ -198,21 +208,27 @@ nsDOMAttributeMap::GetNamedItem(const nsAString& aAttrName,
NS_IMETHODIMP
nsDOMAttributeMap::SetNamedItem(nsIDOMAttr* aAttr, nsIDOMAttr** aReturn)
{
Attr* attribute = static_cast<Attr*>(aAttr);
NS_ENSURE_ARG(attribute);
ErrorResult rv;
*aReturn = SetNamedItemInternal(aAttr, false, rv).get();
*aReturn = SetNamedItem(*attribute, rv).get();
return rv.ErrorCode();
}
NS_IMETHODIMP
nsDOMAttributeMap::SetNamedItemNS(nsIDOMAttr* aAttr, nsIDOMAttr** aReturn)
{
Attr* attribute = static_cast<Attr*>(aAttr);
NS_ENSURE_ARG(attribute);
ErrorResult rv;
*aReturn = SetNamedItemInternal(aAttr, true, rv).get();
*aReturn = SetNamedItemNS(*attribute, rv).get();
return rv.ErrorCode();
}
already_AddRefed<Attr>
nsDOMAttributeMap::SetNamedItemInternal(nsIDOMAttr* aAttr,
nsDOMAttributeMap::SetNamedItemInternal(Attr& aAttr,
bool aWithNS,
ErrorResult& aError)
{
@ -220,17 +236,9 @@ nsDOMAttributeMap::SetNamedItemInternal(nsIDOMAttr* aAttr,
// XXX should check same-origin between mContent and aAttr however
// nsContentUtils::CheckSameOrigin can't deal with attributenodes yet
nsCOMPtr<nsIAttribute> iAttribute(do_QueryInterface(aAttr));
if (!iAttribute) {
aError.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
return nullptr;
}
Attr *attribute = static_cast<Attr*>(iAttribute.get());
// Check that attribute is not owned by somebody else
nsDOMAttributeMap* owner = iAttribute->GetMap();
nsDOMAttributeMap* owner = aAttr.GetMap();
if (owner) {
if (owner != this) {
aError.Throw(NS_ERROR_DOM_INUSE_ATTRIBUTE_ERR);
@ -239,27 +247,19 @@ nsDOMAttributeMap::SetNamedItemInternal(nsIDOMAttr* aAttr,
// setting a preexisting attribute is a no-op, just return the same
// node.
NS_ADDREF(attribute);
return attribute;
nsRefPtr<Attr> attribute = &aAttr;
return attribute.forget();
}
nsresult rv;
if (!mContent->HasSameOwnerDoc(iAttribute)) {
nsCOMPtr<nsIDOMDocument> domDoc =
do_QueryInterface(mContent->OwnerDoc(), &rv);
if (NS_FAILED(rv)) {
aError.Throw(rv);
if (!mContent->HasSameOwnerDoc(&aAttr)) {
nsCOMPtr<nsINode> adoptedNode =
mContent->OwnerDoc()->AdoptNode(aAttr, aError);
if (aError.Failed()) {
return nullptr;
}
nsCOMPtr<nsIDOMNode> adoptedNode;
rv = domDoc->AdoptNode(aAttr, getter_AddRefs(adoptedNode));
if (NS_FAILED(rv)) {
aError.Throw(rv);
return nullptr;
}
NS_ASSERTION(adoptedNode == aAttr, "Uh, adopt node changed nodes?");
NS_ASSERTION(adoptedNode == &aAttr, "Uh, adopt node changed nodes?");
}
// Get nodeinfo and preexisting attribute (if it exists)
@ -270,14 +270,13 @@ nsDOMAttributeMap::SetNamedItemInternal(nsIDOMAttr* aAttr,
// SetNamedItemNS()
if (aWithNS) {
// Return existing attribute, if present
ni = iAttribute->NodeInfo();
ni = aAttr.NodeInfo();
if (mContent->HasAttr(ni->NamespaceID(), ni->NameAtom())) {
attr = RemoveAttribute(ni);
}
}
else { // SetNamedItem()
attribute->GetName(name);
} else { // SetNamedItem()
aAttr.GetName(name);
// get node-info of old attribute
ni = mContent->GetExistingAttrNameFromQName(name);
@ -302,13 +301,13 @@ nsDOMAttributeMap::SetNamedItemInternal(nsIDOMAttr* aAttr,
}
nsAutoString value;
attribute->GetValue(value);
aAttr.GetValue(value);
// Add the new attribute to the attribute map before updating
// its value in the element. @see bug 364413.
nsAttrKey attrkey(ni->NamespaceID(), ni->NameAtom());
mAttributeCache.Put(attrkey, attribute);
iAttribute->SetMap(this);
mAttributeCache.Put(attrkey, &aAttr);
aAttr.SetMap(this);
rv = mContent->SetAttr(ni->NamespaceID(), ni->NameAtom(),
ni->GetPrefixAtom(), value, true);
@ -325,57 +324,76 @@ nsDOMAttributeMap::RemoveNamedItem(const nsAString& aName,
nsIDOMAttr** aReturn)
{
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = nullptr;
NS_ENSURE_TRUE(mContent, NS_OK);
ErrorResult rv;
*aReturn = RemoveNamedItem(aName, rv).get();
return rv.ErrorCode();
}
already_AddRefed<Attr>
nsDOMAttributeMap::RemoveNamedItem(const nsAString& aName, ErrorResult& aError)
{
NS_ENSURE_TRUE(mContent, nullptr);
nsCOMPtr<nsINodeInfo> ni = mContent->GetExistingAttrNameFromQName(aName);
if (!ni) {
return NS_ERROR_DOM_NOT_FOUND_ERR;
aError.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
return nullptr;
}
NS_ADDREF(*aReturn = GetAttribute(ni, true));
nsRefPtr<Attr> attribute = GetAttribute(ni, true);
// This removes the attribute node from the attribute map.
return mContent->UnsetAttr(ni->NamespaceID(), ni->NameAtom(), true);
aError = mContent->UnsetAttr(ni->NamespaceID(), ni->NameAtom(), true);
return attribute.forget();
}
Attr*
nsDOMAttributeMap::GetItemAt(uint32_t aIndex)
nsDOMAttributeMap::IndexedGetter(uint32_t aIndex, bool& aFound)
{
aFound = false;
NS_ENSURE_TRUE(mContent, nullptr);
const nsAttrName* name = mContent->GetAttrNameAt(aIndex);
NS_ENSURE_TRUE(name, nullptr);
// Don't use the nodeinfo even if one exists since it can
// have the wrong owner document.
aFound = true;
// Don't use the nodeinfo even if one exists since it can have the wrong
// owner document.
nsCOMPtr<nsINodeInfo> ni = mContent->NodeInfo()->NodeInfoManager()->
GetNodeInfo(name->LocalName(), name->GetPrefix(), name->NamespaceID(),
nsIDOMNode::ATTRIBUTE_NODE);
return GetAttribute(ni, true);
}
Attr*
nsDOMAttributeMap::Item(uint32_t aIndex)
{
bool dummy;
return IndexedGetter(aIndex, dummy);
}
NS_IMETHODIMP
nsDOMAttributeMap::Item(uint32_t aIndex, nsIDOMAttr** aReturn)
{
NS_IF_ADDREF(*aReturn = GetItemAt(aIndex));
NS_IF_ADDREF(*aReturn = Item(aIndex));
return NS_OK;
}
uint32_t
nsDOMAttributeMap::Length() const
{
NS_ENSURE_TRUE(mContent, 0);
return mContent->GetAttrCount();
}
nsresult
nsDOMAttributeMap::GetLength(uint32_t *aLength)
{
NS_ENSURE_ARG_POINTER(aLength);
if (mContent) {
*aLength = mContent->GetAttrCount();
}
else {
*aLength = 0;
}
*aLength = Length();
return NS_OK;
}
@ -445,20 +463,27 @@ nsDOMAttributeMap::RemoveNamedItemNS(const nsAString& aNamespaceURI,
nsIDOMAttr** aReturn)
{
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = nullptr;
ErrorResult rv;
*aReturn = RemoveNamedItemNS(aNamespaceURI, aLocalName, rv).get();
return rv.ErrorCode();
}
already_AddRefed<Attr>
nsDOMAttributeMap::RemoveNamedItemNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName,
ErrorResult& aError)
{
nsCOMPtr<nsINodeInfo> ni = GetAttrNodeInfo(aNamespaceURI, aLocalName);
if (!ni) {
return NS_ERROR_DOM_NOT_FOUND_ERR;
aError.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
return nullptr;
}
nsRefPtr<Attr> attr = RemoveAttribute(ni);
nsINodeInfo *attrNi = attr->NodeInfo();
nsINodeInfo* attrNi = attr->NodeInfo();
mContent->UnsetAttr(attrNi->NamespaceID(), attrNi->NameAtom(), true);
attr.forget(aReturn);
return NS_OK;
return attr.forget();
}
uint32_t

Просмотреть файл

@ -10,12 +10,12 @@
#ifndef nsDOMAttributeMap_h
#define nsDOMAttributeMap_h
#include "nsIDOMMozNamedAttrMap.h"
#include "nsStringGlue.h"
#include "nsRefPtrHashtable.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIDOMAttr.h"
#include "mozilla/dom/Attr.h"
#include "mozilla/ErrorResult.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIDOMMozNamedAttrMap.h"
#include "nsRefPtrHashtable.h"
#include "nsStringGlue.h"
class nsIAtom;
class nsINodeInfo;
@ -23,7 +23,6 @@ class nsIDocument;
namespace mozilla {
namespace dom {
class Attr;
class Element;
} // namespace dom
} // namespace mozilla
@ -140,8 +139,10 @@ public:
*/
uint32_t Enumerate(AttrCache::EnumReadFunction aFunc, void *aUserArg) const;
Attr* GetItemAt(uint32_t aIndex);
Attr* GetNamedItem(const nsAString& aAttrName);
Attr* GetItemAt(uint32_t aIndex)
{
return Item(aIndex);
}
static nsDOMAttributeMap* FromSupports(nsISupports* aSupports)
{
@ -162,15 +163,37 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMAttributeMap)
// WebIDL
Attr* GetNamedItem(const nsAString& aAttrName);
Attr* NamedGetter(const nsAString& aAttrName, bool& aFound);
already_AddRefed<Attr>
SetNamedItem(Attr& aAttr, ErrorResult& aError)
{
return SetNamedItemInternal(aAttr, false, aError);
}
already_AddRefed<Attr>
RemoveNamedItem(const nsAString& aName, ErrorResult& aError);
Attr* Item(uint32_t aIndex);
Attr* IndexedGetter(uint32_t aIndex, bool& aFound);
uint32_t Length() const;
Attr*
GetNamedItemNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName);
already_AddRefed<Attr>
SetNamedItemNS(Attr& aNode, ErrorResult& aError)
{
return SetNamedItemInternal(aNode, true, aError);
}
already_AddRefed<Attr>
RemoveNamedItemNS(const nsAString& aNamespaceURI, const nsAString& aLocalName,
ErrorResult& aError);
void GetSupportedNames(nsTArray<nsString>& aNames)
{
// No supported names we want to show up in iteration.
}
size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
@ -187,7 +210,7 @@ private:
* true) implementation.
*/
already_AddRefed<Attr>
SetNamedItemInternal(nsIDOMAttr* aNode, bool aWithNS, ErrorResult& aError);
SetNamedItemInternal(Attr& aNode, bool aWithNS, ErrorResult& aError);
already_AddRefed<nsINodeInfo>
GetAttrNodeInfo(const nsAString& aNamespaceURI,