michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=8 sts=2 et sw=2 tw=80: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * nsINodeInfo is an interface to node info, such as name, prefix, namespace michael@0: * ID and possibly other data that is shared between nodes (elements michael@0: * and attributes) that have the same name, prefix and namespace ID within michael@0: * the same document. michael@0: * michael@0: * nsNodeInfoManager's are internal objects that manage a list of michael@0: * nsINodeInfo's, every document object should hold a strong reference to michael@0: * a nsNodeInfoManager and every nsINodeInfo also holds a strong reference michael@0: * to their owning manager. When a nsINodeInfo is no longer used it will michael@0: * automatically remove itself from its owner manager, and when all michael@0: * nsINodeInfo's have been removed from a nsNodeInfoManager and all external michael@0: * references are released the nsNodeInfoManager deletes itself. michael@0: * michael@0: * -- jst@netscape.com michael@0: */ michael@0: michael@0: #ifndef nsINodeInfo_h___ michael@0: #define nsINodeInfo_h___ michael@0: michael@0: #include "nsCOMPtr.h" // for member michael@0: #include "nsIAtom.h" // for member (in nsCOMPtr) michael@0: #include "nsISupports.h" // for base class michael@0: #include "nsNameSpaceManager.h" // for kNameSpaceID_* michael@0: michael@0: #ifdef MOZILLA_INTERNAL_API michael@0: #include "nsDOMString.h" michael@0: #endif michael@0: michael@0: class nsIDocument; michael@0: class nsIURI; michael@0: class nsIPrincipal; michael@0: class nsNodeInfoManager; michael@0: michael@0: // IID for the nsINodeInfo interface michael@0: #define NS_INODEINFO_IID \ michael@0: { 0xc5188ea1, 0x0a9c, 0x43e6, \ michael@0: { 0x95, 0x90, 0xcc, 0x43, 0x6b, 0xe9, 0xcf, 0xa0 } } michael@0: michael@0: class nsINodeInfo : public nsISupports michael@0: { michael@0: public: michael@0: NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODEINFO_IID) michael@0: michael@0: nsINodeInfo() michael@0: : mInner(nullptr, nullptr, kNameSpaceID_None, 0, nullptr) michael@0: { michael@0: } michael@0: michael@0: /* michael@0: * Get the name from this node as a string, this does not include the prefix. michael@0: * michael@0: * For the HTML element "" this will return "body" and for the XML michael@0: * element "" this will return "body". michael@0: */ michael@0: void GetName(nsAString& aName) const michael@0: { michael@0: mInner.mName->ToString(aName); michael@0: } michael@0: michael@0: /* michael@0: * Get the name from this node as an atom, this does not include the prefix. michael@0: * This function never returns a null atom. michael@0: * michael@0: * For the HTML element "" this will return the "body" atom and for michael@0: * the XML element "" this will return the "body" atom. michael@0: */ michael@0: nsIAtom* NameAtom() const michael@0: { michael@0: return mInner.mName; michael@0: } michael@0: michael@0: /* michael@0: * Get the qualified name from this node as a string, the qualified name michael@0: * includes the prefix, if one exists. michael@0: * michael@0: * For the HTML element "" this will return "body" and for the XML michael@0: * element "" this will return "html:body". michael@0: */ michael@0: const nsString& QualifiedName() const { michael@0: return mQualifiedName; michael@0: } michael@0: michael@0: /* michael@0: * Returns the node's nodeName as defined in DOM Core michael@0: */ michael@0: const nsString& NodeName() const { michael@0: return mNodeName; michael@0: } michael@0: michael@0: /* michael@0: * Returns the node's localName as defined in DOM Core michael@0: */ michael@0: const nsString& LocalName() const { michael@0: return mLocalName; michael@0: } michael@0: michael@0: #ifdef MOZILLA_INTERNAL_API michael@0: /* michael@0: * Get the prefix from this node as a string. michael@0: * michael@0: * For the HTML element "" this will return a null string and for michael@0: * the XML element "" this will return the string "html". michael@0: */ michael@0: void GetPrefix(nsAString& aPrefix) const michael@0: { michael@0: if (mInner.mPrefix) { michael@0: mInner.mPrefix->ToString(aPrefix); michael@0: } else { michael@0: SetDOMStringToNull(aPrefix); michael@0: } michael@0: } michael@0: #endif michael@0: michael@0: /* michael@0: * Get the prefix from this node as an atom. michael@0: * michael@0: * For the HTML element "" this will return a null atom and for michael@0: * the XML element "" this will return the "html" atom. michael@0: */ michael@0: nsIAtom* GetPrefixAtom() const michael@0: { michael@0: return mInner.mPrefix; michael@0: } michael@0: michael@0: /* michael@0: * Get the namespace URI for a node, if the node has a namespace URI. michael@0: */ michael@0: virtual void GetNamespaceURI(nsAString& aNameSpaceURI) const = 0; michael@0: michael@0: /* michael@0: * Get the namespace ID for a node if the node has a namespace, if not this michael@0: * returns kNameSpaceID_None. michael@0: */ michael@0: int32_t NamespaceID() const michael@0: { michael@0: return mInner.mNamespaceID; michael@0: } michael@0: michael@0: /* michael@0: * Get the nodetype for the node. Returns the values specified in nsIDOMNode michael@0: * for nsIDOMNode.nodeType michael@0: */ michael@0: uint16_t NodeType() const michael@0: { michael@0: return mInner.mNodeType; michael@0: } michael@0: michael@0: /* michael@0: * Get the extra name, used by PIs and DocTypes, for the node. michael@0: */ michael@0: nsIAtom* GetExtraName() const michael@0: { michael@0: return mInner.mExtraName; michael@0: } michael@0: michael@0: /* michael@0: * Get and set the ID attribute atom for this node. michael@0: * See http://www.w3.org/TR/1998/REC-xml-19980210#sec-attribute-types michael@0: * for the definition of an ID attribute. michael@0: * michael@0: */ michael@0: nsIAtom* GetIDAttributeAtom() const michael@0: { michael@0: return mIDAttributeAtom; michael@0: } michael@0: michael@0: void SetIDAttributeAtom(nsIAtom* aID) michael@0: { michael@0: mIDAttributeAtom = aID; michael@0: } michael@0: michael@0: /** michael@0: * Get the owning node info manager. Only to be used inside Gecko, you can't michael@0: * really do anything with the pointer outside Gecko anyway. michael@0: */ michael@0: nsNodeInfoManager *NodeInfoManager() const michael@0: { michael@0: return mOwnerManager; michael@0: } michael@0: michael@0: /* michael@0: * Utility functions that can be used to check if a nodeinfo holds a specific michael@0: * name, name and prefix, name and prefix and namespace ID, or just michael@0: * namespace ID. michael@0: */ michael@0: bool Equals(nsINodeInfo *aNodeInfo) const michael@0: { michael@0: return aNodeInfo == this || aNodeInfo->Equals(mInner.mName, mInner.mPrefix, michael@0: mInner.mNamespaceID); michael@0: } michael@0: michael@0: bool NameAndNamespaceEquals(nsINodeInfo *aNodeInfo) const michael@0: { michael@0: return aNodeInfo == this || aNodeInfo->Equals(mInner.mName, michael@0: mInner.mNamespaceID); michael@0: } michael@0: michael@0: bool Equals(nsIAtom *aNameAtom) const michael@0: { michael@0: return mInner.mName == aNameAtom; michael@0: } michael@0: michael@0: bool Equals(nsIAtom *aNameAtom, nsIAtom *aPrefixAtom) const michael@0: { michael@0: return (mInner.mName == aNameAtom) && (mInner.mPrefix == aPrefixAtom); michael@0: } michael@0: michael@0: bool Equals(nsIAtom *aNameAtom, int32_t aNamespaceID) const michael@0: { michael@0: return ((mInner.mName == aNameAtom) && michael@0: (mInner.mNamespaceID == aNamespaceID)); michael@0: } michael@0: michael@0: bool Equals(nsIAtom *aNameAtom, nsIAtom *aPrefixAtom, michael@0: int32_t aNamespaceID) const michael@0: { michael@0: return ((mInner.mName == aNameAtom) && michael@0: (mInner.mPrefix == aPrefixAtom) && michael@0: (mInner.mNamespaceID == aNamespaceID)); michael@0: } michael@0: michael@0: bool NamespaceEquals(int32_t aNamespaceID) const michael@0: { michael@0: return mInner.mNamespaceID == aNamespaceID; michael@0: } michael@0: michael@0: bool Equals(const nsAString& aName) const michael@0: { michael@0: return mInner.mName->Equals(aName); michael@0: } michael@0: michael@0: bool Equals(const nsAString& aName, const nsAString& aPrefix) const michael@0: { michael@0: return mInner.mName->Equals(aName) && michael@0: (mInner.mPrefix ? mInner.mPrefix->Equals(aPrefix) : aPrefix.IsEmpty()); michael@0: } michael@0: michael@0: bool Equals(const nsAString& aName, int32_t aNamespaceID) const michael@0: { michael@0: return mInner.mNamespaceID == aNamespaceID && michael@0: mInner.mName->Equals(aName); michael@0: } michael@0: michael@0: bool Equals(const nsAString& aName, const nsAString& aPrefix, michael@0: int32_t aNamespaceID) const michael@0: { michael@0: return mInner.mName->Equals(aName) && mInner.mNamespaceID == aNamespaceID && michael@0: (mInner.mPrefix ? mInner.mPrefix->Equals(aPrefix) : aPrefix.IsEmpty()); michael@0: } michael@0: michael@0: virtual bool NamespaceEquals(const nsAString& aNamespaceURI) const = 0; michael@0: michael@0: bool QualifiedNameEquals(nsIAtom* aNameAtom) const michael@0: { michael@0: NS_PRECONDITION(aNameAtom, "Must have name atom"); michael@0: if (!GetPrefixAtom()) michael@0: return Equals(aNameAtom); michael@0: michael@0: return aNameAtom->Equals(mQualifiedName); michael@0: } michael@0: michael@0: bool QualifiedNameEquals(const nsAString& aQualifiedName) const michael@0: { michael@0: return mQualifiedName == aQualifiedName; michael@0: } michael@0: michael@0: /* michael@0: * Retrieve a pointer to the document that owns this node info. michael@0: */ michael@0: nsIDocument* GetDocument() const michael@0: { michael@0: return mDocument; michael@0: } michael@0: michael@0: protected: michael@0: /* michael@0: * nsNodeInfoInner is used for two things: michael@0: * michael@0: * 1. as a member in nsNodeInfo for holding the name, prefix and michael@0: * namespace ID michael@0: * 2. as the hash key in the hash table in nsNodeInfoManager michael@0: * michael@0: * nsNodeInfoInner does not do any kind of reference counting, michael@0: * that's up to the user of this class. Since nsNodeInfoInner is michael@0: * typically used as a member of nsNodeInfo, the hash table doesn't michael@0: * need to delete the keys. When the value (nsNodeInfo) is deleted michael@0: * the key is automatically deleted. michael@0: */ michael@0: michael@0: class nsNodeInfoInner michael@0: { michael@0: public: michael@0: nsNodeInfoInner() michael@0: : mName(nullptr), mPrefix(nullptr), mNamespaceID(kNameSpaceID_Unknown), michael@0: mNodeType(0), mNameString(nullptr), mExtraName(nullptr) michael@0: { michael@0: } michael@0: nsNodeInfoInner(nsIAtom *aName, nsIAtom *aPrefix, int32_t aNamespaceID, michael@0: uint16_t aNodeType, nsIAtom* aExtraName) michael@0: : mName(aName), mPrefix(aPrefix), mNamespaceID(aNamespaceID), michael@0: mNodeType(aNodeType), mNameString(nullptr), mExtraName(aExtraName) michael@0: { michael@0: } michael@0: nsNodeInfoInner(const nsAString& aTmpName, nsIAtom *aPrefix, michael@0: int32_t aNamespaceID, uint16_t aNodeType) michael@0: : mName(nullptr), mPrefix(aPrefix), mNamespaceID(aNamespaceID), michael@0: mNodeType(aNodeType), mNameString(&aTmpName), mExtraName(nullptr) michael@0: { michael@0: } michael@0: michael@0: nsIAtom* mName; michael@0: nsIAtom* mPrefix; michael@0: int32_t mNamespaceID; michael@0: uint16_t mNodeType; // As defined by nsIDOMNode.nodeType michael@0: const nsAString* mNameString; michael@0: nsIAtom* mExtraName; // Only used by PIs and DocTypes michael@0: }; michael@0: michael@0: // nsNodeInfoManager needs to pass mInner to the hash table. michael@0: friend class nsNodeInfoManager; michael@0: michael@0: nsIDocument* mDocument; // Weak. Cache of mOwnerManager->mDocument michael@0: michael@0: nsNodeInfoInner mInner; michael@0: michael@0: nsCOMPtr mIDAttributeAtom; michael@0: nsRefPtr mOwnerManager; michael@0: michael@0: /* michael@0: * Members for various functions of mName+mPrefix that we can be michael@0: * asked to compute. michael@0: */ michael@0: michael@0: // Qualified name michael@0: nsString mQualifiedName; michael@0: michael@0: // nodeName for the node. michael@0: nsString mNodeName; michael@0: michael@0: // localName for the node. This is either equal to mInner.mName, or a michael@0: // void string, depending on mInner.mNodeType. michael@0: nsString mLocalName; michael@0: }; michael@0: michael@0: NS_DEFINE_STATIC_IID_ACCESSOR(nsINodeInfo, NS_INODEINFO_IID) michael@0: michael@0: #endif /* nsINodeInfo_h___ */