Added epilog and prolog to document. Added processing instructions and CDATASections for XML. Completed document Node methods.

This commit is contained in:
vidur%netscape.com 1999-03-31 20:49:25 +00:00
Родитель ca263b2c48
Коммит f6f2f989a9
59 изменённых файлов: 2892 добавлений и 1467 удалений

Просмотреть файл

@ -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.

Просмотреть файл

@ -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??

Просмотреть файл

@ -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

Просмотреть файл

@ -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;
};

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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.

Просмотреть файл

@ -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,

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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);

Просмотреть файл

@ -232,6 +232,7 @@ public:
static nsIAtom* placeholderPseudo;
static nsIAtom* pointSize;
static nsIAtom* pre;
static nsIAtom* processingInstructionPseudo;
static nsIAtom* profile;
static nsIAtom* prompt;

Просмотреть файл

@ -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 },

Просмотреть файл

@ -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

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -232,6 +232,7 @@ public:
static nsIAtom* placeholderPseudo;
static nsIAtom* pointSize;
static nsIAtom* pre;
static nsIAtom* processingInstructionPseudo;
static nsIAtom* profile;
static nsIAtom* prompt;

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);

Просмотреть файл

@ -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);

Просмотреть файл

@ -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___

Просмотреть файл

@ -40,6 +40,8 @@ INCLUDES += \
CPPSRCS = \
nsXMLElement.cpp \
nsGenericXMLElement.cpp \
nsXMLCDATASection.cpp \
nsXMLProcessingInstruction.cpp \
$(NULL)
EXPORTS = \

Просмотреть файл

@ -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 = \

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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;

Просмотреть файл

@ -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[] = "<?xml-stylesheet";
static char kStyleSheetPI[] = "xml-stylesheet";
static char kCSSType[] = "text/css";
#ifdef XSL
@ -70,6 +71,7 @@ static NS_DEFINE_IID(kIXMLDocumentIID, NS_IXMLDOCUMENT_IID);
static NS_DEFINE_IID(kIDOMCommentIID, NS_IDOMCOMMENT_IID);
static NS_DEFINE_IID(kIScrollableViewIID, NS_ISCROLLABLEVIEW_IID);
static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID);
static NS_DEFINE_IID(kIDOMCDATASectionIID, NS_IDOMCDATASECTION_IID);
static void SetTextStringOnTextNode(const nsString& aTextString, nsIContent* aTextNode);
@ -704,10 +706,13 @@ nsXMLContentSink::AddLeaf(const nsIParserNode& aNode)
case eToken_text:
case eToken_whitespace:
case eToken_newline:
case eToken_cdatasection:
AddText(aNode.GetText());
break;
case eToken_cdatasection:
AddCDATASection(aNode);
break;
case eToken_entity:
{
nsAutoString tmp;
@ -854,15 +859,13 @@ nsXMLContentSink::AddXMLDecl(const nsIParserNode& aNode)
nsresult
nsXMLContentSink::AddContentAsLeaf(nsIContent *aContent)
{
nsIXMLDocument *xmlDoc;
nsresult result = mDocument->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;
result = docURL->GetURLGroup(&urlGroup);
if ((NS_OK == result) && urlGroup) {
result = urlGroup->CreateURL(&url, docURL, href, nsnull);
NS_RELEASE(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;
}
else {
result = NS_NewURL(&url, absURL);
result = GetQuotedAttributeValue(text, "type", type);
if (NS_OK != result) {
return result;
}
NS_RELEASE(docURL);
result = GetQuotedAttributeValue(text, "title", title);
if (NS_OK != result) {
return result;
}
title.CompressWhitespace();
result = GetQuotedAttributeValue(text, "media", media);
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);
if (type.Equals(kCSSType)) {
// Use the SRC attribute value to load the URL
nsIURL* url = nsnull;
nsAutoString absURL;
nsIURL* docURL = mDocument->GetDocumentURL();
nsIURLGroup* urlGroup;
nsIUnicharStreamLoader* loader;
result = NS_NewUnicharStreamLoader(&loader,
url,
(nsStreamCompleteFunc)nsDoneLoadingStyle,
(void *)d);
NS_RELEASE(url);
if (NS_OK == result) {
result = NS_ERROR_HTMLPARSER_BLOCK;
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;
}
}
}
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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,6 +344,7 @@ 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)
{

Просмотреть файл

@ -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;
};

Просмотреть файл

@ -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<nsIContent> 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<nsIContent> 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,

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;

Просмотреть файл

@ -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.

Просмотреть файл

@ -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;

Просмотреть файл

@ -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??

Просмотреть файл

@ -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

Просмотреть файл

@ -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;
};

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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.

Просмотреть файл

@ -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,

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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);

Просмотреть файл

@ -232,6 +232,7 @@ public:
static nsIAtom* placeholderPseudo;
static nsIAtom* pointSize;
static nsIAtom* pre;
static nsIAtom* processingInstructionPseudo;
static nsIAtom* profile;
static nsIAtom* prompt;

Просмотреть файл

@ -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 },

Просмотреть файл

@ -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

Просмотреть файл

@ -874,6 +874,10 @@ sourcetext {
display: none;
}
:-moz-pi {
display: none;
}
:dropdown-visible {
visibility: visible;
}

Просмотреть файл

@ -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<nsIContent> 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<nsIContent> 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,

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -874,6 +874,10 @@ sourcetext {
display: none;
}
:-moz-pi {
display: none;
}
:dropdown-visible {
visibility: visible;
}

Просмотреть файл

@ -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___

Просмотреть файл

@ -40,6 +40,8 @@ INCLUDES += \
CPPSRCS = \
nsXMLElement.cpp \
nsGenericXMLElement.cpp \
nsXMLCDATASection.cpp \
nsXMLProcessingInstruction.cpp \
$(NULL)
EXPORTS = \

Просмотреть файл

@ -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 = \

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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;

Просмотреть файл

@ -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[] = "<?xml-stylesheet";
static char kStyleSheetPI[] = "xml-stylesheet";
static char kCSSType[] = "text/css";
#ifdef XSL
@ -70,6 +71,7 @@ static NS_DEFINE_IID(kIXMLDocumentIID, NS_IXMLDOCUMENT_IID);
static NS_DEFINE_IID(kIDOMCommentIID, NS_IDOMCOMMENT_IID);
static NS_DEFINE_IID(kIScrollableViewIID, NS_ISCROLLABLEVIEW_IID);
static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID);
static NS_DEFINE_IID(kIDOMCDATASectionIID, NS_IDOMCDATASECTION_IID);
static void SetTextStringOnTextNode(const nsString& aTextString, nsIContent* aTextNode);
@ -704,10 +706,13 @@ nsXMLContentSink::AddLeaf(const nsIParserNode& aNode)
case eToken_text:
case eToken_whitespace:
case eToken_newline:
case eToken_cdatasection:
AddText(aNode.GetText());
break;
case eToken_cdatasection:
AddCDATASection(aNode);
break;
case eToken_entity:
{
nsAutoString tmp;
@ -854,15 +859,13 @@ nsXMLContentSink::AddXMLDecl(const nsIParserNode& aNode)
nsresult
nsXMLContentSink::AddContentAsLeaf(nsIContent *aContent)
{
nsIXMLDocument *xmlDoc;
nsresult result = mDocument->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;
result = docURL->GetURLGroup(&urlGroup);
if ((NS_OK == result) && urlGroup) {
result = urlGroup->CreateURL(&url, docURL, href, nsnull);
NS_RELEASE(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;
}
else {
result = NS_NewURL(&url, absURL);
result = GetQuotedAttributeValue(text, "type", type);
if (NS_OK != result) {
return result;
}
NS_RELEASE(docURL);
result = GetQuotedAttributeValue(text, "title", title);
if (NS_OK != result) {
return result;
}
title.CompressWhitespace();
result = GetQuotedAttributeValue(text, "media", media);
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);
if (type.Equals(kCSSType)) {
// Use the SRC attribute value to load the URL
nsIURL* url = nsnull;
nsAutoString absURL;
nsIURL* docURL = mDocument->GetDocumentURL();
nsIURLGroup* urlGroup;
nsIUnicharStreamLoader* loader;
result = NS_NewUnicharStreamLoader(&loader,
url,
(nsStreamCompleteFunc)nsDoneLoadingStyle,
(void *)d);
NS_RELEASE(url);
if (NS_OK == result) {
result = NS_ERROR_HTMLPARSER_BLOCK;
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;
}
}
}
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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,6 +344,7 @@ 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)
{

Просмотреть файл

@ -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;
};