From fdfa2b0b2258a734776fc241c5c992e80aa589df Mon Sep 17 00:00:00 2001 From: "vidur%netscape.com" Date: Tue, 19 Jan 1999 23:07:33 +0000 Subject: [PATCH] Completion of document as node - specifically, the childNodes array. Completion of nodeName, nodeValue and attributes properties for different types of nodes. git-svn-id: svn://10.0.0.236/trunk@18031 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/base/src/nsCommentNode.cpp | 7 + mozilla/content/base/src/nsDOMAttribute.cpp | 3 +- .../content/base/src/nsGenericDOMDataNode.h | 8 +- mozilla/content/base/src/nsTextNode.cpp | 7 + .../html/document/src/nsHTMLDocument.cpp | 9 +- .../xml/document/public/nsIXMLDocument.h | 8 +- .../xml/document/src/nsXMLDocument.cpp | 226 +++++++++++++++++- .../content/xml/document/src/nsXMLDocument.h | 44 +++- mozilla/layout/base/src/nsCommentNode.cpp | 7 + mozilla/layout/base/src/nsDOMAttribute.cpp | 3 +- .../layout/base/src/nsGenericDOMDataNode.h | 8 +- mozilla/layout/base/src/nsTextNode.cpp | 7 + .../html/document/src/nsHTMLDocument.cpp | 9 +- .../xml/document/public/nsIXMLDocument.h | 8 +- .../layout/xml/document/src/nsXMLDocument.cpp | 226 +++++++++++++++++- .../layout/xml/document/src/nsXMLDocument.h | 44 +++- mozilla/rdf/content/src/nsRDFDocument.cpp | 16 +- 17 files changed, 576 insertions(+), 64 deletions(-) diff --git a/mozilla/content/base/src/nsCommentNode.cpp b/mozilla/content/base/src/nsCommentNode.cpp index cdc525ff2e8..ab23cf6d1b5 100644 --- a/mozilla/content/base/src/nsCommentNode.cpp +++ b/mozilla/content/base/src/nsCommentNode.cpp @@ -100,6 +100,13 @@ nsCommentNode::QueryInterface(REFNSIID aIID, void** aInstancePtr) return NS_NOINTERFACE; } +NS_IMETHODIMP +nsCommentNode::GetNodeName(nsString& aNodeName) +{ + aNodeName.SetString("#comment"); + return NS_OK; +} + NS_IMETHODIMP nsCommentNode::GetNodeType(PRUint16* aNodeType) { diff --git a/mozilla/content/base/src/nsDOMAttribute.cpp b/mozilla/content/base/src/nsDOMAttribute.cpp index c5a6f02e710..882d098a384 100644 --- a/mozilla/content/base/src/nsDOMAttribute.cpp +++ b/mozilla/content/base/src/nsDOMAttribute.cpp @@ -227,8 +227,7 @@ nsDOMAttribute::GetNodeValue(nsString& aNodeValue) NS_IMETHODIMP nsDOMAttribute::SetNodeValue(const nsString& aNodeValue) { - // You can't actually do this, but we'll fail silently - return NS_OK; + return SetValue(aNodeValue); } NS_IMETHODIMP diff --git a/mozilla/content/base/src/nsGenericDOMDataNode.h b/mozilla/content/base/src/nsGenericDOMDataNode.h index b688f83cd2b..4be7305e5b5 100644 --- a/mozilla/content/base/src/nsGenericDOMDataNode.h +++ b/mozilla/content/base/src/nsGenericDOMDataNode.h @@ -50,10 +50,6 @@ struct nsGenericDOMDataNode { void Init(nsIContent* aOuterContentObject); // Implementation for nsIDOMNode - nsresult GetNodeName(nsString& aNodeName) { - aNodeName.Truncate(); - return NS_OK; - } nsresult GetNodeValue(nsString& aNodeValue); nsresult SetNodeValue(const nsString& aNodeValue); nsresult GetParentNode(nsIDOMNode** aParentNode); @@ -238,9 +234,7 @@ struct nsGenericDOMDataNode { * NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn); */ #define NS_IMPL_IDOMNODE_USING_GENERIC_DOM_DATA(_g) \ - NS_IMETHOD GetNodeName(nsString& aNodeName) { \ - return _g.GetNodeName(aNodeName); \ - } \ + NS_IMETHOD GetNodeName(nsString& aNodeName); \ NS_IMETHOD GetNodeValue(nsString& aNodeValue) { \ return _g.GetNodeValue(aNodeValue); \ } \ diff --git a/mozilla/content/base/src/nsTextNode.cpp b/mozilla/content/base/src/nsTextNode.cpp index 251fa584bb5..5940363026d 100644 --- a/mozilla/content/base/src/nsTextNode.cpp +++ b/mozilla/content/base/src/nsTextNode.cpp @@ -124,6 +124,13 @@ nsTextNode::QueryInterface(REFNSIID aIID, void** aInstancePtr) return NS_NOINTERFACE; } +NS_IMETHODIMP +nsTextNode::GetNodeName(nsString& aNodeName) +{ + aNodeName.SetString("#text"); + return NS_OK; +} + NS_IMETHODIMP nsTextNode::GetNodeType(PRUint16* aNodeType) { diff --git a/mozilla/content/html/document/src/nsHTMLDocument.cpp b/mozilla/content/html/document/src/nsHTMLDocument.cpp index 674ea474274..f337039727e 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/content/html/document/src/nsHTMLDocument.cpp @@ -28,6 +28,7 @@ #include "nsIPresContext.h" #include "nsIHTMLContent.h" #include "nsIDOMNode.h" // for Find +#include "nsIDOMNodeList.h" #include "nsIDOMElement.h" #include "nsIDOMText.h" #include "nsIDOMComment.h" @@ -74,6 +75,7 @@ static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID); static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID); static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID); static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID); +static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID); static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID); static NS_DEFINE_IID(kIDOMHTMLDocumentIID, NS_IDOMHTMLDOCUMENT_IID); static NS_DEFINE_IID(kIDOMNSHTMLDocumentIID, NS_IDOMNSHTMLDOCUMENT_IID); @@ -746,7 +748,12 @@ nsHTMLDocument::GetElementsByTagName(const nsString& aTagname, nsIDOMNodeList** NS_IMETHODIMP nsHTMLDocument::GetChildNodes(nsIDOMNodeList** aChildNodes) { - return NS_OK; + nsHTMLDocumentChildNodes* childNodes = new nsHTMLDocumentChildNodes((nsIDOMDocument*)(nsIDOMHTMLDocument*)this); + if (nsnull == childNodes) { + return NS_ERROR_OUT_OF_MEMORY; + } + + return childNodes->QueryInterface(kIDOMNodeListIID, (void**)aChildNodes); } NS_IMETHODIMP diff --git a/mozilla/content/xml/document/public/nsIXMLDocument.h b/mozilla/content/xml/document/public/nsIXMLDocument.h index ee1aea8b2d7..dbaca0edaa9 100644 --- a/mozilla/content/xml/document/public/nsIXMLDocument.h +++ b/mozilla/content/xml/document/public/nsIXMLDocument.h @@ -34,12 +34,12 @@ class nsIAtom; */ class nsIXMLDocument : public nsISupports { public: - NS_IMETHOD PrologElementAt(PRInt32 aOffset, nsIContent** aContent)=0; - NS_IMETHOD PrologCount(PRInt32* aCount)=0; + NS_IMETHOD PrologElementAt(PRUint32 aOffset, nsIContent** aContent)=0; + NS_IMETHOD PrologCount(PRUint32* aCount)=0; NS_IMETHOD AppendToProlog(nsIContent* aContent)=0; - NS_IMETHOD EpilogElementAt(PRInt32 aOffset, nsIContent** aContent)=0; - NS_IMETHOD EpilogCount(PRInt32* aCount)=0; + NS_IMETHOD EpilogElementAt(PRUint32 aOffset, nsIContent** aContent)=0; + NS_IMETHOD EpilogCount(PRUint32* aCount)=0; NS_IMETHOD AppendToEpilog(nsIContent* aContent)=0; }; diff --git a/mozilla/content/xml/document/src/nsXMLDocument.cpp b/mozilla/content/xml/document/src/nsXMLDocument.cpp index dee9ff09781..491f04781a7 100644 --- a/mozilla/content/xml/document/src/nsXMLDocument.cpp +++ b/mozilla/content/xml/document/src/nsXMLDocument.cpp @@ -50,7 +50,93 @@ static NS_DEFINE_IID(kIDOMCommentIID, NS_IDOMCOMMENT_IID); static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID); static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID); static NS_DEFINE_IID(kIHTMLContentContainerIID, NS_IHTMLCONTENTCONTAINER_IID); +static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID); +static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID); +// ================================================================== +// = +// ================================================================== +nsXMLDocumentChildNodes::nsXMLDocumentChildNodes(nsXMLDocument* aDocument) +{ + // We don't reference count our document reference (to avoid circular + // references). We'll be told when the document goes away. + mDocument = aDocument; +} + +nsXMLDocumentChildNodes::~nsXMLDocumentChildNodes() +{ +} + +NS_IMETHODIMP +nsXMLDocumentChildNodes::GetLength(PRUint32* aLength) +{ + if (nsnull != mDocument) { + PRUint32 prolog, epilog; + + // The length is the sum of the prolog, epilog and + // document element; + mDocument->PrologCount(&prolog); + mDocument->EpilogCount(&epilog); + *aLength = prolog + epilog + 1; + } + else { + *aLength = 0; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsXMLDocumentChildNodes::Item(PRUint32 aIndex, nsIDOMNode** aReturn) +{ + nsresult result = NS_OK; + + *aReturn = nsnull; + if (nsnull != mDocument) { + PRUint32 prolog, epilog; + + mDocument->PrologCount(&prolog); + if (aIndex < prolog) { + // It's in the prolog + nsIContent* content; + result = mDocument->PrologElementAt(aIndex, &content); + if ((NS_OK == result) && (nsnull != content)) { + result = content->QueryInterface(kIDOMNodeIID, (void**)aReturn); + NS_RELEASE(content); + } + } + else if (aIndex == prolog) { + // It's the document element + nsIDOMElement* element; + result = mDocument->GetDocumentElement(&element); + if (NS_OK == result) { + result = element->QueryInterface(kIDOMNodeIID, (void**)aReturn); + NS_RELEASE(element); + } + } + else { + // It's in the epilog + nsIContent* content; + result = mDocument->EpilogElementAt(aIndex-prolog-1, &content); + if ((NS_OK == result) && (nsnull != content)) { + result = content->QueryInterface(kIDOMNodeIID, (void**)aReturn); + NS_RELEASE(content); + } + } + } + + return result; +} + +void +nsXMLDocumentChildNodes::DropReference() +{ + mDocument = nsnull; +} + +// ================================================================== +// = +// ================================================================== NS_LAYOUT nsresult NS_NewXMLDocument(nsIDocument** aInstancePtrResult) @@ -66,13 +152,16 @@ nsXMLDocument::nsXMLDocument() mInlineStyleSheet = nsnull; mProlog = nsnull; mEpilog = nsnull; - + mChildNodes = nsnull; + // XXX The XML world depends on the html atoms nsHTMLAtoms::AddrefAtoms(); } nsXMLDocument::~nsXMLDocument() { + PRInt32 i, count; + nsIContent* content; NS_IF_RELEASE(mParser); if (nsnull != mAttrStyleSheet) { mAttrStyleSheet->SetOwningDocument(nsnull); @@ -83,11 +172,22 @@ nsXMLDocument::~nsXMLDocument() NS_RELEASE(mInlineStyleSheet); } if (nsnull != mProlog) { + count = mProlog->Count(); + for (i = 0; i < count; i++) { + content = (nsIContent*)mProlog->ElementAt(i); + NS_RELEASE(content); + } delete mProlog; } if (nsnull != mEpilog) { - delete mProlog; + count = mEpilog->Count(); + for (i = 0; i < count; i++) { + content = (nsIContent*)mEpilog->ElementAt(i); + NS_RELEASE(content); + } + delete mEpilog; } + NS_IF_RELEASE(mChildNodes); } NS_IMETHODIMP @@ -253,6 +353,110 @@ void nsXMLDocument::AddStyleSheetToSet(nsIStyleSheet* aSheet, nsIStyleSet* aSet) } } +// nsIDOMNode interface +NS_IMETHODIMP +nsXMLDocument::GetChildNodes(nsIDOMNodeList** aChildNodes) +{ + if (nsnull == mChildNodes) { + mChildNodes = new nsXMLDocumentChildNodes(this); + if (nsnull == mChildNodes) { + return NS_ERROR_OUT_OF_MEMORY; + } + NS_ADDREF(mChildNodes); + } + + return mChildNodes->QueryInterface(kIDOMNodeListIID, (void**)aChildNodes); +} + +NS_IMETHODIMP +nsXMLDocument::GetFirstChild(nsIDOMNode** aFirstChild) +{ + nsresult result = NS_OK; + + if ((nsnull != mProlog) && (0 != mProlog->Count())) { + nsIContent* content; + result = PrologElementAt(0, &content); + if ((NS_OK == result) && (nsnull != content)) { + result = content->QueryInterface(kIDOMNodeIID, (void**)aFirstChild); + NS_RELEASE(content); + } + } + else { + nsIDOMElement* element; + result = GetDocumentElement(&element); + if (NS_OK == result) { + result = element->QueryInterface(kIDOMNodeIID, (void**)aFirstChild); + NS_RELEASE(element); + } + } + + return result; +} + +NS_IMETHODIMP +nsXMLDocument::GetLastChild(nsIDOMNode** aLastChild) +{ + nsresult result = NS_OK; + + if ((nsnull != mEpilog) && (0 != mEpilog->Count())) { + nsIContent* content; + result = EpilogElementAt(mEpilog->Count()-1, &content); + if ((NS_OK == result) && (nsnull != content)) { + result = content->QueryInterface(kIDOMNodeIID, (void**)aLastChild); + NS_RELEASE(content); + } + } + else { + nsIDOMElement* element; + result = GetDocumentElement(&element); + if (NS_OK == result) { + result = element->QueryInterface(kIDOMNodeIID, (void**)aLastChild); + NS_RELEASE(element); + } + } + + return result; +} + +NS_IMETHODIMP +nsXMLDocument::InsertBefore(nsIDOMNode* aNewChild, + nsIDOMNode* aRefChild, + nsIDOMNode** aReturn) +{ + // XXX TBI + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXMLDocument::ReplaceChild(nsIDOMNode* aNewChild, + nsIDOMNode* aOldChild, + nsIDOMNode** aReturn) +{ + // XXX TBI + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXMLDocument::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) +{ + // XXX TBI + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXMLDocument::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn) +{ + // XXX TBI + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXMLDocument::HasChildNodes(PRBool* aReturn) +{ + *aReturn = PR_TRUE; + return NS_OK; +} + // nsIDOMDocument interface NS_IMETHODIMP nsXMLDocument::GetDoctype(nsIDOMDocumentType** aDocumentType) @@ -308,13 +512,13 @@ nsXMLDocument::CreateElement(const nsString& aTagName, // nsIXMLDocument interface NS_IMETHODIMP -nsXMLDocument::PrologElementAt(PRInt32 aIndex, nsIContent** aContent) +nsXMLDocument::PrologElementAt(PRUint32 aIndex, nsIContent** aContent) { if (nsnull == mProlog) { *aContent = nsnull; } else { - *aContent = (nsIContent *)mProlog->ElementAt(aIndex); + *aContent = (nsIContent *)mProlog->ElementAt((PRInt32)aIndex); NS_ADDREF(*aContent); } @@ -322,13 +526,13 @@ nsXMLDocument::PrologElementAt(PRInt32 aIndex, nsIContent** aContent) } NS_IMETHODIMP -nsXMLDocument::PrologCount(PRInt32* aCount) +nsXMLDocument::PrologCount(PRUint32* aCount) { if (nsnull == mProlog) { *aCount = 0; } else { - *aCount = mProlog->Count(); + *aCount = (PRUint32)mProlog->Count(); } return NS_OK; @@ -342,18 +546,19 @@ nsXMLDocument::AppendToProlog(nsIContent* aContent) } mProlog->AppendElement((void *)aContent); + NS_ADDREF(aContent); return NS_OK; } NS_IMETHODIMP -nsXMLDocument::EpilogElementAt(PRInt32 aIndex, nsIContent** aContent) +nsXMLDocument::EpilogElementAt(PRUint32 aIndex, nsIContent** aContent) { if (nsnull == mEpilog) { *aContent = nsnull; } else { - *aContent = (nsIContent *)mEpilog->ElementAt(aIndex); + *aContent = (nsIContent *)mEpilog->ElementAt((PRInt32)aIndex); NS_ADDREF(*aContent); } @@ -361,13 +566,13 @@ nsXMLDocument::EpilogElementAt(PRInt32 aIndex, nsIContent** aContent) } NS_IMETHODIMP -nsXMLDocument::EpilogCount(PRInt32* aCount) +nsXMLDocument::EpilogCount(PRUint32* aCount) { if (nsnull == mEpilog) { *aCount = 0; } else { - *aCount = mEpilog->Count(); + *aCount = (PRUint32)mEpilog->Count(); } return NS_OK; @@ -381,6 +586,7 @@ nsXMLDocument::AppendToEpilog(nsIContent* aContent) } mEpilog->AppendElement((void *)aContent); + NS_ADDREF(aContent); return NS_OK; } diff --git a/mozilla/content/xml/document/src/nsXMLDocument.h b/mozilla/content/xml/document/src/nsXMLDocument.h index 70f127a0adf..a509a87b65e 100644 --- a/mozilla/content/xml/document/src/nsXMLDocument.h +++ b/mozilla/content/xml/document/src/nsXMLDocument.h @@ -23,8 +23,29 @@ #include "nsMarkupDocument.h" #include "nsIXMLDocument.h" #include "nsIHTMLContentContainer.h" +#include "nsGenericDOMNodeList.h" class nsIParser; +class nsIDOMNode; +class nsXMLDocument; + +// Represents the children of an XML document (prolog, epilog and +// document element) +class nsXMLDocumentChildNodes : public nsGenericDOMNodeList +{ +public: + nsXMLDocumentChildNodes(nsXMLDocument* aDocument); + ~nsXMLDocumentChildNodes(); + + NS_IMETHOD GetLength(PRUint32* aLength); + NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn); + + void DropReference(); + +protected: + nsXMLDocument* mDocument; +}; + class nsXMLDocument : public nsMarkupDocument, public nsIXMLDocument, @@ -46,6 +67,20 @@ public: NS_IMETHOD EndLoad(); + // nsIDOMNode interface + NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes); + NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild); + NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild); + 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 HasChildNodes(PRBool* aReturn); + // nsIDOMDocument interface NS_IMETHOD GetDoctype(nsIDOMDocumentType** aDocumentType); NS_IMETHOD CreateCDATASection(const nsString& aData, nsIDOMCDATASection** aReturn); @@ -55,12 +90,12 @@ public: nsIDOMElement** aReturn); // nsIXMLDocument interface - NS_IMETHOD PrologElementAt(PRInt32 aOffset, nsIContent** aContent); - NS_IMETHOD PrologCount(PRInt32* aCount); + NS_IMETHOD PrologElementAt(PRUint32 aOffset, nsIContent** aContent); + NS_IMETHOD PrologCount(PRUint32* aCount); NS_IMETHOD AppendToProlog(nsIContent* aContent); - NS_IMETHOD EpilogElementAt(PRInt32 aOffset, nsIContent** aContent); - NS_IMETHOD EpilogCount(PRInt32* aCount); + NS_IMETHOD EpilogElementAt(PRUint32 aOffset, nsIContent** aContent); + NS_IMETHOD EpilogCount(PRUint32* aCount); NS_IMETHOD AppendToEpilog(nsIContent* aContent); // nsIHTMLContentContainer @@ -80,6 +115,7 @@ protected: nsVoidArray *mEpilog; nsIParser *mParser; + nsXMLDocumentChildNodes* mChildNodes; }; diff --git a/mozilla/layout/base/src/nsCommentNode.cpp b/mozilla/layout/base/src/nsCommentNode.cpp index cdc525ff2e8..ab23cf6d1b5 100644 --- a/mozilla/layout/base/src/nsCommentNode.cpp +++ b/mozilla/layout/base/src/nsCommentNode.cpp @@ -100,6 +100,13 @@ nsCommentNode::QueryInterface(REFNSIID aIID, void** aInstancePtr) return NS_NOINTERFACE; } +NS_IMETHODIMP +nsCommentNode::GetNodeName(nsString& aNodeName) +{ + aNodeName.SetString("#comment"); + return NS_OK; +} + NS_IMETHODIMP nsCommentNode::GetNodeType(PRUint16* aNodeType) { diff --git a/mozilla/layout/base/src/nsDOMAttribute.cpp b/mozilla/layout/base/src/nsDOMAttribute.cpp index c5a6f02e710..882d098a384 100644 --- a/mozilla/layout/base/src/nsDOMAttribute.cpp +++ b/mozilla/layout/base/src/nsDOMAttribute.cpp @@ -227,8 +227,7 @@ nsDOMAttribute::GetNodeValue(nsString& aNodeValue) NS_IMETHODIMP nsDOMAttribute::SetNodeValue(const nsString& aNodeValue) { - // You can't actually do this, but we'll fail silently - return NS_OK; + return SetValue(aNodeValue); } NS_IMETHODIMP diff --git a/mozilla/layout/base/src/nsGenericDOMDataNode.h b/mozilla/layout/base/src/nsGenericDOMDataNode.h index b688f83cd2b..4be7305e5b5 100644 --- a/mozilla/layout/base/src/nsGenericDOMDataNode.h +++ b/mozilla/layout/base/src/nsGenericDOMDataNode.h @@ -50,10 +50,6 @@ struct nsGenericDOMDataNode { void Init(nsIContent* aOuterContentObject); // Implementation for nsIDOMNode - nsresult GetNodeName(nsString& aNodeName) { - aNodeName.Truncate(); - return NS_OK; - } nsresult GetNodeValue(nsString& aNodeValue); nsresult SetNodeValue(const nsString& aNodeValue); nsresult GetParentNode(nsIDOMNode** aParentNode); @@ -238,9 +234,7 @@ struct nsGenericDOMDataNode { * NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn); */ #define NS_IMPL_IDOMNODE_USING_GENERIC_DOM_DATA(_g) \ - NS_IMETHOD GetNodeName(nsString& aNodeName) { \ - return _g.GetNodeName(aNodeName); \ - } \ + NS_IMETHOD GetNodeName(nsString& aNodeName); \ NS_IMETHOD GetNodeValue(nsString& aNodeValue) { \ return _g.GetNodeValue(aNodeValue); \ } \ diff --git a/mozilla/layout/base/src/nsTextNode.cpp b/mozilla/layout/base/src/nsTextNode.cpp index 251fa584bb5..5940363026d 100644 --- a/mozilla/layout/base/src/nsTextNode.cpp +++ b/mozilla/layout/base/src/nsTextNode.cpp @@ -124,6 +124,13 @@ nsTextNode::QueryInterface(REFNSIID aIID, void** aInstancePtr) return NS_NOINTERFACE; } +NS_IMETHODIMP +nsTextNode::GetNodeName(nsString& aNodeName) +{ + aNodeName.SetString("#text"); + return NS_OK; +} + NS_IMETHODIMP nsTextNode::GetNodeType(PRUint16* aNodeType) { diff --git a/mozilla/layout/html/document/src/nsHTMLDocument.cpp b/mozilla/layout/html/document/src/nsHTMLDocument.cpp index 674ea474274..f337039727e 100644 --- a/mozilla/layout/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/layout/html/document/src/nsHTMLDocument.cpp @@ -28,6 +28,7 @@ #include "nsIPresContext.h" #include "nsIHTMLContent.h" #include "nsIDOMNode.h" // for Find +#include "nsIDOMNodeList.h" #include "nsIDOMElement.h" #include "nsIDOMText.h" #include "nsIDOMComment.h" @@ -74,6 +75,7 @@ static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID); static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID); static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID); static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID); +static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID); static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID); static NS_DEFINE_IID(kIDOMHTMLDocumentIID, NS_IDOMHTMLDOCUMENT_IID); static NS_DEFINE_IID(kIDOMNSHTMLDocumentIID, NS_IDOMNSHTMLDOCUMENT_IID); @@ -746,7 +748,12 @@ nsHTMLDocument::GetElementsByTagName(const nsString& aTagname, nsIDOMNodeList** NS_IMETHODIMP nsHTMLDocument::GetChildNodes(nsIDOMNodeList** aChildNodes) { - return NS_OK; + nsHTMLDocumentChildNodes* childNodes = new nsHTMLDocumentChildNodes((nsIDOMDocument*)(nsIDOMHTMLDocument*)this); + if (nsnull == childNodes) { + return NS_ERROR_OUT_OF_MEMORY; + } + + return childNodes->QueryInterface(kIDOMNodeListIID, (void**)aChildNodes); } NS_IMETHODIMP diff --git a/mozilla/layout/xml/document/public/nsIXMLDocument.h b/mozilla/layout/xml/document/public/nsIXMLDocument.h index ee1aea8b2d7..dbaca0edaa9 100644 --- a/mozilla/layout/xml/document/public/nsIXMLDocument.h +++ b/mozilla/layout/xml/document/public/nsIXMLDocument.h @@ -34,12 +34,12 @@ class nsIAtom; */ class nsIXMLDocument : public nsISupports { public: - NS_IMETHOD PrologElementAt(PRInt32 aOffset, nsIContent** aContent)=0; - NS_IMETHOD PrologCount(PRInt32* aCount)=0; + NS_IMETHOD PrologElementAt(PRUint32 aOffset, nsIContent** aContent)=0; + NS_IMETHOD PrologCount(PRUint32* aCount)=0; NS_IMETHOD AppendToProlog(nsIContent* aContent)=0; - NS_IMETHOD EpilogElementAt(PRInt32 aOffset, nsIContent** aContent)=0; - NS_IMETHOD EpilogCount(PRInt32* aCount)=0; + NS_IMETHOD EpilogElementAt(PRUint32 aOffset, nsIContent** aContent)=0; + NS_IMETHOD EpilogCount(PRUint32* aCount)=0; NS_IMETHOD AppendToEpilog(nsIContent* aContent)=0; }; diff --git a/mozilla/layout/xml/document/src/nsXMLDocument.cpp b/mozilla/layout/xml/document/src/nsXMLDocument.cpp index dee9ff09781..491f04781a7 100644 --- a/mozilla/layout/xml/document/src/nsXMLDocument.cpp +++ b/mozilla/layout/xml/document/src/nsXMLDocument.cpp @@ -50,7 +50,93 @@ static NS_DEFINE_IID(kIDOMCommentIID, NS_IDOMCOMMENT_IID); static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID); static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID); static NS_DEFINE_IID(kIHTMLContentContainerIID, NS_IHTMLCONTENTCONTAINER_IID); +static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID); +static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID); +// ================================================================== +// = +// ================================================================== +nsXMLDocumentChildNodes::nsXMLDocumentChildNodes(nsXMLDocument* aDocument) +{ + // We don't reference count our document reference (to avoid circular + // references). We'll be told when the document goes away. + mDocument = aDocument; +} + +nsXMLDocumentChildNodes::~nsXMLDocumentChildNodes() +{ +} + +NS_IMETHODIMP +nsXMLDocumentChildNodes::GetLength(PRUint32* aLength) +{ + if (nsnull != mDocument) { + PRUint32 prolog, epilog; + + // The length is the sum of the prolog, epilog and + // document element; + mDocument->PrologCount(&prolog); + mDocument->EpilogCount(&epilog); + *aLength = prolog + epilog + 1; + } + else { + *aLength = 0; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsXMLDocumentChildNodes::Item(PRUint32 aIndex, nsIDOMNode** aReturn) +{ + nsresult result = NS_OK; + + *aReturn = nsnull; + if (nsnull != mDocument) { + PRUint32 prolog, epilog; + + mDocument->PrologCount(&prolog); + if (aIndex < prolog) { + // It's in the prolog + nsIContent* content; + result = mDocument->PrologElementAt(aIndex, &content); + if ((NS_OK == result) && (nsnull != content)) { + result = content->QueryInterface(kIDOMNodeIID, (void**)aReturn); + NS_RELEASE(content); + } + } + else if (aIndex == prolog) { + // It's the document element + nsIDOMElement* element; + result = mDocument->GetDocumentElement(&element); + if (NS_OK == result) { + result = element->QueryInterface(kIDOMNodeIID, (void**)aReturn); + NS_RELEASE(element); + } + } + else { + // It's in the epilog + nsIContent* content; + result = mDocument->EpilogElementAt(aIndex-prolog-1, &content); + if ((NS_OK == result) && (nsnull != content)) { + result = content->QueryInterface(kIDOMNodeIID, (void**)aReturn); + NS_RELEASE(content); + } + } + } + + return result; +} + +void +nsXMLDocumentChildNodes::DropReference() +{ + mDocument = nsnull; +} + +// ================================================================== +// = +// ================================================================== NS_LAYOUT nsresult NS_NewXMLDocument(nsIDocument** aInstancePtrResult) @@ -66,13 +152,16 @@ nsXMLDocument::nsXMLDocument() mInlineStyleSheet = nsnull; mProlog = nsnull; mEpilog = nsnull; - + mChildNodes = nsnull; + // XXX The XML world depends on the html atoms nsHTMLAtoms::AddrefAtoms(); } nsXMLDocument::~nsXMLDocument() { + PRInt32 i, count; + nsIContent* content; NS_IF_RELEASE(mParser); if (nsnull != mAttrStyleSheet) { mAttrStyleSheet->SetOwningDocument(nsnull); @@ -83,11 +172,22 @@ nsXMLDocument::~nsXMLDocument() NS_RELEASE(mInlineStyleSheet); } if (nsnull != mProlog) { + count = mProlog->Count(); + for (i = 0; i < count; i++) { + content = (nsIContent*)mProlog->ElementAt(i); + NS_RELEASE(content); + } delete mProlog; } if (nsnull != mEpilog) { - delete mProlog; + count = mEpilog->Count(); + for (i = 0; i < count; i++) { + content = (nsIContent*)mEpilog->ElementAt(i); + NS_RELEASE(content); + } + delete mEpilog; } + NS_IF_RELEASE(mChildNodes); } NS_IMETHODIMP @@ -253,6 +353,110 @@ void nsXMLDocument::AddStyleSheetToSet(nsIStyleSheet* aSheet, nsIStyleSet* aSet) } } +// nsIDOMNode interface +NS_IMETHODIMP +nsXMLDocument::GetChildNodes(nsIDOMNodeList** aChildNodes) +{ + if (nsnull == mChildNodes) { + mChildNodes = new nsXMLDocumentChildNodes(this); + if (nsnull == mChildNodes) { + return NS_ERROR_OUT_OF_MEMORY; + } + NS_ADDREF(mChildNodes); + } + + return mChildNodes->QueryInterface(kIDOMNodeListIID, (void**)aChildNodes); +} + +NS_IMETHODIMP +nsXMLDocument::GetFirstChild(nsIDOMNode** aFirstChild) +{ + nsresult result = NS_OK; + + if ((nsnull != mProlog) && (0 != mProlog->Count())) { + nsIContent* content; + result = PrologElementAt(0, &content); + if ((NS_OK == result) && (nsnull != content)) { + result = content->QueryInterface(kIDOMNodeIID, (void**)aFirstChild); + NS_RELEASE(content); + } + } + else { + nsIDOMElement* element; + result = GetDocumentElement(&element); + if (NS_OK == result) { + result = element->QueryInterface(kIDOMNodeIID, (void**)aFirstChild); + NS_RELEASE(element); + } + } + + return result; +} + +NS_IMETHODIMP +nsXMLDocument::GetLastChild(nsIDOMNode** aLastChild) +{ + nsresult result = NS_OK; + + if ((nsnull != mEpilog) && (0 != mEpilog->Count())) { + nsIContent* content; + result = EpilogElementAt(mEpilog->Count()-1, &content); + if ((NS_OK == result) && (nsnull != content)) { + result = content->QueryInterface(kIDOMNodeIID, (void**)aLastChild); + NS_RELEASE(content); + } + } + else { + nsIDOMElement* element; + result = GetDocumentElement(&element); + if (NS_OK == result) { + result = element->QueryInterface(kIDOMNodeIID, (void**)aLastChild); + NS_RELEASE(element); + } + } + + return result; +} + +NS_IMETHODIMP +nsXMLDocument::InsertBefore(nsIDOMNode* aNewChild, + nsIDOMNode* aRefChild, + nsIDOMNode** aReturn) +{ + // XXX TBI + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXMLDocument::ReplaceChild(nsIDOMNode* aNewChild, + nsIDOMNode* aOldChild, + nsIDOMNode** aReturn) +{ + // XXX TBI + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXMLDocument::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) +{ + // XXX TBI + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXMLDocument::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn) +{ + // XXX TBI + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXMLDocument::HasChildNodes(PRBool* aReturn) +{ + *aReturn = PR_TRUE; + return NS_OK; +} + // nsIDOMDocument interface NS_IMETHODIMP nsXMLDocument::GetDoctype(nsIDOMDocumentType** aDocumentType) @@ -308,13 +512,13 @@ nsXMLDocument::CreateElement(const nsString& aTagName, // nsIXMLDocument interface NS_IMETHODIMP -nsXMLDocument::PrologElementAt(PRInt32 aIndex, nsIContent** aContent) +nsXMLDocument::PrologElementAt(PRUint32 aIndex, nsIContent** aContent) { if (nsnull == mProlog) { *aContent = nsnull; } else { - *aContent = (nsIContent *)mProlog->ElementAt(aIndex); + *aContent = (nsIContent *)mProlog->ElementAt((PRInt32)aIndex); NS_ADDREF(*aContent); } @@ -322,13 +526,13 @@ nsXMLDocument::PrologElementAt(PRInt32 aIndex, nsIContent** aContent) } NS_IMETHODIMP -nsXMLDocument::PrologCount(PRInt32* aCount) +nsXMLDocument::PrologCount(PRUint32* aCount) { if (nsnull == mProlog) { *aCount = 0; } else { - *aCount = mProlog->Count(); + *aCount = (PRUint32)mProlog->Count(); } return NS_OK; @@ -342,18 +546,19 @@ nsXMLDocument::AppendToProlog(nsIContent* aContent) } mProlog->AppendElement((void *)aContent); + NS_ADDREF(aContent); return NS_OK; } NS_IMETHODIMP -nsXMLDocument::EpilogElementAt(PRInt32 aIndex, nsIContent** aContent) +nsXMLDocument::EpilogElementAt(PRUint32 aIndex, nsIContent** aContent) { if (nsnull == mEpilog) { *aContent = nsnull; } else { - *aContent = (nsIContent *)mEpilog->ElementAt(aIndex); + *aContent = (nsIContent *)mEpilog->ElementAt((PRInt32)aIndex); NS_ADDREF(*aContent); } @@ -361,13 +566,13 @@ nsXMLDocument::EpilogElementAt(PRInt32 aIndex, nsIContent** aContent) } NS_IMETHODIMP -nsXMLDocument::EpilogCount(PRInt32* aCount) +nsXMLDocument::EpilogCount(PRUint32* aCount) { if (nsnull == mEpilog) { *aCount = 0; } else { - *aCount = mEpilog->Count(); + *aCount = (PRUint32)mEpilog->Count(); } return NS_OK; @@ -381,6 +586,7 @@ nsXMLDocument::AppendToEpilog(nsIContent* aContent) } mEpilog->AppendElement((void *)aContent); + NS_ADDREF(aContent); return NS_OK; } diff --git a/mozilla/layout/xml/document/src/nsXMLDocument.h b/mozilla/layout/xml/document/src/nsXMLDocument.h index 70f127a0adf..a509a87b65e 100644 --- a/mozilla/layout/xml/document/src/nsXMLDocument.h +++ b/mozilla/layout/xml/document/src/nsXMLDocument.h @@ -23,8 +23,29 @@ #include "nsMarkupDocument.h" #include "nsIXMLDocument.h" #include "nsIHTMLContentContainer.h" +#include "nsGenericDOMNodeList.h" class nsIParser; +class nsIDOMNode; +class nsXMLDocument; + +// Represents the children of an XML document (prolog, epilog and +// document element) +class nsXMLDocumentChildNodes : public nsGenericDOMNodeList +{ +public: + nsXMLDocumentChildNodes(nsXMLDocument* aDocument); + ~nsXMLDocumentChildNodes(); + + NS_IMETHOD GetLength(PRUint32* aLength); + NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn); + + void DropReference(); + +protected: + nsXMLDocument* mDocument; +}; + class nsXMLDocument : public nsMarkupDocument, public nsIXMLDocument, @@ -46,6 +67,20 @@ public: NS_IMETHOD EndLoad(); + // nsIDOMNode interface + NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes); + NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild); + NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild); + 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 HasChildNodes(PRBool* aReturn); + // nsIDOMDocument interface NS_IMETHOD GetDoctype(nsIDOMDocumentType** aDocumentType); NS_IMETHOD CreateCDATASection(const nsString& aData, nsIDOMCDATASection** aReturn); @@ -55,12 +90,12 @@ public: nsIDOMElement** aReturn); // nsIXMLDocument interface - NS_IMETHOD PrologElementAt(PRInt32 aOffset, nsIContent** aContent); - NS_IMETHOD PrologCount(PRInt32* aCount); + NS_IMETHOD PrologElementAt(PRUint32 aOffset, nsIContent** aContent); + NS_IMETHOD PrologCount(PRUint32* aCount); NS_IMETHOD AppendToProlog(nsIContent* aContent); - NS_IMETHOD EpilogElementAt(PRInt32 aOffset, nsIContent** aContent); - NS_IMETHOD EpilogCount(PRInt32* aCount); + NS_IMETHOD EpilogElementAt(PRUint32 aOffset, nsIContent** aContent); + NS_IMETHOD EpilogCount(PRUint32* aCount); NS_IMETHOD AppendToEpilog(nsIContent* aContent); // nsIHTMLContentContainer @@ -80,6 +115,7 @@ protected: nsVoidArray *mEpilog; nsIParser *mParser; + nsXMLDocumentChildNodes* mChildNodes; }; diff --git a/mozilla/rdf/content/src/nsRDFDocument.cpp b/mozilla/rdf/content/src/nsRDFDocument.cpp index f6a941f4f10..376534848c5 100644 --- a/mozilla/rdf/content/src/nsRDFDocument.cpp +++ b/mozilla/rdf/content/src/nsRDFDocument.cpp @@ -268,12 +268,12 @@ public: // nsIXMLDocument interface - NS_IMETHOD PrologElementAt(PRInt32 aOffset, nsIContent** aContent); - NS_IMETHOD PrologCount(PRInt32* aCount); + NS_IMETHOD PrologElementAt(PRUint32 aOffset, nsIContent** aContent); + NS_IMETHOD PrologCount(PRUint32* aCount); NS_IMETHOD AppendToProlog(nsIContent* aContent); - NS_IMETHOD EpilogElementAt(PRInt32 aOffset, nsIContent** aContent); - NS_IMETHOD EpilogCount(PRInt32* aCount); + NS_IMETHOD EpilogElementAt(PRUint32 aOffset, nsIContent** aContent); + NS_IMETHOD EpilogCount(PRUint32* aCount); NS_IMETHOD AppendToEpilog(nsIContent* aContent); // nsIRDFDocument interface @@ -1408,14 +1408,14 @@ RDFDocumentImpl::HandleDOMEvent(nsIPresContext& aPresContext, // nsIXMLDocument interface NS_IMETHODIMP -RDFDocumentImpl::PrologElementAt(PRInt32 aOffset, nsIContent** aContent) +RDFDocumentImpl::PrologElementAt(PRUint32 aOffset, nsIContent** aContent) { PR_ASSERT(0); return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP -RDFDocumentImpl::PrologCount(PRInt32* aCount) +RDFDocumentImpl::PrologCount(PRUint32* aCount) { PR_ASSERT(0); return NS_ERROR_NOT_IMPLEMENTED; @@ -1430,14 +1430,14 @@ RDFDocumentImpl::AppendToProlog(nsIContent* aContent) NS_IMETHODIMP -RDFDocumentImpl::EpilogElementAt(PRInt32 aOffset, nsIContent** aContent) +RDFDocumentImpl::EpilogElementAt(PRUint32 aOffset, nsIContent** aContent) { PR_ASSERT(0); return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP -RDFDocumentImpl::EpilogCount(PRInt32* aCount) +RDFDocumentImpl::EpilogCount(PRUint32* aCount) { PR_ASSERT(0); return NS_ERROR_NOT_IMPLEMENTED;