зеркало из https://github.com/mozilla/gecko-dev.git
Bug 852135 - Part c: Implement the remainder of the WebIDL API on nsDOMAttributeMap; r=bz
This commit is contained in:
Родитель
6b81c09a4a
Коммит
1d29441b12
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче