diff --git a/mozilla/content/base/public/nsIDocument.h b/mozilla/content/base/public/nsIDocument.h index 1abb8709712..49397f1e56e 100644 --- a/mozilla/content/base/public/nsIDocument.h +++ b/mozilla/content/base/public/nsIDocument.h @@ -110,6 +110,11 @@ public: */ NS_IMETHOD GetBaseURL(nsIURL*& aURL) const = 0; + /** + * Return the content (mime) type of this document. + */ + NS_IMETHOD GetContentType(nsString& aContentType) const = 0; + /** * Return a standard name for the document's character set. This will * trigger a startDocumentLoad if necessary to answer the question. diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index 6e91ce8f567..7c1e7117dcd 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -64,6 +64,7 @@ #include "nsFileSpec.h" #include "nsFileStream.h" +#include "nsRange.h" #include "nsIDOMText.h" #include "nsIDOMComment.h" @@ -445,8 +446,15 @@ nsDOMImplementation::HasFeature(const nsString& aFeature, { // XXX Currently this is hardcoded. In the future, we should // probably figure out some of this by querying the registry?? - if (aFeature.EqualsIgnoreCase("HTML") || - aFeature.EqualsIgnoreCase("XML")) { + PRInt32 result; + float ver = aVersion.ToFloat(&result); + if (NS_FAILED(result)) { + return result; + } + + if ((aFeature.EqualsIgnoreCase("HTML") || + aFeature.EqualsIgnoreCase("XML")) && + (ver >= 1.0) && (ver <= 2.0)) { *aReturn = PR_TRUE; } else { @@ -911,6 +919,13 @@ nsIURL* nsDocument::GetDocumentURL() const return mDocumentURL; } +NS_IMETHODIMP +nsDocument::GetContentType(nsString& aContentType) const +{ + // Must be implemented by derived class. + return NS_ERROR_NOT_IMPLEMENTED; +} + nsIURLGroup* nsDocument::GetDocumentURLGroup() const { NS_IF_ADDREF(mDocumentURLGroup); @@ -1829,6 +1844,12 @@ nsDocument::CreateElementWithNameSpace(const nsString& aTagName, return NS_OK; } +NS_IMETHODIMP +nsDocument::CreateRange(nsIDOMRange** aReturn) +{ + return NS_NewRange(aReturn); +} + // // nsIDOMNode methods // diff --git a/mozilla/content/base/src/nsDocument.h b/mozilla/content/base/src/nsDocument.h index d388a348fa9..3c4245a9958 100644 --- a/mozilla/content/base/src/nsDocument.h +++ b/mozilla/content/base/src/nsDocument.h @@ -126,6 +126,11 @@ public: */ virtual nsIURL* GetDocumentURL() const; + /** + * Return the content (mime) type of this document. + */ + NS_IMETHOD GetContentType(nsString& aContentType) const; + /** * Return the URLGroup for the document. May return null. */ @@ -323,6 +328,7 @@ public: NS_IMETHOD CreateElementWithNameSpace(const nsString& aTagName, const nsString& aNameSpace, nsIDOMElement** aReturn); + NS_IMETHOD CreateRange(nsIDOMRange** aReturn); // nsIDOMNode interface NS_IMETHOD GetNodeName(nsString& aNodeName); diff --git a/mozilla/content/base/src/nsRange.cpp b/mozilla/content/base/src/nsRange.cpp index 80c5d987663..1ec95aedc6d 100644 --- a/mozilla/content/base/src/nsRange.cpp +++ b/mozilla/content/base/src/nsRange.cpp @@ -33,9 +33,14 @@ #include "nsIContentIterator.h" #include "nsIDOMNodeList.h" #include "nsIScriptGlobalObject.h" +#include "nsIParser.h" +#include "nsIComponentManager.h" +#include "nsParserCIID.h" static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID); +static NS_DEFINE_IID(kCParserIID, NS_IPARSER_IID); +static NS_DEFINE_IID(kCParserCID, NS_PARSER_IID); nsVoidArray* nsRange::mStartAncestors = nsnull; nsVoidArray* nsRange::mEndAncestors = nsnull; @@ -1437,8 +1442,10 @@ nsresult nsRange::ToString(nsString& aReturn) // clear the string aReturn.Truncate(); - if (!cStart || !cEnd) - return NS_ERROR_UNEXPECTED; + // If we're unpositioned, return the empty string + if (!cStart || !cEnd) { + return NS_OK; + } // effeciency hack for simple case if (cStart == cEnd) @@ -1703,6 +1710,87 @@ nsRange::InsertFragment(const nsString& aFragment) return NS_OK; } +NS_IMETHODIMP +nsRange::IsValidFragment(const nsString& aFragment, PRBool* aReturn) +{ + nsresult result = NS_OK; + nsCOMPtr parser; + nsITagStack* tagStack; + + if (!mIsPositioned) { + return NS_ERROR_FAILURE; + } + + // Create a new parser for this entire operation + result = nsComponentManager::CreateInstance(kCParserCID, + nsnull, + kCParserIID, + (void **)getter_AddRefs(parser)); + if (NS_SUCCEEDED(result)) { + result = parser->CreateTagStack(&tagStack); + + if (NS_SUCCEEDED(result)) { + nsCOMPtr parent; + nsCOMPtr content(do_QueryInterface(mStartParent, &result)); + + if (NS_SUCCEEDED(result)) { + nsCOMPtr document; + + result = content->GetDocument(*getter_AddRefs(document)); + + if (NS_SUCCEEDED(result)) { + nsCOMPtr domDocument(do_QueryInterface(document, &result)); + + if (NS_SUCCEEDED(result)) { + parent = mStartParent; + while (parent && + (parent != domDocument) && + NS_SUCCEEDED(result)) { + nsCOMPtr temp; + nsAutoString tagName; + PRUnichar* name = nsnull; + + parent->GetNodeName(tagName); + // XXX Wish we didn't have to allocate here + name = tagName.ToNewUnicode(); + if (nsnull != name) { + tagStack->Push(name); + temp = parent; + result = temp->GetParentNode(getter_AddRefs(parent)); + } + else { + result = NS_ERROR_OUT_OF_MEMORY; + } + } + + if (NS_SUCCEEDED(result)) { + nsAutoString contentType; + + document->GetContentType(contentType); + *aReturn = parser->IsValidFragment(aFragment, + *tagStack, + 0, contentType); + } + } + } + } + + // XXX Ick! Delete strings we allocated above. + PRUnichar* str = nsnull; + str = tagStack->Pop(); + while (nsnull != str) { + delete[] str; + str = tagStack->Pop(); + } + + // XXX Double Ick! Deleting something that someone else newed. + delete tagStack; + } + } + + return result; +} + // BEGIN nsIScriptContextOwner interface implementations NS_IMETHODIMP nsRange::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject) diff --git a/mozilla/content/base/src/nsRange.h b/mozilla/content/base/src/nsRange.h index b8985f82251..ccfebc1ebcc 100644 --- a/mozilla/content/base/src/nsRange.h +++ b/mozilla/content/base/src/nsRange.h @@ -85,6 +85,7 @@ public: // nsIDOMNSRange interface NS_IMETHOD InsertFragment(const nsString& aFragment); + NS_IMETHOD IsValidFragment(const nsString& aFragment, PRBool* aReturn); /*BEGIN nsIScriptObjectOwner interface implementations*/ NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject); diff --git a/mozilla/content/html/document/src/nsHTMLDocument.cpp b/mozilla/content/html/document/src/nsHTMLDocument.cpp index 4a0feb64f44..3331128cc01 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/content/html/document/src/nsHTMLDocument.cpp @@ -261,6 +261,13 @@ nsHTMLDocument::Reset(nsIURL *aURL) return result; } +NS_IMETHODIMP +nsHTMLDocument::GetContentType(nsString& aContentType) const +{ + aContentType.SetString("text/html"); + return NS_OK; +} + NS_IMETHODIMP nsHTMLDocument::StartDocumentLoad(nsIURL *aURL, nsIContentViewerContainer* aContainer, diff --git a/mozilla/content/html/document/src/nsHTMLDocument.h b/mozilla/content/html/document/src/nsHTMLDocument.h index 6b6d997afb3..e6563de4408 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.h +++ b/mozilla/content/html/document/src/nsHTMLDocument.h @@ -50,6 +50,8 @@ public: NS_IMETHOD_(nsrefcnt) AddRef(void); NS_IMETHOD_(nsrefcnt) Release(void); + NS_IMETHOD GetContentType(nsString& aContentType) const; + NS_IMETHOD StartDocumentLoad(nsIURL* aUrl, nsIContentViewerContainer* aContainer, nsIStreamListener** aDocListener, diff --git a/mozilla/content/xml/document/src/nsXMLDocument.cpp b/mozilla/content/xml/document/src/nsXMLDocument.cpp index 2e4f29f45f6..ab98bb1380a 100644 --- a/mozilla/content/xml/document/src/nsXMLDocument.cpp +++ b/mozilla/content/xml/document/src/nsXMLDocument.cpp @@ -165,6 +165,14 @@ nsXMLDocument::Reset(nsIURL* aURL) return result; } +NS_IMETHODIMP +nsXMLDocument::GetContentType(nsString& aContentType) const +{ + // XXX Should get document type from incoming stream + aContentType.SetString("text/xml"); + return NS_OK; +} + NS_IMETHODIMP nsXMLDocument::StartDocumentLoad(nsIURL *aUrl, nsIContentViewerContainer* aContainer, diff --git a/mozilla/content/xml/document/src/nsXMLDocument.h b/mozilla/content/xml/document/src/nsXMLDocument.h index 074e92d3449..d6aefd2b13b 100644 --- a/mozilla/content/xml/document/src/nsXMLDocument.h +++ b/mozilla/content/xml/document/src/nsXMLDocument.h @@ -41,6 +41,8 @@ public: NS_IMETHOD_(nsrefcnt) AddRef(void); NS_IMETHOD_(nsrefcnt) Release(void); + NS_IMETHOD GetContentType(nsString& aContentType) const; + NS_IMETHOD StartDocumentLoad(nsIURL *aUrl, nsIContentViewerContainer* aContainer, nsIStreamListener **aDocListener, diff --git a/mozilla/layout/base/public/nsIDocument.h b/mozilla/layout/base/public/nsIDocument.h index 1abb8709712..49397f1e56e 100644 --- a/mozilla/layout/base/public/nsIDocument.h +++ b/mozilla/layout/base/public/nsIDocument.h @@ -110,6 +110,11 @@ public: */ NS_IMETHOD GetBaseURL(nsIURL*& aURL) const = 0; + /** + * Return the content (mime) type of this document. + */ + NS_IMETHOD GetContentType(nsString& aContentType) const = 0; + /** * Return a standard name for the document's character set. This will * trigger a startDocumentLoad if necessary to answer the question. diff --git a/mozilla/layout/base/src/nsDocument.cpp b/mozilla/layout/base/src/nsDocument.cpp index 6e91ce8f567..7c1e7117dcd 100644 --- a/mozilla/layout/base/src/nsDocument.cpp +++ b/mozilla/layout/base/src/nsDocument.cpp @@ -64,6 +64,7 @@ #include "nsFileSpec.h" #include "nsFileStream.h" +#include "nsRange.h" #include "nsIDOMText.h" #include "nsIDOMComment.h" @@ -445,8 +446,15 @@ nsDOMImplementation::HasFeature(const nsString& aFeature, { // XXX Currently this is hardcoded. In the future, we should // probably figure out some of this by querying the registry?? - if (aFeature.EqualsIgnoreCase("HTML") || - aFeature.EqualsIgnoreCase("XML")) { + PRInt32 result; + float ver = aVersion.ToFloat(&result); + if (NS_FAILED(result)) { + return result; + } + + if ((aFeature.EqualsIgnoreCase("HTML") || + aFeature.EqualsIgnoreCase("XML")) && + (ver >= 1.0) && (ver <= 2.0)) { *aReturn = PR_TRUE; } else { @@ -911,6 +919,13 @@ nsIURL* nsDocument::GetDocumentURL() const return mDocumentURL; } +NS_IMETHODIMP +nsDocument::GetContentType(nsString& aContentType) const +{ + // Must be implemented by derived class. + return NS_ERROR_NOT_IMPLEMENTED; +} + nsIURLGroup* nsDocument::GetDocumentURLGroup() const { NS_IF_ADDREF(mDocumentURLGroup); @@ -1829,6 +1844,12 @@ nsDocument::CreateElementWithNameSpace(const nsString& aTagName, return NS_OK; } +NS_IMETHODIMP +nsDocument::CreateRange(nsIDOMRange** aReturn) +{ + return NS_NewRange(aReturn); +} + // // nsIDOMNode methods // diff --git a/mozilla/layout/base/src/nsDocument.h b/mozilla/layout/base/src/nsDocument.h index d388a348fa9..3c4245a9958 100644 --- a/mozilla/layout/base/src/nsDocument.h +++ b/mozilla/layout/base/src/nsDocument.h @@ -126,6 +126,11 @@ public: */ virtual nsIURL* GetDocumentURL() const; + /** + * Return the content (mime) type of this document. + */ + NS_IMETHOD GetContentType(nsString& aContentType) const; + /** * Return the URLGroup for the document. May return null. */ @@ -323,6 +328,7 @@ public: NS_IMETHOD CreateElementWithNameSpace(const nsString& aTagName, const nsString& aNameSpace, nsIDOMElement** aReturn); + NS_IMETHOD CreateRange(nsIDOMRange** aReturn); // nsIDOMNode interface NS_IMETHOD GetNodeName(nsString& aNodeName); diff --git a/mozilla/layout/base/src/nsRange.cpp b/mozilla/layout/base/src/nsRange.cpp index 80c5d987663..1ec95aedc6d 100644 --- a/mozilla/layout/base/src/nsRange.cpp +++ b/mozilla/layout/base/src/nsRange.cpp @@ -33,9 +33,14 @@ #include "nsIContentIterator.h" #include "nsIDOMNodeList.h" #include "nsIScriptGlobalObject.h" +#include "nsIParser.h" +#include "nsIComponentManager.h" +#include "nsParserCIID.h" static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID); +static NS_DEFINE_IID(kCParserIID, NS_IPARSER_IID); +static NS_DEFINE_IID(kCParserCID, NS_PARSER_IID); nsVoidArray* nsRange::mStartAncestors = nsnull; nsVoidArray* nsRange::mEndAncestors = nsnull; @@ -1437,8 +1442,10 @@ nsresult nsRange::ToString(nsString& aReturn) // clear the string aReturn.Truncate(); - if (!cStart || !cEnd) - return NS_ERROR_UNEXPECTED; + // If we're unpositioned, return the empty string + if (!cStart || !cEnd) { + return NS_OK; + } // effeciency hack for simple case if (cStart == cEnd) @@ -1703,6 +1710,87 @@ nsRange::InsertFragment(const nsString& aFragment) return NS_OK; } +NS_IMETHODIMP +nsRange::IsValidFragment(const nsString& aFragment, PRBool* aReturn) +{ + nsresult result = NS_OK; + nsCOMPtr parser; + nsITagStack* tagStack; + + if (!mIsPositioned) { + return NS_ERROR_FAILURE; + } + + // Create a new parser for this entire operation + result = nsComponentManager::CreateInstance(kCParserCID, + nsnull, + kCParserIID, + (void **)getter_AddRefs(parser)); + if (NS_SUCCEEDED(result)) { + result = parser->CreateTagStack(&tagStack); + + if (NS_SUCCEEDED(result)) { + nsCOMPtr parent; + nsCOMPtr content(do_QueryInterface(mStartParent, &result)); + + if (NS_SUCCEEDED(result)) { + nsCOMPtr document; + + result = content->GetDocument(*getter_AddRefs(document)); + + if (NS_SUCCEEDED(result)) { + nsCOMPtr domDocument(do_QueryInterface(document, &result)); + + if (NS_SUCCEEDED(result)) { + parent = mStartParent; + while (parent && + (parent != domDocument) && + NS_SUCCEEDED(result)) { + nsCOMPtr temp; + nsAutoString tagName; + PRUnichar* name = nsnull; + + parent->GetNodeName(tagName); + // XXX Wish we didn't have to allocate here + name = tagName.ToNewUnicode(); + if (nsnull != name) { + tagStack->Push(name); + temp = parent; + result = temp->GetParentNode(getter_AddRefs(parent)); + } + else { + result = NS_ERROR_OUT_OF_MEMORY; + } + } + + if (NS_SUCCEEDED(result)) { + nsAutoString contentType; + + document->GetContentType(contentType); + *aReturn = parser->IsValidFragment(aFragment, + *tagStack, + 0, contentType); + } + } + } + } + + // XXX Ick! Delete strings we allocated above. + PRUnichar* str = nsnull; + str = tagStack->Pop(); + while (nsnull != str) { + delete[] str; + str = tagStack->Pop(); + } + + // XXX Double Ick! Deleting something that someone else newed. + delete tagStack; + } + } + + return result; +} + // BEGIN nsIScriptContextOwner interface implementations NS_IMETHODIMP nsRange::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject) diff --git a/mozilla/layout/base/src/nsRange.h b/mozilla/layout/base/src/nsRange.h index b8985f82251..ccfebc1ebcc 100644 --- a/mozilla/layout/base/src/nsRange.h +++ b/mozilla/layout/base/src/nsRange.h @@ -85,6 +85,7 @@ public: // nsIDOMNSRange interface NS_IMETHOD InsertFragment(const nsString& aFragment); + NS_IMETHOD IsValidFragment(const nsString& aFragment, PRBool* aReturn); /*BEGIN nsIScriptObjectOwner interface implementations*/ NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject); diff --git a/mozilla/layout/html/document/src/nsHTMLDocument.cpp b/mozilla/layout/html/document/src/nsHTMLDocument.cpp index 4a0feb64f44..3331128cc01 100644 --- a/mozilla/layout/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/layout/html/document/src/nsHTMLDocument.cpp @@ -261,6 +261,13 @@ nsHTMLDocument::Reset(nsIURL *aURL) return result; } +NS_IMETHODIMP +nsHTMLDocument::GetContentType(nsString& aContentType) const +{ + aContentType.SetString("text/html"); + return NS_OK; +} + NS_IMETHODIMP nsHTMLDocument::StartDocumentLoad(nsIURL *aURL, nsIContentViewerContainer* aContainer, diff --git a/mozilla/layout/html/document/src/nsHTMLDocument.h b/mozilla/layout/html/document/src/nsHTMLDocument.h index 6b6d997afb3..e6563de4408 100644 --- a/mozilla/layout/html/document/src/nsHTMLDocument.h +++ b/mozilla/layout/html/document/src/nsHTMLDocument.h @@ -50,6 +50,8 @@ public: NS_IMETHOD_(nsrefcnt) AddRef(void); NS_IMETHOD_(nsrefcnt) Release(void); + NS_IMETHOD GetContentType(nsString& aContentType) const; + NS_IMETHOD StartDocumentLoad(nsIURL* aUrl, nsIContentViewerContainer* aContainer, nsIStreamListener** aDocListener, diff --git a/mozilla/layout/xml/document/src/nsXMLDocument.cpp b/mozilla/layout/xml/document/src/nsXMLDocument.cpp index 2e4f29f45f6..ab98bb1380a 100644 --- a/mozilla/layout/xml/document/src/nsXMLDocument.cpp +++ b/mozilla/layout/xml/document/src/nsXMLDocument.cpp @@ -165,6 +165,14 @@ nsXMLDocument::Reset(nsIURL* aURL) return result; } +NS_IMETHODIMP +nsXMLDocument::GetContentType(nsString& aContentType) const +{ + // XXX Should get document type from incoming stream + aContentType.SetString("text/xml"); + return NS_OK; +} + NS_IMETHODIMP nsXMLDocument::StartDocumentLoad(nsIURL *aUrl, nsIContentViewerContainer* aContainer, diff --git a/mozilla/layout/xml/document/src/nsXMLDocument.h b/mozilla/layout/xml/document/src/nsXMLDocument.h index 074e92d3449..d6aefd2b13b 100644 --- a/mozilla/layout/xml/document/src/nsXMLDocument.h +++ b/mozilla/layout/xml/document/src/nsXMLDocument.h @@ -41,6 +41,8 @@ public: NS_IMETHOD_(nsrefcnt) AddRef(void); NS_IMETHOD_(nsrefcnt) Release(void); + NS_IMETHOD GetContentType(nsString& aContentType) const; + NS_IMETHOD StartDocumentLoad(nsIURL *aUrl, nsIContentViewerContainer* aContainer, nsIStreamListener **aDocListener,