gecko-dev/dom/base/nsDOMAttributeMap.h
Ryan Hunt eb21db799b Bug 1525720, part 17 - Ignore nsIRemoteTab methods after we have destroyed the browser. r=nika
It's possible for front-end references to nsIRemoteTab to outlive the IPDL actor. When
this happens, we should ignore methods and property accesses.

The one special case is that some code expects to be able to
access the TabId after the browser has been destroyed. For this
we can just cache the ID.

Differential Revision: https://phabricator.services.mozilla.com/D31449

--HG--
extra : source : 9b79caa460a01a7bdf9c27ede487de0ec642ae0b
extra : histedit_source : ec32bc78fac57f523b4c1b2aef08fddfccfbe546%2C8770eefa09a764733a09d8256ef9b3e2f04244df
2019-05-15 12:34:14 -05:00

178 lines
5.2 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* Implementation of the |attributes| property of DOM Core's Element object.
*/
#ifndef nsDOMAttributeMap_h
#define nsDOMAttributeMap_h
#include "mozilla/MemoryReporting.h"
#include "mozilla/dom/Attr.h"
#include "mozilla/ErrorResult.h"
#include "nsCycleCollectionParticipant.h"
#include "nsRefPtrHashtable.h"
#include "nsString.h"
#include "nsWrapperCache.h"
class nsAtom;
namespace mozilla {
namespace dom {
class DocGroup;
} // namespace dom
} // namespace mozilla
/**
* Structure used as a key for caching Attrs in nsDOMAttributeMap's
* mAttributeCache.
*/
class nsAttrKey {
public:
/**
* The namespace of the attribute
*/
int32_t mNamespaceID;
/**
* The atom for attribute, stored as void*, to make sure that we only use it
* for the hashcode, and we can never dereference it.
*/
void* mLocalName;
nsAttrKey(int32_t aNs, nsAtom* aName)
: mNamespaceID(aNs), mLocalName(aName) {}
nsAttrKey(const nsAttrKey& aAttr)
: mNamespaceID(aAttr.mNamespaceID), mLocalName(aAttr.mLocalName) {}
};
/**
* PLDHashEntryHdr implementation for nsAttrKey.
*/
class nsAttrHashKey : public PLDHashEntryHdr {
public:
typedef const nsAttrKey& KeyType;
typedef const nsAttrKey* KeyTypePointer;
explicit nsAttrHashKey(KeyTypePointer aKey) : mKey(*aKey) {}
nsAttrHashKey(const nsAttrHashKey& aCopy)
: PLDHashEntryHdr{}, mKey(aCopy.mKey) {}
~nsAttrHashKey() {}
KeyType GetKey() const { return mKey; }
bool KeyEquals(KeyTypePointer aKey) const {
return mKey.mLocalName == aKey->mLocalName &&
mKey.mNamespaceID == aKey->mNamespaceID;
}
static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
static PLDHashNumber HashKey(KeyTypePointer aKey) {
if (!aKey) return 0;
return mozilla::HashGeneric(aKey->mNamespaceID, aKey->mLocalName);
}
enum { ALLOW_MEMMOVE = true };
private:
nsAttrKey mKey;
};
class nsDOMAttributeMap final : public nsISupports, public nsWrapperCache {
public:
typedef mozilla::dom::Attr Attr;
typedef mozilla::dom::DocGroup DocGroup;
typedef mozilla::dom::Document Document;
typedef mozilla::dom::Element Element;
typedef mozilla::ErrorResult ErrorResult;
explicit nsDOMAttributeMap(Element* aContent);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsDOMAttributeMap)
void DropReference();
Element* GetContent() { return mContent; }
/**
* Called when mContent is moved into a new document.
* Updates the nodeinfos of all owned nodes.
*/
nsresult SetOwnerDocument(Document* aDocument);
/**
* Drop an attribute from the map's cache (does not remove the attribute
* from the node!)
*/
void DropAttribute(int32_t aNamespaceID, nsAtom* aLocalName);
/**
* Returns the number of attribute nodes currently in the map.
* Note: this is just the number of cached attribute nodes, not the number of
* attributes in mContent.
*
* @return The number of attribute nodes in the map.
*/
uint32_t Count() const;
typedef nsRefPtrHashtable<nsAttrHashKey, Attr> AttrCache;
static void BlastSubtreeToPieces(nsINode* aNode);
Element* GetParentObject() const { return mContent; }
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
DocGroup* GetDocGroup() const;
// WebIDL
Attr* GetNamedItem(const nsAString& aAttrName);
Attr* NamedGetter(const nsAString& aAttrName, bool& aFound);
already_AddRefed<Attr> RemoveNamedItem(mozilla::dom::NodeInfo* aNodeInfo,
ErrorResult& 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);
already_AddRefed<Attr> RemoveNamedItemNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName,
ErrorResult& aError);
void GetSupportedNames(nsTArray<nsString>& aNames);
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
protected:
virtual ~nsDOMAttributeMap();
private:
nsCOMPtr<Element> mContent;
/**
* Cache of Attrs.
*/
AttrCache mAttributeCache;
already_AddRefed<mozilla::dom::NodeInfo> GetAttrNodeInfo(
const nsAString& aNamespaceURI, const nsAString& aLocalName);
Attr* GetAttribute(mozilla::dom::NodeInfo* aNodeInfo);
};
// XXX khuey yes this is crazy. The bindings code needs to see this include,
// but if we pull it in at the top of the file we get a circular include
// problem.
#include "mozilla/dom/Element.h"
#endif /* nsDOMAttributeMap_h */