Bug 693875, DOMParser + svg, r=jst
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Thu, 13 Oct 2011 13:50:05 +0300
changeset 78610 85a61d68b152ddec8fdd89374ae430d71eb92bab
parent 78609 46a6d0fd13d591805cd4b857450985fbd3895198
child 78611 1ce312b50d30122751de7a169adfab188ecc876e
push id21319
push useropettay@mozilla.com
push dateThu, 13 Oct 2011 11:28:59 +0000
treeherdermozilla-central@85a61d68b152 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjst
bugs693875
milestone10.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 693875, DOMParser + svg, r=jst
content/base/public/nsContentUtils.h
content/base/public/nsIDocument.h
content/base/src/nsContentUtils.cpp
content/base/src/nsDOMParser.cpp
content/base/src/nsDocument.cpp
content/base/src/nsXMLHttpRequest.cpp
content/base/test/Makefile.in
content/base/test/test_bug693875.html
content/xml/document/src/nsXMLDocument.cpp
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1094,25 +1094,27 @@ public:
    *                       insert in the document. If empty no root element will
    *                       be created.
    * @param aDoctype Doctype node to insert in the document.
    * @param aDocumentURI URI of the document. Must not be null.
    * @param aBaseURI Base URI of the document. Must not be null.
    * @param aPrincipal Prinicpal of the document. Must not be null.
    * @param aScriptObject The object from which the context for event handling
    *                      can be got.
+   * @param aSVGDocument Force SVG Document creation.
    * @param aResult [out] The document that was created.
    */
   static nsresult CreateDocument(const nsAString& aNamespaceURI, 
                                  const nsAString& aQualifiedName, 
                                  nsIDOMDocumentType* aDoctype,
                                  nsIURI* aDocumentURI,
                                  nsIURI* aBaseURI,
                                  nsIPrincipal* aPrincipal,
                                  nsIScriptGlobalObject* aScriptObject,
+                                 bool aSVGDocument,
                                  nsIDOMDocument** aResult);
 
   /**
    * Sets the text contents of a node by replacing all existing children
    * with a single text child.
    *
    * The function always notifies.
    *
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -1875,17 +1875,18 @@ nsresult
 NS_NewDOMDocument(nsIDOMDocument** aInstancePtrResult,
                   const nsAString& aNamespaceURI, 
                   const nsAString& aQualifiedName, 
                   nsIDOMDocumentType* aDoctype,
                   nsIURI* aDocumentURI,
                   nsIURI* aBaseURI,
                   nsIPrincipal* aPrincipal,
                   bool aLoadedAsData,
-                  nsIScriptGlobalObject* aEventObject);
+                  nsIScriptGlobalObject* aEventObject,
+                  bool aSVGDocument);
 nsresult
 NS_NewPluginDocument(nsIDocument** aInstancePtrResult);
 
 inline nsIDocument*
 nsINode::GetOwnerDocument() const
 {
   nsIDocument* ownerDoc = GetOwnerDoc();
 
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -3678,21 +3678,22 @@ nsContentUtils::ParseFragmentXML(const n
 /* static */
 nsresult
 nsContentUtils::CreateDocument(const nsAString& aNamespaceURI, 
                                const nsAString& aQualifiedName, 
                                nsIDOMDocumentType* aDoctype,
                                nsIURI* aDocumentURI, nsIURI* aBaseURI,
                                nsIPrincipal* aPrincipal,
                                nsIScriptGlobalObject* aEventObject,
+                               bool aSVGDocument,
                                nsIDOMDocument** aResult)
 {
   nsresult rv = NS_NewDOMDocument(aResult, aNamespaceURI, aQualifiedName,
                                   aDoctype, aDocumentURI, aBaseURI, aPrincipal,
-                                  PR_TRUE, aEventObject);
+                                  PR_TRUE, aEventObject, aSVGDocument);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDocument> document = do_QueryInterface(*aResult);
   
   // created documents are immediately "complete" (ready to use)
   document->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
   return NS_OK;
 }
