Bug 450160 - DOMImplementation createDocument does not create an HTML document, r+sr=bz
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -205,16 +205,17 @@ include $(topsrcdir)/config/rules.mk
file_bug445225_multipart.txt \
file_bug445225_multipart.txt^headers^ \
test_title.html \
test_bug453521.html \
test_bug391728.html \
file_bug391728.html \
file_bug391728_2.html \
test_bug368972.html \
+ test_bug450160.html \
test_bug454326.html \
$(NULL)
libs:: $(_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
check::
@$(EXIT_ON_ERROR) \
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug450160.html
@@ -0,0 +1,150 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=450160
+-->
+<head>
+ <title>Test for Bug 450160</title>
+ <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+ <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=450160">Mozilla Bug 450160</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 450160 **/
+
+
+function testHTMLDocuments(ids, isXHTML) {
+ for (var i = 0; i < ids.length; ++i) {
+ var docType1 =
+ document.implementation.createDocumentType(isXHTML ? "html" : "HTML",
+ ids[i],
+ null);
+ ok(docType1, "No doctype?");
+ ok(!docType1.ownerDocument, "docType shouldn't have ownerDocument!\n");
+ var doc1 = document.implementation.createDocument(null, null, docType1);
+ is(docType1.ownerDocument, doc1, "docType should have ownerDocument!\n");
+ ok(!doc1.documentElement, "Document shouldn't have document element!");
+ is(doc1.body, null, "Shouldn't have .body!");
+ ok(doc1 instanceof Components.interfaces.nsIDOMHTMLDocument,
+ "Document should be an HTML document!");
+ ok(!(doc1 instanceof Components.interfaces.nsIDOMSVGDocument),
+ "Document shouldn't be an SVG document!");
+
+ var docType2 =
+ document.implementation.createDocumentType(isXHTML ? "html" : "HTML",
+ ids[i],
+ null);
+ var doc2 = document.implementation.createDocument(
+ "http://www.w3.org/1999/xhtml", "html", docType2);
+ is(docType2.ownerDocument, doc2, "docType should have ownerDocument!\n");
+ ok(doc2.documentElement, "Document should have document element!");
+ is(doc2.documentElement.localName, "html", "Wrong document element!");
+ is(doc2.body, null, "Shouldn't have .body!");
+ doc2.documentElement.appendChild(doc2.createElement("body"));
+ is(doc2.body, doc2.documentElement.firstChild, "Should have .body!");
+ if (isXHTML) {
+ doc2.body.appendChild(doc2.createElementNS("http://www.w3.org/1999/xhtml", "form"));
+ } else {
+ doc2.body.appendChild(doc2.createElement("form"));
+ }
+ is(doc2.forms.length, 1, "Form wasn't added .forms");
+ }
+}
+
+function testSVGDocument() {
+ var docType1 =
+ document.implementation.createDocumentType("svg",
+ "-//W3C//DTD SVG 1.1//EN",
+ null);
+ ok(docType1, "No doctype?");
+ ok(!docType1.ownerDocument, "docType shouldn't have ownerDocument!\n");
+ var doc1 = document.implementation.createDocument(null, null, docType1);
+ is(docType1.ownerDocument, doc1, "docType should have ownerDocument!\n");
+ ok(!doc1.documentElement, "Document shouldn't have document element!");
+ ok(!(doc1 instanceof Components.interfaces.nsIDOMHTMLDocument),
+ "Document shouldn't be an HTML document!");
+ ok(doc1 instanceof Components.interfaces.nsIDOMSVGDocument,
+ "Document should be an SVG document!");
+
+ // SVG documents have .rootElement.
+ ok("rootElement" in doc1, "No .rootElement in document");
+
+ var docType2 =
+ document.implementation.createDocumentType("svg",
+ "-//W3C//DTD SVG 1.1//EN",
+ null);
+ var doc2 = document.implementation.createDocument("http://www.w3.org/2000/svg",
+ "svg", docType2);
+ ok(doc2.documentElement, "Document should have document element!");
+ ok(doc2.rootElement, "Should have .rootElement in document");
+ is(doc2.rootElement.localName, "svg", "Wrong .rootElement!");
+}
+
+function testFooBarDocument() {
+ var docType1 =
+ document.implementation.createDocumentType("FooBar", "FooBar", null);
+ ok(docType1, "No doctype?");
+ ok(!docType1.ownerDocument, "docType shouldn't have ownerDocument!\n");
+ var doc1 = document.implementation.createDocument(null, null, docType1);
+ is(docType1.ownerDocument, doc1, "docType should have ownerDocument!\n");
+ ok(!doc1.documentElement, "Document shouldn't have document element!");
+ ok(!(doc1 instanceof Components.interfaces.nsIDOMHTMLDocument),
+ "Document shouldn't be an HTML document!");
+ ok(!(doc1 instanceof Components.interfaces.nsIDOMSVGDocument),
+ "Document shouldn't be an SVG document!");
+
+ var docType2 =
+ document.implementation.createDocumentType("FooBar", "FooBar", null);
+ var doc2 = document.implementation.createDocument("FooBarNS",
+ "FooBar", docType2);
+ ok(doc2.documentElement, "Document should have document element!");
+ is(doc2.documentElement.namespaceURI, "FooBarNS", "Wrong namespaceURI!");
+ is(doc2.documentElement.localName, "FooBar", "Wrong localName!");
+}
+
+function testNullDocTypeDocument() {
+ var doc1 = document.implementation.createDocument(null, null, null);
+ ok(!doc1.documentElement, "Document shouldn't have document element!");
+ ok(!(doc1 instanceof Components.interfaces.nsIDOMHTMLDocument),
+ "Document shouldn't be an HTML document!");
+ ok(!(doc1 instanceof Components.interfaces.nsIDOMSVGDocument),
+ "Document shouldn't be an SVG document!");
+
+ var doc2 = document.implementation.createDocument("FooBarNS",
+ "FooBar", null);
+ ok(doc2.documentElement, "Document should have document element!");
+ is(doc2.documentElement.namespaceURI, "FooBarNS", "Wrong namespaceURI!");
+ is(doc2.documentElement.localName, "FooBar", "Wrong localName!");
+}
+
+var htmlPublicIDs =
+ [ "-//W3C//DTD HTML 4.01//EN",
+ "-//W3C//DTD HTML 4.01 Transitional//EN",
+ "-//W3C//DTD HTML 4.01 Frameset//EN",
+ "-//W3C//DTD HTML 4.0//EN",
+ "-//W3C//DTD HTML 4.0 Transitional//EN",
+ "-//W3C//DTD HTML 4.0 Frameset//EN" ];
+
+var xhtmlPublicIDs =
+ [ "-//W3C//DTD XHTML 1.0 Strict//EN",
+ "-//W3C//DTD XHTML 1.0 Transitional//EN",
+ "-//W3C//DTD XHTML 1.0 Frameset//EN" ];
+
+testHTMLDocuments(htmlPublicIDs, false);
+testHTMLDocuments(xhtmlPublicIDs, true);
+testSVGDocument();
+testFooBarDocument();
+testNullDocTypeDocument();
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/html/document/src/nsHTMLDocument.h
+++ b/content/html/document/src/nsHTMLDocument.h
@@ -172,17 +172,17 @@ public:
virtual void ScriptLoading(nsIScriptElement *aScript);
virtual void ScriptExecuted(nsIScriptElement *aScript);
virtual void AddedForm();
virtual void RemovedForm();
virtual PRInt32 GetNumFormsSynchronous();
virtual void TearingDownEditor(nsIEditor *aEditor);
-
+ virtual void SetIsXHTML(PRBool aXHTML) { mIsRegularHTML = !aXHTML; }
PRBool IsXHTML()
{
return !mIsRegularHTML;
}
#ifdef DEBUG
virtual nsresult CreateElem(nsIAtom *aName, nsIAtom *aPrefix,
PRInt32 aNamespaceID,
--- a/content/html/document/src/nsIHTMLDocument.h
+++ b/content/html/document/src/nsIHTMLDocument.h
@@ -50,20 +50,20 @@ class nsIDOMHTMLMapElement;
class nsHTMLStyleSheet;
class nsIStyleSheet;
class nsICSSLoader;
class nsIContent;
class nsIDOMHTMLBodyElement;
class nsIScriptElement;
class nsIEditor;
-// 19d63a6c-cc94-499c-892a-955add772e10
+// 5a959364-a2f4-4cac-9a2c-957055dc3569
#define NS_IHTMLDOCUMENT_IID \
-{ 0x19d63a6c, 0xcc94, 0x499c, \
- { 0x89, 0x2a, 0x95, 0x5a, 0xdd, 0x77, 0x2e, 0x10 } }
+{ 0x5a959364, 0xa2f4, 0x4cac, \
+ { 0x9a, 0x2c, 0x95, 0x70, 0x55, 0xdc, 0x35, 0x69 } }
/**
* HTML document extensions to nsIDocument.
*/
class nsIHTMLDocument : public nsISupports
{
public:
@@ -185,13 +185,15 @@ public:
* anything <frameset>-related (like nsIDOMHTMLDocument::GetBody).
*/
virtual nsIContent* GetBodyContentExternal() = 0;
/**
* Called when this nsIHTMLDocument's editor is destroyed.
*/
virtual void TearingDownEditor(nsIEditor *aEditor) = 0;
+
+ virtual void SetIsXHTML(PRBool aXHTML) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIHTMLDocument, NS_IHTMLDOCUMENT_IID)
#endif /* nsIHTMLDocument_h___ */
--- a/content/xml/document/src/nsXMLDocument.cpp
+++ b/content/xml/document/src/nsXMLDocument.cpp
@@ -87,17 +87,17 @@
#include "nsIScriptGlobalObjectOwner.h"
#include "nsIJSContextStack.h"
#include "nsContentCreatorFunctions.h"
#include "nsIDOMUserDataHandler.h"
#include "nsEventDispatcher.h"
#include "nsNodeUtils.h"
#include "nsIConsoleService.h"
#include "nsIScriptError.h"
-
+#include "nsIHTMLDocument.h"
// ==================================================================
// =
// ==================================================================
nsresult
NS_NewDOMDocument(nsIDOMDocument** aInstancePtrResult,
@@ -112,33 +112,69 @@ NS_NewDOMDocument(nsIDOMDocument** aInst
// 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;
- nsRefPtr<nsXMLDocument> doc = new nsXMLDocument();
- if (!doc)
- return NS_ERROR_OUT_OF_MEMORY;
-
- rv = doc->Init();
+ nsCOMPtr<nsIDocument> d;
+ PRBool isHTML = PR_FALSE;
+ PRBool isXHTML = PR_FALSE;
+ if (aDoctype) {
+ nsAutoString publicId;
+ aDoctype->GetPublicId(publicId);
+ if (publicId.EqualsLiteral("-//W3C//DTD HTML 4.01//EN") ||
+ publicId.EqualsLiteral("-//W3C//DTD HTML 4.01 Frameset//EN") ||
+ publicId.EqualsLiteral("-//W3C//DTD HTML 4.01 Transitional//EN") ||
+ publicId.EqualsLiteral("-//W3C//DTD HTML 4.0//EN") ||
+ publicId.EqualsLiteral("-//W3C//DTD HTML 4.0 Frameset//EN") ||
+ publicId.EqualsLiteral("-//W3C//DTD HTML 4.0 Transitional//EN")) {
+ rv = NS_NewHTMLDocument(getter_AddRefs(d));
+ isHTML = PR_TRUE;
+ } else if (publicId.EqualsLiteral("-//W3C//DTD XHTML 1.0 Strict//EN") ||
+ publicId.EqualsLiteral("-//W3C//DTD XHTML 1.0 Transitional//EN") ||
+ publicId.EqualsLiteral("-//W3C//DTD XHTML 1.0 Frameset//EN")) {
+ rv = NS_NewHTMLDocument(getter_AddRefs(d));
+ isHTML = PR_TRUE;
+ isXHTML = PR_TRUE;
+ }
+#ifdef MOZ_SVG
+ else if (publicId.EqualsLiteral("-//W3C//DTD SVG 1.1//EN")) {
+ rv = NS_NewSVGDocument(getter_AddRefs(d));
+ }
+#endif
+ // XXX Add support for XUL documents.
+ else {
+ rv = NS_NewXMLDocument(getter_AddRefs(d));
+ }
+ } else {
+ rv = NS_NewXMLDocument(getter_AddRefs(d));
+ }
if (NS_FAILED(rv)) {
return rv;
}
+ if (isHTML) {
+ nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(d);
+ NS_ASSERTION(htmlDoc, "HTML Document doesn't implement nsIHTMLDocument?");
+ htmlDoc->SetCompatibilityMode(eCompatibility_FullStandards);
+ htmlDoc->SetIsXHTML(isXHTML);
+ }
+ nsDocument* doc = static_cast<nsDocument*>(d.get());
doc->SetLoadedAsData(aLoadedAsData);
doc->nsDocument::SetDocumentURI(aDocumentURI);
// Must set the principal first, since SetBaseURI checks it.
doc->SetPrincipal(aPrincipal);
doc->SetBaseURI(aBaseURI);
- // XMLDocuments get to be UTF-8 by default, unlike the legacy HTML mess
+ // XMLDocuments and documents "created in memory" get to be UTF-8 by default,
+ // unlike the legacy HTML mess
doc->SetDocumentCharacterSet(NS_LITERAL_CSTRING("UTF-8"));
if (aDoctype) {
nsCOMPtr<nsIDOMNode> tmpNode;
rv = doc->AppendChild(aDoctype, getter_AddRefs(tmpNode));
NS_ENSURE_SUCCESS(rv, rv);
}