diff --git a/content/base/public/nsIDocument.h b/content/base/public/nsIDocument.h index 12838140e70..226ee8e5f9a 100644 --- a/content/base/public/nsIDocument.h +++ b/content/base/public/nsIDocument.h @@ -157,6 +157,22 @@ public: virtual nsIContent* GetRootContent() = 0; virtual void SetRootContent(nsIContent* aRoot) = 0; + /** + * Methods to append to the prolog and epilog of + * a document. The prolog is the content before the document + * element, the epilog after. + */ + NS_IMETHOD AppendToProlog(nsIContent* aContent) = 0; + NS_IMETHOD AppendToEpilog(nsIContent* aContent) = 0; + + /** + * Get the direct children of the document - content in + * the prolog, the root content and content in the epilog. + */ + NS_IMETHOD ChildAt(PRInt32 aIndex, nsIContent*& aResult) const = 0; + NS_IMETHOD IndexOf(nsIContent* aPossibleChild, PRInt32& aIndex) const = 0; + NS_IMETHOD GetChildCount(PRInt32& aCount) = 0; + /** * Get the style sheets owned by this document. * Style sheets are ordered, most significant last. diff --git a/content/base/src/nsContentList.cpp b/content/base/src/nsContentList.cpp index d2bc68af140..367840fb4a2 100644 --- a/content/base/src/nsContentList.cpp +++ b/content/base/src/nsContentList.cpp @@ -331,7 +331,8 @@ nsContentList::Match(nsIContent *aContent, PRBool *aMatch) // If we have to match all, only do those that have // a tagName i.e. only the elements. if (mMatchAll && (nsLayoutAtoms::textTagName != name) && - (nsLayoutAtoms::commentTagName != name)) { + (nsLayoutAtoms::commentTagName != name) && + (nsLayoutAtoms::processingInstructionTagName != name)) { *aMatch = PR_TRUE; } // XXX We don't yet match on namespace. Maybe we should?? diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index b31e5861b76..309d3f90894 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -549,8 +549,62 @@ PRInt32 nsPostData::GetDataLength() return mDataLen; } +// ================================================================== +// = +// ================================================================== +nsDocumentChildNodes::nsDocumentChildNodes(nsIDocument* aDocument) +{ + // We don't reference count our document reference (to avoid circular + // references). We'll be told when the document goes away. + mDocument = aDocument; +} + +nsDocumentChildNodes::~nsDocumentChildNodes() +{ +} + +NS_IMETHODIMP +nsDocumentChildNodes::GetLength(PRUint32* aLength) +{ + if (nsnull != mDocument) { + PRInt32 count; + mDocument->GetChildCount(count); + *aLength = (PRUint32)count; + } + else { + *aLength = 0; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsDocumentChildNodes::Item(PRUint32 aIndex, nsIDOMNode** aReturn) +{ + nsresult result = NS_OK; + nsIContent* content = nsnull; + + *aReturn = nsnull; + if (nsnull != mDocument) { + result = mDocument->ChildAt(aIndex, content); + if ((NS_OK == result) && (nsnull != content)) { + result = content->QueryInterface(kIDOMNodeIID, (void**)aReturn); + } + } + + return result; +} + +void +nsDocumentChildNodes::DropReference() +{ + mDocument = nsnull; +} +// ================================================================== +// = +// ================================================================== nsDocument::nsDocument() { @@ -572,6 +626,9 @@ nsDocument::nsDocument() mNameSpaceManager = nsnull; mHeaderData = nsnull; mLineBreaker = nsnull; + mProlog = nsnull; + mEpilog = nsnull; + mChildNodes = nsnull; mWordBreaker = nsnull; Init();/* XXX */ @@ -585,7 +642,7 @@ nsDocument::~nsDocument() // This notification will occur only after the reference has // been dropped. mInDestructor = PR_TRUE; - PRInt32 index; + PRInt32 index, count; for (index = 0; index < mObservers.Count(); index++) { nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(index); observer->DocumentWillBeDestroyed(this); @@ -617,6 +674,29 @@ nsDocument::~nsDocument() NS_RELEASE(sheet); } + nsIContent* content; + if (nsnull != mProlog) { + count = mProlog->Count(); + for (index = 0; index < count; index++) { + content = (nsIContent*)mProlog->ElementAt(index); + NS_RELEASE(content); + } + delete mProlog; + } + if (nsnull != mEpilog) { + count = mEpilog->Count(); + for (index = 0; index < count; index++) { + content = (nsIContent*)mEpilog->ElementAt(index); + NS_RELEASE(content); + } + delete mEpilog; + } + + if (nsnull != mChildNodes) { + mChildNodes->DropReference(); + NS_RELEASE(mChildNodes); + } + NS_IF_RELEASE(mArena); NS_IF_RELEASE(mScriptContextOwner); NS_IF_RELEASE(mListenerManager); @@ -1047,6 +1127,103 @@ void nsDocument::SetRootContent(nsIContent* aRoot) } } +NS_IMETHODIMP +nsDocument::AppendToProlog(nsIContent* aContent) +{ + if (nsnull == mProlog) { + mProlog = new nsVoidArray(); + } + + mProlog->AppendElement((void *)aContent); + NS_ADDREF(aContent); + + return NS_OK; +} + +NS_IMETHODIMP +nsDocument::AppendToEpilog(nsIContent* aContent) +{ + if (nsnull == mEpilog) { + mEpilog = new nsVoidArray(); + } + + mEpilog->AppendElement((void *)aContent); + NS_ADDREF(aContent); + + return NS_OK; +} + +NS_IMETHODIMP +nsDocument::ChildAt(PRInt32 aIndex, nsIContent*& aResult) const +{ + nsIContent* content = nsnull; + PRInt32 prolog = 0; + + if (nsnull != mProlog) { + prolog = mProlog->Count(); + if (aIndex < prolog) { + // It's in the prolog + content = (nsIContent*)mProlog->ElementAt(aIndex); + } + } + + if (aIndex == prolog) { + // It's the document element + content = mRootContent; + } + else if ((aIndex > prolog) && (nsnull != mEpilog)) { + // It's in the epilog + content = (nsIContent*)mEpilog->ElementAt(aIndex-prolog-1); + } + + NS_IF_ADDREF(content); + aResult = content; + + return NS_OK; +} + +NS_IMETHODIMP +nsDocument::IndexOf(nsIContent* aPossibleChild, PRInt32& aIndex) const +{ + PRInt32 index = -1; + PRInt32 prolog = 0; + + if (nsnull != mProlog) { + index = mProlog->IndexOf(aPossibleChild); + prolog = mProlog->Count(); + } + + if (-1 == index) { + if (aPossibleChild == mRootContent) { + index = prolog; + } + else if (nsnull != mEpilog) { + index = mEpilog->IndexOf(aPossibleChild); + if (-1 != index) { + index += (prolog+1); + } + } + } + + aIndex = index; + + return NS_OK; +} + +NS_IMETHODIMP +nsDocument::GetChildCount(PRInt32& aCount) +{ + aCount = 1; + if (nsnull != mProlog) { + aCount += mProlog->Count(); + } + if (nsnull != mEpilog) { + aCount += mEpilog->Count(); + } + + return NS_OK; +} + PRInt32 nsDocument::GetNumberOfStyleSheets() { return mStyleSheets.Count(); @@ -1504,6 +1681,7 @@ nsDocument::CreateTextNode(const nsString& aData, nsIDOMText** aReturn) if (NS_OK == rv) { rv = text->QueryInterface(kIDOMTextIID, (void**)aReturn); (*aReturn)->AppendData(aData); + NS_RELEASE(text); } return rv; @@ -1524,6 +1702,7 @@ nsDocument::CreateComment(const nsString& aData, nsIDOMComment** aReturn) if (NS_OK == rv) { rv = comment->QueryInterface(kIDOMCommentIID, (void**)aReturn); (*aReturn)->AppendData(aData); + NS_RELEASE(comment); } return rv; @@ -1663,29 +1842,71 @@ nsDocument::GetParentNode(nsIDOMNode** aParentNode) NS_IMETHODIMP nsDocument::GetChildNodes(nsIDOMNodeList** aChildNodes) { - // Should be implemented by subclass - return NS_ERROR_NOT_IMPLEMENTED; + if (nsnull == mChildNodes) { + mChildNodes = new nsDocumentChildNodes(this); + if (nsnull == mChildNodes) { + return NS_ERROR_OUT_OF_MEMORY; + } + NS_ADDREF(mChildNodes); + } + + return mChildNodes->QueryInterface(kIDOMNodeListIID, (void**)aChildNodes); } NS_IMETHODIMP nsDocument::HasChildNodes(PRBool* aHasChildNodes) { - // Should be implemented by subclass - return NS_ERROR_NOT_IMPLEMENTED; + *aHasChildNodes = PR_TRUE; + return NS_OK; } NS_IMETHODIMP nsDocument::GetFirstChild(nsIDOMNode** aFirstChild) { - // Should be implemented by subclass - return NS_ERROR_NOT_IMPLEMENTED; + nsresult result = NS_OK; + + if ((nsnull != mProlog) && (0 != mProlog->Count())) { + nsIContent* content; + content = (nsIContent *)mProlog->ElementAt(0); + + if (nsnull != content) { + result = content->QueryInterface(kIDOMNodeIID, (void**)aFirstChild); + } + } + else { + nsIDOMElement* element; + result = GetDocumentElement(&element); + if (NS_OK == result) { + result = element->QueryInterface(kIDOMNodeIID, (void**)aFirstChild); + NS_RELEASE(element); + } + } + + return result; } NS_IMETHODIMP nsDocument::GetLastChild(nsIDOMNode** aLastChild) { - // Should be implemented by subclass - return NS_ERROR_NOT_IMPLEMENTED; + nsresult result = NS_OK; + + if ((nsnull != mEpilog) && (0 != mEpilog->Count())) { + nsIContent* content; + content = (nsIContent *)mEpilog->ElementAt(mEpilog->Count()-1); + if (nsnull != content) { + result = content->QueryInterface(kIDOMNodeIID, (void**)aLastChild); + } + } + else { + nsIDOMElement* element; + result = GetDocumentElement(&element); + if (NS_OK == result) { + result = element->QueryInterface(kIDOMNodeIID, (void**)aLastChild); + NS_RELEASE(element); + } + } + + return result; } NS_IMETHODIMP @@ -1712,29 +1933,194 @@ nsDocument::GetAttributes(nsIDOMNamedNodeMap** aAttributes) NS_IMETHODIMP nsDocument::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aReturn) { - // Should be implemented by subclass - return NS_ERROR_NOT_IMPLEMENTED; + NS_ASSERTION(nsnull != aNewChild, "null ptr"); + nsresult result = NS_OK; + PRInt32 index; + PRUint16 nodeType; + nsIContent *content, *refContent = nsnull; + + if (nsnull == aNewChild) { + return NS_ERROR_INVALID_ARG; + } + + aNewChild->GetNodeType(&nodeType); + if ((COMMENT_NODE != nodeType) && (PROCESSING_INSTRUCTION_NODE != nodeType)) { + return NS_ERROR_INVALID_ARG; + } + + result = aNewChild->QueryInterface(kIContentIID, (void**)&content); + if (NS_OK != result) { + return result; + } + + if (nsnull == aRefChild) { + AppendToEpilog(content); + } + else { + result = aRefChild->QueryInterface(kIContentIID, (void**)&refContent); + if (NS_OK != result) { + NS_RELEASE(content); + return result; + } + + if ((nsnull != mProlog) && (0 != mProlog->Count())) { + index = mProlog->IndexOf(refContent); + if (-1 != index) { + mProlog->InsertElementAt(content, index); + NS_ADDREF(content); + } + } + + if (refContent == mRootContent) { + AppendToProlog(content); + } + else if ((nsnull != mEpilog) && (0 != mEpilog->Count())) { + index = mEpilog->IndexOf(refContent); + if (-1 != index) { + mEpilog->InsertElementAt(content, index); + NS_ADDREF(content); + } + } + NS_RELEASE(refContent); + } + + if (NS_OK == result) { + content->SetDocument(this, PR_TRUE); + *aReturn = aNewChild; + NS_ADDREF(aNewChild); + } + else { + *aReturn = nsnull; + } + + NS_RELEASE(content); + + return result; } NS_IMETHODIMP nsDocument::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aReturn) { - // Should be implemented by subclass - return NS_ERROR_NOT_IMPLEMENTED; + NS_ASSERTION(((nsnull != aNewChild) && (nsnull != aOldChild)), "null ptr"); + nsresult result = NS_OK; + PRInt32 index; + PRUint16 nodeType; + nsIContent *content, *refContent; + + if ((nsnull == aNewChild) || (nsnull == aOldChild)) { + return NS_ERROR_INVALID_ARG; + } + + aNewChild->GetNodeType(&nodeType); + if ((COMMENT_NODE != nodeType) && (PROCESSING_INSTRUCTION_NODE != nodeType)) { + return NS_ERROR_INVALID_ARG; + } + + result = aNewChild->QueryInterface(kIContentIID, (void**)&content); + if (NS_OK != result) { + return result; + } + + result = aOldChild->QueryInterface(kIContentIID, (void**)&refContent); + if (NS_OK != result) { + NS_RELEASE(content); + return result; + } + + if ((nsnull != mProlog) && (0 != mProlog->Count())) { + index = mProlog->IndexOf(refContent); + if (-1 != index) { + nsIContent* oldContent; + oldContent = (nsIContent*)mProlog->ElementAt(index); + NS_RELEASE(oldContent); + mProlog->ReplaceElementAt(content, index); + NS_ADDREF(content); + } + } + + if (refContent == mRootContent) { + result = NS_ERROR_INVALID_ARG; + } + else if ((nsnull != mEpilog) && (0 != mEpilog->Count())) { + index = mEpilog->IndexOf(refContent); + if (-1 != index) { + nsIContent* oldContent; + oldContent = (nsIContent*)mEpilog->ElementAt(index); + NS_RELEASE(oldContent); + mEpilog->ReplaceElementAt(content, index); + NS_ADDREF(content); + } + } + + if (NS_OK == result) { + content->SetDocument(this, PR_TRUE); + refContent->SetDocument(nsnull, PR_TRUE); + *aReturn = aNewChild; + NS_ADDREF(aNewChild); + } + else { + *aReturn = nsnull; + } + + NS_RELEASE(content); + NS_RELEASE(refContent); + + return result; } NS_IMETHODIMP nsDocument::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) { - // Should be implemented by subclass - return NS_ERROR_NOT_IMPLEMENTED; + NS_ASSERTION(nsnull != aOldChild, "null ptr"); + nsresult result = NS_OK; + PRInt32 index; + nsIContent *content; + + if (nsnull == aOldChild) { + return NS_ERROR_INVALID_ARG; + } + + result = aOldChild->QueryInterface(kIContentIID, (void**)&content); + if (NS_OK != result) { + return result; + } + + if ((nsnull != mProlog) && (0 != mProlog->Count())) { + index = mProlog->IndexOf(content); + if (-1 != index) { + // Don't drop reference count since we're going + // to return this element anyway. + mProlog->RemoveElementAt(index); + } + } + + if (content == mRootContent) { + result = NS_ERROR_INVALID_ARG; + } + else if ((nsnull != mEpilog) && (0 != mEpilog->Count())) { + index = mEpilog->IndexOf(content); + if (-1 != index) { + mEpilog->RemoveElementAt(index); + } + } + + if (NS_OK == result) { + content->SetDocument(nsnull, PR_TRUE); + *aReturn = aOldChild; + } + else { + *aReturn = nsnull; + } + + NS_RELEASE(content); + + return result; } NS_IMETHODIMP nsDocument::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn) { - // Should be implemented by subclass - return NS_ERROR_NOT_IMPLEMENTED; + return InsertBefore(aNewChild, nsnull, aReturn); } NS_IMETHODIMP diff --git a/content/base/src/nsDocument.h b/content/base/src/nsDocument.h index 9224c446108..cc7cd2c4b65 100644 --- a/content/base/src/nsDocument.h +++ b/content/base/src/nsDocument.h @@ -29,11 +29,12 @@ #include "nsXIFConverter.h" #include "nsIJSScriptObject.h" #include "nsIContent.h" +#include "nsGenericDOMNodeList.h" class nsIEventListenerManager; class nsDOMStyleSheetCollection; class nsIDOMSelection; - +class nsDocument; class nsPostData : public nsIPostData { public: @@ -77,6 +78,23 @@ public: nsDocHeaderData* mNext; }; +// Represents the children of a document (prolog, epilog and +// document element) +class nsDocumentChildNodes : public nsGenericDOMNodeList +{ +public: + nsDocumentChildNodes(nsIDocument* aDocument); + ~nsDocumentChildNodes(); + + NS_IMETHOD GetLength(PRUint32* aLength); + NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn); + + void DropReference(); + +protected: + nsIDocument* mDocument; +}; + // Base class for our document implementations class nsDocument : public nsIDocument, public nsIDOMDocument, @@ -169,6 +187,22 @@ public: virtual nsIContent* GetRootContent(); virtual void SetRootContent(nsIContent* aRoot); + /** + * Methods to append to the prolog and epilog of + * a document. The prolog is the content before the document + * element, the epilog after. + */ + NS_IMETHOD AppendToProlog(nsIContent* aContent); + NS_IMETHOD AppendToEpilog(nsIContent* aContent); + + /** + * Get the direct children of the document - content in + * the prolog, the root content and content in the epilog. + */ + NS_IMETHOD ChildAt(PRInt32 aIndex, nsIContent*& aResult) const; + NS_IMETHOD IndexOf(nsIContent* aPossibleChild, PRInt32& aIndex) const; + NS_IMETHOD GetChildCount(PRInt32& aCount); + /** * Get the style sheets owned by this document. * These are ordered, highest priority last @@ -383,6 +417,9 @@ protected: nsINameSpaceManager* mNameSpaceManager; nsDocHeaderData* mHeaderData; nsILineBreaker* mLineBreaker; + nsVoidArray *mProlog; + nsVoidArray *mEpilog; + nsDocumentChildNodes* mChildNodes; nsIWordBreaker* mWordBreaker; }; diff --git a/content/base/src/nsGenericDOMDataNode.cpp b/content/base/src/nsGenericDOMDataNode.cpp index 78500e07985..eb6937b1439 100644 --- a/content/base/src/nsGenericDOMDataNode.cpp +++ b/content/base/src/nsGenericDOMDataNode.cpp @@ -37,6 +37,7 @@ #include "nsIPrivateDOMEvent.h" #include "nsISizeOfHandler.h" #include "nsDOMEvent.h" +#include "nsIDOMText.h" #include "nsIDOMScriptObjectFactory.h" #include "nsIScriptContextOwner.h" #include "prprf.h" @@ -49,6 +50,8 @@ NS_DEFINE_IID(kIDOMCharacterDataIID, NS_IDOMCHARACTERDATA_IID); static NS_DEFINE_IID(kIPrivateDOMEventIID, NS_IPRIVATEDOMEVENT_IID); static NS_DEFINE_IID(kIEnumeratorIID, NS_IENUMERATOR_IID); static NS_DEFINE_IID(kIDOMDocumentIID, NS_IDOMDOCUMENT_IID); +static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID); +static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID); //---------------------------------------------------------------------- @@ -133,49 +136,73 @@ nsGenericDOMDataNode::GetParentNode(nsIDOMNode** aParentNode) } nsresult -nsGenericDOMDataNode::GetPreviousSibling(nsIDOMNode** aNode) +nsGenericDOMDataNode::GetPreviousSibling(nsIDOMNode** aPrevSibling) { + nsIContent* sibling = nsnull; + nsresult result = NS_OK; + if (nsnull != mParent) { PRInt32 pos; mParent->IndexOf(mContent, pos); - if (pos > -1) { - nsIContent* prev; - mParent->ChildAt(--pos, prev); - if (nsnull != prev) { - nsresult res = prev->QueryInterface(kIDOMNodeIID, (void**)aNode); - NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); - NS_RELEASE(prev); // balance the AddRef in ChildAt() - return res; - } + if (pos > -1 ) { + mParent->ChildAt(--pos, sibling); } } - // XXX Nodes that are just below the document (their parent is the - // document) need to go to the document to find their previous sibling. - *aNode = nsnull; - return NS_OK; + else if (nsnull != mDocument) { + // Nodes that are just below the document (their parent is the + // document) need to go to the document to find their next sibling. + PRInt32 pos; + mDocument->IndexOf(mContent, pos); + if (pos > -1 ) { + mDocument->ChildAt(--pos, sibling); + } + } + + if (nsnull != sibling) { + result = sibling->QueryInterface(kIDOMNodeIID,(void**)aPrevSibling); + NS_ASSERTION(NS_OK == result, "Must be a DOM Node"); + NS_RELEASE(sibling); // balance the AddRef in ChildAt() + } + else { + *aPrevSibling = nsnull; + } + + return result; } nsresult nsGenericDOMDataNode::GetNextSibling(nsIDOMNode** aNextSibling) { + nsIContent* sibling = nsnull; + nsresult result = NS_OK; + if (nsnull != mParent) { PRInt32 pos; mParent->IndexOf(mContent, pos); if (pos > -1 ) { - nsIContent* prev; - mParent->ChildAt(++pos, prev); - if (nsnull != prev) { - nsresult res = prev->QueryInterface(kIDOMNodeIID,(void**)aNextSibling); - NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); - NS_RELEASE(prev); // balance the AddRef in ChildAt() - return res; - } + mParent->ChildAt(++pos, sibling); } } - // XXX Nodes that are just below the document (their parent is the - // document) need to go to the document to find their next sibling. - *aNextSibling = nsnull; - return NS_OK; + else if (nsnull != mDocument) { + // Nodes that are just below the document (their parent is the + // document) need to go to the document to find their next sibling. + PRInt32 pos; + mDocument->IndexOf(mContent, pos); + if (pos > -1 ) { + mDocument->ChildAt(++pos, sibling); + } + } + + if (nsnull != sibling) { + result = sibling->QueryInterface(kIDOMNodeIID,(void**)aNextSibling); + NS_ASSERTION(NS_OK == result, "Must be a DOM Node"); + NS_RELEASE(sibling); // balance the AddRef in ChildAt() + } + else { + *aNextSibling = nsnull; + } + + return result; } nsresult @@ -775,3 +802,141 @@ nsGenericDOMDataNode::GetRangeList(nsVoidArray*& aResult) const aResult = mRangeList; return NS_OK; } + + +//---------------------------------------------------------------------- + +// Implementation of the nsIDOMText interface + +nsresult +nsGenericDOMDataNode::SplitText(PRUint32 aOffset, nsIDOMText** aReturn) +{ + nsresult result = NS_OK; + nsIContent* newNode; + nsITextContent* text; + nsAutoString cutText; + nsIContent* parentNode; + PRUint32 length; + + GetLength(&length); + // Cut the second part out of the original text node + result = SubstringData(aOffset, length-aOffset, cutText); + if (NS_OK == result) { + result = DeleteData(aOffset, length-aOffset); + if (NS_OK == result) { + // Create a new text node and set its data to the + // string we just cut out + result = NS_NewTextNode(&newNode); + if (NS_OK == result) { + result = newNode->QueryInterface(kITextContentIID, (void**)&text); + if (NS_OK == result) { + text->SetText(cutText, cutText.Length(), PR_FALSE); + // Find the parent of the current node and insert the + // new text node as a child after the current node + GetParent(parentNode); + if (nsnull != parentNode) { + PRInt32 index; + + result = parentNode->IndexOf(mContent, index); + if (NS_OK == result) { + result = parentNode->InsertChildAt(newNode, index+1, PR_TRUE); + } + NS_RELEASE(parentNode); + } + result = text->QueryInterface(kIDOMTextIID, (void**)aReturn); + NS_RELEASE(text); + } + NS_RELEASE(newNode); + } + } + } + + return result; +} + +//---------------------------------------------------------------------- + +// Implementation of the nsITextContent interface + +nsresult +nsGenericDOMDataNode::GetText(const nsTextFragment*& aFragmentsResult, + PRInt32& aNumFragmentsResult) +{ + aFragmentsResult = &mText; + aNumFragmentsResult = 1; + return NS_OK; +} + +nsresult +nsGenericDOMDataNode::SetText(const PRUnichar* aBuffer, PRInt32 aLength, + PRBool aNotify) +{ + NS_PRECONDITION((aLength >= 0) && (nsnull != aBuffer), "bad args"); + if (aLength < 0) { + return NS_ERROR_ILLEGAL_VALUE; + } + if (nsnull == aBuffer) { + return NS_ERROR_NULL_POINTER; + } + mText.SetTo(aBuffer, aLength); + + // Trigger a reflow + if (aNotify && (nsnull != mDocument)) { + mDocument->ContentChanged(mContent, nsnull); + } + return NS_OK; +} + +nsresult +nsGenericDOMDataNode::SetText(const char* aBuffer, + PRInt32 aLength, + PRBool aNotify) +{ + NS_PRECONDITION((aLength >= 0) && (nsnull != aBuffer), "bad args"); + if (aLength < 0) { + return NS_ERROR_ILLEGAL_VALUE; + } + if (nsnull == aBuffer) { + return NS_ERROR_NULL_POINTER; + } + mText.SetTo(aBuffer, aLength); + + // Trigger a reflow + if (aNotify && (nsnull != mDocument)) { + mDocument->ContentChanged(mContent, nsnull); + } + return NS_OK; +} + + +nsresult +nsGenericDOMDataNode::IsOnlyWhitespace(PRBool* aResult) +{ + nsTextFragment& frag = mText; + if (frag.Is2b()) { + const PRUnichar* cp = frag.Get2b(); + const PRUnichar* end = cp + frag.GetLength(); + while (cp < end) { + PRUnichar ch = *cp++; + if (!XP_IS_SPACE(ch)) { + *aResult = PR_FALSE; + return NS_OK; + } + } + } + else { + const char* cp = frag.Get1b(); + const char* end = cp + frag.GetLength(); + while (cp < end) { + PRUnichar ch = PRUnichar(*(unsigned char*)cp); + cp++; + if (!XP_IS_SPACE(ch)) { + *aResult = PR_FALSE; + return NS_OK; + } + } + } + + *aResult = PR_TRUE; + return NS_OK; +} diff --git a/content/base/src/nsGenericDOMDataNode.h b/content/base/src/nsGenericDOMDataNode.h index 635822c723a..7884edac762 100644 --- a/content/base/src/nsGenericDOMDataNode.h +++ b/content/base/src/nsGenericDOMDataNode.h @@ -26,6 +26,7 @@ #include "nsTextFragment.h" #include "nsVoidArray.h" #include "nsINameSpaceManager.h" +#include "nsITextContent.h" extern const nsIID kIDOMCharacterDataIID; extern const nsIID kIDOMNodeIID; @@ -43,6 +44,7 @@ class nsIFrame; class nsIStyleContext; class nsIStyleRule; class nsISupportsArray; +class nsIDOMText; struct nsGenericDOMDataNode { nsGenericDOMDataNode(); @@ -206,6 +208,18 @@ struct nsGenericDOMDataNode { return NS_OK; } + nsresult SplitText(PRUint32 aOffset, nsIDOMText** aReturn); + + nsresult GetText(const nsTextFragment*& aFragmentsResult, + PRInt32& aNumFragmentsResult); + nsresult SetText(const PRUnichar* aBuffer, + PRInt32 aLength, + PRBool aNotify); + nsresult SetText(const char* aBuffer, + PRInt32 aLength, + PRBool aNotify); + nsresult IsOnlyWhitespace(PRBool* aResult); + //---------------------------------------- void ToCString(nsString& aBuf, PRInt32 aOffset, PRInt32 aLen) const; @@ -464,6 +478,38 @@ struct nsGenericDOMDataNode { return _g.GetRangeList(aResult); \ } +/** + * Implement the nsIDOMText API by forwarding the methods to a + * generic character data content object. + */ +#define NS_IMPL_IDOMTEXT_USING_GENERIC_DOM_DATA(_g) \ + NS_IMETHOD SplitText(PRUint32 aOffset, nsIDOMText** aReturn){ \ + return _g.SplitText(aOffset, aReturn); \ + } + +/** + * Implement the nsITextContent API by forwarding the methods to a + * generic character data content object. + */ +#define NS_IMPL_ITEXTCONTENT_USING_GENERIC_DOM_DATA(_g) \ + NS_IMETHOD GetText(const nsTextFragment*& aFragmentsResult, \ + PRInt32& aNumFragmentsResult){ \ + return mInner.GetText(aFragmentsResult, aNumFragmentsResult); \ + } \ + NS_IMETHOD SetText(const PRUnichar* aBuffer, \ + PRInt32 aLength, \ + PRBool aNotify){ \ + return mInner.SetText(aBuffer, aLength, aNotify); \ + } \ + NS_IMETHOD SetText(const char* aBuffer, \ + PRInt32 aLength, \ + PRBool aNotify){ \ + return mInner.SetText(aBuffer, aLength, aNotify); \ + } \ + NS_IMETHOD IsOnlyWhitespace(PRBool* aResult){ \ + return mInner.IsOnlyWhitespace(aResult); \ + } + /** * This macro implements the portion of query interface that is * generic to all html content objects. diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp index 03977c7b3c0..910c788a3c1 100644 --- a/content/base/src/nsGenericElement.cpp +++ b/content/base/src/nsGenericElement.cpp @@ -293,49 +293,73 @@ nsGenericElement::GetParentNode(nsIDOMNode** aParentNode) } nsresult -nsGenericElement::GetPreviousSibling(nsIDOMNode** aNode) +nsGenericElement::GetPreviousSibling(nsIDOMNode** aPrevSibling) { + nsIContent* sibling = nsnull; + nsresult result = NS_OK; + if (nsnull != mParent) { PRInt32 pos; mParent->IndexOf(mContent, pos); - if (pos > -1) { - nsIContent* prev; - mParent->ChildAt(--pos, prev); - if (nsnull != prev) { - nsresult res = prev->QueryInterface(kIDOMNodeIID, (void**)aNode); - NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); - NS_RELEASE(prev); // balance the AddRef in ChildAt() - return res; - } + if (pos > -1 ) { + mParent->ChildAt(--pos, sibling); } } - // XXX Nodes that are just below the document (their parent is the - // document) need to go to the document to find their previous sibling. - *aNode = nsnull; - return NS_OK; + else if (nsnull != mDocument) { + // Nodes that are just below the document (their parent is the + // document) need to go to the document to find their next sibling. + PRInt32 pos; + mDocument->IndexOf(mContent, pos); + if (pos > -1 ) { + mDocument->ChildAt(--pos, sibling); + } + } + + if (nsnull != sibling) { + result = sibling->QueryInterface(kIDOMNodeIID,(void**)aPrevSibling); + NS_ASSERTION(NS_OK == result, "Must be a DOM Node"); + NS_RELEASE(sibling); // balance the AddRef in ChildAt() + } + else { + *aPrevSibling = nsnull; + } + + return result; } nsresult nsGenericElement::GetNextSibling(nsIDOMNode** aNextSibling) { + nsIContent* sibling = nsnull; + nsresult result = NS_OK; + if (nsnull != mParent) { PRInt32 pos; mParent->IndexOf(mContent, pos); if (pos > -1 ) { - nsIContent* prev; - mParent->ChildAt(++pos, prev); - if (nsnull != prev) { - nsresult res = prev->QueryInterface(kIDOMNodeIID,(void**)aNextSibling); - NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); - NS_RELEASE(prev); // balance the AddRef in ChildAt() - return res; - } + mParent->ChildAt(++pos, sibling); } } - // XXX Nodes that are just below the document (their parent is the - // document) need to go to the document to find their next sibling. - *aNextSibling = nsnull; - return NS_OK; + else if (nsnull != mDocument) { + // Nodes that are just below the document (their parent is the + // document) need to go to the document to find their next sibling. + PRInt32 pos; + mDocument->IndexOf(mContent, pos); + if (pos > -1 ) { + mDocument->ChildAt(++pos, sibling); + } + } + + if (nsnull != sibling) { + result = sibling->QueryInterface(kIDOMNodeIID,(void**)aNextSibling); + NS_ASSERTION(NS_OK == result, "Must be a DOM Node"); + NS_RELEASE(sibling); // balance the AddRef in ChildAt() + } + else { + *aNextSibling = nsnull; + } + + return result; } nsresult @@ -1436,9 +1460,6 @@ nsGenericContainerElement::GetLastChild(nsIDOMNode** aNode) return NS_OK; } -// XXX It's possible that newChild has already been inserted in the -// tree; if this is the case then we need to remove it from where it -// was before placing it in it's new home nsresult nsGenericContainerElement::InsertBefore(nsIDOMNode* aNewChild, diff --git a/content/base/src/nsTextNode.cpp b/content/base/src/nsTextNode.cpp index e5c3bd035ca..cf85d5cc297 100644 --- a/content/base/src/nsTextNode.cpp +++ b/content/base/src/nsTextNode.cpp @@ -16,12 +16,13 @@ * Corporation. Portions created by Netscape are Copyright (C) 1998 * Netscape Communications Corporation. All Rights Reserved. */ + #include "nsIDOMText.h" -#include "nsGenericDOMDataNode.h" #include "nsIScriptObjectOwner.h" #include "nsIDOMEventReceiver.h" #include "nsIContent.h" #include "nsITextContent.h" +#include "nsGenericDOMDataNode.h" #include "nsFrame.h" #include "nsIDocument.h" #include "nsCRT.h" @@ -30,8 +31,6 @@ static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID); static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID); -/* XXX should not be html content; should be nsITextContent */ - class nsTextNode : public nsIDOMText, public nsIScriptObjectOwner, public nsIDOMEventReceiver, @@ -52,7 +51,7 @@ public: NS_IMPL_IDOMCHARACTERDATA_USING_GENERIC_DOM_DATA(mInner) // nsIDOMText - NS_IMETHOD SplitText(PRUint32 aOffset, nsIDOMText** aReturn); + NS_IMPL_IDOMTEXT_USING_GENERIC_DOM_DATA(mInner) // nsIScriptObjectOwner NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC_DOM_DATA(mInner) @@ -64,16 +63,7 @@ public: NS_IMPL_ICONTENT_USING_GENERIC_DOM_DATA(mInner) // nsITextContent - NS_IMETHOD GetText(const nsTextFragment*& aFragmentsResult, - PRInt32& aNumFragmentsResult); - NS_IMETHOD SetText(const PRUnichar* aBuffer, - PRInt32 aLength, - PRBool aNotify); - NS_IMETHOD SetText(const char* aBuffer, - PRInt32 aLength, - PRBool aNotify); - - NS_IMETHOD IsOnlyWhitespace(PRBool* aResult); + NS_IMPL_ITEXTCONTENT_USING_GENERIC_DOM_DATA(mInner) protected: nsGenericDOMDataNode mInner; @@ -197,138 +187,3 @@ nsTextNode::HandleDOMEvent(nsIPresContext& aPresContext, return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus); } - -//---------------------------------------------------------------------- - -// Implementation of the nsIDOMText interface - -NS_IMETHODIMP -nsTextNode::SplitText(PRUint32 aOffset, nsIDOMText** aReturn) -{ - nsresult result = NS_OK; - nsIContent* newNode; - nsITextContent* text; - nsAutoString cutText; - nsIContent* parentNode; - PRUint32 length; - - GetLength(&length); - // Cut the second part out of the original text node - result = SubstringData(aOffset, length-aOffset, cutText); - if (NS_OK == result) { - result = DeleteData(aOffset, length-aOffset); - if (NS_OK == result) { - // Create a new text node and set its data to the - // string we just cut out - result = NS_NewTextNode(&newNode); - if (NS_OK == result) { - result = newNode->QueryInterface(kITextContentIID, (void**)&text); - if (NS_OK == result) { - text->SetText(cutText, cutText.Length(), PR_FALSE); - // Find the parent of the current node and insert the - // new text node as a child after the current node - GetParent(parentNode); - if (nsnull != parentNode) { - PRInt32 index; - - result = parentNode->IndexOf(this, index); - if (NS_OK == result) { - result = parentNode->InsertChildAt(newNode, index+1, PR_TRUE); - } - NS_RELEASE(parentNode); - } - result = text->QueryInterface(kIDOMTextIID, (void**)aReturn); - NS_RELEASE(text); - } - NS_RELEASE(newNode); - } - } - } - - return result; -} - -//---------------------------------------------------------------------- - -// Implementation of the nsITextContent interface - -NS_IMETHODIMP -nsTextNode::GetText(const nsTextFragment*& aFragmentsResult, - PRInt32& aNumFragmentsResult) -{ - aFragmentsResult = &mInner.mText; - aNumFragmentsResult = 1; - return NS_OK; -} - -NS_IMETHODIMP -nsTextNode::SetText(const PRUnichar* aBuffer, PRInt32 aLength, - PRBool aNotify) -{ - NS_PRECONDITION((aLength >= 0) && (nsnull != aBuffer), "bad args"); - if (aLength < 0) { - return NS_ERROR_ILLEGAL_VALUE; - } - if (nsnull == aBuffer) { - return NS_ERROR_NULL_POINTER; - } - mInner.mText.SetTo(aBuffer, aLength); - - // Trigger a reflow - if (aNotify && (nsnull != mInner.mDocument)) { - mInner.mDocument->ContentChanged(this, nsnull); - } - return NS_OK; -} - -NS_IMETHODIMP -nsTextNode::SetText(const char* aBuffer, PRInt32 aLength, - PRBool aNotify) -{ - NS_PRECONDITION((aLength >= 0) && (nsnull != aBuffer), "bad args"); - if (aLength < 0) { - return NS_ERROR_ILLEGAL_VALUE; - } - if (nsnull == aBuffer) { - return NS_ERROR_NULL_POINTER; - } - mInner.mText.SetTo(aBuffer, aLength); - - // Trigger a reflow - if (aNotify && (nsnull != mInner.mDocument)) { - mInner.mDocument->ContentChanged(this, nsnull); - } - return NS_OK; -} - -NS_IMETHODIMP -nsTextNode::IsOnlyWhitespace(PRBool* aResult) -{ - nsTextFragment& frag = mInner.mText; - if (frag.Is2b()) { - const PRUnichar* cp = frag.Get2b(); - const PRUnichar* end = cp + frag.GetLength(); - while (cp < end) { - PRUnichar ch = *cp++; - if (!XP_IS_SPACE(ch)) { - *aResult = PR_FALSE; - return NS_OK; - } - } - } - else { - const char* cp = frag.Get1b(); - const char* end = cp + frag.GetLength(); - while (cp < end) { - PRUnichar ch = PRUnichar(*(unsigned char*)cp); - cp++; - if (!XP_IS_SPACE(ch)) { - *aResult = PR_FALSE; - return NS_OK; - } - } - } - - *aResult = PR_TRUE; - return NS_OK; -} diff --git a/content/html/content/src/nsHTMLAtoms.cpp b/content/html/content/src/nsHTMLAtoms.cpp index c3406639db9..f7a99122e82 100644 --- a/content/html/content/src/nsHTMLAtoms.cpp +++ b/content/html/content/src/nsHTMLAtoms.cpp @@ -200,6 +200,7 @@ nsIAtom* nsHTMLAtoms::param; nsIAtom* nsHTMLAtoms::placeholderPseudo; nsIAtom* nsHTMLAtoms::pointSize; nsIAtom* nsHTMLAtoms::pre; +nsIAtom* nsHTMLAtoms::processingInstructionPseudo; nsIAtom* nsHTMLAtoms::profile; nsIAtom* nsHTMLAtoms::prompt; nsIAtom* nsHTMLAtoms::readonly; @@ -457,6 +458,7 @@ void nsHTMLAtoms::AddrefAtoms() placeholderPseudo = NS_NewAtom(":placeholder-frame"); pointSize = NS_NewAtom("point-size"); pre = NS_NewAtom("pre"); + processingInstructionPseudo = NS_NewAtom(":-moz-pi"); profile = NS_NewAtom("profile"); prompt = NS_NewAtom("prompt"); readonly = NS_NewAtom("readonly"); @@ -706,6 +708,7 @@ void nsHTMLAtoms::ReleaseAtoms() NS_RELEASE(placeholderPseudo); NS_RELEASE(pointSize); NS_RELEASE(pre); + NS_RELEASE(processingInstructionPseudo); NS_RELEASE(profile); NS_RELEASE(prompt); NS_RELEASE(readonly); diff --git a/content/html/content/src/nsHTMLAtoms.h b/content/html/content/src/nsHTMLAtoms.h index a414388c166..764b1b39647 100644 --- a/content/html/content/src/nsHTMLAtoms.h +++ b/content/html/content/src/nsHTMLAtoms.h @@ -232,6 +232,7 @@ public: static nsIAtom* placeholderPseudo; static nsIAtom* pointSize; static nsIAtom* pre; + static nsIAtom* processingInstructionPseudo; static nsIAtom* profile; static nsIAtom* prompt; diff --git a/content/html/content/src/nsHTMLLIElement.cpp b/content/html/content/src/nsHTMLLIElement.cpp index d4fb72aed06..27e8e36b6fd 100644 --- a/content/html/content/src/nsHTMLLIElement.cpp +++ b/content/html/content/src/nsHTMLLIElement.cpp @@ -129,6 +129,7 @@ NS_IMPL_STRING_ATTR(nsHTMLLIElement, Type, type) NS_IMPL_INT_ATTR(nsHTMLLIElement, Value, value) static nsGenericHTMLElement::EnumTable kListItemTypeTable[] = { + { "disc", NS_STYLE_LIST_STYLE_DISC }, { "circle", NS_STYLE_LIST_STYLE_CIRCLE }, { "round", NS_STYLE_LIST_STYLE_CIRCLE }, { "square", NS_STYLE_LIST_STYLE_SQUARE }, diff --git a/content/html/document/src/nsHTMLDocument.cpp b/content/html/document/src/nsHTMLDocument.cpp index 864d6c762fd..fe6b0e44551 100644 --- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -87,59 +87,6 @@ static NS_DEFINE_IID(kIHTMLContentContainerIID, NS_IHTMLCONTENTCONTAINER_IID); static NS_DEFINE_IID(kIDOMHTMLElementIID, NS_IDOMHTMLELEMENT_IID); static NS_DEFINE_IID(kIDOMHTMLBodyElementIID, NS_IDOMHTMLBODYELEMENT_IID); -// ================================================================== -// = -// ================================================================== -class nsHTMLDocumentChildNodes : public nsGenericDOMNodeList -{ -public: - nsHTMLDocumentChildNodes(nsIDOMDocument* aDocument); - ~nsHTMLDocumentChildNodes(); - - NS_IMETHOD GetLength(PRUint32* aLength); - NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn); - -protected: - nsIDOMDocument* mDocument; -}; - -nsHTMLDocumentChildNodes::nsHTMLDocumentChildNodes(nsIDOMDocument* aDocument) -{ - mDocument = aDocument; - NS_ADDREF(mDocument); -} - -nsHTMLDocumentChildNodes::~nsHTMLDocumentChildNodes() -{ - NS_RELEASE(mDocument); -} - -NS_IMETHODIMP -nsHTMLDocumentChildNodes::GetLength(PRUint32* aLength) -{ - *aLength = 1; - return NS_OK; -} - -NS_IMETHODIMP -nsHTMLDocumentChildNodes::Item(PRUint32 aIndex, nsIDOMNode** aReturn) -{ - nsresult result = NS_OK; - if (0 == aIndex) { - nsIDOMElement* root; - - result = mDocument->GetDocumentElement(&root); - if (NS_OK == result) { - result = root->QueryInterface(kIDOMNodeIID, (void**)aReturn); - NS_RELEASE(root); - } - } - else { - *aReturn = nsnull; - } - - return result; -} // ================================================================== // = @@ -840,36 +787,19 @@ nsHTMLDocument::GetElementsByTagName(const nsString& aTagname, nsIDOMNodeList** NS_IMETHODIMP nsHTMLDocument::GetChildNodes(nsIDOMNodeList** aChildNodes) { - nsHTMLDocumentChildNodes* childNodes = new nsHTMLDocumentChildNodes((nsIDOMDocument*)(nsIDOMHTMLDocument*)this); - if (nsnull == childNodes) { - return NS_ERROR_OUT_OF_MEMORY; - } - - return childNodes->QueryInterface(kIDOMNodeListIID, (void**)aChildNodes); + return nsDocument::GetChildNodes(aChildNodes); } NS_IMETHODIMP nsHTMLDocument::GetFirstChild(nsIDOMNode** aFirstChild) { - if (nsnull != mRootContent) { - return mRootContent->QueryInterface(kIDOMNodeIID, (void**)aFirstChild); - } - else { - *aFirstChild = nsnull; - return NS_OK; - } + return nsDocument::GetFirstChild(aFirstChild); } NS_IMETHODIMP nsHTMLDocument::GetLastChild(nsIDOMNode** aLastChild) { - if (nsnull != mRootContent) { - return mRootContent->QueryInterface(kIDOMNodeIID, (void**)aLastChild); - } - else { - *aLastChild = nsnull; - return NS_OK; - } + return nsDocument::GetLastChild(aLastChild); } NS_IMETHODIMP @@ -877,8 +807,7 @@ nsHTMLDocument::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aReturn) { - *aReturn = nsnull; - return NS_OK; + return nsDocument::InsertBefore(aNewChild, aRefChild, aReturn); } NS_IMETHODIMP @@ -886,29 +815,25 @@ nsHTMLDocument::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aReturn) { - *aReturn = nsnull; - return NS_OK; + return nsDocument::ReplaceChild(aNewChild, aOldChild, aReturn); } NS_IMETHODIMP nsHTMLDocument::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) { - *aReturn = nsnull; - return NS_OK; + return nsDocument::RemoveChild(aOldChild, aReturn); } NS_IMETHODIMP nsHTMLDocument::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn) { - *aReturn = nsnull; - return NS_OK; + return nsDocument::AppendChild(aNewChild, aReturn); } NS_IMETHODIMP nsHTMLDocument::HasChildNodes(PRBool* aReturn) { - *aReturn = PR_TRUE; - return NS_OK; + return nsDocument::HasChildNodes(aReturn); } NS_IMETHODIMP diff --git a/content/html/style/src/nsCSSStyleSheet.cpp b/content/html/style/src/nsCSSStyleSheet.cpp index 6e30e4cbde9..689f48d24da 100644 --- a/content/html/style/src/nsCSSStyleSheet.cpp +++ b/content/html/style/src/nsCSSStyleSheet.cpp @@ -1068,7 +1068,8 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext, nsIAtom* tag; firstChild->GetTag(tag); if ((tag != nsLayoutAtoms::textTagName) && - (tag != nsLayoutAtoms::commentTagName)) { + (tag != nsLayoutAtoms::commentTagName) && + (tag != nsLayoutAtoms::processingInstructionTagName)) { NS_IF_RELEASE(tag); break; } diff --git a/content/shared/public/nsHTMLAtoms.h b/content/shared/public/nsHTMLAtoms.h index a414388c166..764b1b39647 100644 --- a/content/shared/public/nsHTMLAtoms.h +++ b/content/shared/public/nsHTMLAtoms.h @@ -232,6 +232,7 @@ public: static nsIAtom* placeholderPseudo; static nsIAtom* pointSize; static nsIAtom* pre; + static nsIAtom* processingInstructionPseudo; static nsIAtom* profile; static nsIAtom* prompt; diff --git a/content/shared/public/nsLayoutAtoms.h b/content/shared/public/nsLayoutAtoms.h index 4abb0486bd6..8315904eb5a 100644 --- a/content/shared/public/nsLayoutAtoms.h +++ b/content/shared/public/nsLayoutAtoms.h @@ -60,6 +60,7 @@ public: // Alphabetical list of pseudo tag names for non-element content static nsIAtom* commentTagName; static nsIAtom* textTagName; + static nsIAtom* processingInstructionTagName; static nsIAtom* viewportPseudo; static nsIAtom* pagePseudo; diff --git a/content/shared/src/nsHTMLAtoms.cpp b/content/shared/src/nsHTMLAtoms.cpp index c3406639db9..f7a99122e82 100644 --- a/content/shared/src/nsHTMLAtoms.cpp +++ b/content/shared/src/nsHTMLAtoms.cpp @@ -200,6 +200,7 @@ nsIAtom* nsHTMLAtoms::param; nsIAtom* nsHTMLAtoms::placeholderPseudo; nsIAtom* nsHTMLAtoms::pointSize; nsIAtom* nsHTMLAtoms::pre; +nsIAtom* nsHTMLAtoms::processingInstructionPseudo; nsIAtom* nsHTMLAtoms::profile; nsIAtom* nsHTMLAtoms::prompt; nsIAtom* nsHTMLAtoms::readonly; @@ -457,6 +458,7 @@ void nsHTMLAtoms::AddrefAtoms() placeholderPseudo = NS_NewAtom(":placeholder-frame"); pointSize = NS_NewAtom("point-size"); pre = NS_NewAtom("pre"); + processingInstructionPseudo = NS_NewAtom(":-moz-pi"); profile = NS_NewAtom("profile"); prompt = NS_NewAtom("prompt"); readonly = NS_NewAtom("readonly"); @@ -706,6 +708,7 @@ void nsHTMLAtoms::ReleaseAtoms() NS_RELEASE(placeholderPseudo); NS_RELEASE(pointSize); NS_RELEASE(pre); + NS_RELEASE(processingInstructionPseudo); NS_RELEASE(profile); NS_RELEASE(prompt); NS_RELEASE(readonly); diff --git a/content/shared/src/nsLayoutAtoms.cpp b/content/shared/src/nsLayoutAtoms.cpp index d8b77d55cad..3528d6c0a75 100644 --- a/content/shared/src/nsLayoutAtoms.cpp +++ b/content/shared/src/nsLayoutAtoms.cpp @@ -46,6 +46,7 @@ nsIAtom* nsLayoutAtoms::floaterList; // pseudo tag names for non-element content nsIAtom* nsLayoutAtoms::commentTagName; nsIAtom* nsLayoutAtoms::textTagName; +nsIAtom* nsLayoutAtoms::processingInstructionTagName; nsIAtom* nsLayoutAtoms::viewportPseudo; nsIAtom* nsLayoutAtoms::pagePseudo; @@ -90,6 +91,7 @@ void nsLayoutAtoms::AddrefAtoms() commentTagName = NS_NewAtom("__moz_comment"); textTagName = NS_NewAtom("__moz_text"); + processingInstructionTagName = NS_NewAtom("__moz_pi"); viewportPseudo = NS_NewAtom(":-moz-viewport"); pagePseudo = NS_NewAtom(":-moz-page"); @@ -135,6 +137,7 @@ void nsLayoutAtoms::ReleaseAtoms() NS_RELEASE(commentTagName); NS_RELEASE(textTagName); + NS_RELEASE(processingInstructionTagName); NS_RELEASE(viewportPseudo); NS_RELEASE(pagePseudo); diff --git a/content/xml/content/public/nsIXMLContent.h b/content/xml/content/public/nsIXMLContent.h index 2d9f3a92ebd..789e3ec0d21 100644 --- a/content/xml/content/public/nsIXMLContent.h +++ b/content/xml/content/public/nsIXMLContent.h @@ -46,4 +46,13 @@ public: extern nsresult NS_NewXMLElement(nsIXMLContent** aResult, nsIAtom* aTag); +// XXX These belongs elsewhere +extern nsresult +NS_NewXMLProcessingInstruction(nsIContent** aInstancePtrResult, + const nsString& aTarget, + const nsString& aData); + +extern nsresult +NS_NewXMLCDATASection(nsIContent** aInstancePtrResult); + #endif // nsIXMLContent_h___ diff --git a/content/xml/content/src/Makefile.in b/content/xml/content/src/Makefile.in index 211613a0c71..11f2f7286be 100644 --- a/content/xml/content/src/Makefile.in +++ b/content/xml/content/src/Makefile.in @@ -40,6 +40,8 @@ INCLUDES += \ CPPSRCS = \ nsXMLElement.cpp \ nsGenericXMLElement.cpp \ + nsXMLCDATASection.cpp \ + nsXMLProcessingInstruction.cpp \ $(NULL) EXPORTS = \ diff --git a/content/xml/content/src/makefile.win b/content/xml/content/src/makefile.win index 2bc0c041c61..3e2aa193ae6 100644 --- a/content/xml/content/src/makefile.win +++ b/content/xml/content/src/makefile.win @@ -26,11 +26,15 @@ DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN CPPSRCS= \ nsXMLElement.cpp \ nsGenericXMLElement.cpp \ + nsXMLCDATASection.cpp \ + nsXMLProcessingInstruction.cpp \ $(NULL) CPP_OBJS= \ .\$(OBJDIR)\nsXMLElement.obj \ .\$(OBJDIR)\nsGenericXMLElement.obj \ + .\$(OBJDIR)\nsXMLCDATASection.obj \ + .\$(OBJDIR)\nsXMLProcessingInstruction.obj \ $(NULL) EXPORTS = \ diff --git a/content/xml/content/src/nsXMLCDATASection.cpp b/content/xml/content/src/nsXMLCDATASection.cpp new file mode 100644 index 00000000000..c785a57c17b --- /dev/null +++ b/content/xml/content/src/nsXMLCDATASection.cpp @@ -0,0 +1,195 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + +#include "nsIDOMCDATASection.h" +#include "nsIScriptObjectOwner.h" +#include "nsIDOMEventReceiver.h" +#include "nsIContent.h" +#include "nsITextContent.h" +#include "nsGenericDOMDataNode.h" +#include "nsFrame.h" +#include "nsIDocument.h" +#include "nsCRT.h" +#include "nsLayoutAtoms.h" +#include "nsIXMLContent.h" + +static NS_DEFINE_IID(kIDOMCDATASectionIID, NS_IDOMCDATASECTION_IID); +static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID); +static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID); + +class nsXMLCDATASection : public nsIDOMCDATASection, + public nsIScriptObjectOwner, + public nsIDOMEventReceiver, + public nsIContent, + public nsITextContent +{ +public: + nsXMLCDATASection(); + virtual ~nsXMLCDATASection(); + + // nsISupports + NS_DECL_ISUPPORTS + + // nsIDOMNode + NS_IMPL_IDOMNODE_USING_GENERIC_DOM_DATA(mInner) + + // nsIDOMCharacterData + NS_IMPL_IDOMCHARACTERDATA_USING_GENERIC_DOM_DATA(mInner) + + // nsIDOMText + NS_IMPL_IDOMTEXT_USING_GENERIC_DOM_DATA(mInner) + + // nsIScriptObjectOwner + NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC_DOM_DATA(mInner) + + // nsIDOMEventReceiver + NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC_DOM_DATA(mInner) + + // nsIContent + NS_IMPL_ICONTENT_USING_GENERIC_DOM_DATA(mInner) + + // nsITextContent + NS_IMPL_ITEXTCONTENT_USING_GENERIC_DOM_DATA(mInner) + +protected: + nsGenericDOMDataNode mInner; +}; + +nsresult +NS_NewXMLCDATASection(nsIContent** aInstancePtrResult) +{ + NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); + if (nsnull == aInstancePtrResult) { + return NS_ERROR_NULL_POINTER; + } + nsIContent* it = new nsXMLCDATASection(); + if (nsnull == it) { + return NS_ERROR_OUT_OF_MEMORY; + } + return it->QueryInterface(kIContentIID, (void **) aInstancePtrResult); +} + +nsXMLCDATASection::nsXMLCDATASection() +{ + NS_INIT_REFCNT(); + mInner.Init(this); +} + +nsXMLCDATASection::~nsXMLCDATASection() +{ +} + +NS_IMPL_ADDREF(nsXMLCDATASection) +NS_IMPL_RELEASE(nsXMLCDATASection) + +NS_IMETHODIMP +nsXMLCDATASection::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + NS_IMPL_DOM_DATA_QUERY_INTERFACE(aIID, aInstancePtr, this) + if (aIID.Equals(kIDOMCDATASectionIID)) { + nsIDOMCDATASection* tmp = this; + *aInstancePtr = (void*) tmp; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(kIDOMTextIID)) { + nsIDOMText* tmp = this; + *aInstancePtr = (void*) tmp; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(kITextContentIID)) { + nsITextContent* tmp = this; + *aInstancePtr = (void*) tmp; + NS_ADDREF_THIS(); + return NS_OK; + } + return NS_NOINTERFACE; +} + +NS_IMETHODIMP +nsXMLCDATASection::GetTag(nsIAtom*& aResult) const +{ + aResult = nsLayoutAtoms::textTagName; + NS_ADDREF(aResult); + return NS_OK; +} + +NS_IMETHODIMP +nsXMLCDATASection::GetNodeName(nsString& aNodeName) +{ + aNodeName.SetString("#cdata-section"); + return NS_OK; +} + +NS_IMETHODIMP +nsXMLCDATASection::GetNodeType(PRUint16* aNodeType) +{ + *aNodeType = (PRUint16)nsIDOMNode::CDATA_SECTION_NODE; + return NS_OK; +} + +NS_IMETHODIMP +nsXMLCDATASection::CloneNode(PRBool aDeep, nsIDOMNode** aReturn) +{ + nsXMLCDATASection* it; + NS_NEWXPCOM(it, nsXMLCDATASection); + if (nsnull == it) { + return NS_ERROR_OUT_OF_MEMORY; + } + nsAutoString data; + nsresult result = GetData(data); + if (NS_FAILED(result)) { + return result; + } + result = it->SetData(data); + if (NS_FAILED(result)) { + return result; + } + return it->QueryInterface(kIDOMNodeIID, (void**) aReturn); +} + +NS_IMETHODIMP +nsXMLCDATASection::List(FILE* out, PRInt32 aIndent) const +{ + NS_PRECONDITION(nsnull != mInner.mDocument, "bad content"); + + PRInt32 index; + for (index = aIndent; --index >= 0; ) fputs(" ", out); + + fprintf(out, "CDATASection refcount=%d<", mRefCnt); + + nsAutoString tmp; + mInner.ToCString(tmp, 0, mInner.mText.GetLength()); + fputs(tmp, out); + + fputs(">\n", out); + return NS_OK; +} + +NS_IMETHODIMP +nsXMLCDATASection::HandleDOMEvent(nsIPresContext& aPresContext, + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, + nsEventStatus& aEventStatus) +{ + return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent, + aFlags, aEventStatus); +} diff --git a/content/xml/content/src/nsXMLProcessingInstruction.cpp b/content/xml/content/src/nsXMLProcessingInstruction.cpp new file mode 100644 index 00000000000..c9e5837d449 --- /dev/null +++ b/content/xml/content/src/nsXMLProcessingInstruction.cpp @@ -0,0 +1,275 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + + +#include "nsIDOMProcessingInstruction.h" +#include "nsIScriptObjectOwner.h" +#include "nsIDOMEventReceiver.h" +#include "nsIContent.h" +#include "nsGenericDOMDataNode.h" +#include "nsGenericElement.h" +#include "nsIDOMScriptObjectFactory.h" +#include "nsLayoutAtoms.h" +#include "nsString.h" +#include "nsIXMLContent.h" + +static NS_DEFINE_IID(kIDOMProcessingInstructionIID, NS_IDOMPROCESSINGINSTRUCTION_IID); + +class nsXMLProcessingInstruction : public nsIDOMProcessingInstruction, + public nsIScriptObjectOwner, + public nsIDOMEventReceiver, + public nsIContent +{ +public: + nsXMLProcessingInstruction(const nsString& aTarget, const nsString& aData); + virtual ~nsXMLProcessingInstruction(); + + // nsISupports + NS_DECL_ISUPPORTS + + // nsIDOMNode + NS_IMPL_IDOMNODE_USING_GENERIC_DOM_DATA(mInner) + + // nsIDOMProcessingInstruction + NS_IMETHOD GetTarget(nsString& aTarget); + NS_IMETHOD GetData(nsString& aData); + NS_IMETHOD SetData(const nsString& aData); + + // nsIScriptObjectOwner interface + NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject); + NS_IMETHOD SetScriptObject(void *aScriptObject); + + // nsIDOMEventReceiver + NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC_DOM_DATA(mInner) + + // nsIContent + NS_IMPL_ICONTENT_USING_GENERIC_DOM_DATA(mInner) + +protected: + // XXX Processing instructions are currently implemented by using + // the generic CharacterData inner object, even though PIs are not + // character data. This is done simply for convenience and should + // be changed if this restricts what should be done for character data. + nsGenericDOMDataNode mInner; + nsString mTarget; + void* mScriptObject; +}; + +nsresult +NS_NewXMLProcessingInstruction(nsIContent** aInstancePtrResult, + const nsString& aTarget, + const nsString& aData) +{ + NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); + if (nsnull == aInstancePtrResult) { + return NS_ERROR_NULL_POINTER; + } + nsIContent* it = new nsXMLProcessingInstruction(aTarget, aData); + if (nsnull == it) { + return NS_ERROR_OUT_OF_MEMORY; + } + return it->QueryInterface(kIContentIID, (void **) aInstancePtrResult); +} + +nsXMLProcessingInstruction::nsXMLProcessingInstruction(const nsString& aTarget, + const nsString& aData) : + mTarget(aTarget) +{ + NS_INIT_REFCNT(); + mInner.Init(this); + mInner.SetData(aData); + mScriptObject = nsnull; +} + +nsXMLProcessingInstruction::~nsXMLProcessingInstruction() +{ +} + +NS_IMPL_ADDREF(nsXMLProcessingInstruction) +NS_IMPL_RELEASE(nsXMLProcessingInstruction) + +nsresult +nsXMLProcessingInstruction::QueryInterface(REFNSIID aIID, void** aInstancePtrResult) +{ + if (NULL == aInstancePtrResult) { + return NS_ERROR_NULL_POINTER; + } + + if (aIID.Equals(kISupportsIID)) { + nsIDOMProcessingInstruction* tmp = this; + nsISupports* tmp2 = tmp; + *aInstancePtrResult = (void*) tmp2; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(kIDOMNodeIID)) { + nsIDOMNode* tmp = this; + *aInstancePtrResult = (void*) tmp; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(kIDOMEventReceiverIID)) { + nsIDOMEventReceiver* tmp = this; + *aInstancePtrResult = (void*) tmp; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(kIScriptObjectOwnerIID)) { + nsIScriptObjectOwner* tmp = this; + *aInstancePtrResult = (void*) tmp; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(kIContentIID)) { + nsIContent* tmp = this; + *aInstancePtrResult = (void*) tmp; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(kIDOMProcessingInstructionIID)) { + nsIDOMProcessingInstruction* tmp = this; + *aInstancePtrResult = (void*) tmp; + NS_ADDREF_THIS(); + return NS_OK; + } + return NS_NOINTERFACE; +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::GetTarget(nsString& aTarget) +{ + aTarget.SetString(mTarget); + + return NS_OK; +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::GetData(nsString& aData) +{ + return mInner.GetData(aData); +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::SetData(const nsString& aData) +{ + // XXX Check if this is a stylesheet PI. If so, we may need + // to parse the contents and see if anything has changed. + return mInner.SetData(aData); +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::GetScriptObject(nsIScriptContext* aContext, + void** aScriptObject) +{ + nsresult res = NS_OK; + if (nsnull == mScriptObject) { + nsIDOMScriptObjectFactory *factory; + + res = nsGenericElement::GetScriptObjectFactory(&factory); + if (NS_OK != res) { + return res; + } + + res = factory->NewScriptProcessingInstruction(aContext, + (nsISupports*)(nsIDOMProcessingInstruction*)this, + mInner.mParent, + (void**)&mScriptObject); + + NS_RELEASE(factory); + } + *aScriptObject = mScriptObject; + return res; +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::SetScriptObject(void *aScriptObject) +{ + mScriptObject = aScriptObject; + return NS_OK; +} + + +NS_IMETHODIMP +nsXMLProcessingInstruction::GetTag(nsIAtom*& aResult) const +{ + aResult = nsLayoutAtoms::processingInstructionTagName; + NS_ADDREF(aResult); + return NS_OK; +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::GetNodeName(nsString& aNodeName) +{ + aNodeName.SetString(mTarget); + return NS_OK; +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::GetNodeType(PRUint16* aNodeType) +{ + *aNodeType = (PRUint16)nsIDOMNode::PROCESSING_INSTRUCTION_NODE; + return NS_OK; +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::CloneNode(PRBool aDeep, nsIDOMNode** aReturn) +{ + nsString data; + mInner.GetData(data); + + nsXMLProcessingInstruction* it = new nsXMLProcessingInstruction(mTarget, + data); + if (nsnull == it) { + return NS_ERROR_OUT_OF_MEMORY; + } + return it->QueryInterface(kIDOMNodeIID, (void**) aReturn); +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::List(FILE* out, PRInt32 aIndent) const +{ + NS_PRECONDITION(nsnull != mInner.mDocument, "bad content"); + + PRInt32 index; + for (index = aIndent; --index >= 0; ) fputs(" ", out); + + fprintf(out, "Processing instruction refcount=%d<", mRefCnt); + + nsAutoString tmp; + mInner.ToCString(tmp, 0, mInner.mText.GetLength()); + tmp.Insert(mTarget, 0); + fputs(tmp, out); + + fputs(">\n", out); + return NS_OK; +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::HandleDOMEvent(nsIPresContext& aPresContext, + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, + nsEventStatus& aEventStatus) +{ + // We should never be getting events + NS_ASSERTION(0, "event handler called for processing instruction"); + return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent, + aFlags, aEventStatus); +} + diff --git a/content/xml/document/public/nsIXMLDocument.h b/content/xml/document/public/nsIXMLDocument.h index c3ecce7b9d2..cca3881af90 100644 --- a/content/xml/document/public/nsIXMLDocument.h +++ b/content/xml/document/public/nsIXMLDocument.h @@ -34,14 +34,6 @@ class nsIAtom; */ class nsIXMLDocument : public nsISupports { public: - NS_IMETHOD PrologElementAt(PRUint32 aOffset, nsIContent** aContent)=0; - NS_IMETHOD PrologCount(PRUint32* aCount)=0; - NS_IMETHOD AppendToProlog(nsIContent* aContent)=0; - - NS_IMETHOD EpilogElementAt(PRUint32 aOffset, nsIContent** aContent)=0; - NS_IMETHOD EpilogCount(PRUint32* aCount)=0; - NS_IMETHOD AppendToEpilog(nsIContent* aContent)=0; - // XXX This (or a variant thereof) should be in a DOM interface. // Since it isn't, we add it here temporarily NS_IMETHOD GetContentById(const nsString& aName, nsIContent** aContent)=0; diff --git a/content/xml/document/src/nsXMLContentSink.cpp b/content/xml/document/src/nsXMLContentSink.cpp index 65613d9a293..cffd4a22bbb 100644 --- a/content/xml/document/src/nsXMLContentSink.cpp +++ b/content/xml/document/src/nsXMLContentSink.cpp @@ -34,6 +34,7 @@ #include "nsIPresShell.h" #include "nsIViewManager.h" #include "nsIDOMComment.h" +#include "nsIDOMCDATASection.h" #include "nsIHTMLContent.h" #include "nsHTMLEntities.h" #include "nsHTMLParts.h" @@ -56,7 +57,7 @@ static char kNameSpaceSeparator[] = ":"; static char kNameSpaceDef[] = "xmlns"; -static char kStyleSheetPI[] = "QueryInterface(kIXMLDocumentIID, - (void **)&xmlDoc); + nsresult result = NS_OK; if (eXMLContentSinkState_InProlog == mState) { - result = xmlDoc->AppendToProlog(aContent); + result = mDocument->AppendToProlog(aContent); } else if (eXMLContentSinkState_InEpilog == mState) { - result = xmlDoc->AppendToEpilog(aContent); + result = mDocument->AppendToEpilog(aContent); } else { nsIContent *parent = GetCurrentContent(); @@ -872,7 +875,6 @@ nsXMLContentSink::AddContentAsLeaf(nsIContent *aContent) } } - NS_RELEASE(xmlDoc); return result; } @@ -903,6 +905,33 @@ nsXMLContentSink::AddComment(const nsIParserNode& aNode) return result; } +NS_IMETHODIMP +nsXMLContentSink::AddCDATASection(const nsIParserNode& aNode) +{ + FlushText(); + + nsAutoString text; + nsIContent *cdata; + nsIDOMCDATASection *domCDATA; + nsresult result = NS_OK; + + text = aNode.GetText(); + result = NS_NewXMLCDATASection(&cdata); + if (NS_OK == result) { + result = cdata->QueryInterface(kIDOMCDATASectionIID, (void **)&domCDATA); + if (NS_OK == result) { + domCDATA->AppendData(text); + NS_RELEASE(domCDATA); + + cdata->SetDocument(mDocument, PR_FALSE); + result = AddContentAsLeaf(cdata); + } + NS_RELEASE(cdata); + } + + return result; +} + // XXX Borrowed from HTMLContentSink. Should be shared. NS_IMETHODIMP nsXMLContentSink::LoadStyleSheet(nsIURL* aURL, @@ -1088,87 +1117,111 @@ nsXMLContentSink::LoadXSLStyleSheet(const nsIURL* aUrl) } #endif +static void +ParseProcessingInstruction(const nsString& aText, + nsString& aTarget, + nsString& aData) +{ + PRInt32 offset; + + aTarget.Truncate(); + aData.Truncate(); + + offset = aText.FindCharInSet(" \n\r\t"); + if (-1 != offset) { + aText.Mid(aTarget, 2, offset-2); + aText.Mid(aData, offset+1, aText.Length()-offset-3); + } +} + #ifndef XSL NS_IMETHODIMP nsXMLContentSink::AddProcessingInstruction(const nsIParserNode& aNode) { + nsresult result = NS_OK; + nsAutoString text, target, data; + nsIContent* node; + FlushText(); - // XXX For now, we don't add the PI to the content model. - // We just check for a style sheet PI - nsAutoString text, type, href, title, media; - PRInt32 offset; - nsresult result = NS_OK; - text = aNode.GetText(); + ParseProcessingInstruction(text, target, data); + result = NS_NewXMLProcessingInstruction(&node, target, data); + if (NS_OK == result) { + node->SetDocument(mDocument, PR_FALSE); + result = AddContentAsLeaf(node); + } - offset = text.Find(kStyleSheetPI); - // If it's a stylesheet PI... - if (0 == offset) { - result = GetQuotedAttributeValue(text, "href", href); - // If there was an error or there's no href, we can't do - // anything with this PI - if ((NS_OK != result) || (0 == href.Length())) { - return result; - } + if (NS_OK == result) { + nsAutoString type, href, title, media; - result = GetQuotedAttributeValue(text, "type", type); - if (NS_OK != result) { - return result; - } - result = GetQuotedAttributeValue(text, "title", title); - if (NS_OK != result) { - return result; - } - title.CompressWhitespace(); - result = GetQuotedAttributeValue(text, "media", media); - if (NS_OK != result) { - return result; - } - - if (type.Equals(kCSSType)) { - // Use the SRC attribute value to load the URL - nsIURL* url = nsnull; - nsAutoString absURL; - nsIURL* docURL = mDocument->GetDocumentURL(); - nsIURLGroup* urlGroup; + // If it's a stylesheet PI... + if (target.EqualsIgnoreCase(kStyleSheetPI)) { + result = GetQuotedAttributeValue(text, "href", href); + // If there was an error or there's no href, we can't do + // anything with this PI + if ((NS_OK != result) || (0 == href.Length())) { + return result; + } - result = docURL->GetURLGroup(&urlGroup); - - if ((NS_OK == result) && urlGroup) { - result = urlGroup->CreateURL(&url, docURL, href, nsnull); - NS_RELEASE(urlGroup); - } - else { - result = NS_NewURL(&url, absURL); - } - NS_RELEASE(docURL); + result = GetQuotedAttributeValue(text, "type", type); if (NS_OK != result) { return result; } - - nsAsyncStyleProcessingDataXML* d = new nsAsyncStyleProcessingDataXML; - if (nsnull == d) { - return NS_ERROR_OUT_OF_MEMORY; + result = GetQuotedAttributeValue(text, "title", title); + if (NS_OK != result) { + return result; } - d->mTitle.SetString(title); - d->mMedia.SetString(media); - d->mIsActive = PR_TRUE; - d->mURL = url; - NS_ADDREF(url); - // XXX Need to create PI node - d->mElement = nsnull; - d->mSink = this; - NS_ADDREF(this); - - nsIUnicharStreamLoader* loader; - result = NS_NewUnicharStreamLoader(&loader, - url, - (nsStreamCompleteFunc)nsDoneLoadingStyle, - (void *)d); - NS_RELEASE(url); - if (NS_OK == result) { - result = NS_ERROR_HTMLPARSER_BLOCK; + title.CompressWhitespace(); + result = GetQuotedAttributeValue(text, "media", media); + if (NS_OK != result) { + return result; + } + + if (type.Equals(kCSSType)) { + // Use the SRC attribute value to load the URL + nsIURL* url = nsnull; + nsAutoString absURL; + nsIURL* docURL = mDocument->GetDocumentURL(); + nsIURLGroup* urlGroup; + + result = docURL->GetURLGroup(&urlGroup); + + if ((NS_OK == result) && urlGroup) { + result = urlGroup->CreateURL(&url, docURL, href, nsnull); + NS_RELEASE(urlGroup); + } + else { + result = NS_NewURL(&url, absURL); + } + NS_RELEASE(docURL); + if (NS_OK != result) { + return result; + } + + nsAsyncStyleProcessingDataXML* d = new nsAsyncStyleProcessingDataXML; + if (nsnull == d) { + return NS_ERROR_OUT_OF_MEMORY; + } + d->mTitle.SetString(title); + d->mMedia.SetString(media); + d->mIsActive = PR_TRUE; + d->mURL = url; + NS_ADDREF(url); + // XXX Need to create PI node + d->mElement = nsnull; + d->mSink = this; + NS_ADDREF(this); + + nsIUnicharStreamLoader* loader; + result = NS_NewUnicharStreamLoader(&loader, + url, + (nsStreamCompleteFunc)nsDoneLoadingStyle, + (void *)d); + NS_RELEASE(url); + if (NS_OK == result) { + result = NS_ERROR_HTMLPARSER_BLOCK; + } } } } diff --git a/content/xml/document/src/nsXMLContentSink.h b/content/xml/document/src/nsXMLContentSink.h index ee2c0f97655..a67a14ea4a9 100644 --- a/content/xml/document/src/nsXMLContentSink.h +++ b/content/xml/document/src/nsXMLContentSink.h @@ -73,6 +73,7 @@ public: NS_IMETHOD AddLeaf(const nsIParserNode& aNode); NS_IMETHOD AddComment(const nsIParserNode& aNode); NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode); + NS_IMETHOD AddCDATASection(const nsIParserNode& aNode); NS_IMETHOD NotifyError(const nsParserError* aError); // nsIXMLContentSink diff --git a/content/xml/document/src/nsXMLDocument.cpp b/content/xml/document/src/nsXMLDocument.cpp index 7493cdc0653..867183c32ae 100644 --- a/content/xml/document/src/nsXMLDocument.cpp +++ b/content/xml/document/src/nsXMLDocument.cpp @@ -38,6 +38,8 @@ #include "nsIDOMComment.h" #include "nsIDOMElement.h" #include "nsIDOMText.h" +#include "nsIDOMCDATASection.h" +#include "nsIDOMProcessingInstruction.h" #include "nsExpatDTD.h" #include "nsINameSpaceManager.h" @@ -57,87 +59,10 @@ 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); +static NS_DEFINE_IID(kIDOMProcessingInstructionIID, NS_IDOMPROCESSINGINSTRUCTION_IID); +static NS_DEFINE_IID(kIDOMCDATASectionIID, NS_IDOMCDATASECTION_IID); +static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_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; - - 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; -} // ================================================================== // = @@ -155,9 +80,6 @@ nsXMLDocument::nsXMLDocument() mParser = nsnull; mAttrStyleSheet = nsnull; mInlineStyleSheet = nsnull; - mProlog = nsnull; - mEpilog = nsnull; - mChildNodes = nsnull; // XXX The XML world depends on the html atoms nsHTMLAtoms::AddrefAtoms(); @@ -169,8 +91,6 @@ nsXMLDocument::nsXMLDocument() nsXMLDocument::~nsXMLDocument() { - PRInt32 i, count; - nsIContent* content; NS_IF_RELEASE(mParser); if (nsnull != mAttrStyleSheet) { mAttrStyleSheet->SetOwningDocument(nsnull); @@ -180,23 +100,6 @@ nsXMLDocument::~nsXMLDocument() mInlineStyleSheet->SetOwningDocument(nsnull); 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) { - count = mEpilog->Count(); - for (i = 0; i < count; i++) { - content = (nsIContent*)mEpilog->ElementAt(i); - NS_RELEASE(content); - } - delete mEpilog; - } - NS_IF_RELEASE(mChildNodes); #ifdef INCLUDE_XUL nsXULAtoms::ReleaseAtoms(); #endif @@ -377,111 +280,6 @@ void nsXMLDocument::InternalAddStyleSheet(nsIStyleSheet* aSheet) // subclass ho } } - -// 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) @@ -494,25 +292,41 @@ nsXMLDocument::GetDoctype(nsIDOMDocumentType** aDocumentType) NS_IMETHODIMP nsXMLDocument::CreateCDATASection(const nsString& aData, nsIDOMCDATASection** aReturn) { - // XXX TBI - *aReturn = nsnull; - return NS_ERROR_NOT_IMPLEMENTED; + nsIContent* content; + nsresult rv = NS_NewXMLCDATASection(&content); + + if (NS_OK == rv) { + rv = content->QueryInterface(kIDOMCDATASectionIID, (void**)aReturn); + (*aReturn)->AppendData(aData); + NS_RELEASE(content); + } + + return rv; } NS_IMETHODIMP nsXMLDocument::CreateEntityReference(const nsString& aName, nsIDOMEntityReference** aReturn) { - // XXX TBI *aReturn = nsnull; - return NS_ERROR_NOT_IMPLEMENTED; + return NS_OK; } NS_IMETHODIMP -nsXMLDocument::CreateProcessingInstruction(const nsString& aTarget, const nsString& aData, nsIDOMProcessingInstruction** aReturn) +nsXMLDocument::CreateProcessingInstruction(const nsString& aTarget, + const nsString& aData, + nsIDOMProcessingInstruction** aReturn) { - // XXX TBI - *aReturn = nsnull; - return NS_ERROR_NOT_IMPLEMENTED; + nsIContent* content; + nsresult rv = NS_NewXMLProcessingInstruction(&content, aTarget, aData); + + if (NS_OK != rv) { + return rv; + } + + rv = content->QueryInterface(kIDOMProcessingInstructionIID, (void**)aReturn); + NS_RELEASE(content); + + return rv; } static char kNameSpaceSeparator[] = ":"; @@ -530,7 +344,8 @@ nsXMLDocument::CreateElement(const nsString& aTagName, return rv; } rv = content->QueryInterface(kIDOMElementIID, (void**)aReturn); - + NS_RELEASE(content); + return rv; } @@ -576,86 +391,6 @@ nsXMLDocument::CreateElementWithNameSpace(const nsString& aTagName, // nsIXMLDocument interface -NS_IMETHODIMP -nsXMLDocument::PrologElementAt(PRUint32 aIndex, nsIContent** aContent) -{ - if (nsnull == mProlog) { - *aContent = nsnull; - } - else { - *aContent = (nsIContent *)mProlog->ElementAt((PRInt32)aIndex); - NS_ADDREF(*aContent); - } - - return NS_OK; -} - -NS_IMETHODIMP -nsXMLDocument::PrologCount(PRUint32* aCount) -{ - if (nsnull == mProlog) { - *aCount = 0; - } - else { - *aCount = (PRUint32)mProlog->Count(); - } - - return NS_OK; -} - -NS_IMETHODIMP -nsXMLDocument::AppendToProlog(nsIContent* aContent) -{ - if (nsnull == mProlog) { - mProlog = new nsVoidArray(); - } - - mProlog->AppendElement((void *)aContent); - NS_ADDREF(aContent); - - return NS_OK; -} - -NS_IMETHODIMP -nsXMLDocument::EpilogElementAt(PRUint32 aIndex, nsIContent** aContent) -{ - if (nsnull == mEpilog) { - *aContent = nsnull; - } - else { - *aContent = (nsIContent *)mEpilog->ElementAt((PRInt32)aIndex); - NS_ADDREF(*aContent); - } - - return NS_OK; -} - -NS_IMETHODIMP -nsXMLDocument::EpilogCount(PRUint32* aCount) -{ - if (nsnull == mEpilog) { - *aCount = 0; - } - else { - *aCount = (PRUint32)mEpilog->Count(); - } - - return NS_OK; -} - -NS_IMETHODIMP -nsXMLDocument::AppendToEpilog(nsIContent* aContent) -{ - if (nsnull == mEpilog) { - mEpilog = new nsVoidArray(); - } - - mEpilog->AppendElement((void *)aContent); - NS_ADDREF(aContent); - - return NS_OK; -} - static nsIContent * MatchName(nsIContent *aContent, const nsString& aName) { diff --git a/content/xml/document/src/nsXMLDocument.h b/content/xml/document/src/nsXMLDocument.h index 2262f896b6b..074e92d3449 100644 --- a/content/xml/document/src/nsXMLDocument.h +++ b/content/xml/document/src/nsXMLDocument.h @@ -23,28 +23,9 @@ #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, @@ -67,20 +48,6 @@ 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); @@ -93,14 +60,6 @@ public: nsIDOMElement** aReturn); // nsIXMLDocument interface - NS_IMETHOD PrologElementAt(PRUint32 aOffset, nsIContent** aContent); - NS_IMETHOD PrologCount(PRUint32* aCount); - NS_IMETHOD AppendToProlog(nsIContent* aContent); - - NS_IMETHOD EpilogElementAt(PRUint32 aOffset, nsIContent** aContent); - NS_IMETHOD EpilogCount(PRUint32* aCount); - NS_IMETHOD AppendToEpilog(nsIContent* aContent); - NS_IMETHOD GetContentById(const nsString& aName, nsIContent** aContent); // nsIHTMLContentContainer @@ -111,16 +70,11 @@ protected: virtual void InternalAddStyleSheet(nsIStyleSheet* aSheet); // subclass hook for sheet ordering virtual nsresult Reset(nsIURL* aUrl); - // For HTML elements in our content model nsIHTMLStyleSheet* mAttrStyleSheet; nsIHTMLCSSStyleSheet* mInlineStyleSheet; - nsVoidArray *mProlog; - nsVoidArray *mEpilog; - nsIParser *mParser; - nsXMLDocumentChildNodes* mChildNodes; }; diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 50ddf85cea2..c38e2e5dd42 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -2962,6 +2962,17 @@ nsCSSFrameConstructor::ResolveStyleContext(nsIPresContext* aPresContext, parentStyleContext, PR_FALSE, aStyleContext); + } else if (nsLayoutAtoms::processingInstructionTagName == aTag) { + // Use a special pseudo element style context for comments + nsCOMPtr parentContent; + if (nsnull != aParentFrame) { + aParentFrame->GetContent(getter_AddRefs(parentContent)); + } + rv = aPresContext->ResolvePseudoStyleContextFor(parentContent, + nsHTMLAtoms::processingInstructionPseudo, + parentStyleContext, + PR_FALSE, + aStyleContext); } else { rv = aPresContext->ResolveStyleContextFor(aContent, parentStyleContext, PR_FALSE, @@ -3019,6 +3030,17 @@ nsCSSFrameConstructor::ConstructFrame(nsIPresContext* aPresContext, parentStyleContext, PR_FALSE, getter_AddRefs(styleContext)); + } else if (nsLayoutAtoms::processingInstructionTagName == tag) { + // Use a special pseudo element style context for comments + nsCOMPtr parentContent; + if (nsnull != aParentFrame) { + aParentFrame->GetContent(getter_AddRefs(parentContent)); + } + rv = aPresContext->ResolvePseudoStyleContextFor(parentContent, + nsHTMLAtoms::processingInstructionPseudo, + parentStyleContext, + PR_FALSE, + getter_AddRefs(styleContext)); } else { rv = aPresContext->ResolveStyleContextFor(aContent, parentStyleContext, PR_FALSE, diff --git a/layout/base/nsLayoutAtoms.cpp b/layout/base/nsLayoutAtoms.cpp index d8b77d55cad..3528d6c0a75 100644 --- a/layout/base/nsLayoutAtoms.cpp +++ b/layout/base/nsLayoutAtoms.cpp @@ -46,6 +46,7 @@ nsIAtom* nsLayoutAtoms::floaterList; // pseudo tag names for non-element content nsIAtom* nsLayoutAtoms::commentTagName; nsIAtom* nsLayoutAtoms::textTagName; +nsIAtom* nsLayoutAtoms::processingInstructionTagName; nsIAtom* nsLayoutAtoms::viewportPseudo; nsIAtom* nsLayoutAtoms::pagePseudo; @@ -90,6 +91,7 @@ void nsLayoutAtoms::AddrefAtoms() commentTagName = NS_NewAtom("__moz_comment"); textTagName = NS_NewAtom("__moz_text"); + processingInstructionTagName = NS_NewAtom("__moz_pi"); viewportPseudo = NS_NewAtom(":-moz-viewport"); pagePseudo = NS_NewAtom(":-moz-page"); @@ -135,6 +137,7 @@ void nsLayoutAtoms::ReleaseAtoms() NS_RELEASE(commentTagName); NS_RELEASE(textTagName); + NS_RELEASE(processingInstructionTagName); NS_RELEASE(viewportPseudo); NS_RELEASE(pagePseudo); diff --git a/layout/base/nsLayoutAtoms.h b/layout/base/nsLayoutAtoms.h index 4abb0486bd6..8315904eb5a 100644 --- a/layout/base/nsLayoutAtoms.h +++ b/layout/base/nsLayoutAtoms.h @@ -60,6 +60,7 @@ public: // Alphabetical list of pseudo tag names for non-element content static nsIAtom* commentTagName; static nsIAtom* textTagName; + static nsIAtom* processingInstructionTagName; static nsIAtom* viewportPseudo; static nsIAtom* pagePseudo; diff --git a/layout/base/public/nsIDocument.h b/layout/base/public/nsIDocument.h index 12838140e70..226ee8e5f9a 100644 --- a/layout/base/public/nsIDocument.h +++ b/layout/base/public/nsIDocument.h @@ -157,6 +157,22 @@ public: virtual nsIContent* GetRootContent() = 0; virtual void SetRootContent(nsIContent* aRoot) = 0; + /** + * Methods to append to the prolog and epilog of + * a document. The prolog is the content before the document + * element, the epilog after. + */ + NS_IMETHOD AppendToProlog(nsIContent* aContent) = 0; + NS_IMETHOD AppendToEpilog(nsIContent* aContent) = 0; + + /** + * Get the direct children of the document - content in + * the prolog, the root content and content in the epilog. + */ + NS_IMETHOD ChildAt(PRInt32 aIndex, nsIContent*& aResult) const = 0; + NS_IMETHOD IndexOf(nsIContent* aPossibleChild, PRInt32& aIndex) const = 0; + NS_IMETHOD GetChildCount(PRInt32& aCount) = 0; + /** * Get the style sheets owned by this document. * Style sheets are ordered, most significant last. diff --git a/layout/base/public/nsLayoutAtoms.h b/layout/base/public/nsLayoutAtoms.h index 4abb0486bd6..8315904eb5a 100644 --- a/layout/base/public/nsLayoutAtoms.h +++ b/layout/base/public/nsLayoutAtoms.h @@ -60,6 +60,7 @@ public: // Alphabetical list of pseudo tag names for non-element content static nsIAtom* commentTagName; static nsIAtom* textTagName; + static nsIAtom* processingInstructionTagName; static nsIAtom* viewportPseudo; static nsIAtom* pagePseudo; diff --git a/layout/base/src/nsContentList.cpp b/layout/base/src/nsContentList.cpp index d2bc68af140..367840fb4a2 100644 --- a/layout/base/src/nsContentList.cpp +++ b/layout/base/src/nsContentList.cpp @@ -331,7 +331,8 @@ nsContentList::Match(nsIContent *aContent, PRBool *aMatch) // If we have to match all, only do those that have // a tagName i.e. only the elements. if (mMatchAll && (nsLayoutAtoms::textTagName != name) && - (nsLayoutAtoms::commentTagName != name)) { + (nsLayoutAtoms::commentTagName != name) && + (nsLayoutAtoms::processingInstructionTagName != name)) { *aMatch = PR_TRUE; } // XXX We don't yet match on namespace. Maybe we should?? diff --git a/layout/base/src/nsDocument.cpp b/layout/base/src/nsDocument.cpp index b31e5861b76..309d3f90894 100644 --- a/layout/base/src/nsDocument.cpp +++ b/layout/base/src/nsDocument.cpp @@ -549,8 +549,62 @@ PRInt32 nsPostData::GetDataLength() return mDataLen; } +// ================================================================== +// = +// ================================================================== +nsDocumentChildNodes::nsDocumentChildNodes(nsIDocument* aDocument) +{ + // We don't reference count our document reference (to avoid circular + // references). We'll be told when the document goes away. + mDocument = aDocument; +} + +nsDocumentChildNodes::~nsDocumentChildNodes() +{ +} + +NS_IMETHODIMP +nsDocumentChildNodes::GetLength(PRUint32* aLength) +{ + if (nsnull != mDocument) { + PRInt32 count; + mDocument->GetChildCount(count); + *aLength = (PRUint32)count; + } + else { + *aLength = 0; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsDocumentChildNodes::Item(PRUint32 aIndex, nsIDOMNode** aReturn) +{ + nsresult result = NS_OK; + nsIContent* content = nsnull; + + *aReturn = nsnull; + if (nsnull != mDocument) { + result = mDocument->ChildAt(aIndex, content); + if ((NS_OK == result) && (nsnull != content)) { + result = content->QueryInterface(kIDOMNodeIID, (void**)aReturn); + } + } + + return result; +} + +void +nsDocumentChildNodes::DropReference() +{ + mDocument = nsnull; +} +// ================================================================== +// = +// ================================================================== nsDocument::nsDocument() { @@ -572,6 +626,9 @@ nsDocument::nsDocument() mNameSpaceManager = nsnull; mHeaderData = nsnull; mLineBreaker = nsnull; + mProlog = nsnull; + mEpilog = nsnull; + mChildNodes = nsnull; mWordBreaker = nsnull; Init();/* XXX */ @@ -585,7 +642,7 @@ nsDocument::~nsDocument() // This notification will occur only after the reference has // been dropped. mInDestructor = PR_TRUE; - PRInt32 index; + PRInt32 index, count; for (index = 0; index < mObservers.Count(); index++) { nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(index); observer->DocumentWillBeDestroyed(this); @@ -617,6 +674,29 @@ nsDocument::~nsDocument() NS_RELEASE(sheet); } + nsIContent* content; + if (nsnull != mProlog) { + count = mProlog->Count(); + for (index = 0; index < count; index++) { + content = (nsIContent*)mProlog->ElementAt(index); + NS_RELEASE(content); + } + delete mProlog; + } + if (nsnull != mEpilog) { + count = mEpilog->Count(); + for (index = 0; index < count; index++) { + content = (nsIContent*)mEpilog->ElementAt(index); + NS_RELEASE(content); + } + delete mEpilog; + } + + if (nsnull != mChildNodes) { + mChildNodes->DropReference(); + NS_RELEASE(mChildNodes); + } + NS_IF_RELEASE(mArena); NS_IF_RELEASE(mScriptContextOwner); NS_IF_RELEASE(mListenerManager); @@ -1047,6 +1127,103 @@ void nsDocument::SetRootContent(nsIContent* aRoot) } } +NS_IMETHODIMP +nsDocument::AppendToProlog(nsIContent* aContent) +{ + if (nsnull == mProlog) { + mProlog = new nsVoidArray(); + } + + mProlog->AppendElement((void *)aContent); + NS_ADDREF(aContent); + + return NS_OK; +} + +NS_IMETHODIMP +nsDocument::AppendToEpilog(nsIContent* aContent) +{ + if (nsnull == mEpilog) { + mEpilog = new nsVoidArray(); + } + + mEpilog->AppendElement((void *)aContent); + NS_ADDREF(aContent); + + return NS_OK; +} + +NS_IMETHODIMP +nsDocument::ChildAt(PRInt32 aIndex, nsIContent*& aResult) const +{ + nsIContent* content = nsnull; + PRInt32 prolog = 0; + + if (nsnull != mProlog) { + prolog = mProlog->Count(); + if (aIndex < prolog) { + // It's in the prolog + content = (nsIContent*)mProlog->ElementAt(aIndex); + } + } + + if (aIndex == prolog) { + // It's the document element + content = mRootContent; + } + else if ((aIndex > prolog) && (nsnull != mEpilog)) { + // It's in the epilog + content = (nsIContent*)mEpilog->ElementAt(aIndex-prolog-1); + } + + NS_IF_ADDREF(content); + aResult = content; + + return NS_OK; +} + +NS_IMETHODIMP +nsDocument::IndexOf(nsIContent* aPossibleChild, PRInt32& aIndex) const +{ + PRInt32 index = -1; + PRInt32 prolog = 0; + + if (nsnull != mProlog) { + index = mProlog->IndexOf(aPossibleChild); + prolog = mProlog->Count(); + } + + if (-1 == index) { + if (aPossibleChild == mRootContent) { + index = prolog; + } + else if (nsnull != mEpilog) { + index = mEpilog->IndexOf(aPossibleChild); + if (-1 != index) { + index += (prolog+1); + } + } + } + + aIndex = index; + + return NS_OK; +} + +NS_IMETHODIMP +nsDocument::GetChildCount(PRInt32& aCount) +{ + aCount = 1; + if (nsnull != mProlog) { + aCount += mProlog->Count(); + } + if (nsnull != mEpilog) { + aCount += mEpilog->Count(); + } + + return NS_OK; +} + PRInt32 nsDocument::GetNumberOfStyleSheets() { return mStyleSheets.Count(); @@ -1504,6 +1681,7 @@ nsDocument::CreateTextNode(const nsString& aData, nsIDOMText** aReturn) if (NS_OK == rv) { rv = text->QueryInterface(kIDOMTextIID, (void**)aReturn); (*aReturn)->AppendData(aData); + NS_RELEASE(text); } return rv; @@ -1524,6 +1702,7 @@ nsDocument::CreateComment(const nsString& aData, nsIDOMComment** aReturn) if (NS_OK == rv) { rv = comment->QueryInterface(kIDOMCommentIID, (void**)aReturn); (*aReturn)->AppendData(aData); + NS_RELEASE(comment); } return rv; @@ -1663,29 +1842,71 @@ nsDocument::GetParentNode(nsIDOMNode** aParentNode) NS_IMETHODIMP nsDocument::GetChildNodes(nsIDOMNodeList** aChildNodes) { - // Should be implemented by subclass - return NS_ERROR_NOT_IMPLEMENTED; + if (nsnull == mChildNodes) { + mChildNodes = new nsDocumentChildNodes(this); + if (nsnull == mChildNodes) { + return NS_ERROR_OUT_OF_MEMORY; + } + NS_ADDREF(mChildNodes); + } + + return mChildNodes->QueryInterface(kIDOMNodeListIID, (void**)aChildNodes); } NS_IMETHODIMP nsDocument::HasChildNodes(PRBool* aHasChildNodes) { - // Should be implemented by subclass - return NS_ERROR_NOT_IMPLEMENTED; + *aHasChildNodes = PR_TRUE; + return NS_OK; } NS_IMETHODIMP nsDocument::GetFirstChild(nsIDOMNode** aFirstChild) { - // Should be implemented by subclass - return NS_ERROR_NOT_IMPLEMENTED; + nsresult result = NS_OK; + + if ((nsnull != mProlog) && (0 != mProlog->Count())) { + nsIContent* content; + content = (nsIContent *)mProlog->ElementAt(0); + + if (nsnull != content) { + result = content->QueryInterface(kIDOMNodeIID, (void**)aFirstChild); + } + } + else { + nsIDOMElement* element; + result = GetDocumentElement(&element); + if (NS_OK == result) { + result = element->QueryInterface(kIDOMNodeIID, (void**)aFirstChild); + NS_RELEASE(element); + } + } + + return result; } NS_IMETHODIMP nsDocument::GetLastChild(nsIDOMNode** aLastChild) { - // Should be implemented by subclass - return NS_ERROR_NOT_IMPLEMENTED; + nsresult result = NS_OK; + + if ((nsnull != mEpilog) && (0 != mEpilog->Count())) { + nsIContent* content; + content = (nsIContent *)mEpilog->ElementAt(mEpilog->Count()-1); + if (nsnull != content) { + result = content->QueryInterface(kIDOMNodeIID, (void**)aLastChild); + } + } + else { + nsIDOMElement* element; + result = GetDocumentElement(&element); + if (NS_OK == result) { + result = element->QueryInterface(kIDOMNodeIID, (void**)aLastChild); + NS_RELEASE(element); + } + } + + return result; } NS_IMETHODIMP @@ -1712,29 +1933,194 @@ nsDocument::GetAttributes(nsIDOMNamedNodeMap** aAttributes) NS_IMETHODIMP nsDocument::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aReturn) { - // Should be implemented by subclass - return NS_ERROR_NOT_IMPLEMENTED; + NS_ASSERTION(nsnull != aNewChild, "null ptr"); + nsresult result = NS_OK; + PRInt32 index; + PRUint16 nodeType; + nsIContent *content, *refContent = nsnull; + + if (nsnull == aNewChild) { + return NS_ERROR_INVALID_ARG; + } + + aNewChild->GetNodeType(&nodeType); + if ((COMMENT_NODE != nodeType) && (PROCESSING_INSTRUCTION_NODE != nodeType)) { + return NS_ERROR_INVALID_ARG; + } + + result = aNewChild->QueryInterface(kIContentIID, (void**)&content); + if (NS_OK != result) { + return result; + } + + if (nsnull == aRefChild) { + AppendToEpilog(content); + } + else { + result = aRefChild->QueryInterface(kIContentIID, (void**)&refContent); + if (NS_OK != result) { + NS_RELEASE(content); + return result; + } + + if ((nsnull != mProlog) && (0 != mProlog->Count())) { + index = mProlog->IndexOf(refContent); + if (-1 != index) { + mProlog->InsertElementAt(content, index); + NS_ADDREF(content); + } + } + + if (refContent == mRootContent) { + AppendToProlog(content); + } + else if ((nsnull != mEpilog) && (0 != mEpilog->Count())) { + index = mEpilog->IndexOf(refContent); + if (-1 != index) { + mEpilog->InsertElementAt(content, index); + NS_ADDREF(content); + } + } + NS_RELEASE(refContent); + } + + if (NS_OK == result) { + content->SetDocument(this, PR_TRUE); + *aReturn = aNewChild; + NS_ADDREF(aNewChild); + } + else { + *aReturn = nsnull; + } + + NS_RELEASE(content); + + return result; } NS_IMETHODIMP nsDocument::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aReturn) { - // Should be implemented by subclass - return NS_ERROR_NOT_IMPLEMENTED; + NS_ASSERTION(((nsnull != aNewChild) && (nsnull != aOldChild)), "null ptr"); + nsresult result = NS_OK; + PRInt32 index; + PRUint16 nodeType; + nsIContent *content, *refContent; + + if ((nsnull == aNewChild) || (nsnull == aOldChild)) { + return NS_ERROR_INVALID_ARG; + } + + aNewChild->GetNodeType(&nodeType); + if ((COMMENT_NODE != nodeType) && (PROCESSING_INSTRUCTION_NODE != nodeType)) { + return NS_ERROR_INVALID_ARG; + } + + result = aNewChild->QueryInterface(kIContentIID, (void**)&content); + if (NS_OK != result) { + return result; + } + + result = aOldChild->QueryInterface(kIContentIID, (void**)&refContent); + if (NS_OK != result) { + NS_RELEASE(content); + return result; + } + + if ((nsnull != mProlog) && (0 != mProlog->Count())) { + index = mProlog->IndexOf(refContent); + if (-1 != index) { + nsIContent* oldContent; + oldContent = (nsIContent*)mProlog->ElementAt(index); + NS_RELEASE(oldContent); + mProlog->ReplaceElementAt(content, index); + NS_ADDREF(content); + } + } + + if (refContent == mRootContent) { + result = NS_ERROR_INVALID_ARG; + } + else if ((nsnull != mEpilog) && (0 != mEpilog->Count())) { + index = mEpilog->IndexOf(refContent); + if (-1 != index) { + nsIContent* oldContent; + oldContent = (nsIContent*)mEpilog->ElementAt(index); + NS_RELEASE(oldContent); + mEpilog->ReplaceElementAt(content, index); + NS_ADDREF(content); + } + } + + if (NS_OK == result) { + content->SetDocument(this, PR_TRUE); + refContent->SetDocument(nsnull, PR_TRUE); + *aReturn = aNewChild; + NS_ADDREF(aNewChild); + } + else { + *aReturn = nsnull; + } + + NS_RELEASE(content); + NS_RELEASE(refContent); + + return result; } NS_IMETHODIMP nsDocument::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) { - // Should be implemented by subclass - return NS_ERROR_NOT_IMPLEMENTED; + NS_ASSERTION(nsnull != aOldChild, "null ptr"); + nsresult result = NS_OK; + PRInt32 index; + nsIContent *content; + + if (nsnull == aOldChild) { + return NS_ERROR_INVALID_ARG; + } + + result = aOldChild->QueryInterface(kIContentIID, (void**)&content); + if (NS_OK != result) { + return result; + } + + if ((nsnull != mProlog) && (0 != mProlog->Count())) { + index = mProlog->IndexOf(content); + if (-1 != index) { + // Don't drop reference count since we're going + // to return this element anyway. + mProlog->RemoveElementAt(index); + } + } + + if (content == mRootContent) { + result = NS_ERROR_INVALID_ARG; + } + else if ((nsnull != mEpilog) && (0 != mEpilog->Count())) { + index = mEpilog->IndexOf(content); + if (-1 != index) { + mEpilog->RemoveElementAt(index); + } + } + + if (NS_OK == result) { + content->SetDocument(nsnull, PR_TRUE); + *aReturn = aOldChild; + } + else { + *aReturn = nsnull; + } + + NS_RELEASE(content); + + return result; } NS_IMETHODIMP nsDocument::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn) { - // Should be implemented by subclass - return NS_ERROR_NOT_IMPLEMENTED; + return InsertBefore(aNewChild, nsnull, aReturn); } NS_IMETHODIMP diff --git a/layout/base/src/nsDocument.h b/layout/base/src/nsDocument.h index 9224c446108..cc7cd2c4b65 100644 --- a/layout/base/src/nsDocument.h +++ b/layout/base/src/nsDocument.h @@ -29,11 +29,12 @@ #include "nsXIFConverter.h" #include "nsIJSScriptObject.h" #include "nsIContent.h" +#include "nsGenericDOMNodeList.h" class nsIEventListenerManager; class nsDOMStyleSheetCollection; class nsIDOMSelection; - +class nsDocument; class nsPostData : public nsIPostData { public: @@ -77,6 +78,23 @@ public: nsDocHeaderData* mNext; }; +// Represents the children of a document (prolog, epilog and +// document element) +class nsDocumentChildNodes : public nsGenericDOMNodeList +{ +public: + nsDocumentChildNodes(nsIDocument* aDocument); + ~nsDocumentChildNodes(); + + NS_IMETHOD GetLength(PRUint32* aLength); + NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn); + + void DropReference(); + +protected: + nsIDocument* mDocument; +}; + // Base class for our document implementations class nsDocument : public nsIDocument, public nsIDOMDocument, @@ -169,6 +187,22 @@ public: virtual nsIContent* GetRootContent(); virtual void SetRootContent(nsIContent* aRoot); + /** + * Methods to append to the prolog and epilog of + * a document. The prolog is the content before the document + * element, the epilog after. + */ + NS_IMETHOD AppendToProlog(nsIContent* aContent); + NS_IMETHOD AppendToEpilog(nsIContent* aContent); + + /** + * Get the direct children of the document - content in + * the prolog, the root content and content in the epilog. + */ + NS_IMETHOD ChildAt(PRInt32 aIndex, nsIContent*& aResult) const; + NS_IMETHOD IndexOf(nsIContent* aPossibleChild, PRInt32& aIndex) const; + NS_IMETHOD GetChildCount(PRInt32& aCount); + /** * Get the style sheets owned by this document. * These are ordered, highest priority last @@ -383,6 +417,9 @@ protected: nsINameSpaceManager* mNameSpaceManager; nsDocHeaderData* mHeaderData; nsILineBreaker* mLineBreaker; + nsVoidArray *mProlog; + nsVoidArray *mEpilog; + nsDocumentChildNodes* mChildNodes; nsIWordBreaker* mWordBreaker; }; diff --git a/layout/base/src/nsGenericDOMDataNode.cpp b/layout/base/src/nsGenericDOMDataNode.cpp index 78500e07985..eb6937b1439 100644 --- a/layout/base/src/nsGenericDOMDataNode.cpp +++ b/layout/base/src/nsGenericDOMDataNode.cpp @@ -37,6 +37,7 @@ #include "nsIPrivateDOMEvent.h" #include "nsISizeOfHandler.h" #include "nsDOMEvent.h" +#include "nsIDOMText.h" #include "nsIDOMScriptObjectFactory.h" #include "nsIScriptContextOwner.h" #include "prprf.h" @@ -49,6 +50,8 @@ NS_DEFINE_IID(kIDOMCharacterDataIID, NS_IDOMCHARACTERDATA_IID); static NS_DEFINE_IID(kIPrivateDOMEventIID, NS_IPRIVATEDOMEVENT_IID); static NS_DEFINE_IID(kIEnumeratorIID, NS_IENUMERATOR_IID); static NS_DEFINE_IID(kIDOMDocumentIID, NS_IDOMDOCUMENT_IID); +static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID); +static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID); //---------------------------------------------------------------------- @@ -133,49 +136,73 @@ nsGenericDOMDataNode::GetParentNode(nsIDOMNode** aParentNode) } nsresult -nsGenericDOMDataNode::GetPreviousSibling(nsIDOMNode** aNode) +nsGenericDOMDataNode::GetPreviousSibling(nsIDOMNode** aPrevSibling) { + nsIContent* sibling = nsnull; + nsresult result = NS_OK; + if (nsnull != mParent) { PRInt32 pos; mParent->IndexOf(mContent, pos); - if (pos > -1) { - nsIContent* prev; - mParent->ChildAt(--pos, prev); - if (nsnull != prev) { - nsresult res = prev->QueryInterface(kIDOMNodeIID, (void**)aNode); - NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); - NS_RELEASE(prev); // balance the AddRef in ChildAt() - return res; - } + if (pos > -1 ) { + mParent->ChildAt(--pos, sibling); } } - // XXX Nodes that are just below the document (their parent is the - // document) need to go to the document to find their previous sibling. - *aNode = nsnull; - return NS_OK; + else if (nsnull != mDocument) { + // Nodes that are just below the document (their parent is the + // document) need to go to the document to find their next sibling. + PRInt32 pos; + mDocument->IndexOf(mContent, pos); + if (pos > -1 ) { + mDocument->ChildAt(--pos, sibling); + } + } + + if (nsnull != sibling) { + result = sibling->QueryInterface(kIDOMNodeIID,(void**)aPrevSibling); + NS_ASSERTION(NS_OK == result, "Must be a DOM Node"); + NS_RELEASE(sibling); // balance the AddRef in ChildAt() + } + else { + *aPrevSibling = nsnull; + } + + return result; } nsresult nsGenericDOMDataNode::GetNextSibling(nsIDOMNode** aNextSibling) { + nsIContent* sibling = nsnull; + nsresult result = NS_OK; + if (nsnull != mParent) { PRInt32 pos; mParent->IndexOf(mContent, pos); if (pos > -1 ) { - nsIContent* prev; - mParent->ChildAt(++pos, prev); - if (nsnull != prev) { - nsresult res = prev->QueryInterface(kIDOMNodeIID,(void**)aNextSibling); - NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); - NS_RELEASE(prev); // balance the AddRef in ChildAt() - return res; - } + mParent->ChildAt(++pos, sibling); } } - // XXX Nodes that are just below the document (their parent is the - // document) need to go to the document to find their next sibling. - *aNextSibling = nsnull; - return NS_OK; + else if (nsnull != mDocument) { + // Nodes that are just below the document (their parent is the + // document) need to go to the document to find their next sibling. + PRInt32 pos; + mDocument->IndexOf(mContent, pos); + if (pos > -1 ) { + mDocument->ChildAt(++pos, sibling); + } + } + + if (nsnull != sibling) { + result = sibling->QueryInterface(kIDOMNodeIID,(void**)aNextSibling); + NS_ASSERTION(NS_OK == result, "Must be a DOM Node"); + NS_RELEASE(sibling); // balance the AddRef in ChildAt() + } + else { + *aNextSibling = nsnull; + } + + return result; } nsresult @@ -775,3 +802,141 @@ nsGenericDOMDataNode::GetRangeList(nsVoidArray*& aResult) const aResult = mRangeList; return NS_OK; } + + +//---------------------------------------------------------------------- + +// Implementation of the nsIDOMText interface + +nsresult +nsGenericDOMDataNode::SplitText(PRUint32 aOffset, nsIDOMText** aReturn) +{ + nsresult result = NS_OK; + nsIContent* newNode; + nsITextContent* text; + nsAutoString cutText; + nsIContent* parentNode; + PRUint32 length; + + GetLength(&length); + // Cut the second part out of the original text node + result = SubstringData(aOffset, length-aOffset, cutText); + if (NS_OK == result) { + result = DeleteData(aOffset, length-aOffset); + if (NS_OK == result) { + // Create a new text node and set its data to the + // string we just cut out + result = NS_NewTextNode(&newNode); + if (NS_OK == result) { + result = newNode->QueryInterface(kITextContentIID, (void**)&text); + if (NS_OK == result) { + text->SetText(cutText, cutText.Length(), PR_FALSE); + // Find the parent of the current node and insert the + // new text node as a child after the current node + GetParent(parentNode); + if (nsnull != parentNode) { + PRInt32 index; + + result = parentNode->IndexOf(mContent, index); + if (NS_OK == result) { + result = parentNode->InsertChildAt(newNode, index+1, PR_TRUE); + } + NS_RELEASE(parentNode); + } + result = text->QueryInterface(kIDOMTextIID, (void**)aReturn); + NS_RELEASE(text); + } + NS_RELEASE(newNode); + } + } + } + + return result; +} + +//---------------------------------------------------------------------- + +// Implementation of the nsITextContent interface + +nsresult +nsGenericDOMDataNode::GetText(const nsTextFragment*& aFragmentsResult, + PRInt32& aNumFragmentsResult) +{ + aFragmentsResult = &mText; + aNumFragmentsResult = 1; + return NS_OK; +} + +nsresult +nsGenericDOMDataNode::SetText(const PRUnichar* aBuffer, PRInt32 aLength, + PRBool aNotify) +{ + NS_PRECONDITION((aLength >= 0) && (nsnull != aBuffer), "bad args"); + if (aLength < 0) { + return NS_ERROR_ILLEGAL_VALUE; + } + if (nsnull == aBuffer) { + return NS_ERROR_NULL_POINTER; + } + mText.SetTo(aBuffer, aLength); + + // Trigger a reflow + if (aNotify && (nsnull != mDocument)) { + mDocument->ContentChanged(mContent, nsnull); + } + return NS_OK; +} + +nsresult +nsGenericDOMDataNode::SetText(const char* aBuffer, + PRInt32 aLength, + PRBool aNotify) +{ + NS_PRECONDITION((aLength >= 0) && (nsnull != aBuffer), "bad args"); + if (aLength < 0) { + return NS_ERROR_ILLEGAL_VALUE; + } + if (nsnull == aBuffer) { + return NS_ERROR_NULL_POINTER; + } + mText.SetTo(aBuffer, aLength); + + // Trigger a reflow + if (aNotify && (nsnull != mDocument)) { + mDocument->ContentChanged(mContent, nsnull); + } + return NS_OK; +} + + +nsresult +nsGenericDOMDataNode::IsOnlyWhitespace(PRBool* aResult) +{ + nsTextFragment& frag = mText; + if (frag.Is2b()) { + const PRUnichar* cp = frag.Get2b(); + const PRUnichar* end = cp + frag.GetLength(); + while (cp < end) { + PRUnichar ch = *cp++; + if (!XP_IS_SPACE(ch)) { + *aResult = PR_FALSE; + return NS_OK; + } + } + } + else { + const char* cp = frag.Get1b(); + const char* end = cp + frag.GetLength(); + while (cp < end) { + PRUnichar ch = PRUnichar(*(unsigned char*)cp); + cp++; + if (!XP_IS_SPACE(ch)) { + *aResult = PR_FALSE; + return NS_OK; + } + } + } + + *aResult = PR_TRUE; + return NS_OK; +} diff --git a/layout/base/src/nsGenericDOMDataNode.h b/layout/base/src/nsGenericDOMDataNode.h index 635822c723a..7884edac762 100644 --- a/layout/base/src/nsGenericDOMDataNode.h +++ b/layout/base/src/nsGenericDOMDataNode.h @@ -26,6 +26,7 @@ #include "nsTextFragment.h" #include "nsVoidArray.h" #include "nsINameSpaceManager.h" +#include "nsITextContent.h" extern const nsIID kIDOMCharacterDataIID; extern const nsIID kIDOMNodeIID; @@ -43,6 +44,7 @@ class nsIFrame; class nsIStyleContext; class nsIStyleRule; class nsISupportsArray; +class nsIDOMText; struct nsGenericDOMDataNode { nsGenericDOMDataNode(); @@ -206,6 +208,18 @@ struct nsGenericDOMDataNode { return NS_OK; } + nsresult SplitText(PRUint32 aOffset, nsIDOMText** aReturn); + + nsresult GetText(const nsTextFragment*& aFragmentsResult, + PRInt32& aNumFragmentsResult); + nsresult SetText(const PRUnichar* aBuffer, + PRInt32 aLength, + PRBool aNotify); + nsresult SetText(const char* aBuffer, + PRInt32 aLength, + PRBool aNotify); + nsresult IsOnlyWhitespace(PRBool* aResult); + //---------------------------------------- void ToCString(nsString& aBuf, PRInt32 aOffset, PRInt32 aLen) const; @@ -464,6 +478,38 @@ struct nsGenericDOMDataNode { return _g.GetRangeList(aResult); \ } +/** + * Implement the nsIDOMText API by forwarding the methods to a + * generic character data content object. + */ +#define NS_IMPL_IDOMTEXT_USING_GENERIC_DOM_DATA(_g) \ + NS_IMETHOD SplitText(PRUint32 aOffset, nsIDOMText** aReturn){ \ + return _g.SplitText(aOffset, aReturn); \ + } + +/** + * Implement the nsITextContent API by forwarding the methods to a + * generic character data content object. + */ +#define NS_IMPL_ITEXTCONTENT_USING_GENERIC_DOM_DATA(_g) \ + NS_IMETHOD GetText(const nsTextFragment*& aFragmentsResult, \ + PRInt32& aNumFragmentsResult){ \ + return mInner.GetText(aFragmentsResult, aNumFragmentsResult); \ + } \ + NS_IMETHOD SetText(const PRUnichar* aBuffer, \ + PRInt32 aLength, \ + PRBool aNotify){ \ + return mInner.SetText(aBuffer, aLength, aNotify); \ + } \ + NS_IMETHOD SetText(const char* aBuffer, \ + PRInt32 aLength, \ + PRBool aNotify){ \ + return mInner.SetText(aBuffer, aLength, aNotify); \ + } \ + NS_IMETHOD IsOnlyWhitespace(PRBool* aResult){ \ + return mInner.IsOnlyWhitespace(aResult); \ + } + /** * This macro implements the portion of query interface that is * generic to all html content objects. diff --git a/layout/base/src/nsGenericElement.cpp b/layout/base/src/nsGenericElement.cpp index 03977c7b3c0..910c788a3c1 100644 --- a/layout/base/src/nsGenericElement.cpp +++ b/layout/base/src/nsGenericElement.cpp @@ -293,49 +293,73 @@ nsGenericElement::GetParentNode(nsIDOMNode** aParentNode) } nsresult -nsGenericElement::GetPreviousSibling(nsIDOMNode** aNode) +nsGenericElement::GetPreviousSibling(nsIDOMNode** aPrevSibling) { + nsIContent* sibling = nsnull; + nsresult result = NS_OK; + if (nsnull != mParent) { PRInt32 pos; mParent->IndexOf(mContent, pos); - if (pos > -1) { - nsIContent* prev; - mParent->ChildAt(--pos, prev); - if (nsnull != prev) { - nsresult res = prev->QueryInterface(kIDOMNodeIID, (void**)aNode); - NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); - NS_RELEASE(prev); // balance the AddRef in ChildAt() - return res; - } + if (pos > -1 ) { + mParent->ChildAt(--pos, sibling); } } - // XXX Nodes that are just below the document (their parent is the - // document) need to go to the document to find their previous sibling. - *aNode = nsnull; - return NS_OK; + else if (nsnull != mDocument) { + // Nodes that are just below the document (their parent is the + // document) need to go to the document to find their next sibling. + PRInt32 pos; + mDocument->IndexOf(mContent, pos); + if (pos > -1 ) { + mDocument->ChildAt(--pos, sibling); + } + } + + if (nsnull != sibling) { + result = sibling->QueryInterface(kIDOMNodeIID,(void**)aPrevSibling); + NS_ASSERTION(NS_OK == result, "Must be a DOM Node"); + NS_RELEASE(sibling); // balance the AddRef in ChildAt() + } + else { + *aPrevSibling = nsnull; + } + + return result; } nsresult nsGenericElement::GetNextSibling(nsIDOMNode** aNextSibling) { + nsIContent* sibling = nsnull; + nsresult result = NS_OK; + if (nsnull != mParent) { PRInt32 pos; mParent->IndexOf(mContent, pos); if (pos > -1 ) { - nsIContent* prev; - mParent->ChildAt(++pos, prev); - if (nsnull != prev) { - nsresult res = prev->QueryInterface(kIDOMNodeIID,(void**)aNextSibling); - NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); - NS_RELEASE(prev); // balance the AddRef in ChildAt() - return res; - } + mParent->ChildAt(++pos, sibling); } } - // XXX Nodes that are just below the document (their parent is the - // document) need to go to the document to find their next sibling. - *aNextSibling = nsnull; - return NS_OK; + else if (nsnull != mDocument) { + // Nodes that are just below the document (their parent is the + // document) need to go to the document to find their next sibling. + PRInt32 pos; + mDocument->IndexOf(mContent, pos); + if (pos > -1 ) { + mDocument->ChildAt(++pos, sibling); + } + } + + if (nsnull != sibling) { + result = sibling->QueryInterface(kIDOMNodeIID,(void**)aNextSibling); + NS_ASSERTION(NS_OK == result, "Must be a DOM Node"); + NS_RELEASE(sibling); // balance the AddRef in ChildAt() + } + else { + *aNextSibling = nsnull; + } + + return result; } nsresult @@ -1436,9 +1460,6 @@ nsGenericContainerElement::GetLastChild(nsIDOMNode** aNode) return NS_OK; } -// XXX It's possible that newChild has already been inserted in the -// tree; if this is the case then we need to remove it from where it -// was before placing it in it's new home nsresult nsGenericContainerElement::InsertBefore(nsIDOMNode* aNewChild, diff --git a/layout/base/src/nsLayoutAtoms.cpp b/layout/base/src/nsLayoutAtoms.cpp index d8b77d55cad..3528d6c0a75 100644 --- a/layout/base/src/nsLayoutAtoms.cpp +++ b/layout/base/src/nsLayoutAtoms.cpp @@ -46,6 +46,7 @@ nsIAtom* nsLayoutAtoms::floaterList; // pseudo tag names for non-element content nsIAtom* nsLayoutAtoms::commentTagName; nsIAtom* nsLayoutAtoms::textTagName; +nsIAtom* nsLayoutAtoms::processingInstructionTagName; nsIAtom* nsLayoutAtoms::viewportPseudo; nsIAtom* nsLayoutAtoms::pagePseudo; @@ -90,6 +91,7 @@ void nsLayoutAtoms::AddrefAtoms() commentTagName = NS_NewAtom("__moz_comment"); textTagName = NS_NewAtom("__moz_text"); + processingInstructionTagName = NS_NewAtom("__moz_pi"); viewportPseudo = NS_NewAtom(":-moz-viewport"); pagePseudo = NS_NewAtom(":-moz-page"); @@ -135,6 +137,7 @@ void nsLayoutAtoms::ReleaseAtoms() NS_RELEASE(commentTagName); NS_RELEASE(textTagName); + NS_RELEASE(processingInstructionTagName); NS_RELEASE(viewportPseudo); NS_RELEASE(pagePseudo); diff --git a/layout/base/src/nsTextNode.cpp b/layout/base/src/nsTextNode.cpp index e5c3bd035ca..cf85d5cc297 100644 --- a/layout/base/src/nsTextNode.cpp +++ b/layout/base/src/nsTextNode.cpp @@ -16,12 +16,13 @@ * Corporation. Portions created by Netscape are Copyright (C) 1998 * Netscape Communications Corporation. All Rights Reserved. */ + #include "nsIDOMText.h" -#include "nsGenericDOMDataNode.h" #include "nsIScriptObjectOwner.h" #include "nsIDOMEventReceiver.h" #include "nsIContent.h" #include "nsITextContent.h" +#include "nsGenericDOMDataNode.h" #include "nsFrame.h" #include "nsIDocument.h" #include "nsCRT.h" @@ -30,8 +31,6 @@ static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID); static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID); -/* XXX should not be html content; should be nsITextContent */ - class nsTextNode : public nsIDOMText, public nsIScriptObjectOwner, public nsIDOMEventReceiver, @@ -52,7 +51,7 @@ public: NS_IMPL_IDOMCHARACTERDATA_USING_GENERIC_DOM_DATA(mInner) // nsIDOMText - NS_IMETHOD SplitText(PRUint32 aOffset, nsIDOMText** aReturn); + NS_IMPL_IDOMTEXT_USING_GENERIC_DOM_DATA(mInner) // nsIScriptObjectOwner NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC_DOM_DATA(mInner) @@ -64,16 +63,7 @@ public: NS_IMPL_ICONTENT_USING_GENERIC_DOM_DATA(mInner) // nsITextContent - NS_IMETHOD GetText(const nsTextFragment*& aFragmentsResult, - PRInt32& aNumFragmentsResult); - NS_IMETHOD SetText(const PRUnichar* aBuffer, - PRInt32 aLength, - PRBool aNotify); - NS_IMETHOD SetText(const char* aBuffer, - PRInt32 aLength, - PRBool aNotify); - - NS_IMETHOD IsOnlyWhitespace(PRBool* aResult); + NS_IMPL_ITEXTCONTENT_USING_GENERIC_DOM_DATA(mInner) protected: nsGenericDOMDataNode mInner; @@ -197,138 +187,3 @@ nsTextNode::HandleDOMEvent(nsIPresContext& aPresContext, return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus); } - -//---------------------------------------------------------------------- - -// Implementation of the nsIDOMText interface - -NS_IMETHODIMP -nsTextNode::SplitText(PRUint32 aOffset, nsIDOMText** aReturn) -{ - nsresult result = NS_OK; - nsIContent* newNode; - nsITextContent* text; - nsAutoString cutText; - nsIContent* parentNode; - PRUint32 length; - - GetLength(&length); - // Cut the second part out of the original text node - result = SubstringData(aOffset, length-aOffset, cutText); - if (NS_OK == result) { - result = DeleteData(aOffset, length-aOffset); - if (NS_OK == result) { - // Create a new text node and set its data to the - // string we just cut out - result = NS_NewTextNode(&newNode); - if (NS_OK == result) { - result = newNode->QueryInterface(kITextContentIID, (void**)&text); - if (NS_OK == result) { - text->SetText(cutText, cutText.Length(), PR_FALSE); - // Find the parent of the current node and insert the - // new text node as a child after the current node - GetParent(parentNode); - if (nsnull != parentNode) { - PRInt32 index; - - result = parentNode->IndexOf(this, index); - if (NS_OK == result) { - result = parentNode->InsertChildAt(newNode, index+1, PR_TRUE); - } - NS_RELEASE(parentNode); - } - result = text->QueryInterface(kIDOMTextIID, (void**)aReturn); - NS_RELEASE(text); - } - NS_RELEASE(newNode); - } - } - } - - return result; -} - -//---------------------------------------------------------------------- - -// Implementation of the nsITextContent interface - -NS_IMETHODIMP -nsTextNode::GetText(const nsTextFragment*& aFragmentsResult, - PRInt32& aNumFragmentsResult) -{ - aFragmentsResult = &mInner.mText; - aNumFragmentsResult = 1; - return NS_OK; -} - -NS_IMETHODIMP -nsTextNode::SetText(const PRUnichar* aBuffer, PRInt32 aLength, - PRBool aNotify) -{ - NS_PRECONDITION((aLength >= 0) && (nsnull != aBuffer), "bad args"); - if (aLength < 0) { - return NS_ERROR_ILLEGAL_VALUE; - } - if (nsnull == aBuffer) { - return NS_ERROR_NULL_POINTER; - } - mInner.mText.SetTo(aBuffer, aLength); - - // Trigger a reflow - if (aNotify && (nsnull != mInner.mDocument)) { - mInner.mDocument->ContentChanged(this, nsnull); - } - return NS_OK; -} - -NS_IMETHODIMP -nsTextNode::SetText(const char* aBuffer, PRInt32 aLength, - PRBool aNotify) -{ - NS_PRECONDITION((aLength >= 0) && (nsnull != aBuffer), "bad args"); - if (aLength < 0) { - return NS_ERROR_ILLEGAL_VALUE; - } - if (nsnull == aBuffer) { - return NS_ERROR_NULL_POINTER; - } - mInner.mText.SetTo(aBuffer, aLength); - - // Trigger a reflow - if (aNotify && (nsnull != mInner.mDocument)) { - mInner.mDocument->ContentChanged(this, nsnull); - } - return NS_OK; -} - -NS_IMETHODIMP -nsTextNode::IsOnlyWhitespace(PRBool* aResult) -{ - nsTextFragment& frag = mInner.mText; - if (frag.Is2b()) { - const PRUnichar* cp = frag.Get2b(); - const PRUnichar* end = cp + frag.GetLength(); - while (cp < end) { - PRUnichar ch = *cp++; - if (!XP_IS_SPACE(ch)) { - *aResult = PR_FALSE; - return NS_OK; - } - } - } - else { - const char* cp = frag.Get1b(); - const char* end = cp + frag.GetLength(); - while (cp < end) { - PRUnichar ch = PRUnichar(*(unsigned char*)cp); - cp++; - if (!XP_IS_SPACE(ch)) { - *aResult = PR_FALSE; - return NS_OK; - } - } - } - - *aResult = PR_TRUE; - return NS_OK; -} diff --git a/layout/html/base/src/nsHTMLAtoms.cpp b/layout/html/base/src/nsHTMLAtoms.cpp index c3406639db9..f7a99122e82 100644 --- a/layout/html/base/src/nsHTMLAtoms.cpp +++ b/layout/html/base/src/nsHTMLAtoms.cpp @@ -200,6 +200,7 @@ nsIAtom* nsHTMLAtoms::param; nsIAtom* nsHTMLAtoms::placeholderPseudo; nsIAtom* nsHTMLAtoms::pointSize; nsIAtom* nsHTMLAtoms::pre; +nsIAtom* nsHTMLAtoms::processingInstructionPseudo; nsIAtom* nsHTMLAtoms::profile; nsIAtom* nsHTMLAtoms::prompt; nsIAtom* nsHTMLAtoms::readonly; @@ -457,6 +458,7 @@ void nsHTMLAtoms::AddrefAtoms() placeholderPseudo = NS_NewAtom(":placeholder-frame"); pointSize = NS_NewAtom("point-size"); pre = NS_NewAtom("pre"); + processingInstructionPseudo = NS_NewAtom(":-moz-pi"); profile = NS_NewAtom("profile"); prompt = NS_NewAtom("prompt"); readonly = NS_NewAtom("readonly"); @@ -706,6 +708,7 @@ void nsHTMLAtoms::ReleaseAtoms() NS_RELEASE(placeholderPseudo); NS_RELEASE(pointSize); NS_RELEASE(pre); + NS_RELEASE(processingInstructionPseudo); NS_RELEASE(profile); NS_RELEASE(prompt); NS_RELEASE(readonly); diff --git a/layout/html/base/src/nsHTMLAtoms.h b/layout/html/base/src/nsHTMLAtoms.h index a414388c166..764b1b39647 100644 --- a/layout/html/base/src/nsHTMLAtoms.h +++ b/layout/html/base/src/nsHTMLAtoms.h @@ -232,6 +232,7 @@ public: static nsIAtom* placeholderPseudo; static nsIAtom* pointSize; static nsIAtom* pre; + static nsIAtom* processingInstructionPseudo; static nsIAtom* profile; static nsIAtom* prompt; diff --git a/layout/html/content/src/nsHTMLLIElement.cpp b/layout/html/content/src/nsHTMLLIElement.cpp index d4fb72aed06..27e8e36b6fd 100644 --- a/layout/html/content/src/nsHTMLLIElement.cpp +++ b/layout/html/content/src/nsHTMLLIElement.cpp @@ -129,6 +129,7 @@ NS_IMPL_STRING_ATTR(nsHTMLLIElement, Type, type) NS_IMPL_INT_ATTR(nsHTMLLIElement, Value, value) static nsGenericHTMLElement::EnumTable kListItemTypeTable[] = { + { "disc", NS_STYLE_LIST_STYLE_DISC }, { "circle", NS_STYLE_LIST_STYLE_CIRCLE }, { "round", NS_STYLE_LIST_STYLE_CIRCLE }, { "square", NS_STYLE_LIST_STYLE_SQUARE }, diff --git a/layout/html/document/src/nsHTMLDocument.cpp b/layout/html/document/src/nsHTMLDocument.cpp index 864d6c762fd..fe6b0e44551 100644 --- a/layout/html/document/src/nsHTMLDocument.cpp +++ b/layout/html/document/src/nsHTMLDocument.cpp @@ -87,59 +87,6 @@ static NS_DEFINE_IID(kIHTMLContentContainerIID, NS_IHTMLCONTENTCONTAINER_IID); static NS_DEFINE_IID(kIDOMHTMLElementIID, NS_IDOMHTMLELEMENT_IID); static NS_DEFINE_IID(kIDOMHTMLBodyElementIID, NS_IDOMHTMLBODYELEMENT_IID); -// ================================================================== -// = -// ================================================================== -class nsHTMLDocumentChildNodes : public nsGenericDOMNodeList -{ -public: - nsHTMLDocumentChildNodes(nsIDOMDocument* aDocument); - ~nsHTMLDocumentChildNodes(); - - NS_IMETHOD GetLength(PRUint32* aLength); - NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn); - -protected: - nsIDOMDocument* mDocument; -}; - -nsHTMLDocumentChildNodes::nsHTMLDocumentChildNodes(nsIDOMDocument* aDocument) -{ - mDocument = aDocument; - NS_ADDREF(mDocument); -} - -nsHTMLDocumentChildNodes::~nsHTMLDocumentChildNodes() -{ - NS_RELEASE(mDocument); -} - -NS_IMETHODIMP -nsHTMLDocumentChildNodes::GetLength(PRUint32* aLength) -{ - *aLength = 1; - return NS_OK; -} - -NS_IMETHODIMP -nsHTMLDocumentChildNodes::Item(PRUint32 aIndex, nsIDOMNode** aReturn) -{ - nsresult result = NS_OK; - if (0 == aIndex) { - nsIDOMElement* root; - - result = mDocument->GetDocumentElement(&root); - if (NS_OK == result) { - result = root->QueryInterface(kIDOMNodeIID, (void**)aReturn); - NS_RELEASE(root); - } - } - else { - *aReturn = nsnull; - } - - return result; -} // ================================================================== // = @@ -840,36 +787,19 @@ nsHTMLDocument::GetElementsByTagName(const nsString& aTagname, nsIDOMNodeList** NS_IMETHODIMP nsHTMLDocument::GetChildNodes(nsIDOMNodeList** aChildNodes) { - nsHTMLDocumentChildNodes* childNodes = new nsHTMLDocumentChildNodes((nsIDOMDocument*)(nsIDOMHTMLDocument*)this); - if (nsnull == childNodes) { - return NS_ERROR_OUT_OF_MEMORY; - } - - return childNodes->QueryInterface(kIDOMNodeListIID, (void**)aChildNodes); + return nsDocument::GetChildNodes(aChildNodes); } NS_IMETHODIMP nsHTMLDocument::GetFirstChild(nsIDOMNode** aFirstChild) { - if (nsnull != mRootContent) { - return mRootContent->QueryInterface(kIDOMNodeIID, (void**)aFirstChild); - } - else { - *aFirstChild = nsnull; - return NS_OK; - } + return nsDocument::GetFirstChild(aFirstChild); } NS_IMETHODIMP nsHTMLDocument::GetLastChild(nsIDOMNode** aLastChild) { - if (nsnull != mRootContent) { - return mRootContent->QueryInterface(kIDOMNodeIID, (void**)aLastChild); - } - else { - *aLastChild = nsnull; - return NS_OK; - } + return nsDocument::GetLastChild(aLastChild); } NS_IMETHODIMP @@ -877,8 +807,7 @@ nsHTMLDocument::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aReturn) { - *aReturn = nsnull; - return NS_OK; + return nsDocument::InsertBefore(aNewChild, aRefChild, aReturn); } NS_IMETHODIMP @@ -886,29 +815,25 @@ nsHTMLDocument::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aReturn) { - *aReturn = nsnull; - return NS_OK; + return nsDocument::ReplaceChild(aNewChild, aOldChild, aReturn); } NS_IMETHODIMP nsHTMLDocument::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) { - *aReturn = nsnull; - return NS_OK; + return nsDocument::RemoveChild(aOldChild, aReturn); } NS_IMETHODIMP nsHTMLDocument::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn) { - *aReturn = nsnull; - return NS_OK; + return nsDocument::AppendChild(aNewChild, aReturn); } NS_IMETHODIMP nsHTMLDocument::HasChildNodes(PRBool* aReturn) { - *aReturn = PR_TRUE; - return NS_OK; + return nsDocument::HasChildNodes(aReturn); } NS_IMETHODIMP diff --git a/layout/html/document/src/ua.css b/layout/html/document/src/ua.css index 07fec5f98f8..79114d5bf59 100644 --- a/layout/html/document/src/ua.css +++ b/layout/html/document/src/ua.css @@ -874,6 +874,10 @@ sourcetext { display: none; } +:-moz-pi { + display: none; +} + :dropdown-visible { visibility: visible; } diff --git a/layout/html/style/src/nsCSSFrameConstructor.cpp b/layout/html/style/src/nsCSSFrameConstructor.cpp index 50ddf85cea2..c38e2e5dd42 100644 --- a/layout/html/style/src/nsCSSFrameConstructor.cpp +++ b/layout/html/style/src/nsCSSFrameConstructor.cpp @@ -2962,6 +2962,17 @@ nsCSSFrameConstructor::ResolveStyleContext(nsIPresContext* aPresContext, parentStyleContext, PR_FALSE, aStyleContext); + } else if (nsLayoutAtoms::processingInstructionTagName == aTag) { + // Use a special pseudo element style context for comments + nsCOMPtr parentContent; + if (nsnull != aParentFrame) { + aParentFrame->GetContent(getter_AddRefs(parentContent)); + } + rv = aPresContext->ResolvePseudoStyleContextFor(parentContent, + nsHTMLAtoms::processingInstructionPseudo, + parentStyleContext, + PR_FALSE, + aStyleContext); } else { rv = aPresContext->ResolveStyleContextFor(aContent, parentStyleContext, PR_FALSE, @@ -3019,6 +3030,17 @@ nsCSSFrameConstructor::ConstructFrame(nsIPresContext* aPresContext, parentStyleContext, PR_FALSE, getter_AddRefs(styleContext)); + } else if (nsLayoutAtoms::processingInstructionTagName == tag) { + // Use a special pseudo element style context for comments + nsCOMPtr parentContent; + if (nsnull != aParentFrame) { + aParentFrame->GetContent(getter_AddRefs(parentContent)); + } + rv = aPresContext->ResolvePseudoStyleContextFor(parentContent, + nsHTMLAtoms::processingInstructionPseudo, + parentStyleContext, + PR_FALSE, + getter_AddRefs(styleContext)); } else { rv = aPresContext->ResolveStyleContextFor(aContent, parentStyleContext, PR_FALSE, diff --git a/layout/html/style/src/nsCSSStyleSheet.cpp b/layout/html/style/src/nsCSSStyleSheet.cpp index 6e30e4cbde9..689f48d24da 100644 --- a/layout/html/style/src/nsCSSStyleSheet.cpp +++ b/layout/html/style/src/nsCSSStyleSheet.cpp @@ -1068,7 +1068,8 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext, nsIAtom* tag; firstChild->GetTag(tag); if ((tag != nsLayoutAtoms::textTagName) && - (tag != nsLayoutAtoms::commentTagName)) { + (tag != nsLayoutAtoms::commentTagName) && + (tag != nsLayoutAtoms::processingInstructionTagName)) { NS_IF_RELEASE(tag); break; } diff --git a/layout/style/nsCSSStyleSheet.cpp b/layout/style/nsCSSStyleSheet.cpp index 6e30e4cbde9..689f48d24da 100644 --- a/layout/style/nsCSSStyleSheet.cpp +++ b/layout/style/nsCSSStyleSheet.cpp @@ -1068,7 +1068,8 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext, nsIAtom* tag; firstChild->GetTag(tag); if ((tag != nsLayoutAtoms::textTagName) && - (tag != nsLayoutAtoms::commentTagName)) { + (tag != nsLayoutAtoms::commentTagName) && + (tag != nsLayoutAtoms::processingInstructionTagName)) { NS_IF_RELEASE(tag); break; } diff --git a/layout/style/ua.css b/layout/style/ua.css index 07fec5f98f8..79114d5bf59 100644 --- a/layout/style/ua.css +++ b/layout/style/ua.css @@ -874,6 +874,10 @@ sourcetext { display: none; } +:-moz-pi { + display: none; +} + :dropdown-visible { visibility: visible; } diff --git a/layout/xml/content/public/nsIXMLContent.h b/layout/xml/content/public/nsIXMLContent.h index 2d9f3a92ebd..789e3ec0d21 100644 --- a/layout/xml/content/public/nsIXMLContent.h +++ b/layout/xml/content/public/nsIXMLContent.h @@ -46,4 +46,13 @@ public: extern nsresult NS_NewXMLElement(nsIXMLContent** aResult, nsIAtom* aTag); +// XXX These belongs elsewhere +extern nsresult +NS_NewXMLProcessingInstruction(nsIContent** aInstancePtrResult, + const nsString& aTarget, + const nsString& aData); + +extern nsresult +NS_NewXMLCDATASection(nsIContent** aInstancePtrResult); + #endif // nsIXMLContent_h___ diff --git a/layout/xml/content/src/Makefile.in b/layout/xml/content/src/Makefile.in index 211613a0c71..11f2f7286be 100644 --- a/layout/xml/content/src/Makefile.in +++ b/layout/xml/content/src/Makefile.in @@ -40,6 +40,8 @@ INCLUDES += \ CPPSRCS = \ nsXMLElement.cpp \ nsGenericXMLElement.cpp \ + nsXMLCDATASection.cpp \ + nsXMLProcessingInstruction.cpp \ $(NULL) EXPORTS = \ diff --git a/layout/xml/content/src/makefile.win b/layout/xml/content/src/makefile.win index 2bc0c041c61..3e2aa193ae6 100644 --- a/layout/xml/content/src/makefile.win +++ b/layout/xml/content/src/makefile.win @@ -26,11 +26,15 @@ DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN CPPSRCS= \ nsXMLElement.cpp \ nsGenericXMLElement.cpp \ + nsXMLCDATASection.cpp \ + nsXMLProcessingInstruction.cpp \ $(NULL) CPP_OBJS= \ .\$(OBJDIR)\nsXMLElement.obj \ .\$(OBJDIR)\nsGenericXMLElement.obj \ + .\$(OBJDIR)\nsXMLCDATASection.obj \ + .\$(OBJDIR)\nsXMLProcessingInstruction.obj \ $(NULL) EXPORTS = \ diff --git a/layout/xml/content/src/nsXMLCDATASection.cpp b/layout/xml/content/src/nsXMLCDATASection.cpp new file mode 100644 index 00000000000..c785a57c17b --- /dev/null +++ b/layout/xml/content/src/nsXMLCDATASection.cpp @@ -0,0 +1,195 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + +#include "nsIDOMCDATASection.h" +#include "nsIScriptObjectOwner.h" +#include "nsIDOMEventReceiver.h" +#include "nsIContent.h" +#include "nsITextContent.h" +#include "nsGenericDOMDataNode.h" +#include "nsFrame.h" +#include "nsIDocument.h" +#include "nsCRT.h" +#include "nsLayoutAtoms.h" +#include "nsIXMLContent.h" + +static NS_DEFINE_IID(kIDOMCDATASectionIID, NS_IDOMCDATASECTION_IID); +static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID); +static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID); + +class nsXMLCDATASection : public nsIDOMCDATASection, + public nsIScriptObjectOwner, + public nsIDOMEventReceiver, + public nsIContent, + public nsITextContent +{ +public: + nsXMLCDATASection(); + virtual ~nsXMLCDATASection(); + + // nsISupports + NS_DECL_ISUPPORTS + + // nsIDOMNode + NS_IMPL_IDOMNODE_USING_GENERIC_DOM_DATA(mInner) + + // nsIDOMCharacterData + NS_IMPL_IDOMCHARACTERDATA_USING_GENERIC_DOM_DATA(mInner) + + // nsIDOMText + NS_IMPL_IDOMTEXT_USING_GENERIC_DOM_DATA(mInner) + + // nsIScriptObjectOwner + NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC_DOM_DATA(mInner) + + // nsIDOMEventReceiver + NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC_DOM_DATA(mInner) + + // nsIContent + NS_IMPL_ICONTENT_USING_GENERIC_DOM_DATA(mInner) + + // nsITextContent + NS_IMPL_ITEXTCONTENT_USING_GENERIC_DOM_DATA(mInner) + +protected: + nsGenericDOMDataNode mInner; +}; + +nsresult +NS_NewXMLCDATASection(nsIContent** aInstancePtrResult) +{ + NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); + if (nsnull == aInstancePtrResult) { + return NS_ERROR_NULL_POINTER; + } + nsIContent* it = new nsXMLCDATASection(); + if (nsnull == it) { + return NS_ERROR_OUT_OF_MEMORY; + } + return it->QueryInterface(kIContentIID, (void **) aInstancePtrResult); +} + +nsXMLCDATASection::nsXMLCDATASection() +{ + NS_INIT_REFCNT(); + mInner.Init(this); +} + +nsXMLCDATASection::~nsXMLCDATASection() +{ +} + +NS_IMPL_ADDREF(nsXMLCDATASection) +NS_IMPL_RELEASE(nsXMLCDATASection) + +NS_IMETHODIMP +nsXMLCDATASection::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + NS_IMPL_DOM_DATA_QUERY_INTERFACE(aIID, aInstancePtr, this) + if (aIID.Equals(kIDOMCDATASectionIID)) { + nsIDOMCDATASection* tmp = this; + *aInstancePtr = (void*) tmp; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(kIDOMTextIID)) { + nsIDOMText* tmp = this; + *aInstancePtr = (void*) tmp; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(kITextContentIID)) { + nsITextContent* tmp = this; + *aInstancePtr = (void*) tmp; + NS_ADDREF_THIS(); + return NS_OK; + } + return NS_NOINTERFACE; +} + +NS_IMETHODIMP +nsXMLCDATASection::GetTag(nsIAtom*& aResult) const +{ + aResult = nsLayoutAtoms::textTagName; + NS_ADDREF(aResult); + return NS_OK; +} + +NS_IMETHODIMP +nsXMLCDATASection::GetNodeName(nsString& aNodeName) +{ + aNodeName.SetString("#cdata-section"); + return NS_OK; +} + +NS_IMETHODIMP +nsXMLCDATASection::GetNodeType(PRUint16* aNodeType) +{ + *aNodeType = (PRUint16)nsIDOMNode::CDATA_SECTION_NODE; + return NS_OK; +} + +NS_IMETHODIMP +nsXMLCDATASection::CloneNode(PRBool aDeep, nsIDOMNode** aReturn) +{ + nsXMLCDATASection* it; + NS_NEWXPCOM(it, nsXMLCDATASection); + if (nsnull == it) { + return NS_ERROR_OUT_OF_MEMORY; + } + nsAutoString data; + nsresult result = GetData(data); + if (NS_FAILED(result)) { + return result; + } + result = it->SetData(data); + if (NS_FAILED(result)) { + return result; + } + return it->QueryInterface(kIDOMNodeIID, (void**) aReturn); +} + +NS_IMETHODIMP +nsXMLCDATASection::List(FILE* out, PRInt32 aIndent) const +{ + NS_PRECONDITION(nsnull != mInner.mDocument, "bad content"); + + PRInt32 index; + for (index = aIndent; --index >= 0; ) fputs(" ", out); + + fprintf(out, "CDATASection refcount=%d<", mRefCnt); + + nsAutoString tmp; + mInner.ToCString(tmp, 0, mInner.mText.GetLength()); + fputs(tmp, out); + + fputs(">\n", out); + return NS_OK; +} + +NS_IMETHODIMP +nsXMLCDATASection::HandleDOMEvent(nsIPresContext& aPresContext, + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, + nsEventStatus& aEventStatus) +{ + return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent, + aFlags, aEventStatus); +} diff --git a/layout/xml/content/src/nsXMLProcessingInstruction.cpp b/layout/xml/content/src/nsXMLProcessingInstruction.cpp new file mode 100644 index 00000000000..c9e5837d449 --- /dev/null +++ b/layout/xml/content/src/nsXMLProcessingInstruction.cpp @@ -0,0 +1,275 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + + +#include "nsIDOMProcessingInstruction.h" +#include "nsIScriptObjectOwner.h" +#include "nsIDOMEventReceiver.h" +#include "nsIContent.h" +#include "nsGenericDOMDataNode.h" +#include "nsGenericElement.h" +#include "nsIDOMScriptObjectFactory.h" +#include "nsLayoutAtoms.h" +#include "nsString.h" +#include "nsIXMLContent.h" + +static NS_DEFINE_IID(kIDOMProcessingInstructionIID, NS_IDOMPROCESSINGINSTRUCTION_IID); + +class nsXMLProcessingInstruction : public nsIDOMProcessingInstruction, + public nsIScriptObjectOwner, + public nsIDOMEventReceiver, + public nsIContent +{ +public: + nsXMLProcessingInstruction(const nsString& aTarget, const nsString& aData); + virtual ~nsXMLProcessingInstruction(); + + // nsISupports + NS_DECL_ISUPPORTS + + // nsIDOMNode + NS_IMPL_IDOMNODE_USING_GENERIC_DOM_DATA(mInner) + + // nsIDOMProcessingInstruction + NS_IMETHOD GetTarget(nsString& aTarget); + NS_IMETHOD GetData(nsString& aData); + NS_IMETHOD SetData(const nsString& aData); + + // nsIScriptObjectOwner interface + NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject); + NS_IMETHOD SetScriptObject(void *aScriptObject); + + // nsIDOMEventReceiver + NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC_DOM_DATA(mInner) + + // nsIContent + NS_IMPL_ICONTENT_USING_GENERIC_DOM_DATA(mInner) + +protected: + // XXX Processing instructions are currently implemented by using + // the generic CharacterData inner object, even though PIs are not + // character data. This is done simply for convenience and should + // be changed if this restricts what should be done for character data. + nsGenericDOMDataNode mInner; + nsString mTarget; + void* mScriptObject; +}; + +nsresult +NS_NewXMLProcessingInstruction(nsIContent** aInstancePtrResult, + const nsString& aTarget, + const nsString& aData) +{ + NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); + if (nsnull == aInstancePtrResult) { + return NS_ERROR_NULL_POINTER; + } + nsIContent* it = new nsXMLProcessingInstruction(aTarget, aData); + if (nsnull == it) { + return NS_ERROR_OUT_OF_MEMORY; + } + return it->QueryInterface(kIContentIID, (void **) aInstancePtrResult); +} + +nsXMLProcessingInstruction::nsXMLProcessingInstruction(const nsString& aTarget, + const nsString& aData) : + mTarget(aTarget) +{ + NS_INIT_REFCNT(); + mInner.Init(this); + mInner.SetData(aData); + mScriptObject = nsnull; +} + +nsXMLProcessingInstruction::~nsXMLProcessingInstruction() +{ +} + +NS_IMPL_ADDREF(nsXMLProcessingInstruction) +NS_IMPL_RELEASE(nsXMLProcessingInstruction) + +nsresult +nsXMLProcessingInstruction::QueryInterface(REFNSIID aIID, void** aInstancePtrResult) +{ + if (NULL == aInstancePtrResult) { + return NS_ERROR_NULL_POINTER; + } + + if (aIID.Equals(kISupportsIID)) { + nsIDOMProcessingInstruction* tmp = this; + nsISupports* tmp2 = tmp; + *aInstancePtrResult = (void*) tmp2; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(kIDOMNodeIID)) { + nsIDOMNode* tmp = this; + *aInstancePtrResult = (void*) tmp; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(kIDOMEventReceiverIID)) { + nsIDOMEventReceiver* tmp = this; + *aInstancePtrResult = (void*) tmp; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(kIScriptObjectOwnerIID)) { + nsIScriptObjectOwner* tmp = this; + *aInstancePtrResult = (void*) tmp; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(kIContentIID)) { + nsIContent* tmp = this; + *aInstancePtrResult = (void*) tmp; + NS_ADDREF_THIS(); + return NS_OK; + } + if (aIID.Equals(kIDOMProcessingInstructionIID)) { + nsIDOMProcessingInstruction* tmp = this; + *aInstancePtrResult = (void*) tmp; + NS_ADDREF_THIS(); + return NS_OK; + } + return NS_NOINTERFACE; +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::GetTarget(nsString& aTarget) +{ + aTarget.SetString(mTarget); + + return NS_OK; +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::GetData(nsString& aData) +{ + return mInner.GetData(aData); +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::SetData(const nsString& aData) +{ + // XXX Check if this is a stylesheet PI. If so, we may need + // to parse the contents and see if anything has changed. + return mInner.SetData(aData); +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::GetScriptObject(nsIScriptContext* aContext, + void** aScriptObject) +{ + nsresult res = NS_OK; + if (nsnull == mScriptObject) { + nsIDOMScriptObjectFactory *factory; + + res = nsGenericElement::GetScriptObjectFactory(&factory); + if (NS_OK != res) { + return res; + } + + res = factory->NewScriptProcessingInstruction(aContext, + (nsISupports*)(nsIDOMProcessingInstruction*)this, + mInner.mParent, + (void**)&mScriptObject); + + NS_RELEASE(factory); + } + *aScriptObject = mScriptObject; + return res; +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::SetScriptObject(void *aScriptObject) +{ + mScriptObject = aScriptObject; + return NS_OK; +} + + +NS_IMETHODIMP +nsXMLProcessingInstruction::GetTag(nsIAtom*& aResult) const +{ + aResult = nsLayoutAtoms::processingInstructionTagName; + NS_ADDREF(aResult); + return NS_OK; +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::GetNodeName(nsString& aNodeName) +{ + aNodeName.SetString(mTarget); + return NS_OK; +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::GetNodeType(PRUint16* aNodeType) +{ + *aNodeType = (PRUint16)nsIDOMNode::PROCESSING_INSTRUCTION_NODE; + return NS_OK; +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::CloneNode(PRBool aDeep, nsIDOMNode** aReturn) +{ + nsString data; + mInner.GetData(data); + + nsXMLProcessingInstruction* it = new nsXMLProcessingInstruction(mTarget, + data); + if (nsnull == it) { + return NS_ERROR_OUT_OF_MEMORY; + } + return it->QueryInterface(kIDOMNodeIID, (void**) aReturn); +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::List(FILE* out, PRInt32 aIndent) const +{ + NS_PRECONDITION(nsnull != mInner.mDocument, "bad content"); + + PRInt32 index; + for (index = aIndent; --index >= 0; ) fputs(" ", out); + + fprintf(out, "Processing instruction refcount=%d<", mRefCnt); + + nsAutoString tmp; + mInner.ToCString(tmp, 0, mInner.mText.GetLength()); + tmp.Insert(mTarget, 0); + fputs(tmp, out); + + fputs(">\n", out); + return NS_OK; +} + +NS_IMETHODIMP +nsXMLProcessingInstruction::HandleDOMEvent(nsIPresContext& aPresContext, + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, + nsEventStatus& aEventStatus) +{ + // We should never be getting events + NS_ASSERTION(0, "event handler called for processing instruction"); + return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent, + aFlags, aEventStatus); +} + diff --git a/layout/xml/document/public/nsIXMLDocument.h b/layout/xml/document/public/nsIXMLDocument.h index c3ecce7b9d2..cca3881af90 100644 --- a/layout/xml/document/public/nsIXMLDocument.h +++ b/layout/xml/document/public/nsIXMLDocument.h @@ -34,14 +34,6 @@ class nsIAtom; */ class nsIXMLDocument : public nsISupports { public: - NS_IMETHOD PrologElementAt(PRUint32 aOffset, nsIContent** aContent)=0; - NS_IMETHOD PrologCount(PRUint32* aCount)=0; - NS_IMETHOD AppendToProlog(nsIContent* aContent)=0; - - NS_IMETHOD EpilogElementAt(PRUint32 aOffset, nsIContent** aContent)=0; - NS_IMETHOD EpilogCount(PRUint32* aCount)=0; - NS_IMETHOD AppendToEpilog(nsIContent* aContent)=0; - // XXX This (or a variant thereof) should be in a DOM interface. // Since it isn't, we add it here temporarily NS_IMETHOD GetContentById(const nsString& aName, nsIContent** aContent)=0; diff --git a/layout/xml/document/src/nsXMLContentSink.cpp b/layout/xml/document/src/nsXMLContentSink.cpp index 65613d9a293..cffd4a22bbb 100644 --- a/layout/xml/document/src/nsXMLContentSink.cpp +++ b/layout/xml/document/src/nsXMLContentSink.cpp @@ -34,6 +34,7 @@ #include "nsIPresShell.h" #include "nsIViewManager.h" #include "nsIDOMComment.h" +#include "nsIDOMCDATASection.h" #include "nsIHTMLContent.h" #include "nsHTMLEntities.h" #include "nsHTMLParts.h" @@ -56,7 +57,7 @@ static char kNameSpaceSeparator[] = ":"; static char kNameSpaceDef[] = "xmlns"; -static char kStyleSheetPI[] = "QueryInterface(kIXMLDocumentIID, - (void **)&xmlDoc); + nsresult result = NS_OK; if (eXMLContentSinkState_InProlog == mState) { - result = xmlDoc->AppendToProlog(aContent); + result = mDocument->AppendToProlog(aContent); } else if (eXMLContentSinkState_InEpilog == mState) { - result = xmlDoc->AppendToEpilog(aContent); + result = mDocument->AppendToEpilog(aContent); } else { nsIContent *parent = GetCurrentContent(); @@ -872,7 +875,6 @@ nsXMLContentSink::AddContentAsLeaf(nsIContent *aContent) } } - NS_RELEASE(xmlDoc); return result; } @@ -903,6 +905,33 @@ nsXMLContentSink::AddComment(const nsIParserNode& aNode) return result; } +NS_IMETHODIMP +nsXMLContentSink::AddCDATASection(const nsIParserNode& aNode) +{ + FlushText(); + + nsAutoString text; + nsIContent *cdata; + nsIDOMCDATASection *domCDATA; + nsresult result = NS_OK; + + text = aNode.GetText(); + result = NS_NewXMLCDATASection(&cdata); + if (NS_OK == result) { + result = cdata->QueryInterface(kIDOMCDATASectionIID, (void **)&domCDATA); + if (NS_OK == result) { + domCDATA->AppendData(text); + NS_RELEASE(domCDATA); + + cdata->SetDocument(mDocument, PR_FALSE); + result = AddContentAsLeaf(cdata); + } + NS_RELEASE(cdata); + } + + return result; +} + // XXX Borrowed from HTMLContentSink. Should be shared. NS_IMETHODIMP nsXMLContentSink::LoadStyleSheet(nsIURL* aURL, @@ -1088,87 +1117,111 @@ nsXMLContentSink::LoadXSLStyleSheet(const nsIURL* aUrl) } #endif +static void +ParseProcessingInstruction(const nsString& aText, + nsString& aTarget, + nsString& aData) +{ + PRInt32 offset; + + aTarget.Truncate(); + aData.Truncate(); + + offset = aText.FindCharInSet(" \n\r\t"); + if (-1 != offset) { + aText.Mid(aTarget, 2, offset-2); + aText.Mid(aData, offset+1, aText.Length()-offset-3); + } +} + #ifndef XSL NS_IMETHODIMP nsXMLContentSink::AddProcessingInstruction(const nsIParserNode& aNode) { + nsresult result = NS_OK; + nsAutoString text, target, data; + nsIContent* node; + FlushText(); - // XXX For now, we don't add the PI to the content model. - // We just check for a style sheet PI - nsAutoString text, type, href, title, media; - PRInt32 offset; - nsresult result = NS_OK; - text = aNode.GetText(); + ParseProcessingInstruction(text, target, data); + result = NS_NewXMLProcessingInstruction(&node, target, data); + if (NS_OK == result) { + node->SetDocument(mDocument, PR_FALSE); + result = AddContentAsLeaf(node); + } - offset = text.Find(kStyleSheetPI); - // If it's a stylesheet PI... - if (0 == offset) { - result = GetQuotedAttributeValue(text, "href", href); - // If there was an error or there's no href, we can't do - // anything with this PI - if ((NS_OK != result) || (0 == href.Length())) { - return result; - } + if (NS_OK == result) { + nsAutoString type, href, title, media; - result = GetQuotedAttributeValue(text, "type", type); - if (NS_OK != result) { - return result; - } - result = GetQuotedAttributeValue(text, "title", title); - if (NS_OK != result) { - return result; - } - title.CompressWhitespace(); - result = GetQuotedAttributeValue(text, "media", media); - if (NS_OK != result) { - return result; - } - - if (type.Equals(kCSSType)) { - // Use the SRC attribute value to load the URL - nsIURL* url = nsnull; - nsAutoString absURL; - nsIURL* docURL = mDocument->GetDocumentURL(); - nsIURLGroup* urlGroup; + // If it's a stylesheet PI... + if (target.EqualsIgnoreCase(kStyleSheetPI)) { + result = GetQuotedAttributeValue(text, "href", href); + // If there was an error or there's no href, we can't do + // anything with this PI + if ((NS_OK != result) || (0 == href.Length())) { + return result; + } - result = docURL->GetURLGroup(&urlGroup); - - if ((NS_OK == result) && urlGroup) { - result = urlGroup->CreateURL(&url, docURL, href, nsnull); - NS_RELEASE(urlGroup); - } - else { - result = NS_NewURL(&url, absURL); - } - NS_RELEASE(docURL); + result = GetQuotedAttributeValue(text, "type", type); if (NS_OK != result) { return result; } - - nsAsyncStyleProcessingDataXML* d = new nsAsyncStyleProcessingDataXML; - if (nsnull == d) { - return NS_ERROR_OUT_OF_MEMORY; + result = GetQuotedAttributeValue(text, "title", title); + if (NS_OK != result) { + return result; } - d->mTitle.SetString(title); - d->mMedia.SetString(media); - d->mIsActive = PR_TRUE; - d->mURL = url; - NS_ADDREF(url); - // XXX Need to create PI node - d->mElement = nsnull; - d->mSink = this; - NS_ADDREF(this); - - nsIUnicharStreamLoader* loader; - result = NS_NewUnicharStreamLoader(&loader, - url, - (nsStreamCompleteFunc)nsDoneLoadingStyle, - (void *)d); - NS_RELEASE(url); - if (NS_OK == result) { - result = NS_ERROR_HTMLPARSER_BLOCK; + title.CompressWhitespace(); + result = GetQuotedAttributeValue(text, "media", media); + if (NS_OK != result) { + return result; + } + + if (type.Equals(kCSSType)) { + // Use the SRC attribute value to load the URL + nsIURL* url = nsnull; + nsAutoString absURL; + nsIURL* docURL = mDocument->GetDocumentURL(); + nsIURLGroup* urlGroup; + + result = docURL->GetURLGroup(&urlGroup); + + if ((NS_OK == result) && urlGroup) { + result = urlGroup->CreateURL(&url, docURL, href, nsnull); + NS_RELEASE(urlGroup); + } + else { + result = NS_NewURL(&url, absURL); + } + NS_RELEASE(docURL); + if (NS_OK != result) { + return result; + } + + nsAsyncStyleProcessingDataXML* d = new nsAsyncStyleProcessingDataXML; + if (nsnull == d) { + return NS_ERROR_OUT_OF_MEMORY; + } + d->mTitle.SetString(title); + d->mMedia.SetString(media); + d->mIsActive = PR_TRUE; + d->mURL = url; + NS_ADDREF(url); + // XXX Need to create PI node + d->mElement = nsnull; + d->mSink = this; + NS_ADDREF(this); + + nsIUnicharStreamLoader* loader; + result = NS_NewUnicharStreamLoader(&loader, + url, + (nsStreamCompleteFunc)nsDoneLoadingStyle, + (void *)d); + NS_RELEASE(url); + if (NS_OK == result) { + result = NS_ERROR_HTMLPARSER_BLOCK; + } } } } diff --git a/layout/xml/document/src/nsXMLContentSink.h b/layout/xml/document/src/nsXMLContentSink.h index ee2c0f97655..a67a14ea4a9 100644 --- a/layout/xml/document/src/nsXMLContentSink.h +++ b/layout/xml/document/src/nsXMLContentSink.h @@ -73,6 +73,7 @@ public: NS_IMETHOD AddLeaf(const nsIParserNode& aNode); NS_IMETHOD AddComment(const nsIParserNode& aNode); NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode); + NS_IMETHOD AddCDATASection(const nsIParserNode& aNode); NS_IMETHOD NotifyError(const nsParserError* aError); // nsIXMLContentSink diff --git a/layout/xml/document/src/nsXMLDocument.cpp b/layout/xml/document/src/nsXMLDocument.cpp index 7493cdc0653..867183c32ae 100644 --- a/layout/xml/document/src/nsXMLDocument.cpp +++ b/layout/xml/document/src/nsXMLDocument.cpp @@ -38,6 +38,8 @@ #include "nsIDOMComment.h" #include "nsIDOMElement.h" #include "nsIDOMText.h" +#include "nsIDOMCDATASection.h" +#include "nsIDOMProcessingInstruction.h" #include "nsExpatDTD.h" #include "nsINameSpaceManager.h" @@ -57,87 +59,10 @@ 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); +static NS_DEFINE_IID(kIDOMProcessingInstructionIID, NS_IDOMPROCESSINGINSTRUCTION_IID); +static NS_DEFINE_IID(kIDOMCDATASectionIID, NS_IDOMCDATASECTION_IID); +static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_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; - - 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; -} // ================================================================== // = @@ -155,9 +80,6 @@ nsXMLDocument::nsXMLDocument() mParser = nsnull; mAttrStyleSheet = nsnull; mInlineStyleSheet = nsnull; - mProlog = nsnull; - mEpilog = nsnull; - mChildNodes = nsnull; // XXX The XML world depends on the html atoms nsHTMLAtoms::AddrefAtoms(); @@ -169,8 +91,6 @@ nsXMLDocument::nsXMLDocument() nsXMLDocument::~nsXMLDocument() { - PRInt32 i, count; - nsIContent* content; NS_IF_RELEASE(mParser); if (nsnull != mAttrStyleSheet) { mAttrStyleSheet->SetOwningDocument(nsnull); @@ -180,23 +100,6 @@ nsXMLDocument::~nsXMLDocument() mInlineStyleSheet->SetOwningDocument(nsnull); 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) { - count = mEpilog->Count(); - for (i = 0; i < count; i++) { - content = (nsIContent*)mEpilog->ElementAt(i); - NS_RELEASE(content); - } - delete mEpilog; - } - NS_IF_RELEASE(mChildNodes); #ifdef INCLUDE_XUL nsXULAtoms::ReleaseAtoms(); #endif @@ -377,111 +280,6 @@ void nsXMLDocument::InternalAddStyleSheet(nsIStyleSheet* aSheet) // subclass ho } } - -// 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) @@ -494,25 +292,41 @@ nsXMLDocument::GetDoctype(nsIDOMDocumentType** aDocumentType) NS_IMETHODIMP nsXMLDocument::CreateCDATASection(const nsString& aData, nsIDOMCDATASection** aReturn) { - // XXX TBI - *aReturn = nsnull; - return NS_ERROR_NOT_IMPLEMENTED; + nsIContent* content; + nsresult rv = NS_NewXMLCDATASection(&content); + + if (NS_OK == rv) { + rv = content->QueryInterface(kIDOMCDATASectionIID, (void**)aReturn); + (*aReturn)->AppendData(aData); + NS_RELEASE(content); + } + + return rv; } NS_IMETHODIMP nsXMLDocument::CreateEntityReference(const nsString& aName, nsIDOMEntityReference** aReturn) { - // XXX TBI *aReturn = nsnull; - return NS_ERROR_NOT_IMPLEMENTED; + return NS_OK; } NS_IMETHODIMP -nsXMLDocument::CreateProcessingInstruction(const nsString& aTarget, const nsString& aData, nsIDOMProcessingInstruction** aReturn) +nsXMLDocument::CreateProcessingInstruction(const nsString& aTarget, + const nsString& aData, + nsIDOMProcessingInstruction** aReturn) { - // XXX TBI - *aReturn = nsnull; - return NS_ERROR_NOT_IMPLEMENTED; + nsIContent* content; + nsresult rv = NS_NewXMLProcessingInstruction(&content, aTarget, aData); + + if (NS_OK != rv) { + return rv; + } + + rv = content->QueryInterface(kIDOMProcessingInstructionIID, (void**)aReturn); + NS_RELEASE(content); + + return rv; } static char kNameSpaceSeparator[] = ":"; @@ -530,7 +344,8 @@ nsXMLDocument::CreateElement(const nsString& aTagName, return rv; } rv = content->QueryInterface(kIDOMElementIID, (void**)aReturn); - + NS_RELEASE(content); + return rv; } @@ -576,86 +391,6 @@ nsXMLDocument::CreateElementWithNameSpace(const nsString& aTagName, // nsIXMLDocument interface -NS_IMETHODIMP -nsXMLDocument::PrologElementAt(PRUint32 aIndex, nsIContent** aContent) -{ - if (nsnull == mProlog) { - *aContent = nsnull; - } - else { - *aContent = (nsIContent *)mProlog->ElementAt((PRInt32)aIndex); - NS_ADDREF(*aContent); - } - - return NS_OK; -} - -NS_IMETHODIMP -nsXMLDocument::PrologCount(PRUint32* aCount) -{ - if (nsnull == mProlog) { - *aCount = 0; - } - else { - *aCount = (PRUint32)mProlog->Count(); - } - - return NS_OK; -} - -NS_IMETHODIMP -nsXMLDocument::AppendToProlog(nsIContent* aContent) -{ - if (nsnull == mProlog) { - mProlog = new nsVoidArray(); - } - - mProlog->AppendElement((void *)aContent); - NS_ADDREF(aContent); - - return NS_OK; -} - -NS_IMETHODIMP -nsXMLDocument::EpilogElementAt(PRUint32 aIndex, nsIContent** aContent) -{ - if (nsnull == mEpilog) { - *aContent = nsnull; - } - else { - *aContent = (nsIContent *)mEpilog->ElementAt((PRInt32)aIndex); - NS_ADDREF(*aContent); - } - - return NS_OK; -} - -NS_IMETHODIMP -nsXMLDocument::EpilogCount(PRUint32* aCount) -{ - if (nsnull == mEpilog) { - *aCount = 0; - } - else { - *aCount = (PRUint32)mEpilog->Count(); - } - - return NS_OK; -} - -NS_IMETHODIMP -nsXMLDocument::AppendToEpilog(nsIContent* aContent) -{ - if (nsnull == mEpilog) { - mEpilog = new nsVoidArray(); - } - - mEpilog->AppendElement((void *)aContent); - NS_ADDREF(aContent); - - return NS_OK; -} - static nsIContent * MatchName(nsIContent *aContent, const nsString& aName) { diff --git a/layout/xml/document/src/nsXMLDocument.h b/layout/xml/document/src/nsXMLDocument.h index 2262f896b6b..074e92d3449 100644 --- a/layout/xml/document/src/nsXMLDocument.h +++ b/layout/xml/document/src/nsXMLDocument.h @@ -23,28 +23,9 @@ #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, @@ -67,20 +48,6 @@ 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); @@ -93,14 +60,6 @@ public: nsIDOMElement** aReturn); // nsIXMLDocument interface - NS_IMETHOD PrologElementAt(PRUint32 aOffset, nsIContent** aContent); - NS_IMETHOD PrologCount(PRUint32* aCount); - NS_IMETHOD AppendToProlog(nsIContent* aContent); - - NS_IMETHOD EpilogElementAt(PRUint32 aOffset, nsIContent** aContent); - NS_IMETHOD EpilogCount(PRUint32* aCount); - NS_IMETHOD AppendToEpilog(nsIContent* aContent); - NS_IMETHOD GetContentById(const nsString& aName, nsIContent** aContent); // nsIHTMLContentContainer @@ -111,16 +70,11 @@ protected: virtual void InternalAddStyleSheet(nsIStyleSheet* aSheet); // subclass hook for sheet ordering virtual nsresult Reset(nsIURL* aUrl); - // For HTML elements in our content model nsIHTMLStyleSheet* mAttrStyleSheet; nsIHTMLCSSStyleSheet* mInlineStyleSheet; - nsVoidArray *mProlog; - nsVoidArray *mEpilog; - nsIParser *mParser; - nsXMLDocumentChildNodes* mChildNodes; };