diff --git a/content/base/public/nsIContent.h b/content/base/public/nsIContent.h index 759ed5a9486e..5fe330b8d8f1 100644 --- a/content/base/public/nsIContent.h +++ b/content/base/public/nsIContent.h @@ -90,6 +90,32 @@ public: */ NS_IMETHOD IsSynthetic(PRBool& aResult) = 0; + /** + * Parses an attribute string into an atom that represents the + * attribute name and an identifier that represents the namespace + * of the attribute. The namespace identifier may be computed + * from a namespace prefix that must be interpreted in the context + * of the content itself. + * + * @param aStr the unparsed attribute string + * @param aName out parameter representing the name of the attribute + * @param aNameSpaceID out parameter reprsenting the namespace + * of the attribute + */ + NS_IMETHOD ParseAttributeString(const nsString& aStr, + nsIAtom*& aName, + PRInt32& aNameSpaceID) = 0; + + /** + * Returns the prefix for the specified name space identifier in + * the context of the content element itself. + * + * @param aNameSpaceID identifier of the namespace + * @param aPrefix out parameter representing the prefix for the namespace + */ + NS_IMETHOD GetNameSpacePrefix(PRInt32 aNameSpaceID, + nsIAtom*& aPrefix) = 0; + /** * Set attribute values. All attribute values are assumed to have a * canonical String representation that can be used for these diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index 342b2463447b..a10d97aacee6 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -40,6 +40,7 @@ #include "nsIDOMEventListener.h" #include "nsIDOMStyleSheet.h" #include "nsIDOMStyleSheetCollection.h" +#include "nsDOMAttribute.h" #include "nsCSSPropIDs.h" #include "nsCSSProps.h" @@ -67,6 +68,7 @@ static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID); static NS_DEFINE_IID(kIDOMDocumentIID, NS_IDOMDOCUMENT_IID); static NS_DEFINE_IID(kIDOMNSDocumentIID, NS_IDOMNSDOCUMENT_IID); +static NS_DEFINE_IID(kIDOMAttrIID, NS_IDOMATTR_IID); static NS_DEFINE_IID(kIScriptEventListenerIID, NS_ISCRIPTEVENTLISTENER_IID); static NS_DEFINE_IID(kIDOMEventCapturerIID, NS_IDOMEVENTCAPTURER_IID); static NS_DEFINE_IID(kIPrivateDOMEventIID, NS_IPRIVATEDOMEVENT_IID); @@ -1104,8 +1106,16 @@ NS_IMETHODIMP nsDocument::CreateAttribute(const nsString& aName, nsIDOMAttr** aReturn) { - // Should be implemented by subclass - return NS_ERROR_NOT_IMPLEMENTED; + nsAutoString value; + nsDOMAttribute* attribute; + + value.Truncate(); + attribute = new nsDOMAttribute(nsnull, aName, value); + if (nsnull == attribute) { + return NS_ERROR_OUT_OF_MEMORY; + } + + return attribute->QueryInterface(kIDOMAttrIID, (void**)aReturn); } NS_IMETHODIMP diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp index 56ecd4b2b37d..35027bd35f62 100644 --- a/content/base/src/nsGenericElement.cpp +++ b/content/base/src/nsGenericElement.cpp @@ -18,12 +18,11 @@ */ #include "nsGenericElement.h" - +#include "nsDOMAttribute.h" +#include "nsDOMAttributeMap.h" #include "nsIAtom.h" #include "nsIDocument.h" -#include "nsIDOMAttr.h" #include "nsIDOMEventReceiver.h" -#include "nsIDOMNamedNodeMap.h" #include "nsIDOMNodeList.h" #include "nsIDOMDocument.h" #include "nsIDOMDocumentFragment.h" @@ -75,382 +74,6 @@ static NS_DEFINE_IID(kIDOMDocumentFragmentIID, NS_IDOMDOCUMENTFRAGMENT_IID); //---------------------------------------------------------------------- -nsDOMAttribute::nsDOMAttribute(const nsString& aName, const nsString& aValue) - : mName(aName), mValue(aValue) -{ - mRefCnt = 1; - mScriptObject = nsnull; -} - -nsDOMAttribute::~nsDOMAttribute() -{ -} - -nsresult -nsDOMAttribute::QueryInterface(REFNSIID aIID, void** aInstancePtr) -{ - if (NULL == aInstancePtr) { - return NS_ERROR_NULL_POINTER; - } - if (aIID.Equals(kIDOMAttrIID)) { - nsIDOMAttr* tmp = this; - *aInstancePtr = (void*)tmp; - NS_ADDREF_THIS(); - return NS_OK; - } - if (aIID.Equals(kIScriptObjectOwnerIID)) { - nsIScriptObjectOwner* tmp = this; - *aInstancePtr = (void*)tmp; - NS_ADDREF_THIS(); - return NS_OK; - } - if (aIID.Equals(kISupportsIID)) { - nsIDOMAttr* tmp1 = this; - nsISupports* tmp2 = tmp1; - *aInstancePtr = (void*)tmp2; - NS_ADDREF_THIS(); - return NS_OK; - } - return NS_NOINTERFACE; -} - -NS_IMPL_ADDREF(nsDOMAttribute) - -NS_IMPL_RELEASE(nsDOMAttribute) - -nsresult -nsDOMAttribute::GetScriptObject(nsIScriptContext *aContext, - void** aScriptObject) -{ - nsresult res = NS_OK; - if (nsnull == mScriptObject) { - res = NS_NewScriptAttr(aContext, - (nsISupports *)(nsIDOMAttr *)this, - nsnull, - (void **)&mScriptObject); - } - *aScriptObject = mScriptObject; - return res; -} - -nsresult -nsDOMAttribute::SetScriptObject(void *aScriptObject) -{ - mScriptObject = aScriptObject; - return NS_OK; -} - -nsresult -nsDOMAttribute::GetName(nsString& aName) -{ - aName = mName; - return NS_OK; -} - -nsresult -nsDOMAttribute::GetValue(nsString& aValue) -{ - aValue = mValue; - return NS_OK; -} - -nsresult -nsDOMAttribute::SetValue(const nsString& aValue) -{ - mValue = aValue; - return NS_OK; -} - -nsresult -nsDOMAttribute::GetSpecified(PRBool* aSpecified) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -nsDOMAttribute::GetNodeName(nsString& aNodeName) -{ - return GetName(aNodeName); -} - -NS_IMETHODIMP -nsDOMAttribute::GetNodeValue(nsString& aNodeValue) -{ - return GetValue(aNodeValue); -} - -NS_IMETHODIMP -nsDOMAttribute::SetNodeValue(const nsString& aNodeValue) -{ - // You can't actually do this, but we'll fail silently - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetNodeType(PRUint16* aNodeType) -{ - *aNodeType = (PRUint16)nsIDOMNode::ATTRIBUTE_NODE; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetParentNode(nsIDOMNode** aParentNode) -{ - *aParentNode = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetChildNodes(nsIDOMNodeList** aChildNodes) -{ - *aChildNodes = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::HasChildNodes(PRBool* aHasChildNodes) -{ - *aHasChildNodes = PR_FALSE; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetFirstChild(nsIDOMNode** aFirstChild) -{ - *aFirstChild = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetLastChild(nsIDOMNode** aLastChild) -{ - *aLastChild = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetPreviousSibling(nsIDOMNode** aPreviousSibling) -{ - *aPreviousSibling = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetNextSibling(nsIDOMNode** aNextSibling) -{ - *aNextSibling = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetAttributes(nsIDOMNamedNodeMap** aAttributes) -{ - *aAttributes = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aReturn) -{ - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -nsDOMAttribute::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aReturn) -{ - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -nsDOMAttribute::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) -{ - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -nsDOMAttribute::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn) -{ - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -nsDOMAttribute::CloneNode(PRBool aDeep, nsIDOMNode** aReturn) -{ - nsDOMAttribute* newAttr = new nsDOMAttribute(mName, mValue); - if (nsnull == newAttr) { - return NS_ERROR_OUT_OF_MEMORY; - } - - *aReturn = newAttr; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetOwnerDocument(nsIDOMDocument** aOwnerDocument) -{ - // XXX TBI - return NS_ERROR_NOT_IMPLEMENTED; -} - -//---------------------------------------------------------------------- - -nsDOMAttributeMap::nsDOMAttributeMap(nsIContent* aContent) - : mContent(aContent) -{ - mRefCnt = 1; - NS_ADDREF(mContent); - mScriptObject = nsnull; -} - -nsDOMAttributeMap::~nsDOMAttributeMap() -{ - NS_RELEASE(mContent); -} - -nsresult -nsDOMAttributeMap::QueryInterface(REFNSIID aIID, void** aInstancePtr) -{ - if (NULL == aInstancePtr) { - return NS_ERROR_NULL_POINTER; - } - if (aIID.Equals(kIDOMNamedNodeMapIID)) { - nsIDOMNamedNodeMap* tmp = this; - *aInstancePtr = (void*)tmp; - NS_ADDREF_THIS(); - return NS_OK; - } - if (aIID.Equals(kIScriptObjectOwnerIID)) { - nsIScriptObjectOwner* tmp = this; - *aInstancePtr = (void*)tmp; - NS_ADDREF_THIS(); - return NS_OK; - } - if (aIID.Equals(kISupportsIID)) { - nsIDOMNamedNodeMap* tmp1 = this; - nsISupports* tmp2 = tmp1; - *aInstancePtr = (void*)tmp2; - NS_ADDREF_THIS(); - return NS_OK; - } - return NS_NOINTERFACE; -} - -NS_IMPL_ADDREF(nsDOMAttributeMap) - -NS_IMPL_RELEASE(nsDOMAttributeMap) - -nsresult -nsDOMAttributeMap::GetScriptObject(nsIScriptContext *aContext, - void** aScriptObject) -{ - nsresult res = NS_OK; - if (nsnull == mScriptObject) { - res = NS_NewScriptNamedNodeMap(aContext, - (nsISupports *)(nsIDOMNamedNodeMap *)this, - nsnull, - (void**)&mScriptObject); - } - *aScriptObject = mScriptObject; - return res; -} - -nsresult -nsDOMAttributeMap::SetScriptObject(void *aScriptObject) -{ - mScriptObject = aScriptObject; - return NS_OK; -} - -nsresult -nsDOMAttributeMap::GetNamedItem(const nsString &aAttrName, - nsIDOMNode** aAttribute) -{ - nsAutoString value; - // XXX need to parse namespace fom attribute name - // XXX need to uppercace name only if HTML namespace - nsAutoString upper; - aAttrName.ToUpperCase(upper); - nsIAtom* nameAtom = NS_NewAtom(upper); - mContent->GetAttribute(kNameSpaceID_HTML, nameAtom, value); - NS_RELEASE(nameAtom); - *aAttribute = (nsIDOMNode *) new nsDOMAttribute(aAttrName, value); - return NS_OK; -} - -nsresult -nsDOMAttributeMap::SetNamedItem(nsIDOMNode *aNode, nsIDOMNode **aReturn) -{ - nsIDOMAttr *attribute; - nsAutoString name, value; - nsresult err; - - if (NS_OK != (err = aNode->QueryInterface(kIDOMAttrIID, - (void **)&attribute))) { - return err; - } - - attribute->GetName(name); - attribute->GetValue(value); - NS_RELEASE(attribute); - - // XXX need to parse namespace from attribute name - // XXX also need to uppercase name only if HTML namespace - name.ToUpperCase(); - nsIAtom* nameAtom = NS_NewAtom(name); - mContent->SetAttribute(kNameSpaceID_HTML, nameAtom, value, PR_TRUE); - NS_RELEASE(nameAtom); - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttributeMap::RemoveNamedItem(const nsString& aName, nsIDOMNode** aReturn) -{ - nsresult res = GetNamedItem(aName, aReturn); - if (NS_OK == res) { - // XXX need to parse namespace from attribute name - // XXX need to uppercase only if HTML namespace - nsAutoString upper; - aName.ToUpperCase(upper); - nsIAtom* attr = NS_NewAtom(upper); - mContent->UnsetAttribute(kNameSpaceID_HTML, attr, PR_TRUE); - } - - return res; -} - -nsresult -nsDOMAttributeMap::Item(PRUint32 aIndex, nsIDOMNode** aReturn) -{ - nsresult res = NS_ERROR_FAILURE; - - PRInt32 nameSpaceID; - nsIAtom* nameAtom = nsnull; - if (NS_SUCCEEDED(mContent->GetAttributeNameAt(aIndex, nameSpaceID, nameAtom))) { - nsAutoString value; - if (NS_CONTENT_ATTR_NOT_THERE != mContent->GetAttribute(nameSpaceID, nameAtom, value)) { - // XXX need to prefix namespace if present - nsAutoString name; - nameAtom->ToString(name); - *aReturn = (nsIDOMNode *)new nsDOMAttribute(name, value); - res = NS_OK; - } - NS_RELEASE(nameAtom); - } - - return res; -} - -nsresult -nsDOMAttributeMap::GetLength(PRUint32 *aLength) -{ - PRInt32 n; - nsresult rv = mContent->GetAttributeCount(n); - *aLength = PRUint32(n); - return rv; -} - -//---------------------------------------------------------------------- - nsChildContentList::nsChildContentList(nsIContent *aContent) { NS_INIT_REFCNT(); @@ -607,6 +230,10 @@ nsGenericElement::~nsGenericElement() mDOMSlots->mStyle->DropReference(); NS_RELEASE(mDOMSlots->mStyle); } + if (nsnull != mDOMSlots->mAttributeMap) { + mDOMSlots->mAttributeMap->DropReference(); + NS_RELEASE(mDOMSlots->mAttributeMap); + } // XXX Should really be arena managed PR_DELETE(mDOMSlots); } @@ -620,6 +247,7 @@ nsGenericElement::GetDOMSlots() mDOMSlots->mScriptObject = nsnull; mDOMSlots->mChildNodes = nsnull; mDOMSlots->mStyle = nsnull; + mDOMSlots->mAttributeMap = nsnull; mDOMSlots->mRangeList = nsnull; } @@ -738,13 +366,18 @@ nsresult nsGenericElement::GetAttributes(nsIDOMNamedNodeMap** aAttributes) { NS_PRECONDITION(nsnull != aAttributes, "null pointer argument"); - // XXX Should we create a new one every time or should we - // cache one after we create it? If we find that this is - // something that's called often, we might need to do the - // latter. - *aAttributes = new nsDOMAttributeMap(mContent); + nsDOMSlots *slots = GetDOMSlots(); - return NS_OK; + if (nsnull == slots->mAttributeMap) { + slots->mAttributeMap = new nsDOMAttributeMap(mContent); + if (nsnull == slots->mAttributeMap) { + return NS_ERROR_OUT_OF_MEMORY; + } + NS_ADDREF(slots->mAttributeMap); + } + + return slots->mAttributeMap->QueryInterface(kIDOMNamedNodeMapIID, + (void **)aAttributes); } nsresult @@ -760,103 +393,126 @@ nsGenericElement::GetTagName(nsString& aTagName) } nsresult -nsGenericElement::GetDOMAttribute(const nsString& aName, nsString& aReturn) +nsGenericElement::GetAttribute(const nsString& aName, nsString& aReturn) { - // XXX need to parse namespace from name - // XXX need to uppercase name if HTML namespace - nsIAtom* nameAtom = NS_NewAtom(aName); - nsresult rv = mContent->GetAttribute(kNameSpaceID_None, nameAtom, aReturn); + nsIAtom* nameAtom; + PRInt32 nameSpaceID; + + mContent->ParseAttributeString(aName, nameAtom, nameSpaceID); + mContent->GetAttribute(nameSpaceID, nameAtom, aReturn); NS_RELEASE(nameAtom); - return rv; + + return NS_OK; } nsresult -nsGenericElement::SetDOMAttribute(const nsString& aName, - const nsString& aValue) +nsGenericElement::SetAttribute(const nsString& aName, + const nsString& aValue) { - // XXX need to parse namespace from name - // XXX need to uppercase name if HTML namespace - nsIAtom* nameAtom = NS_NewAtom(aName); - nsresult rv = mContent->SetAttribute(kNameSpaceID_None, nameAtom, aValue, PR_TRUE); + nsIAtom* nameAtom; + PRInt32 nameSpaceID; + nsresult result = NS_OK; + + mContent->ParseAttributeString(aName, nameAtom, nameSpaceID); + result = mContent->SetAttribute(nameSpaceID, nameAtom, aValue, PR_TRUE); NS_RELEASE(nameAtom); - return rv; + + return result; } nsresult nsGenericElement::RemoveAttribute(const nsString& aName) { - // XXX need to parse namespace from name - // XXX need to uppercase name if HTML namespace - nsIAtom* nameAtom = NS_NewAtom(aName); - nsresult rv = mContent->UnsetAttribute(kNameSpaceID_None, nameAtom, PR_TRUE); + nsIAtom* nameAtom; + PRInt32 nameSpaceID; + nsresult result = NS_OK; + + mContent->ParseAttributeString(aName, nameAtom, nameSpaceID); + result = mContent->UnsetAttribute(nameSpaceID, nameAtom, PR_TRUE); NS_RELEASE(nameAtom); - return rv; + + return result; } nsresult nsGenericElement::GetAttributeNode(const nsString& aName, nsIDOMAttr** aReturn) { - // XXX need to parse namespace from name - // XXX need to uppercase name if HTML namespace - nsIAtom* nameAtom = NS_NewAtom(aName); - nsAutoString value; - if (NS_CONTENT_ATTR_NOT_THERE != mContent->GetAttribute(kNameSpaceID_None, nameAtom, value)) { - *aReturn = new nsDOMAttribute(aName, value); + if (nsnull == aReturn) { + return NS_ERROR_NULL_POINTER; } - else { - *aReturn = nsnull; + nsIDOMNamedNodeMap* map; + nsresult result = GetAttributes(&map); + + *aReturn = nsnull; + if (NS_OK == result) { + nsIDOMNode* node; + result = map->GetNamedItem(aName, &node); + if ((NS_OK == result) && (nsnull != node)) { + result = node->QueryInterface(kIDOMAttrIID, (void **)aReturn); + NS_IF_RELEASE(node); + } + NS_RELEASE(map); } - NS_RELEASE(nameAtom); - return NS_OK; + + return result; } nsresult nsGenericElement::SetAttributeNode(nsIDOMAttr* aAttribute, - nsIDOMAttr** aReturn) + nsIDOMAttr** aReturn) { - NS_PRECONDITION(nsnull != aAttribute, "null attribute"); - - nsresult res = NS_ERROR_FAILURE; - - if (nsnull != aAttribute) { - nsAutoString name, value; - res = aAttribute->GetName(name); - if (NS_OK == res) { - res = aAttribute->GetValue(value); - if (NS_OK == res) { - // XXX need to parse namespace from name - // XXX need to uppercase name if HTML namespace - nsIAtom* nameAtom = NS_NewAtom(name); - mContent->SetAttribute(kNameSpaceID_None, nameAtom, value, PR_TRUE); - NS_RELEASE(nameAtom); - } - } + if ((nsnull == aReturn) || (nsnull == aAttribute)) { + return NS_ERROR_NULL_POINTER; } - return res; + nsIDOMNamedNodeMap* map; + nsresult result = GetAttributes(&map); + + *aReturn = nsnull; + if (NS_OK == result) { + nsIDOMNode *node, *returnNode; + result = aAttribute->QueryInterface(kIDOMNodeIID, (void **)&node); + if (NS_OK == result) { + result = map->SetNamedItem(node, &returnNode); + if ((NS_OK == result) && (nsnull != returnNode)) { + result = returnNode->QueryInterface(kIDOMAttrIID, (void **)aReturn); + NS_IF_RELEASE(returnNode); + } + NS_RELEASE(node); + } + NS_RELEASE(map); + } + + return result; } nsresult nsGenericElement::RemoveAttributeNode(nsIDOMAttr* aAttribute, - nsIDOMAttr** aReturn) + nsIDOMAttr** aReturn) { - NS_PRECONDITION(nsnull != aAttribute, "null attribute"); + if ((nsnull == aReturn) || (nsnull == aAttribute)) { + return NS_ERROR_NULL_POINTER; + } + nsIDOMNamedNodeMap* map; + nsresult result = GetAttributes(&map); - nsresult res = NS_ERROR_FAILURE; - - if (nsnull != aAttribute) { + *aReturn = nsnull; + if (NS_OK == result) { nsAutoString name; - res = aAttribute->GetName(name); - if (NS_OK == res) { - // XXX need to parse namespace from name - // XXX need to uppercase name if HTML namespace - nsIAtom* nameAtom = NS_NewAtom(name); - mContent->UnsetAttribute(kNameSpaceID_None, nameAtom, PR_TRUE); - NS_RELEASE(nameAtom); + + result = aAttribute->GetName(name); + if (NS_OK == result) { + nsIDOMNode* node; + result = map->RemoveNamedItem(name, &node); + if ((NS_OK == result) && (nsnull != node)) { + result = node->QueryInterface(kIDOMAttrIID, (void **)aReturn); + NS_RELEASE(node); + } } + NS_RELEASE(map); } - return res; + return result; } nsresult @@ -1482,6 +1138,23 @@ nsGenericElement::AddScriptEventListener(nsIAtom* aAttribute, return ret; } +static char kNameSpaceSeparator[] = ":"; + +nsIAtom* +nsGenericElement::CutNameSpacePrefix(nsString& aString) +{ + nsAutoString prefix; + PRInt32 nsoffset = aString.Find(kNameSpaceSeparator); + if (-1 != nsoffset) { + aString.Left(prefix, nsoffset); + aString.Cut(0, nsoffset+1); + } + if (0 < prefix.Length()) { + return NS_NewAtom(prefix); + } + return nsnull; +} + //---------------------------------------------------------------------- struct nsGenericAttribute @@ -1531,8 +1204,6 @@ nsresult nsGenericContainerElement::CopyInnerTo(nsIContent* aSrcContent, nsGenericContainerElement* aDst) { - aDst->mContent = aSrcContent; - // XXX should the node's document be set? // XXX copy attributes not yet impelemented // XXX deep copy? return NS_OK; diff --git a/content/base/src/nsGenericElement.h b/content/base/src/nsGenericElement.h index 8321698fd4b6..9a4c7fe7cb4c 100644 --- a/content/base/src/nsGenericElement.h +++ b/content/base/src/nsGenericElement.h @@ -45,78 +45,7 @@ class nsISupportsArray; class nsIDOMScriptObjectFactory; class nsDOMCSSDeclaration; class nsIDOMCSSStyleDeclaration; - -// Attribute helper class used to wrap up an attribute with a dom -// object that implements nsIDOMAttr and nsIDOMNode and -// nsIScriptObjectOwner -class nsDOMAttribute : public nsIDOMAttr, public nsIScriptObjectOwner { -public: - nsDOMAttribute(const nsString &aName, const nsString &aValue); - ~nsDOMAttribute(); - - NS_DECL_ISUPPORTS - - NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject); - NS_IMETHOD SetScriptObject(void *aScriptObject); - - // nsIDOMAttr interface - NS_IMETHOD GetSpecified(PRBool* aSpecified); - NS_IMETHOD GetName(nsString& aReturn); - NS_IMETHOD GetValue(nsString& aReturn); - NS_IMETHOD SetValue(const nsString& aValue); - - // nsIDOMNode interface - NS_IMETHOD GetNodeName(nsString& aNodeName); - NS_IMETHOD GetNodeValue(nsString& aNodeValue); - NS_IMETHOD SetNodeValue(const nsString& aNodeValue); - NS_IMETHOD GetNodeType(PRUint16* aNodeType); - NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode); - NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes); - NS_IMETHOD HasChildNodes(PRBool* aHasChildNodes); - NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild); - NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild); - NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling); - NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling); - NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes); - NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, - nsIDOMNode** aReturn); - NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, - nsIDOMNode** aReturn); - NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn); - NS_IMETHOD AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn); - NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn); - NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument); - -private: - nsString mName; - nsString mValue; - void* mScriptObject; -}; - -// Another helper class that implements the nsIDOMNamedNodeMap interface. -class nsDOMAttributeMap : public nsIDOMNamedNodeMap, - public nsIScriptObjectOwner -{ -public: - nsDOMAttributeMap(nsIContent* aContent); - ~nsDOMAttributeMap(); - - NS_DECL_ISUPPORTS - - NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject); - NS_IMETHOD SetScriptObject(void *aScriptObject); - - // nsIDOMNamedNodeMap interface - NS_IMETHOD GetLength(PRUint32* aSize); - NS_IMETHOD GetNamedItem(const nsString& aName, nsIDOMNode** aReturn); - NS_IMETHOD SetNamedItem(nsIDOMNode* aNode, nsIDOMNode** aReturn); - NS_IMETHOD RemoveNamedItem(const nsString& aName, nsIDOMNode** aReturn); - NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn); - -private: - nsIContent* mContent; - void* mScriptObject; -}; +class nsDOMAttributeMap; // Class that holds the child list of a content element and also @@ -153,6 +82,7 @@ typedef struct { void *mScriptObject; nsChildContentList *mChildNodes; nsDOMCSSDeclaration *mStyle; + nsDOMAttributeMap* mAttributeMap; nsVoidArray *mRangeList; PRBool mIsContainer; } nsDOMSlots; @@ -177,8 +107,8 @@ public: // Implementation for nsIDOMElement nsresult GetTagName(nsString& aTagName); - nsresult GetDOMAttribute(const nsString& aName, nsString& aReturn); - nsresult SetDOMAttribute(const nsString& aName, const nsString& aValue); + nsresult GetAttribute(const nsString& aName, nsString& aReturn); + nsresult SetAttribute(const nsString& aName, const nsString& aValue); nsresult RemoveAttribute(const nsString& aName); nsresult GetAttributeNode(const nsString& aName, nsIDOMAttr** aReturn); @@ -257,6 +187,8 @@ public: static nsIDOMScriptObjectFactory *gScriptObjectFactory; + static nsIAtom* CutNameSpacePrefix(nsString& aString); + nsDOMSlots *GetDOMSlots(); // Up pointer to the real content object that we are @@ -272,8 +204,6 @@ public: nsDOMSlots *mDOMSlots; }; -//---------------------------------------------------------------------- - class nsGenericContainerElement : public nsGenericElement { public: nsGenericContainerElement(); @@ -283,6 +213,14 @@ public: nsGenericContainerElement* aDest); // Remainder of nsIDOMHTMLElement (and nsIDOMNode) + nsresult GetAttribute(const nsString& aName, nsString& aReturn) + { + return nsGenericElement::GetAttribute(aName, aReturn); + } + nsresult SetAttribute(const nsString& aName, const nsString& aValue) + { + return nsGenericElement::SetAttribute(aName, aValue); + } nsresult GetChildNodes(nsIDOMNodeList** aChildNodes); nsresult HasChildNodes(PRBool* aHasChildNodes); nsresult GetFirstChild(nsIDOMNode** aFirstChild); @@ -327,6 +265,7 @@ public: nsVoidArray mChildren; }; + //---------------------------------------------------------------------- /** @@ -402,11 +341,11 @@ public: NS_IMETHOD GetTagName(nsString& aTagName) { \ return _g.GetTagName(aTagName); \ } \ - NS_IMETHOD GetDOMAttribute(const nsString& aName, nsString& aReturn) { \ - return _g.GetDOMAttribute(aName, aReturn); \ + NS_IMETHOD GetAttribute(const nsString& aName, nsString& aReturn) { \ + return _g.GetAttribute(aName, aReturn); \ } \ - NS_IMETHOD SetDOMAttribute(const nsString& aName, const nsString& aValue) { \ - return _g.SetDOMAttribute(aName, aValue); \ + NS_IMETHOD SetAttribute(const nsString& aName, const nsString& aValue) { \ + return _g.SetAttribute(aName, aValue); \ } \ NS_IMETHOD RemoveAttribute(const nsString& aName) { \ return _g.RemoveAttribute(aName); \ @@ -498,6 +437,15 @@ public: NS_IMETHOD GetTag(nsIAtom*& aResult) const { \ return _g.GetTag(aResult); \ } \ + NS_IMETHOD ParseAttributeString(const nsString& aStr, \ + nsIAtom*& aName, \ + PRInt32& aNameSpaceID) { \ + return _g.ParseAttributeString(aStr, aName, aNameSpaceID); \ + } \ + NS_IMETHOD GetNameSpacePrefix(PRInt32 aNameSpaceID, \ + nsIAtom*& aPrefix) { \ + return _g.GetNameSpacePrefix(aNameSpaceID, aPrefix); \ + } \ NS_IMETHOD SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, \ const nsString& aValue, PRBool aNotify) { \ return _g.SetAttribute(aNameSpaceID, aName, aValue, aNotify); \ @@ -548,6 +496,18 @@ public: return _g.GetRangeList(aResult); \ } +/** + * Implement the nsIScriptObjectOwner API by forwarding the methods to a + * generic content object + */ +#define NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC(_g) \ + NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, \ + void** aScriptObject) { \ + return _g.GetScriptObject(aContext, aScriptObject); \ + } \ + NS_IMETHOD SetScriptObject(void *aScriptObject) { \ + return _g.SetScriptObject(aScriptObject); \ + } #define NS_IMPL_CONTENT_QUERY_INTERFACE(_id, _iptr, _this, _base) \ if (_id.Equals(kISupportsIID)) { \ diff --git a/content/html/content/src/nsGenericHTMLElement.cpp b/content/html/content/src/nsGenericHTMLElement.cpp index 3eca4a45ff6d..59386025e010 100644 --- a/content/html/content/src/nsGenericHTMLElement.cpp +++ b/content/html/content/src/nsGenericHTMLElement.cpp @@ -244,115 +244,7 @@ nsGenericHTMLElement::~nsGenericHTMLElement() } } - // Implementation for nsIDOMElement -nsresult -nsGenericHTMLElement::GetDOMAttribute(const nsString& aName, nsString& aReturn) -{ - // XXX need to parse namepsace from name, presume HTML if none - // XXX need to uppercase name only if HTML namespace - nsAutoString upper; - aName.ToUpperCase(upper); - nsIAtom* nameAtom = NS_NewAtom(upper); - nsresult rv = mContent->GetAttribute(kNameSpaceID_HTML, nameAtom, aReturn); - NS_RELEASE(nameAtom); - return rv; -} - -nsresult -nsGenericHTMLElement::SetDOMAttribute(const nsString& aName, const nsString& aValue) -{ - // XXX need to parse namepsace from name, presume HTML if none - // XXX need to uppercase name only if HTML namespace - nsAutoString upper; - aName.ToUpperCase(upper); - nsIAtom* nameAtom = NS_NewAtom(upper); - nsresult rv = mContent->SetAttribute(kNameSpaceID_HTML, nameAtom, aValue, PR_TRUE); - NS_RELEASE(nameAtom); - return rv; -} - -nsresult -nsGenericHTMLElement::RemoveAttribute(const nsString& aName) -{ - // XXX need to parse namepsace from name, presume HTML if none - // XXX need to uppercase name only if HTML namespace - nsAutoString upper; - aName.ToUpperCase(upper); - nsIAtom* nameAtom = NS_NewAtom(upper); - nsresult rv = mContent->UnsetAttribute(kNameSpaceID_HTML, nameAtom, PR_TRUE); - NS_RELEASE(nameAtom); - return rv; -} - -nsresult -nsGenericHTMLElement::GetAttributeNode(const nsString& aName, - nsIDOMAttr** aReturn) -{ - // XXX need to parse namepsace from name, presume HTML if none - // XXX need to uppercase name only if HTML namespace - nsAutoString upper; - aName.ToUpperCase(upper); - nsIAtom* nameAtom = NS_NewAtom(upper); - nsAutoString value; - if (NS_CONTENT_ATTR_NOT_THERE != mContent->GetAttribute(kNameSpaceID_HTML, nameAtom, value)) { - *aReturn = new nsDOMAttribute(aName, value); - } - else { - *aReturn = nsnull; - } - NS_RELEASE(nameAtom); - return NS_OK; -} - -nsresult -nsGenericHTMLElement::SetAttributeNode(nsIDOMAttr* aAttribute, nsIDOMAttr** aReturn) -{ - NS_PRECONDITION(nsnull != aAttribute, "null attribute"); - - nsresult res = NS_ERROR_FAILURE; - - if (nsnull != aAttribute) { - nsAutoString name, value; - res = aAttribute->GetName(name); - if (NS_OK == res) { - res = aAttribute->GetValue(value); - if (NS_OK == res) { - // XXX need to parse out namespace - // XXX need to only uppercase if HTML namespace (or none since this is an HTML element) - name.ToUpperCase(); - nsIAtom* nameAtom = NS_NewAtom(name); - mContent->SetAttribute(kNameSpaceID_HTML, nameAtom, value, PR_TRUE); - NS_RELEASE(nameAtom); - } - } - } - return res; -} - -nsresult -nsGenericHTMLElement::RemoveAttributeNode(nsIDOMAttr* aAttribute, nsIDOMAttr** aReturn) -{ - NS_PRECONDITION(nsnull != aAttribute, "null attribute"); - - nsresult res = NS_ERROR_FAILURE; - - if (nsnull != aAttribute) { - nsAutoString name; - res = aAttribute->GetName(name); - if (NS_OK == res) { - // XXX need to parse out namespace - // XXX need to only uppercase if HTML namespace (or none since this is an HTML element) - name.ToUpperCase(); - nsIAtom* nameAtom = NS_NewAtom(name); - mContent->UnsetAttribute(kNameSpaceID_HTML, nameAtom, PR_TRUE); - NS_RELEASE(nameAtom); - } - } - - return res; -} - - +// Implementation for nsIDOMHTMLElement nsresult nsGenericHTMLElement::GetId(nsString& aId) { @@ -517,6 +409,27 @@ static nsGenericHTMLElement::EnumTable kDirTable[] = { }; #endif +nsresult +nsGenericHTMLElement::ParseAttributeString(const nsString& aStr, + nsIAtom*& aName, + PRInt32& aNameSpaceID) +{ + nsAutoString upper; + aStr.ToUpperCase(upper); + aName = NS_NewAtom(upper); + aNameSpaceID = kNameSpaceID_HTML; + + return NS_OK; +} + +nsresult +nsGenericHTMLElement::GetNameSpacePrefix(PRInt32 aNameSpaceID, + nsIAtom*& aPrefix) +{ + aPrefix = nsnull; + return NS_OK; +} + nsresult nsGenericHTMLElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute, diff --git a/content/html/content/src/nsGenericHTMLElement.h b/content/html/content/src/nsGenericHTMLElement.h index 9ef5ecccc442..d03bffad6240 100644 --- a/content/html/content/src/nsGenericHTMLElement.h +++ b/content/html/content/src/nsGenericHTMLElement.h @@ -52,13 +52,14 @@ public: ~nsGenericHTMLElement(); // Implementation for nsIDOMElement - nsresult GetDOMAttribute(const nsString& aName, nsString& aReturn); - nsresult SetDOMAttribute(const nsString& aName, const nsString& aValue); - nsresult RemoveAttribute(const nsString& aName); - nsresult GetAttributeNode(const nsString& aName, - nsIDOMAttr** aReturn); - nsresult SetAttributeNode(nsIDOMAttr* aNewAttr, nsIDOMAttr** aReturn); - nsresult RemoveAttributeNode(nsIDOMAttr* aOldAttr, nsIDOMAttr** aReturn); + nsresult GetAttribute(const nsString& aName, nsString& aReturn) + { + return nsGenericElement::GetAttribute(aName, aReturn); + } + nsresult SetAttribute(const nsString& aName, const nsString& aValue) + { + return nsGenericElement::SetAttribute(aName, aValue); + } // Implementation for nsIDOMHTMLElement nsresult GetId(nsString& aId); @@ -76,6 +77,11 @@ public: // Implementation for nsIContent nsresult GetNameSpaceID(PRInt32& aNameSpaceID) const; nsresult SetDocument(nsIDocument* aDocument, PRBool aDeep); + nsresult ParseAttributeString(const nsString& aStr, + nsIAtom*& aName, + PRInt32& aNameSpaceID); + nsresult GetNameSpacePrefix(PRInt32 aNameSpaceID, + nsIAtom*& aPrefix); nsresult SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, const nsString& aValue, PRBool aNotify); nsresult GetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, nsString& aResult) const; @@ -387,21 +393,6 @@ public: return _g.GetStyle(aStyle); \ } -/** - * Implement the nsIScriptObjectOwner API by forwarding the methods to a - * generic content object (either nsGenericHTMLLeafElement or - * nsGenericHTMLContainerContent) - */ -#define NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC(_g) \ - NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, \ - void** aScriptObject) { \ - return _g.GetScriptObject(aContext, aScriptObject); \ - } \ - NS_IMETHOD SetScriptObject(void *aScriptObject) { \ - return _g.SetScriptObject(aScriptObject); \ - } - - #define NS_IMPL_IHTMLCONTENT_USING_GENERIC(_g) \ NS_IMETHOD Compact() { \ return _g.Compact(); \ diff --git a/content/html/document/src/nsHTMLDocument.cpp b/content/html/document/src/nsHTMLDocument.cpp index b86931d41358..f62c5f077294 100644 --- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -592,13 +592,6 @@ nsHTMLDocument::CreateEntityReference(const nsString& aName, return NS_OK; } -NS_IMETHODIMP -nsHTMLDocument::CreateAttribute(const nsString& aName, - nsIDOMAttr** aReturn) -{ - // XXX To be implemented - return NS_ERROR_NOT_IMPLEMENTED; -} NS_IMETHODIMP nsHTMLDocument::GetDoctype(nsIDOMDocumentType** aDocumentType) diff --git a/content/html/document/src/nsHTMLDocument.h b/content/html/document/src/nsHTMLDocument.h index 3868428feb0a..a4454bd39aab 100644 --- a/content/html/document/src/nsHTMLDocument.h +++ b/content/html/document/src/nsHTMLDocument.h @@ -92,7 +92,8 @@ public: { return nsDocument::CreateDocumentFragment(aReturn); } NS_IMETHOD CreateComment(const nsString& aData, nsIDOMComment** aReturn); NS_IMETHOD CreateProcessingInstruction(const nsString& aTarget, const nsString& aData, nsIDOMProcessingInstruction** aReturn); - NS_IMETHOD CreateAttribute(const nsString& aName, nsIDOMAttr** aReturn); + NS_IMETHOD CreateAttribute(const nsString& aName, nsIDOMAttr** aReturn) + { return nsDocument::CreateAttribute(aName, aReturn); } NS_IMETHOD CreateElement(const nsString& aTagName, nsIDOMElement** aReturn); NS_IMETHOD CreateTextNode(const nsString& aData, nsIDOMText** aReturn); diff --git a/content/xml/content/public/nsIXMLContent.h b/content/xml/content/public/nsIXMLContent.h index 0dc6f936a6bd..2d9f3a92ebdd 100644 --- a/content/xml/content/public/nsIXMLContent.h +++ b/content/xml/content/public/nsIXMLContent.h @@ -23,6 +23,8 @@ #include "nsISupports.h" #include "nsIContent.h" +class nsINameSpace; + #define NS_IXMLCONTENT_IID \ { 0xa6cf90cb, 0x15b3, 0x11d2, \ { 0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32 } } @@ -32,7 +34,9 @@ */ class nsIXMLContent : public nsIContent { public: - // XXX A convenience - the id can be used to get the namespace Atom + NS_IMETHOD SetContainingNameSpace(nsINameSpace* aNameSpace) = 0; + NS_IMETHOD GetContainingNameSpace(nsINameSpace*& aNameSpace) const = 0; + NS_IMETHOD SetNameSpacePrefix(nsIAtom* aNameSpace) = 0; NS_IMETHOD GetNameSpacePrefix(nsIAtom*& aNameSpace) const = 0; diff --git a/content/xml/content/src/Makefile.in b/content/xml/content/src/Makefile.in index d3d6306fdbf4..0a8a0fb2ecc1 100644 --- a/content/xml/content/src/Makefile.in +++ b/content/xml/content/src/Makefile.in @@ -39,6 +39,7 @@ INCLUDES += \ # Note the sophisticated alphabetical ordering :-| CPPSRCS = \ nsXMLElement.cpp \ + nsGenericXMLElement.cpp \ $(NULL) EXPORTS = \ diff --git a/content/xml/content/src/makefile.win b/content/xml/content/src/makefile.win index a068996224f9..a376b32db0a4 100644 --- a/content/xml/content/src/makefile.win +++ b/content/xml/content/src/makefile.win @@ -25,10 +25,12 @@ DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN CPPSRCS= \ nsXMLElement.cpp \ + nsGenericXMLElement.cpp \ $(NULL) CPP_OBJS= \ .\$(OBJDIR)\nsXMLElement.obj \ + .\$(OBJDIR)\nsGenericXMLElement.obj \ $(NULL) EXPORTS = \ diff --git a/content/xml/content/src/nsXMLElement.cpp b/content/xml/content/src/nsXMLElement.cpp index 9368f9be7a91..e33565fcbe94 100644 --- a/content/xml/content/src/nsXMLElement.cpp +++ b/content/xml/content/src/nsXMLElement.cpp @@ -25,6 +25,7 @@ #include "nsIEventStateManager.h" #include "nsDOMEvent.h" +#include "nsINameSpace.h" #include "nsINameSpaceManager.h" //static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID); @@ -52,9 +53,6 @@ nsXMLElement::nsXMLElement(nsIAtom *aTag) { NS_INIT_REFCNT(); mInner.Init((nsIContent *)(nsIXMLContent *)this, aTag); - mNameSpacePrefix = nsnull; - mNameSpaceID = kNameSpaceID_None; - mScriptObject = nsnull; mIsLink = PR_FALSE; if (nsnull == kLinkAtom) { @@ -71,7 +69,6 @@ nsXMLElement::nsXMLElement(nsIAtom *aTag) nsXMLElement::~nsXMLElement() { - NS_IF_RELEASE(mNameSpacePrefix); nsrefcnt refcnt; NS_RELEASE2(kLinkAtom, refcnt); NS_RELEASE2(kHrefAtom, refcnt); @@ -96,92 +93,6 @@ nsXMLElement::QueryInterface(REFNSIID aIID, NS_IMPL_ADDREF(nsXMLElement) NS_IMPL_RELEASE(nsXMLElement) -NS_IMETHODIMP -nsXMLElement::GetScriptObject(nsIScriptContext* aContext, void** aScriptObject) -{ - nsresult res = NS_OK; - - // XXX Yuck! Reaching into the generic content object isn't good. - nsDOMSlots *slots = mInner.GetDOMSlots(); - if (nsnull == slots->mScriptObject) { - nsIDOMScriptObjectFactory *factory; - - res = nsGenericElement::GetScriptObjectFactory(&factory); - if (NS_OK != res) { - return res; - } - - nsAutoString tag; - nsIContent* parent; - - mInner.GetTagName(tag); - mInner.GetParent(parent); - - res = factory->NewScriptXMLElement(tag, aContext, - (nsISupports *)(nsIDOMElement *)this, - parent, (void**)&slots->mScriptObject); - NS_IF_RELEASE(parent); - NS_RELEASE(factory); - - char tagBuf[50]; - tag.ToCString(tagBuf, sizeof(tagBuf)); - - nsIDocument *document; - mInner.GetDocument(document); - if (nsnull != document) { - aContext->AddNamedReference((void *)&slots->mScriptObject, - slots->mScriptObject, - tagBuf); - NS_RELEASE(document); - } - } - *aScriptObject = slots->mScriptObject; - return res; -} - -NS_IMETHODIMP -nsXMLElement::SetScriptObject(void *aScriptObject) -{ - return mInner.SetScriptObject(aScriptObject); -} - -NS_IMETHODIMP -nsXMLElement::SetNameSpacePrefix(nsIAtom* aNameSpacePrefix) -{ - NS_IF_RELEASE(mNameSpacePrefix); - - mNameSpacePrefix = aNameSpacePrefix; - - NS_IF_ADDREF(mNameSpacePrefix); - - return NS_OK; -} - -NS_IMETHODIMP -nsXMLElement::GetNameSpacePrefix(nsIAtom*& aNameSpacePrefix) const -{ - aNameSpacePrefix = mNameSpacePrefix; - - NS_IF_ADDREF(mNameSpacePrefix); - - return NS_OK; -} - -NS_IMETHODIMP -nsXMLElement::SetNameSpaceID(PRInt32 aNameSpaceID) -{ - mNameSpaceID = aNameSpaceID; - - return NS_OK; -} - -NS_IMETHODIMP -nsXMLElement::GetNameSpaceID(PRInt32& aNameSpaceID) const -{ - aNameSpaceID = mNameSpaceID; - - return NS_OK; -} NS_IMETHODIMP nsXMLElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, @@ -292,9 +203,6 @@ nsXMLElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn) return NS_ERROR_OUT_OF_MEMORY; } mInner.CopyInnerTo((nsIContent *)(nsIXMLContent *)this, &it->mInner); - it->mNameSpacePrefix = mNameSpacePrefix; - NS_IF_ADDREF(mNameSpacePrefix); - it->mNameSpaceID = mNameSpaceID; return it->QueryInterface(kIDOMNodeIID, (void**) aReturn); } diff --git a/content/xml/content/src/nsXMLElement.h b/content/xml/content/src/nsXMLElement.h index d2a4279759b6..b14a62be9256 100644 --- a/content/xml/content/src/nsXMLElement.h +++ b/content/xml/content/src/nsXMLElement.h @@ -25,7 +25,7 @@ #include "nsIDOMEventReceiver.h" #include "nsIXMLContent.h" #include "nsIJSScriptObject.h" -#include "nsGenericElement.h" +#include "nsGenericXMLElement.h" class nsIDocument; class nsIAtom; @@ -52,8 +52,7 @@ public: NS_IMPL_IDOMELEMENT_USING_GENERIC(mInner) // nsIScriptObjectOwner - NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject); - NS_IMETHOD SetScriptObject(void *aScriptObject); + NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC(mInner) // nsIContent NS_IMETHOD GetDocument(nsIDocument*& aResult) const { @@ -68,6 +67,9 @@ public: NS_IMETHOD SetParent(nsIContent* aParent) { return mInner.SetParent(aParent); } + NS_IMETHOD GetNameSpaceID(PRInt32& aNameSpaceId) const { + return mInner.GetNameSpaceID(aNameSpaceId); + } NS_IMETHOD CanContainChildren(PRBool& aResult) const { return mInner.CanContainChildren(aResult); } @@ -97,10 +99,18 @@ public: NS_IMETHOD IsSynthetic(PRBool& aResult) { return mInner.IsSynthetic(aResult); } - NS_IMETHOD GetNameSpaceID(PRInt32& aResult) const; NS_IMETHOD GetTag(nsIAtom*& aResult) const { return mInner.GetTag(aResult); } + NS_IMETHOD ParseAttributeString(const nsString& aStr, + nsIAtom*& aName, + PRInt32& aNameSpaceID) { + return mInner.ParseAttributeString(aStr, aName, aNameSpaceID); + } + NS_IMETHOD GetNameSpacePrefix(PRInt32 aNameSpaceID, + nsIAtom*& aPrefix) { + return mInner.GetNameSpacePrefix(aNameSpaceID, aPrefix); + } NS_IMETHOD SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, const nsString& aValue, PRBool aNotify); NS_IMETHOD GetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, @@ -149,9 +159,21 @@ public: } // nsIXMLContent - NS_IMETHOD SetNameSpacePrefix(nsIAtom* aNameSpace); - NS_IMETHOD GetNameSpacePrefix(nsIAtom*& aNameSpace) const; - NS_IMETHOD SetNameSpaceID(PRInt32 aNameSpaceId); + NS_IMETHOD SetContainingNameSpace(nsINameSpace* aNameSpace) { + return mInner.SetContainingNameSpace(aNameSpace); + } + NS_IMETHOD GetContainingNameSpace(nsINameSpace*& aNameSpace) const { + return mInner.GetContainingNameSpace(aNameSpace); + } + NS_IMETHOD SetNameSpacePrefix(nsIAtom* aNameSpace) { + return mInner.SetNameSpacePrefix(aNameSpace); + } + NS_IMETHOD GetNameSpacePrefix(nsIAtom*& aNameSpace) const { + return mInner.GetNameSpacePrefix(aNameSpace); + } + NS_IMETHOD SetNameSpaceID(PRInt32 aNameSpaceId) { + return mInner.SetNameSpaceID(aNameSpaceId); + } // nsIDOMEventReceiver NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC(mInner) @@ -183,11 +205,7 @@ public: } protected: - nsGenericContainerElement mInner; - - nsIAtom* mNameSpacePrefix; - PRInt32 mNameSpaceID; - void *mScriptObject; + nsGenericXMLElement mInner; PRBool mIsLink; }; diff --git a/content/xml/document/src/nsXMLContentSink.cpp b/content/xml/document/src/nsXMLContentSink.cpp index e667d7e55c46..cd570cc20e99 100644 --- a/content/xml/document/src/nsXMLContentSink.cpp +++ b/content/xml/document/src/nsXMLContentSink.cpp @@ -61,6 +61,7 @@ static char kXSLType[] = "text/xsl"; static NS_DEFINE_IID(kIXMLContentSinkIID, NS_IXMLCONTENT_SINK_IID); +static NS_DEFINE_IID(kIXMLContentIID, NS_IXMLCONTENT_IID); static NS_DEFINE_IID(kIXMLDocumentIID, NS_IXMLDOCUMENT_IID); static NS_DEFINE_IID(kIDOMCommentIID, NS_IDOMCOMMENT_IID); static NS_DEFINE_IID(kIScrollableViewIID, NS_ISCROLLABLEVIEW_IID); @@ -653,8 +654,9 @@ nsXMLContentSink::CloseContainer(const nsIParserNode& aNode) NS_RELEASE(tagAtom); } + nsIContent* content = nsnull; if (popContent) { - nsIContent* content = PopContent(); + content = PopContent(); if (nsnull != content) { if (mDocElement == content) { mState = eXMLContentSinkState_InEpilog; @@ -667,7 +669,16 @@ nsXMLContentSink::CloseContainer(const nsIParserNode& aNode) PR_ASSERT(0); } } - PopNameSpaces(); + nsINameSpace* nameSpace = PopNameSpaces(); + if (nsnull != content) { + nsIXMLContent* xmlContent; + if (NS_OK == content->QueryInterface(kIXMLContentIID, + (void **)&xmlContent)) { + xmlContent->SetContainingNameSpace(nameSpace); + NS_RELEASE(xmlContent); + } + } + NS_IF_RELEASE(nameSpace); return result; } @@ -1245,15 +1256,17 @@ nsXMLContentSink::GetNameSpaceId(nsIAtom* aPrefix) return id; } -void +nsINameSpace* nsXMLContentSink::PopNameSpaces() { if ((nsnull != mNameSpaceStack) && (0 < mNameSpaceStack->Count())) { PRInt32 index = mNameSpaceStack->Count() - 1; nsINameSpace* nameSpace = (nsINameSpace*)mNameSpaceStack->ElementAt(index); mNameSpaceStack->RemoveElementAt(index); - NS_RELEASE(nameSpace); + return nameSpace; } + + return nsnull; } PRBool diff --git a/content/xml/document/src/nsXMLContentSink.h b/content/xml/document/src/nsXMLContentSink.h index 783b2dde3b18..a67759cad71e 100644 --- a/content/xml/document/src/nsXMLContentSink.h +++ b/content/xml/document/src/nsXMLContentSink.h @@ -33,6 +33,7 @@ class nsVoidArray; class nsIXMLDocument; class nsIUnicharInputStream; class nsIParser; +class nsINameSpace; typedef enum { eXMLContentSinkState_InProlog, @@ -104,7 +105,7 @@ protected: void PushNameSpacesFrom(const nsIParserNode& aNode); nsIAtom* CutNameSpacePrefix(nsString& aString); PRInt32 GetNameSpaceId(nsIAtom* aPrefix); - void PopNameSpaces(); + nsINameSpace* PopNameSpaces(); PRBool IsHTMLNameSpace(PRInt32 aId); nsIContent* GetCurrentContent(); diff --git a/content/xml/document/src/nsXMLDocument.cpp b/content/xml/document/src/nsXMLDocument.cpp index bd601082da9d..167eff155557 100644 --- a/content/xml/document/src/nsXMLDocument.cpp +++ b/content/xml/document/src/nsXMLDocument.cpp @@ -301,14 +301,6 @@ nsXMLDocument::CreateProcessingInstruction(const nsString& aTarget, const nsStri return NS_ERROR_NOT_IMPLEMENTED; } -NS_IMETHODIMP -nsXMLDocument::CreateAttribute(const nsString& aName, nsIDOMAttr** aReturn) -{ - // XXX TBI - *aReturn = nsnull; - return NS_ERROR_NOT_IMPLEMENTED; -} - NS_IMETHODIMP nsXMLDocument::CreateElement(const nsString& aTagName, nsIDOMElement** aReturn) diff --git a/content/xml/document/src/nsXMLDocument.h b/content/xml/document/src/nsXMLDocument.h index 15e74da8402c..511cbf6c7997 100644 --- a/content/xml/document/src/nsXMLDocument.h +++ b/content/xml/document/src/nsXMLDocument.h @@ -52,7 +52,6 @@ public: NS_IMETHOD CreateEntityReference(const nsString& aName, nsIDOMEntityReference** aReturn); NS_IMETHOD CreateComment(const nsString& aData, nsIDOMComment** aReturn); NS_IMETHOD CreateProcessingInstruction(const nsString& aTarget, const nsString& aData, nsIDOMProcessingInstruction** aReturn); - NS_IMETHOD CreateAttribute(const nsString& aName, nsIDOMAttr** aReturn); NS_IMETHOD CreateElement(const nsString& aTagName, nsIDOMElement** aReturn); NS_IMETHOD CreateTextNode(const nsString& aData, nsIDOMText** aReturn); diff --git a/layout/base/public/nsIContent.h b/layout/base/public/nsIContent.h index 759ed5a9486e..5fe330b8d8f1 100644 --- a/layout/base/public/nsIContent.h +++ b/layout/base/public/nsIContent.h @@ -90,6 +90,32 @@ public: */ NS_IMETHOD IsSynthetic(PRBool& aResult) = 0; + /** + * Parses an attribute string into an atom that represents the + * attribute name and an identifier that represents the namespace + * of the attribute. The namespace identifier may be computed + * from a namespace prefix that must be interpreted in the context + * of the content itself. + * + * @param aStr the unparsed attribute string + * @param aName out parameter representing the name of the attribute + * @param aNameSpaceID out parameter reprsenting the namespace + * of the attribute + */ + NS_IMETHOD ParseAttributeString(const nsString& aStr, + nsIAtom*& aName, + PRInt32& aNameSpaceID) = 0; + + /** + * Returns the prefix for the specified name space identifier in + * the context of the content element itself. + * + * @param aNameSpaceID identifier of the namespace + * @param aPrefix out parameter representing the prefix for the namespace + */ + NS_IMETHOD GetNameSpacePrefix(PRInt32 aNameSpaceID, + nsIAtom*& aPrefix) = 0; + /** * Set attribute values. All attribute values are assumed to have a * canonical String representation that can be used for these diff --git a/layout/base/src/Makefile.in b/layout/base/src/Makefile.in index 855eb6245602..ea81d820037a 100644 --- a/layout/base/src/Makefile.in +++ b/layout/base/src/Makefile.in @@ -32,6 +32,8 @@ CPPSRCS = \ nsContentList.cpp \ nsDocument.cpp \ nsDocumentFragment.cpp \ + nsDOMAttribute.cpp \ + nsDOMAttributeMap.cpp \ nsFrameImageLoader.cpp \ nsFrameUtil.cpp \ nsGalleyContext.cpp \ diff --git a/layout/base/src/makefile.win b/layout/base/src/makefile.win index ab4ecd956be3..312d829a2546 100644 --- a/layout/base/src/makefile.win +++ b/layout/base/src/makefile.win @@ -29,6 +29,8 @@ CPPSRCS = \ nsContentIterator.cpp \ nsDocument.cpp \ nsDocumentFragment.cpp \ + nsDOMAttribute.cpp \ + nsDOMAttributeMap.cpp \ nsFrameImageLoader.cpp \ nsFrameUtil.cpp \ nsGalleyContext.cpp \ @@ -54,9 +56,11 @@ EXPORTS=nsSelectionRange.h nsSelectionPoint.h CPP_OBJS= \ .\$(OBJDIR)\nsGenericElement.obj \ .\$(OBJDIR)\nsContentList.obj \ - .\$(OBJDIR)\nsContentIterator.obj \ + .\$(OBJDIR)\nsContentIterator.obj \ .\$(OBJDIR)\nsDocument.obj \ .\$(OBJDIR)\nsDocumentFragment.obj \ + .\$(OBJDIR)\nsDOMAttribute.obj \ + .\$(OBJDIR)\nsDOMAttributeMap.obj \ .\$(OBJDIR)\nsFrameImageLoader.obj \ .\$(OBJDIR)\nsFrameUtil.obj \ .\$(OBJDIR)\nsGalleyContext.obj \ diff --git a/layout/base/src/nsDocument.cpp b/layout/base/src/nsDocument.cpp index 342b2463447b..a10d97aacee6 100644 --- a/layout/base/src/nsDocument.cpp +++ b/layout/base/src/nsDocument.cpp @@ -40,6 +40,7 @@ #include "nsIDOMEventListener.h" #include "nsIDOMStyleSheet.h" #include "nsIDOMStyleSheetCollection.h" +#include "nsDOMAttribute.h" #include "nsCSSPropIDs.h" #include "nsCSSProps.h" @@ -67,6 +68,7 @@ static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID); static NS_DEFINE_IID(kIDOMDocumentIID, NS_IDOMDOCUMENT_IID); static NS_DEFINE_IID(kIDOMNSDocumentIID, NS_IDOMNSDOCUMENT_IID); +static NS_DEFINE_IID(kIDOMAttrIID, NS_IDOMATTR_IID); static NS_DEFINE_IID(kIScriptEventListenerIID, NS_ISCRIPTEVENTLISTENER_IID); static NS_DEFINE_IID(kIDOMEventCapturerIID, NS_IDOMEVENTCAPTURER_IID); static NS_DEFINE_IID(kIPrivateDOMEventIID, NS_IPRIVATEDOMEVENT_IID); @@ -1104,8 +1106,16 @@ NS_IMETHODIMP nsDocument::CreateAttribute(const nsString& aName, nsIDOMAttr** aReturn) { - // Should be implemented by subclass - return NS_ERROR_NOT_IMPLEMENTED; + nsAutoString value; + nsDOMAttribute* attribute; + + value.Truncate(); + attribute = new nsDOMAttribute(nsnull, aName, value); + if (nsnull == attribute) { + return NS_ERROR_OUT_OF_MEMORY; + } + + return attribute->QueryInterface(kIDOMAttrIID, (void**)aReturn); } NS_IMETHODIMP diff --git a/layout/base/src/nsDocumentFragment.h b/layout/base/src/nsDocumentFragment.h index f34c4e6af78f..38da6f72a3a6 100644 --- a/layout/base/src/nsDocumentFragment.h +++ b/layout/base/src/nsDocumentFragment.h @@ -27,8 +27,8 @@ class nsIDocument; class nsDocumentFragment : public nsIContent, - public nsIDOMDocumentFragment, - public nsIScriptObjectOwner + public nsIDOMDocumentFragment, + public nsIScriptObjectOwner { public: nsDocumentFragment(nsIDocument* aOwnerDocument); @@ -88,6 +88,19 @@ public: NS_IMETHOD SetScriptObject(void* aScriptObject); // interface nsIContent + NS_IMETHOD ParseAttributeString(const nsString& aStr, + nsIAtom*& aName, + PRInt32& aNameSpaceID) + { aName = nsnull; + aNameSpaceID = kNameSpaceID_None; + return NS_OK; + } + NS_IMETHOD GetNameSpacePrefix(PRInt32 aNameSpaceID, + nsIAtom*& aPrefix) + { + aPrefix = nsnull; + return NS_OK; + } NS_IMETHOD GetDocument(nsIDocument*& aResult) const { return mInner.GetDocument(aResult); } NS_IMETHOD SetDocument(nsIDocument* aDocument, PRBool aDeep) diff --git a/layout/base/src/nsGenericElement.cpp b/layout/base/src/nsGenericElement.cpp index 56ecd4b2b37d..35027bd35f62 100644 --- a/layout/base/src/nsGenericElement.cpp +++ b/layout/base/src/nsGenericElement.cpp @@ -18,12 +18,11 @@ */ #include "nsGenericElement.h" - +#include "nsDOMAttribute.h" +#include "nsDOMAttributeMap.h" #include "nsIAtom.h" #include "nsIDocument.h" -#include "nsIDOMAttr.h" #include "nsIDOMEventReceiver.h" -#include "nsIDOMNamedNodeMap.h" #include "nsIDOMNodeList.h" #include "nsIDOMDocument.h" #include "nsIDOMDocumentFragment.h" @@ -75,382 +74,6 @@ static NS_DEFINE_IID(kIDOMDocumentFragmentIID, NS_IDOMDOCUMENTFRAGMENT_IID); //---------------------------------------------------------------------- -nsDOMAttribute::nsDOMAttribute(const nsString& aName, const nsString& aValue) - : mName(aName), mValue(aValue) -{ - mRefCnt = 1; - mScriptObject = nsnull; -} - -nsDOMAttribute::~nsDOMAttribute() -{ -} - -nsresult -nsDOMAttribute::QueryInterface(REFNSIID aIID, void** aInstancePtr) -{ - if (NULL == aInstancePtr) { - return NS_ERROR_NULL_POINTER; - } - if (aIID.Equals(kIDOMAttrIID)) { - nsIDOMAttr* tmp = this; - *aInstancePtr = (void*)tmp; - NS_ADDREF_THIS(); - return NS_OK; - } - if (aIID.Equals(kIScriptObjectOwnerIID)) { - nsIScriptObjectOwner* tmp = this; - *aInstancePtr = (void*)tmp; - NS_ADDREF_THIS(); - return NS_OK; - } - if (aIID.Equals(kISupportsIID)) { - nsIDOMAttr* tmp1 = this; - nsISupports* tmp2 = tmp1; - *aInstancePtr = (void*)tmp2; - NS_ADDREF_THIS(); - return NS_OK; - } - return NS_NOINTERFACE; -} - -NS_IMPL_ADDREF(nsDOMAttribute) - -NS_IMPL_RELEASE(nsDOMAttribute) - -nsresult -nsDOMAttribute::GetScriptObject(nsIScriptContext *aContext, - void** aScriptObject) -{ - nsresult res = NS_OK; - if (nsnull == mScriptObject) { - res = NS_NewScriptAttr(aContext, - (nsISupports *)(nsIDOMAttr *)this, - nsnull, - (void **)&mScriptObject); - } - *aScriptObject = mScriptObject; - return res; -} - -nsresult -nsDOMAttribute::SetScriptObject(void *aScriptObject) -{ - mScriptObject = aScriptObject; - return NS_OK; -} - -nsresult -nsDOMAttribute::GetName(nsString& aName) -{ - aName = mName; - return NS_OK; -} - -nsresult -nsDOMAttribute::GetValue(nsString& aValue) -{ - aValue = mValue; - return NS_OK; -} - -nsresult -nsDOMAttribute::SetValue(const nsString& aValue) -{ - mValue = aValue; - return NS_OK; -} - -nsresult -nsDOMAttribute::GetSpecified(PRBool* aSpecified) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -nsDOMAttribute::GetNodeName(nsString& aNodeName) -{ - return GetName(aNodeName); -} - -NS_IMETHODIMP -nsDOMAttribute::GetNodeValue(nsString& aNodeValue) -{ - return GetValue(aNodeValue); -} - -NS_IMETHODIMP -nsDOMAttribute::SetNodeValue(const nsString& aNodeValue) -{ - // You can't actually do this, but we'll fail silently - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetNodeType(PRUint16* aNodeType) -{ - *aNodeType = (PRUint16)nsIDOMNode::ATTRIBUTE_NODE; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetParentNode(nsIDOMNode** aParentNode) -{ - *aParentNode = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetChildNodes(nsIDOMNodeList** aChildNodes) -{ - *aChildNodes = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::HasChildNodes(PRBool* aHasChildNodes) -{ - *aHasChildNodes = PR_FALSE; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetFirstChild(nsIDOMNode** aFirstChild) -{ - *aFirstChild = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetLastChild(nsIDOMNode** aLastChild) -{ - *aLastChild = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetPreviousSibling(nsIDOMNode** aPreviousSibling) -{ - *aPreviousSibling = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetNextSibling(nsIDOMNode** aNextSibling) -{ - *aNextSibling = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetAttributes(nsIDOMNamedNodeMap** aAttributes) -{ - *aAttributes = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aReturn) -{ - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -nsDOMAttribute::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aReturn) -{ - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -nsDOMAttribute::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) -{ - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -nsDOMAttribute::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn) -{ - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -nsDOMAttribute::CloneNode(PRBool aDeep, nsIDOMNode** aReturn) -{ - nsDOMAttribute* newAttr = new nsDOMAttribute(mName, mValue); - if (nsnull == newAttr) { - return NS_ERROR_OUT_OF_MEMORY; - } - - *aReturn = newAttr; - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttribute::GetOwnerDocument(nsIDOMDocument** aOwnerDocument) -{ - // XXX TBI - return NS_ERROR_NOT_IMPLEMENTED; -} - -//---------------------------------------------------------------------- - -nsDOMAttributeMap::nsDOMAttributeMap(nsIContent* aContent) - : mContent(aContent) -{ - mRefCnt = 1; - NS_ADDREF(mContent); - mScriptObject = nsnull; -} - -nsDOMAttributeMap::~nsDOMAttributeMap() -{ - NS_RELEASE(mContent); -} - -nsresult -nsDOMAttributeMap::QueryInterface(REFNSIID aIID, void** aInstancePtr) -{ - if (NULL == aInstancePtr) { - return NS_ERROR_NULL_POINTER; - } - if (aIID.Equals(kIDOMNamedNodeMapIID)) { - nsIDOMNamedNodeMap* tmp = this; - *aInstancePtr = (void*)tmp; - NS_ADDREF_THIS(); - return NS_OK; - } - if (aIID.Equals(kIScriptObjectOwnerIID)) { - nsIScriptObjectOwner* tmp = this; - *aInstancePtr = (void*)tmp; - NS_ADDREF_THIS(); - return NS_OK; - } - if (aIID.Equals(kISupportsIID)) { - nsIDOMNamedNodeMap* tmp1 = this; - nsISupports* tmp2 = tmp1; - *aInstancePtr = (void*)tmp2; - NS_ADDREF_THIS(); - return NS_OK; - } - return NS_NOINTERFACE; -} - -NS_IMPL_ADDREF(nsDOMAttributeMap) - -NS_IMPL_RELEASE(nsDOMAttributeMap) - -nsresult -nsDOMAttributeMap::GetScriptObject(nsIScriptContext *aContext, - void** aScriptObject) -{ - nsresult res = NS_OK; - if (nsnull == mScriptObject) { - res = NS_NewScriptNamedNodeMap(aContext, - (nsISupports *)(nsIDOMNamedNodeMap *)this, - nsnull, - (void**)&mScriptObject); - } - *aScriptObject = mScriptObject; - return res; -} - -nsresult -nsDOMAttributeMap::SetScriptObject(void *aScriptObject) -{ - mScriptObject = aScriptObject; - return NS_OK; -} - -nsresult -nsDOMAttributeMap::GetNamedItem(const nsString &aAttrName, - nsIDOMNode** aAttribute) -{ - nsAutoString value; - // XXX need to parse namespace fom attribute name - // XXX need to uppercace name only if HTML namespace - nsAutoString upper; - aAttrName.ToUpperCase(upper); - nsIAtom* nameAtom = NS_NewAtom(upper); - mContent->GetAttribute(kNameSpaceID_HTML, nameAtom, value); - NS_RELEASE(nameAtom); - *aAttribute = (nsIDOMNode *) new nsDOMAttribute(aAttrName, value); - return NS_OK; -} - -nsresult -nsDOMAttributeMap::SetNamedItem(nsIDOMNode *aNode, nsIDOMNode **aReturn) -{ - nsIDOMAttr *attribute; - nsAutoString name, value; - nsresult err; - - if (NS_OK != (err = aNode->QueryInterface(kIDOMAttrIID, - (void **)&attribute))) { - return err; - } - - attribute->GetName(name); - attribute->GetValue(value); - NS_RELEASE(attribute); - - // XXX need to parse namespace from attribute name - // XXX also need to uppercase name only if HTML namespace - name.ToUpperCase(); - nsIAtom* nameAtom = NS_NewAtom(name); - mContent->SetAttribute(kNameSpaceID_HTML, nameAtom, value, PR_TRUE); - NS_RELEASE(nameAtom); - return NS_OK; -} - -NS_IMETHODIMP -nsDOMAttributeMap::RemoveNamedItem(const nsString& aName, nsIDOMNode** aReturn) -{ - nsresult res = GetNamedItem(aName, aReturn); - if (NS_OK == res) { - // XXX need to parse namespace from attribute name - // XXX need to uppercase only if HTML namespace - nsAutoString upper; - aName.ToUpperCase(upper); - nsIAtom* attr = NS_NewAtom(upper); - mContent->UnsetAttribute(kNameSpaceID_HTML, attr, PR_TRUE); - } - - return res; -} - -nsresult -nsDOMAttributeMap::Item(PRUint32 aIndex, nsIDOMNode** aReturn) -{ - nsresult res = NS_ERROR_FAILURE; - - PRInt32 nameSpaceID; - nsIAtom* nameAtom = nsnull; - if (NS_SUCCEEDED(mContent->GetAttributeNameAt(aIndex, nameSpaceID, nameAtom))) { - nsAutoString value; - if (NS_CONTENT_ATTR_NOT_THERE != mContent->GetAttribute(nameSpaceID, nameAtom, value)) { - // XXX need to prefix namespace if present - nsAutoString name; - nameAtom->ToString(name); - *aReturn = (nsIDOMNode *)new nsDOMAttribute(name, value); - res = NS_OK; - } - NS_RELEASE(nameAtom); - } - - return res; -} - -nsresult -nsDOMAttributeMap::GetLength(PRUint32 *aLength) -{ - PRInt32 n; - nsresult rv = mContent->GetAttributeCount(n); - *aLength = PRUint32(n); - return rv; -} - -//---------------------------------------------------------------------- - nsChildContentList::nsChildContentList(nsIContent *aContent) { NS_INIT_REFCNT(); @@ -607,6 +230,10 @@ nsGenericElement::~nsGenericElement() mDOMSlots->mStyle->DropReference(); NS_RELEASE(mDOMSlots->mStyle); } + if (nsnull != mDOMSlots->mAttributeMap) { + mDOMSlots->mAttributeMap->DropReference(); + NS_RELEASE(mDOMSlots->mAttributeMap); + } // XXX Should really be arena managed PR_DELETE(mDOMSlots); } @@ -620,6 +247,7 @@ nsGenericElement::GetDOMSlots() mDOMSlots->mScriptObject = nsnull; mDOMSlots->mChildNodes = nsnull; mDOMSlots->mStyle = nsnull; + mDOMSlots->mAttributeMap = nsnull; mDOMSlots->mRangeList = nsnull; } @@ -738,13 +366,18 @@ nsresult nsGenericElement::GetAttributes(nsIDOMNamedNodeMap** aAttributes) { NS_PRECONDITION(nsnull != aAttributes, "null pointer argument"); - // XXX Should we create a new one every time or should we - // cache one after we create it? If we find that this is - // something that's called often, we might need to do the - // latter. - *aAttributes = new nsDOMAttributeMap(mContent); + nsDOMSlots *slots = GetDOMSlots(); - return NS_OK; + if (nsnull == slots->mAttributeMap) { + slots->mAttributeMap = new nsDOMAttributeMap(mContent); + if (nsnull == slots->mAttributeMap) { + return NS_ERROR_OUT_OF_MEMORY; + } + NS_ADDREF(slots->mAttributeMap); + } + + return slots->mAttributeMap->QueryInterface(kIDOMNamedNodeMapIID, + (void **)aAttributes); } nsresult @@ -760,103 +393,126 @@ nsGenericElement::GetTagName(nsString& aTagName) } nsresult -nsGenericElement::GetDOMAttribute(const nsString& aName, nsString& aReturn) +nsGenericElement::GetAttribute(const nsString& aName, nsString& aReturn) { - // XXX need to parse namespace from name - // XXX need to uppercase name if HTML namespace - nsIAtom* nameAtom = NS_NewAtom(aName); - nsresult rv = mContent->GetAttribute(kNameSpaceID_None, nameAtom, aReturn); + nsIAtom* nameAtom; + PRInt32 nameSpaceID; + + mContent->ParseAttributeString(aName, nameAtom, nameSpaceID); + mContent->GetAttribute(nameSpaceID, nameAtom, aReturn); NS_RELEASE(nameAtom); - return rv; + + return NS_OK; } nsresult -nsGenericElement::SetDOMAttribute(const nsString& aName, - const nsString& aValue) +nsGenericElement::SetAttribute(const nsString& aName, + const nsString& aValue) { - // XXX need to parse namespace from name - // XXX need to uppercase name if HTML namespace - nsIAtom* nameAtom = NS_NewAtom(aName); - nsresult rv = mContent->SetAttribute(kNameSpaceID_None, nameAtom, aValue, PR_TRUE); + nsIAtom* nameAtom; + PRInt32 nameSpaceID; + nsresult result = NS_OK; + + mContent->ParseAttributeString(aName, nameAtom, nameSpaceID); + result = mContent->SetAttribute(nameSpaceID, nameAtom, aValue, PR_TRUE); NS_RELEASE(nameAtom); - return rv; + + return result; } nsresult nsGenericElement::RemoveAttribute(const nsString& aName) { - // XXX need to parse namespace from name - // XXX need to uppercase name if HTML namespace - nsIAtom* nameAtom = NS_NewAtom(aName); - nsresult rv = mContent->UnsetAttribute(kNameSpaceID_None, nameAtom, PR_TRUE); + nsIAtom* nameAtom; + PRInt32 nameSpaceID; + nsresult result = NS_OK; + + mContent->ParseAttributeString(aName, nameAtom, nameSpaceID); + result = mContent->UnsetAttribute(nameSpaceID, nameAtom, PR_TRUE); NS_RELEASE(nameAtom); - return rv; + + return result; } nsresult nsGenericElement::GetAttributeNode(const nsString& aName, nsIDOMAttr** aReturn) { - // XXX need to parse namespace from name - // XXX need to uppercase name if HTML namespace - nsIAtom* nameAtom = NS_NewAtom(aName); - nsAutoString value; - if (NS_CONTENT_ATTR_NOT_THERE != mContent->GetAttribute(kNameSpaceID_None, nameAtom, value)) { - *aReturn = new nsDOMAttribute(aName, value); + if (nsnull == aReturn) { + return NS_ERROR_NULL_POINTER; } - else { - *aReturn = nsnull; + nsIDOMNamedNodeMap* map; + nsresult result = GetAttributes(&map); + + *aReturn = nsnull; + if (NS_OK == result) { + nsIDOMNode* node; + result = map->GetNamedItem(aName, &node); + if ((NS_OK == result) && (nsnull != node)) { + result = node->QueryInterface(kIDOMAttrIID, (void **)aReturn); + NS_IF_RELEASE(node); + } + NS_RELEASE(map); } - NS_RELEASE(nameAtom); - return NS_OK; + + return result; } nsresult nsGenericElement::SetAttributeNode(nsIDOMAttr* aAttribute, - nsIDOMAttr** aReturn) + nsIDOMAttr** aReturn) { - NS_PRECONDITION(nsnull != aAttribute, "null attribute"); - - nsresult res = NS_ERROR_FAILURE; - - if (nsnull != aAttribute) { - nsAutoString name, value; - res = aAttribute->GetName(name); - if (NS_OK == res) { - res = aAttribute->GetValue(value); - if (NS_OK == res) { - // XXX need to parse namespace from name - // XXX need to uppercase name if HTML namespace - nsIAtom* nameAtom = NS_NewAtom(name); - mContent->SetAttribute(kNameSpaceID_None, nameAtom, value, PR_TRUE); - NS_RELEASE(nameAtom); - } - } + if ((nsnull == aReturn) || (nsnull == aAttribute)) { + return NS_ERROR_NULL_POINTER; } - return res; + nsIDOMNamedNodeMap* map; + nsresult result = GetAttributes(&map); + + *aReturn = nsnull; + if (NS_OK == result) { + nsIDOMNode *node, *returnNode; + result = aAttribute->QueryInterface(kIDOMNodeIID, (void **)&node); + if (NS_OK == result) { + result = map->SetNamedItem(node, &returnNode); + if ((NS_OK == result) && (nsnull != returnNode)) { + result = returnNode->QueryInterface(kIDOMAttrIID, (void **)aReturn); + NS_IF_RELEASE(returnNode); + } + NS_RELEASE(node); + } + NS_RELEASE(map); + } + + return result; } nsresult nsGenericElement::RemoveAttributeNode(nsIDOMAttr* aAttribute, - nsIDOMAttr** aReturn) + nsIDOMAttr** aReturn) { - NS_PRECONDITION(nsnull != aAttribute, "null attribute"); + if ((nsnull == aReturn) || (nsnull == aAttribute)) { + return NS_ERROR_NULL_POINTER; + } + nsIDOMNamedNodeMap* map; + nsresult result = GetAttributes(&map); - nsresult res = NS_ERROR_FAILURE; - - if (nsnull != aAttribute) { + *aReturn = nsnull; + if (NS_OK == result) { nsAutoString name; - res = aAttribute->GetName(name); - if (NS_OK == res) { - // XXX need to parse namespace from name - // XXX need to uppercase name if HTML namespace - nsIAtom* nameAtom = NS_NewAtom(name); - mContent->UnsetAttribute(kNameSpaceID_None, nameAtom, PR_TRUE); - NS_RELEASE(nameAtom); + + result = aAttribute->GetName(name); + if (NS_OK == result) { + nsIDOMNode* node; + result = map->RemoveNamedItem(name, &node); + if ((NS_OK == result) && (nsnull != node)) { + result = node->QueryInterface(kIDOMAttrIID, (void **)aReturn); + NS_RELEASE(node); + } } + NS_RELEASE(map); } - return res; + return result; } nsresult @@ -1482,6 +1138,23 @@ nsGenericElement::AddScriptEventListener(nsIAtom* aAttribute, return ret; } +static char kNameSpaceSeparator[] = ":"; + +nsIAtom* +nsGenericElement::CutNameSpacePrefix(nsString& aString) +{ + nsAutoString prefix; + PRInt32 nsoffset = aString.Find(kNameSpaceSeparator); + if (-1 != nsoffset) { + aString.Left(prefix, nsoffset); + aString.Cut(0, nsoffset+1); + } + if (0 < prefix.Length()) { + return NS_NewAtom(prefix); + } + return nsnull; +} + //---------------------------------------------------------------------- struct nsGenericAttribute @@ -1531,8 +1204,6 @@ nsresult nsGenericContainerElement::CopyInnerTo(nsIContent* aSrcContent, nsGenericContainerElement* aDst) { - aDst->mContent = aSrcContent; - // XXX should the node's document be set? // XXX copy attributes not yet impelemented // XXX deep copy? return NS_OK; diff --git a/layout/base/src/nsGenericElement.h b/layout/base/src/nsGenericElement.h index 8321698fd4b6..9a4c7fe7cb4c 100644 --- a/layout/base/src/nsGenericElement.h +++ b/layout/base/src/nsGenericElement.h @@ -45,78 +45,7 @@ class nsISupportsArray; class nsIDOMScriptObjectFactory; class nsDOMCSSDeclaration; class nsIDOMCSSStyleDeclaration; - -// Attribute helper class used to wrap up an attribute with a dom -// object that implements nsIDOMAttr and nsIDOMNode and -// nsIScriptObjectOwner -class nsDOMAttribute : public nsIDOMAttr, public nsIScriptObjectOwner { -public: - nsDOMAttribute(const nsString &aName, const nsString &aValue); - ~nsDOMAttribute(); - - NS_DECL_ISUPPORTS - - NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject); - NS_IMETHOD SetScriptObject(void *aScriptObject); - - // nsIDOMAttr interface - NS_IMETHOD GetSpecified(PRBool* aSpecified); - NS_IMETHOD GetName(nsString& aReturn); - NS_IMETHOD GetValue(nsString& aReturn); - NS_IMETHOD SetValue(const nsString& aValue); - - // nsIDOMNode interface - NS_IMETHOD GetNodeName(nsString& aNodeName); - NS_IMETHOD GetNodeValue(nsString& aNodeValue); - NS_IMETHOD SetNodeValue(const nsString& aNodeValue); - NS_IMETHOD GetNodeType(PRUint16* aNodeType); - NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode); - NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes); - NS_IMETHOD HasChildNodes(PRBool* aHasChildNodes); - NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild); - NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild); - NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling); - NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling); - NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes); - NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, - nsIDOMNode** aReturn); - NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, - nsIDOMNode** aReturn); - NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn); - NS_IMETHOD AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn); - NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn); - NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument); - -private: - nsString mName; - nsString mValue; - void* mScriptObject; -}; - -// Another helper class that implements the nsIDOMNamedNodeMap interface. -class nsDOMAttributeMap : public nsIDOMNamedNodeMap, - public nsIScriptObjectOwner -{ -public: - nsDOMAttributeMap(nsIContent* aContent); - ~nsDOMAttributeMap(); - - NS_DECL_ISUPPORTS - - NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject); - NS_IMETHOD SetScriptObject(void *aScriptObject); - - // nsIDOMNamedNodeMap interface - NS_IMETHOD GetLength(PRUint32* aSize); - NS_IMETHOD GetNamedItem(const nsString& aName, nsIDOMNode** aReturn); - NS_IMETHOD SetNamedItem(nsIDOMNode* aNode, nsIDOMNode** aReturn); - NS_IMETHOD RemoveNamedItem(const nsString& aName, nsIDOMNode** aReturn); - NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn); - -private: - nsIContent* mContent; - void* mScriptObject; -}; +class nsDOMAttributeMap; // Class that holds the child list of a content element and also @@ -153,6 +82,7 @@ typedef struct { void *mScriptObject; nsChildContentList *mChildNodes; nsDOMCSSDeclaration *mStyle; + nsDOMAttributeMap* mAttributeMap; nsVoidArray *mRangeList; PRBool mIsContainer; } nsDOMSlots; @@ -177,8 +107,8 @@ public: // Implementation for nsIDOMElement nsresult GetTagName(nsString& aTagName); - nsresult GetDOMAttribute(const nsString& aName, nsString& aReturn); - nsresult SetDOMAttribute(const nsString& aName, const nsString& aValue); + nsresult GetAttribute(const nsString& aName, nsString& aReturn); + nsresult SetAttribute(const nsString& aName, const nsString& aValue); nsresult RemoveAttribute(const nsString& aName); nsresult GetAttributeNode(const nsString& aName, nsIDOMAttr** aReturn); @@ -257,6 +187,8 @@ public: static nsIDOMScriptObjectFactory *gScriptObjectFactory; + static nsIAtom* CutNameSpacePrefix(nsString& aString); + nsDOMSlots *GetDOMSlots(); // Up pointer to the real content object that we are @@ -272,8 +204,6 @@ public: nsDOMSlots *mDOMSlots; }; -//---------------------------------------------------------------------- - class nsGenericContainerElement : public nsGenericElement { public: nsGenericContainerElement(); @@ -283,6 +213,14 @@ public: nsGenericContainerElement* aDest); // Remainder of nsIDOMHTMLElement (and nsIDOMNode) + nsresult GetAttribute(const nsString& aName, nsString& aReturn) + { + return nsGenericElement::GetAttribute(aName, aReturn); + } + nsresult SetAttribute(const nsString& aName, const nsString& aValue) + { + return nsGenericElement::SetAttribute(aName, aValue); + } nsresult GetChildNodes(nsIDOMNodeList** aChildNodes); nsresult HasChildNodes(PRBool* aHasChildNodes); nsresult GetFirstChild(nsIDOMNode** aFirstChild); @@ -327,6 +265,7 @@ public: nsVoidArray mChildren; }; + //---------------------------------------------------------------------- /** @@ -402,11 +341,11 @@ public: NS_IMETHOD GetTagName(nsString& aTagName) { \ return _g.GetTagName(aTagName); \ } \ - NS_IMETHOD GetDOMAttribute(const nsString& aName, nsString& aReturn) { \ - return _g.GetDOMAttribute(aName, aReturn); \ + NS_IMETHOD GetAttribute(const nsString& aName, nsString& aReturn) { \ + return _g.GetAttribute(aName, aReturn); \ } \ - NS_IMETHOD SetDOMAttribute(const nsString& aName, const nsString& aValue) { \ - return _g.SetDOMAttribute(aName, aValue); \ + NS_IMETHOD SetAttribute(const nsString& aName, const nsString& aValue) { \ + return _g.SetAttribute(aName, aValue); \ } \ NS_IMETHOD RemoveAttribute(const nsString& aName) { \ return _g.RemoveAttribute(aName); \ @@ -498,6 +437,15 @@ public: NS_IMETHOD GetTag(nsIAtom*& aResult) const { \ return _g.GetTag(aResult); \ } \ + NS_IMETHOD ParseAttributeString(const nsString& aStr, \ + nsIAtom*& aName, \ + PRInt32& aNameSpaceID) { \ + return _g.ParseAttributeString(aStr, aName, aNameSpaceID); \ + } \ + NS_IMETHOD GetNameSpacePrefix(PRInt32 aNameSpaceID, \ + nsIAtom*& aPrefix) { \ + return _g.GetNameSpacePrefix(aNameSpaceID, aPrefix); \ + } \ NS_IMETHOD SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, \ const nsString& aValue, PRBool aNotify) { \ return _g.SetAttribute(aNameSpaceID, aName, aValue, aNotify); \ @@ -548,6 +496,18 @@ public: return _g.GetRangeList(aResult); \ } +/** + * Implement the nsIScriptObjectOwner API by forwarding the methods to a + * generic content object + */ +#define NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC(_g) \ + NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, \ + void** aScriptObject) { \ + return _g.GetScriptObject(aContext, aScriptObject); \ + } \ + NS_IMETHOD SetScriptObject(void *aScriptObject) { \ + return _g.SetScriptObject(aScriptObject); \ + } #define NS_IMPL_CONTENT_QUERY_INTERFACE(_id, _iptr, _this, _base) \ if (_id.Equals(kISupportsIID)) { \ diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index 8d60f5a6afd9..ff8876c54f07 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -182,7 +182,7 @@ nsHTMLImageLoader::StartLoadImage(nsIPresContext* aPresContext, // so transparent images are always rendered using a transparency mask rv = aPresContext->StartLoadImage(src, nsnull, aForFrame, aCallBack, aNeedSizeUpdate, mImageLoader); - if (NS_OK != rv) { + if ((NS_OK != rv) || (nsnull == mImageLoader)) { return rv; } } diff --git a/layout/html/base/src/nsImageFrame.cpp b/layout/html/base/src/nsImageFrame.cpp index 8d60f5a6afd9..ff8876c54f07 100644 --- a/layout/html/base/src/nsImageFrame.cpp +++ b/layout/html/base/src/nsImageFrame.cpp @@ -182,7 +182,7 @@ nsHTMLImageLoader::StartLoadImage(nsIPresContext* aPresContext, // so transparent images are always rendered using a transparency mask rv = aPresContext->StartLoadImage(src, nsnull, aForFrame, aCallBack, aNeedSizeUpdate, mImageLoader); - if (NS_OK != rv) { + if ((NS_OK != rv) || (nsnull == mImageLoader)) { return rv; } } diff --git a/layout/html/content/src/nsGenericDOMDataNode.h b/layout/html/content/src/nsGenericDOMDataNode.h index 9c66e582e819..122797ad4353 100644 --- a/layout/html/content/src/nsGenericDOMDataNode.h +++ b/layout/html/content/src/nsGenericDOMDataNode.h @@ -137,6 +137,18 @@ struct nsGenericDOMDataNode { aResult = nsnull; return NS_OK; } + nsresult ParseAttributeString(const nsString& aStr, + nsIAtom*& aName, + PRInt32& aNameSpaceID) { + aName = nsnull; + aNameSpaceID = kNameSpaceID_None; + return NS_OK; + } + NS_IMETHOD GetNameSpacePrefix(PRInt32 aNameSpaceID, + nsIAtom*& aPrefix) { + aPrefix = nsnull; + return NS_OK; + } nsresult SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute, const nsString& aValue, PRBool aNotify) { return NS_OK; @@ -429,6 +441,15 @@ struct nsGenericDOMDataNode { NS_IMETHOD GetTag(nsIAtom*& aResult) const { \ return _g.GetTag(aResult); \ } \ + NS_IMETHOD ParseAttributeString(const nsString& aStr, \ + nsIAtom*& aName, \ + PRInt32& aNameSpaceID) { \ + return _g.ParseAttributeString(aStr, aName, aNameSpaceID); \ + } \ + NS_IMETHOD GetNameSpacePrefix(PRInt32 aNameSpaceID, \ + nsIAtom*& aPrefix) { \ + return _g.GetNameSpacePrefix(aNameSpaceID, aPrefix); \ + } \ NS_IMETHOD GetAttribute(PRInt32 aNameSpaceID, nsIAtom *aAttribute, \ nsString &aResult) const { \ return _g.GetAttribute(aNameSpaceID, aAttribute, aResult); \ diff --git a/layout/html/content/src/nsGenericHTMLElement.cpp b/layout/html/content/src/nsGenericHTMLElement.cpp index 3eca4a45ff6d..59386025e010 100644 --- a/layout/html/content/src/nsGenericHTMLElement.cpp +++ b/layout/html/content/src/nsGenericHTMLElement.cpp @@ -244,115 +244,7 @@ nsGenericHTMLElement::~nsGenericHTMLElement() } } - // Implementation for nsIDOMElement -nsresult -nsGenericHTMLElement::GetDOMAttribute(const nsString& aName, nsString& aReturn) -{ - // XXX need to parse namepsace from name, presume HTML if none - // XXX need to uppercase name only if HTML namespace - nsAutoString upper; - aName.ToUpperCase(upper); - nsIAtom* nameAtom = NS_NewAtom(upper); - nsresult rv = mContent->GetAttribute(kNameSpaceID_HTML, nameAtom, aReturn); - NS_RELEASE(nameAtom); - return rv; -} - -nsresult -nsGenericHTMLElement::SetDOMAttribute(const nsString& aName, const nsString& aValue) -{ - // XXX need to parse namepsace from name, presume HTML if none - // XXX need to uppercase name only if HTML namespace - nsAutoString upper; - aName.ToUpperCase(upper); - nsIAtom* nameAtom = NS_NewAtom(upper); - nsresult rv = mContent->SetAttribute(kNameSpaceID_HTML, nameAtom, aValue, PR_TRUE); - NS_RELEASE(nameAtom); - return rv; -} - -nsresult -nsGenericHTMLElement::RemoveAttribute(const nsString& aName) -{ - // XXX need to parse namepsace from name, presume HTML if none - // XXX need to uppercase name only if HTML namespace - nsAutoString upper; - aName.ToUpperCase(upper); - nsIAtom* nameAtom = NS_NewAtom(upper); - nsresult rv = mContent->UnsetAttribute(kNameSpaceID_HTML, nameAtom, PR_TRUE); - NS_RELEASE(nameAtom); - return rv; -} - -nsresult -nsGenericHTMLElement::GetAttributeNode(const nsString& aName, - nsIDOMAttr** aReturn) -{ - // XXX need to parse namepsace from name, presume HTML if none - // XXX need to uppercase name only if HTML namespace - nsAutoString upper; - aName.ToUpperCase(upper); - nsIAtom* nameAtom = NS_NewAtom(upper); - nsAutoString value; - if (NS_CONTENT_ATTR_NOT_THERE != mContent->GetAttribute(kNameSpaceID_HTML, nameAtom, value)) { - *aReturn = new nsDOMAttribute(aName, value); - } - else { - *aReturn = nsnull; - } - NS_RELEASE(nameAtom); - return NS_OK; -} - -nsresult -nsGenericHTMLElement::SetAttributeNode(nsIDOMAttr* aAttribute, nsIDOMAttr** aReturn) -{ - NS_PRECONDITION(nsnull != aAttribute, "null attribute"); - - nsresult res = NS_ERROR_FAILURE; - - if (nsnull != aAttribute) { - nsAutoString name, value; - res = aAttribute->GetName(name); - if (NS_OK == res) { - res = aAttribute->GetValue(value); - if (NS_OK == res) { - // XXX need to parse out namespace - // XXX need to only uppercase if HTML namespace (or none since this is an HTML element) - name.ToUpperCase(); - nsIAtom* nameAtom = NS_NewAtom(name); - mContent->SetAttribute(kNameSpaceID_HTML, nameAtom, value, PR_TRUE); - NS_RELEASE(nameAtom); - } - } - } - return res; -} - -nsresult -nsGenericHTMLElement::RemoveAttributeNode(nsIDOMAttr* aAttribute, nsIDOMAttr** aReturn) -{ - NS_PRECONDITION(nsnull != aAttribute, "null attribute"); - - nsresult res = NS_ERROR_FAILURE; - - if (nsnull != aAttribute) { - nsAutoString name; - res = aAttribute->GetName(name); - if (NS_OK == res) { - // XXX need to parse out namespace - // XXX need to only uppercase if HTML namespace (or none since this is an HTML element) - name.ToUpperCase(); - nsIAtom* nameAtom = NS_NewAtom(name); - mContent->UnsetAttribute(kNameSpaceID_HTML, nameAtom, PR_TRUE); - NS_RELEASE(nameAtom); - } - } - - return res; -} - - +// Implementation for nsIDOMHTMLElement nsresult nsGenericHTMLElement::GetId(nsString& aId) { @@ -517,6 +409,27 @@ static nsGenericHTMLElement::EnumTable kDirTable[] = { }; #endif +nsresult +nsGenericHTMLElement::ParseAttributeString(const nsString& aStr, + nsIAtom*& aName, + PRInt32& aNameSpaceID) +{ + nsAutoString upper; + aStr.ToUpperCase(upper); + aName = NS_NewAtom(upper); + aNameSpaceID = kNameSpaceID_HTML; + + return NS_OK; +} + +nsresult +nsGenericHTMLElement::GetNameSpacePrefix(PRInt32 aNameSpaceID, + nsIAtom*& aPrefix) +{ + aPrefix = nsnull; + return NS_OK; +} + nsresult nsGenericHTMLElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute, diff --git a/layout/html/content/src/nsGenericHTMLElement.h b/layout/html/content/src/nsGenericHTMLElement.h index 9ef5ecccc442..d03bffad6240 100644 --- a/layout/html/content/src/nsGenericHTMLElement.h +++ b/layout/html/content/src/nsGenericHTMLElement.h @@ -52,13 +52,14 @@ public: ~nsGenericHTMLElement(); // Implementation for nsIDOMElement - nsresult GetDOMAttribute(const nsString& aName, nsString& aReturn); - nsresult SetDOMAttribute(const nsString& aName, const nsString& aValue); - nsresult RemoveAttribute(const nsString& aName); - nsresult GetAttributeNode(const nsString& aName, - nsIDOMAttr** aReturn); - nsresult SetAttributeNode(nsIDOMAttr* aNewAttr, nsIDOMAttr** aReturn); - nsresult RemoveAttributeNode(nsIDOMAttr* aOldAttr, nsIDOMAttr** aReturn); + nsresult GetAttribute(const nsString& aName, nsString& aReturn) + { + return nsGenericElement::GetAttribute(aName, aReturn); + } + nsresult SetAttribute(const nsString& aName, const nsString& aValue) + { + return nsGenericElement::SetAttribute(aName, aValue); + } // Implementation for nsIDOMHTMLElement nsresult GetId(nsString& aId); @@ -76,6 +77,11 @@ public: // Implementation for nsIContent nsresult GetNameSpaceID(PRInt32& aNameSpaceID) const; nsresult SetDocument(nsIDocument* aDocument, PRBool aDeep); + nsresult ParseAttributeString(const nsString& aStr, + nsIAtom*& aName, + PRInt32& aNameSpaceID); + nsresult GetNameSpacePrefix(PRInt32 aNameSpaceID, + nsIAtom*& aPrefix); nsresult SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, const nsString& aValue, PRBool aNotify); nsresult GetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, nsString& aResult) const; @@ -387,21 +393,6 @@ public: return _g.GetStyle(aStyle); \ } -/** - * Implement the nsIScriptObjectOwner API by forwarding the methods to a - * generic content object (either nsGenericHTMLLeafElement or - * nsGenericHTMLContainerContent) - */ -#define NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC(_g) \ - NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, \ - void** aScriptObject) { \ - return _g.GetScriptObject(aContext, aScriptObject); \ - } \ - NS_IMETHOD SetScriptObject(void *aScriptObject) { \ - return _g.SetScriptObject(aScriptObject); \ - } - - #define NS_IMPL_IHTMLCONTENT_USING_GENERIC(_g) \ NS_IMETHOD Compact() { \ return _g.Compact(); \ diff --git a/layout/html/document/src/nsHTMLDocument.cpp b/layout/html/document/src/nsHTMLDocument.cpp index b86931d41358..f62c5f077294 100644 --- a/layout/html/document/src/nsHTMLDocument.cpp +++ b/layout/html/document/src/nsHTMLDocument.cpp @@ -592,13 +592,6 @@ nsHTMLDocument::CreateEntityReference(const nsString& aName, return NS_OK; } -NS_IMETHODIMP -nsHTMLDocument::CreateAttribute(const nsString& aName, - nsIDOMAttr** aReturn) -{ - // XXX To be implemented - return NS_ERROR_NOT_IMPLEMENTED; -} NS_IMETHODIMP nsHTMLDocument::GetDoctype(nsIDOMDocumentType** aDocumentType) diff --git a/layout/html/document/src/nsHTMLDocument.h b/layout/html/document/src/nsHTMLDocument.h index 3868428feb0a..a4454bd39aab 100644 --- a/layout/html/document/src/nsHTMLDocument.h +++ b/layout/html/document/src/nsHTMLDocument.h @@ -92,7 +92,8 @@ public: { return nsDocument::CreateDocumentFragment(aReturn); } NS_IMETHOD CreateComment(const nsString& aData, nsIDOMComment** aReturn); NS_IMETHOD CreateProcessingInstruction(const nsString& aTarget, const nsString& aData, nsIDOMProcessingInstruction** aReturn); - NS_IMETHOD CreateAttribute(const nsString& aName, nsIDOMAttr** aReturn); + NS_IMETHOD CreateAttribute(const nsString& aName, nsIDOMAttr** aReturn) + { return nsDocument::CreateAttribute(aName, aReturn); } NS_IMETHOD CreateElement(const nsString& aTagName, nsIDOMElement** aReturn); NS_IMETHOD CreateTextNode(const nsString& aData, nsIDOMText** aReturn); diff --git a/layout/xml/content/public/nsIXMLContent.h b/layout/xml/content/public/nsIXMLContent.h index 0dc6f936a6bd..2d9f3a92ebdd 100644 --- a/layout/xml/content/public/nsIXMLContent.h +++ b/layout/xml/content/public/nsIXMLContent.h @@ -23,6 +23,8 @@ #include "nsISupports.h" #include "nsIContent.h" +class nsINameSpace; + #define NS_IXMLCONTENT_IID \ { 0xa6cf90cb, 0x15b3, 0x11d2, \ { 0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32 } } @@ -32,7 +34,9 @@ */ class nsIXMLContent : public nsIContent { public: - // XXX A convenience - the id can be used to get the namespace Atom + NS_IMETHOD SetContainingNameSpace(nsINameSpace* aNameSpace) = 0; + NS_IMETHOD GetContainingNameSpace(nsINameSpace*& aNameSpace) const = 0; + NS_IMETHOD SetNameSpacePrefix(nsIAtom* aNameSpace) = 0; NS_IMETHOD GetNameSpacePrefix(nsIAtom*& aNameSpace) const = 0; diff --git a/layout/xml/content/src/Makefile.in b/layout/xml/content/src/Makefile.in index d3d6306fdbf4..0a8a0fb2ecc1 100644 --- a/layout/xml/content/src/Makefile.in +++ b/layout/xml/content/src/Makefile.in @@ -39,6 +39,7 @@ INCLUDES += \ # Note the sophisticated alphabetical ordering :-| CPPSRCS = \ nsXMLElement.cpp \ + nsGenericXMLElement.cpp \ $(NULL) EXPORTS = \ diff --git a/layout/xml/content/src/makefile.win b/layout/xml/content/src/makefile.win index a068996224f9..a376b32db0a4 100644 --- a/layout/xml/content/src/makefile.win +++ b/layout/xml/content/src/makefile.win @@ -25,10 +25,12 @@ DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN CPPSRCS= \ nsXMLElement.cpp \ + nsGenericXMLElement.cpp \ $(NULL) CPP_OBJS= \ .\$(OBJDIR)\nsXMLElement.obj \ + .\$(OBJDIR)\nsGenericXMLElement.obj \ $(NULL) EXPORTS = \ diff --git a/layout/xml/content/src/nsXMLElement.cpp b/layout/xml/content/src/nsXMLElement.cpp index 9368f9be7a91..e33565fcbe94 100644 --- a/layout/xml/content/src/nsXMLElement.cpp +++ b/layout/xml/content/src/nsXMLElement.cpp @@ -25,6 +25,7 @@ #include "nsIEventStateManager.h" #include "nsDOMEvent.h" +#include "nsINameSpace.h" #include "nsINameSpaceManager.h" //static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID); @@ -52,9 +53,6 @@ nsXMLElement::nsXMLElement(nsIAtom *aTag) { NS_INIT_REFCNT(); mInner.Init((nsIContent *)(nsIXMLContent *)this, aTag); - mNameSpacePrefix = nsnull; - mNameSpaceID = kNameSpaceID_None; - mScriptObject = nsnull; mIsLink = PR_FALSE; if (nsnull == kLinkAtom) { @@ -71,7 +69,6 @@ nsXMLElement::nsXMLElement(nsIAtom *aTag) nsXMLElement::~nsXMLElement() { - NS_IF_RELEASE(mNameSpacePrefix); nsrefcnt refcnt; NS_RELEASE2(kLinkAtom, refcnt); NS_RELEASE2(kHrefAtom, refcnt); @@ -96,92 +93,6 @@ nsXMLElement::QueryInterface(REFNSIID aIID, NS_IMPL_ADDREF(nsXMLElement) NS_IMPL_RELEASE(nsXMLElement) -NS_IMETHODIMP -nsXMLElement::GetScriptObject(nsIScriptContext* aContext, void** aScriptObject) -{ - nsresult res = NS_OK; - - // XXX Yuck! Reaching into the generic content object isn't good. - nsDOMSlots *slots = mInner.GetDOMSlots(); - if (nsnull == slots->mScriptObject) { - nsIDOMScriptObjectFactory *factory; - - res = nsGenericElement::GetScriptObjectFactory(&factory); - if (NS_OK != res) { - return res; - } - - nsAutoString tag; - nsIContent* parent; - - mInner.GetTagName(tag); - mInner.GetParent(parent); - - res = factory->NewScriptXMLElement(tag, aContext, - (nsISupports *)(nsIDOMElement *)this, - parent, (void**)&slots->mScriptObject); - NS_IF_RELEASE(parent); - NS_RELEASE(factory); - - char tagBuf[50]; - tag.ToCString(tagBuf, sizeof(tagBuf)); - - nsIDocument *document; - mInner.GetDocument(document); - if (nsnull != document) { - aContext->AddNamedReference((void *)&slots->mScriptObject, - slots->mScriptObject, - tagBuf); - NS_RELEASE(document); - } - } - *aScriptObject = slots->mScriptObject; - return res; -} - -NS_IMETHODIMP -nsXMLElement::SetScriptObject(void *aScriptObject) -{ - return mInner.SetScriptObject(aScriptObject); -} - -NS_IMETHODIMP -nsXMLElement::SetNameSpacePrefix(nsIAtom* aNameSpacePrefix) -{ - NS_IF_RELEASE(mNameSpacePrefix); - - mNameSpacePrefix = aNameSpacePrefix; - - NS_IF_ADDREF(mNameSpacePrefix); - - return NS_OK; -} - -NS_IMETHODIMP -nsXMLElement::GetNameSpacePrefix(nsIAtom*& aNameSpacePrefix) const -{ - aNameSpacePrefix = mNameSpacePrefix; - - NS_IF_ADDREF(mNameSpacePrefix); - - return NS_OK; -} - -NS_IMETHODIMP -nsXMLElement::SetNameSpaceID(PRInt32 aNameSpaceID) -{ - mNameSpaceID = aNameSpaceID; - - return NS_OK; -} - -NS_IMETHODIMP -nsXMLElement::GetNameSpaceID(PRInt32& aNameSpaceID) const -{ - aNameSpaceID = mNameSpaceID; - - return NS_OK; -} NS_IMETHODIMP nsXMLElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, @@ -292,9 +203,6 @@ nsXMLElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn) return NS_ERROR_OUT_OF_MEMORY; } mInner.CopyInnerTo((nsIContent *)(nsIXMLContent *)this, &it->mInner); - it->mNameSpacePrefix = mNameSpacePrefix; - NS_IF_ADDREF(mNameSpacePrefix); - it->mNameSpaceID = mNameSpaceID; return it->QueryInterface(kIDOMNodeIID, (void**) aReturn); } diff --git a/layout/xml/content/src/nsXMLElement.h b/layout/xml/content/src/nsXMLElement.h index d2a4279759b6..b14a62be9256 100644 --- a/layout/xml/content/src/nsXMLElement.h +++ b/layout/xml/content/src/nsXMLElement.h @@ -25,7 +25,7 @@ #include "nsIDOMEventReceiver.h" #include "nsIXMLContent.h" #include "nsIJSScriptObject.h" -#include "nsGenericElement.h" +#include "nsGenericXMLElement.h" class nsIDocument; class nsIAtom; @@ -52,8 +52,7 @@ public: NS_IMPL_IDOMELEMENT_USING_GENERIC(mInner) // nsIScriptObjectOwner - NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject); - NS_IMETHOD SetScriptObject(void *aScriptObject); + NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC(mInner) // nsIContent NS_IMETHOD GetDocument(nsIDocument*& aResult) const { @@ -68,6 +67,9 @@ public: NS_IMETHOD SetParent(nsIContent* aParent) { return mInner.SetParent(aParent); } + NS_IMETHOD GetNameSpaceID(PRInt32& aNameSpaceId) const { + return mInner.GetNameSpaceID(aNameSpaceId); + } NS_IMETHOD CanContainChildren(PRBool& aResult) const { return mInner.CanContainChildren(aResult); } @@ -97,10 +99,18 @@ public: NS_IMETHOD IsSynthetic(PRBool& aResult) { return mInner.IsSynthetic(aResult); } - NS_IMETHOD GetNameSpaceID(PRInt32& aResult) const; NS_IMETHOD GetTag(nsIAtom*& aResult) const { return mInner.GetTag(aResult); } + NS_IMETHOD ParseAttributeString(const nsString& aStr, + nsIAtom*& aName, + PRInt32& aNameSpaceID) { + return mInner.ParseAttributeString(aStr, aName, aNameSpaceID); + } + NS_IMETHOD GetNameSpacePrefix(PRInt32 aNameSpaceID, + nsIAtom*& aPrefix) { + return mInner.GetNameSpacePrefix(aNameSpaceID, aPrefix); + } NS_IMETHOD SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, const nsString& aValue, PRBool aNotify); NS_IMETHOD GetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, @@ -149,9 +159,21 @@ public: } // nsIXMLContent - NS_IMETHOD SetNameSpacePrefix(nsIAtom* aNameSpace); - NS_IMETHOD GetNameSpacePrefix(nsIAtom*& aNameSpace) const; - NS_IMETHOD SetNameSpaceID(PRInt32 aNameSpaceId); + NS_IMETHOD SetContainingNameSpace(nsINameSpace* aNameSpace) { + return mInner.SetContainingNameSpace(aNameSpace); + } + NS_IMETHOD GetContainingNameSpace(nsINameSpace*& aNameSpace) const { + return mInner.GetContainingNameSpace(aNameSpace); + } + NS_IMETHOD SetNameSpacePrefix(nsIAtom* aNameSpace) { + return mInner.SetNameSpacePrefix(aNameSpace); + } + NS_IMETHOD GetNameSpacePrefix(nsIAtom*& aNameSpace) const { + return mInner.GetNameSpacePrefix(aNameSpace); + } + NS_IMETHOD SetNameSpaceID(PRInt32 aNameSpaceId) { + return mInner.SetNameSpaceID(aNameSpaceId); + } // nsIDOMEventReceiver NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC(mInner) @@ -183,11 +205,7 @@ public: } protected: - nsGenericContainerElement mInner; - - nsIAtom* mNameSpacePrefix; - PRInt32 mNameSpaceID; - void *mScriptObject; + nsGenericXMLElement mInner; PRBool mIsLink; }; diff --git a/layout/xml/document/src/nsXMLContentSink.cpp b/layout/xml/document/src/nsXMLContentSink.cpp index e667d7e55c46..cd570cc20e99 100644 --- a/layout/xml/document/src/nsXMLContentSink.cpp +++ b/layout/xml/document/src/nsXMLContentSink.cpp @@ -61,6 +61,7 @@ static char kXSLType[] = "text/xsl"; static NS_DEFINE_IID(kIXMLContentSinkIID, NS_IXMLCONTENT_SINK_IID); +static NS_DEFINE_IID(kIXMLContentIID, NS_IXMLCONTENT_IID); static NS_DEFINE_IID(kIXMLDocumentIID, NS_IXMLDOCUMENT_IID); static NS_DEFINE_IID(kIDOMCommentIID, NS_IDOMCOMMENT_IID); static NS_DEFINE_IID(kIScrollableViewIID, NS_ISCROLLABLEVIEW_IID); @@ -653,8 +654,9 @@ nsXMLContentSink::CloseContainer(const nsIParserNode& aNode) NS_RELEASE(tagAtom); } + nsIContent* content = nsnull; if (popContent) { - nsIContent* content = PopContent(); + content = PopContent(); if (nsnull != content) { if (mDocElement == content) { mState = eXMLContentSinkState_InEpilog; @@ -667,7 +669,16 @@ nsXMLContentSink::CloseContainer(const nsIParserNode& aNode) PR_ASSERT(0); } } - PopNameSpaces(); + nsINameSpace* nameSpace = PopNameSpaces(); + if (nsnull != content) { + nsIXMLContent* xmlContent; + if (NS_OK == content->QueryInterface(kIXMLContentIID, + (void **)&xmlContent)) { + xmlContent->SetContainingNameSpace(nameSpace); + NS_RELEASE(xmlContent); + } + } + NS_IF_RELEASE(nameSpace); return result; } @@ -1245,15 +1256,17 @@ nsXMLContentSink::GetNameSpaceId(nsIAtom* aPrefix) return id; } -void +nsINameSpace* nsXMLContentSink::PopNameSpaces() { if ((nsnull != mNameSpaceStack) && (0 < mNameSpaceStack->Count())) { PRInt32 index = mNameSpaceStack->Count() - 1; nsINameSpace* nameSpace = (nsINameSpace*)mNameSpaceStack->ElementAt(index); mNameSpaceStack->RemoveElementAt(index); - NS_RELEASE(nameSpace); + return nameSpace; } + + return nsnull; } PRBool diff --git a/layout/xml/document/src/nsXMLContentSink.h b/layout/xml/document/src/nsXMLContentSink.h index 783b2dde3b18..a67759cad71e 100644 --- a/layout/xml/document/src/nsXMLContentSink.h +++ b/layout/xml/document/src/nsXMLContentSink.h @@ -33,6 +33,7 @@ class nsVoidArray; class nsIXMLDocument; class nsIUnicharInputStream; class nsIParser; +class nsINameSpace; typedef enum { eXMLContentSinkState_InProlog, @@ -104,7 +105,7 @@ protected: void PushNameSpacesFrom(const nsIParserNode& aNode); nsIAtom* CutNameSpacePrefix(nsString& aString); PRInt32 GetNameSpaceId(nsIAtom* aPrefix); - void PopNameSpaces(); + nsINameSpace* PopNameSpaces(); PRBool IsHTMLNameSpace(PRInt32 aId); nsIContent* GetCurrentContent(); diff --git a/layout/xml/document/src/nsXMLDocument.cpp b/layout/xml/document/src/nsXMLDocument.cpp index bd601082da9d..167eff155557 100644 --- a/layout/xml/document/src/nsXMLDocument.cpp +++ b/layout/xml/document/src/nsXMLDocument.cpp @@ -301,14 +301,6 @@ nsXMLDocument::CreateProcessingInstruction(const nsString& aTarget, const nsStri return NS_ERROR_NOT_IMPLEMENTED; } -NS_IMETHODIMP -nsXMLDocument::CreateAttribute(const nsString& aName, nsIDOMAttr** aReturn) -{ - // XXX TBI - *aReturn = nsnull; - return NS_ERROR_NOT_IMPLEMENTED; -} - NS_IMETHODIMP nsXMLDocument::CreateElement(const nsString& aTagName, nsIDOMElement** aReturn) diff --git a/layout/xml/document/src/nsXMLDocument.h b/layout/xml/document/src/nsXMLDocument.h index 15e74da8402c..511cbf6c7997 100644 --- a/layout/xml/document/src/nsXMLDocument.h +++ b/layout/xml/document/src/nsXMLDocument.h @@ -52,7 +52,6 @@ public: NS_IMETHOD CreateEntityReference(const nsString& aName, nsIDOMEntityReference** aReturn); NS_IMETHOD CreateComment(const nsString& aData, nsIDOMComment** aReturn); NS_IMETHOD CreateProcessingInstruction(const nsString& aTarget, const nsString& aData, nsIDOMProcessingInstruction** aReturn); - NS_IMETHOD CreateAttribute(const nsString& aName, nsIDOMAttr** aReturn); NS_IMETHOD CreateElement(const nsString& aTagName, nsIDOMElement** aReturn); NS_IMETHOD CreateTextNode(const nsString& aData, nsIDOMText** aReturn);