--- a/content/base/src/nsDOMParser.cpp
+++ b/content/base/src/nsDOMParser.cpp
@@ -136,20 +136,25 @@ nsDOMParser::ParseFromStream(nsIInputStr
                              const char *contentType,
                              nsIDOMDocument **aResult)
 {
   NS_ENSURE_ARG(stream);
   NS_ENSURE_ARG(contentType);
   NS_ENSURE_ARG_POINTER(aResult);
   *aResult = nsnull;
 
+  bool svg = nsCRT::strcmp(contentType, "image/svg+xml") == 0;
+
   // For now, we can only create XML documents.
+  //XXXsmaug Should we create an HTMLDocument (in XHTML mode)
+  //         for "application/xhtml+xml"?
   if ((nsCRT::strcmp(contentType, "text/xml") != 0) &&
       (nsCRT::strcmp(contentType, "application/xml") != 0) &&
-      (nsCRT::strcmp(contentType, "application/xhtml+xml") != 0))
+      (nsCRT::strcmp(contentType, "application/xhtml+xml") != 0) &&
+      !svg)
     return NS_ERROR_NOT_IMPLEMENTED;
 
   nsCOMPtr<nsIScriptGlobalObject> scriptHandlingObject =
     do_QueryReferent(mScriptHandlingObject);
   nsresult rv;
   if (!mPrincipal) {
     NS_ENSURE_TRUE(!mAttemptedInit, NS_ERROR_NOT_INITIALIZED);
     AttemptedInitMarker marker(&mAttemptedInit);
@@ -178,17 +183,17 @@ nsDOMParser::ParseFromStream(nsIInputStr
   // Here we have to cheat a little bit...  Setting the base URI won't
   // work if the document has a null principal, so use
   // mOriginalPrincipal when creating the document, then reset the
   // principal.
   nsCOMPtr<nsIDOMDocument> domDocument;
   rv = nsContentUtils::CreateDocument(EmptyString(), EmptyString(), nsnull,
                                       mDocumentURI, mBaseURI,
                                       mOriginalPrincipal,
-                                      scriptHandlingObject,
+                                      scriptHandlingObject, svg,
                                       getter_AddRefs(domDocument));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Create a fake channel 
   nsCOMPtr<nsIChannel> parserChannel;
   NS_NewInputStreamChannel(getter_AddRefs(parserChannel), mDocumentURI, nsnull,
                            nsDependentCString(contentType), nsnull);
   NS_ENSURE_STATE(parserChannel);
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1432,17 +1432,17 @@ nsDOMImplementation::CreateDocument(cons
   nsCOMPtr<nsIScriptGlobalObject> scriptHandlingObject =
     do_QueryReferent(mScriptObject);
   
   NS_ENSURE_STATE(!mScriptObject || scriptHandlingObject);
 
   return nsContentUtils::CreateDocument(aNamespaceURI, aQualifiedName, aDoctype,
                                         mDocumentURI, mBaseURI,
                                         mOwner->NodePrincipal(),
-                                        scriptHandlingObject, aReturn);
+                                        scriptHandlingObject, false, aReturn);
 }
 
 NS_IMETHODIMP
 nsDOMImplementation::CreateHTMLDocument(const nsAString& aTitle,
                                         nsIDOMDocument** aReturn)
 {
   *aReturn = nsnull;
   NS_ENSURE_STATE(mOwner);
@@ -1464,17 +1464,17 @@ nsDOMImplementation::CreateHTMLDocument(
     do_QueryReferent(mScriptObject);
 
   NS_ENSURE_STATE(!mScriptObject || scriptHandlingObject);
                                                        
   nsCOMPtr<nsIDOMDocument> document;
   rv = nsContentUtils::CreateDocument(EmptyString(), EmptyString(),
                                       doctype, mDocumentURI, mBaseURI,
                                       mOwner->NodePrincipal(),
-                                      scriptHandlingObject,
+                                      scriptHandlingObject, false,
                                       getter_AddRefs(document));
   NS_ENSURE_SUCCESS(rv, rv);
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(document);
 
   nsCOMPtr<nsIContent> root;
   rv = doc->CreateElem(NS_LITERAL_STRING("html"), NULL, kNameSpaceID_XHTML,
                        false, getter_AddRefs(root));
   NS_ENSURE_SUCCESS(rv, rv);
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -1875,17 +1875,17 @@ nsXMLHttpRequest::OnStartRequest(nsIRequ
 
     // Create an empty document from it.  Here we have to cheat a little bit...
     // Setting the base URI to |baseURI| won't work if the document has a null
     // principal, so use mPrincipal when creating the document, then reset the
     // principal.
     const nsAString& emptyStr = EmptyString();
     nsCOMPtr<nsIScriptGlobalObject> global = do_QueryInterface(mOwner);
     rv = nsContentUtils::CreateDocument(emptyStr, emptyStr, nsnull, docURI,
-                                        baseURI, mPrincipal, global,
+                                        baseURI, mPrincipal, global, false,
                                         getter_AddRefs(mResponseXML));
     NS_ENSURE_SUCCESS(rv, rv);
     nsCOMPtr<nsIDocument> responseDoc = do_QueryInterface(mResponseXML);
     responseDoc->SetPrincipal(documentPrincipal);
 
     if (IsSystemXHR()) {
       responseDoc->ForceEnableXULXBL();
     }
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -514,16 +514,17 @@ include $(topsrcdir)/config/rules.mk
 		bug682592-subframe.html \
 		bug682592-subframe-ref.html \
 		test_bug684671.html \
 		test_bug685798.html \
 		test_bug686449.xhtml \
 		test_bug690056.html \
 		test_bug692434.html \
 		file_bug692434.xml \
+		test_bug693875.html \
 		$(NULL)
 
 _CHROME_FILES =	\
 		test_bug357450.js \
 		$(NULL)
 
 # This test fails on the Mac for some reason
 ifneq (,$(filter gtk2 windows,$(MOZ_WIDGET_TOOLKIT)))
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug693875.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=693875
+-->
+<head>
+  <title>Test for Bug 693875</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=693875">Mozilla Bug 693875</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 693875 **/
+
+var dp = new DOMParser();
+var d = dp.parseFromString("<?xml version='1.0'?><svg xmlns='http://www.w3.org/2000/svg'></svg>",
+                           "image/svg+xml");
+
+ok(d instanceof SVGDocument, "Should have created an SVG document.");
+ok("rootElement" in d, "Should have created an SVG document, which has .rootElement.");
+is(d.documentElement.localName, "svg", "Root element should be svg.");
+is(d.documentElement.namespaceURI, "http://www.w3.org/2000/svg",
+   "Root element should be in svg namespace.");
+
+dp = new DOMParser();
+d = dp.parseFromString("<?xml version='1.0'?><svg xmlns='http://www.w3.org/2000/svg'></svg>",
+                       "text/xml");
+ok(!(d instanceof SVGDocument), "Should not have created an SVG document!");
+</script>
+</pre>
+</body>
+</html>
--- a/content/xml/document/src/nsXMLDocument.cpp
+++ b/content/xml/document/src/nsXMLDocument.cpp
@@ -99,30 +99,33 @@ nsresult
 NS_NewDOMDocument(nsIDOMDocument** aInstancePtrResult,
                   const nsAString& aNamespaceURI, 
                   const nsAString& aQualifiedName, 
                   nsIDOMDocumentType* aDoctype,
                   nsIURI* aDocumentURI,
                   nsIURI* aBaseURI,
                   nsIPrincipal* aPrincipal,
                   bool aLoadedAsData,
-                  nsIScriptGlobalObject* aEventObject)
+                  nsIScriptGlobalObject* aEventObject,
+                  bool aSVGDocument)
 {
   // Note: can't require that aDocumentURI/aBaseURI/aPrincipal be non-null,
   // since at least one caller (XMLHttpRequest) doesn't have decent args to
   // pass in.
   
   nsresult rv;
 
   *aInstancePtrResult = nsnull;
 
   nsCOMPtr<nsIDocument> d;
   bool isHTML = false;
   bool isXHTML = false;
-  if (aDoctype) {
+  if (aSVGDocument) {
+    rv = NS_NewSVGDocument(getter_AddRefs(d));
+  } else if (aDoctype) {
     nsAutoString publicId, name;
     aDoctype->GetPublicId(publicId);
     if (publicId.IsEmpty()) {
       aDoctype->GetName(name);
     }
     if (name.EqualsLiteral("html") ||
         publicId.EqualsLiteral("-//W3C//DTD HTML 4.01//EN") ||
         publicId.EqualsLiteral("-//W3C//DTD HTML 4.01 Frameset//EN") ||