Document.contentType implementation
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 16 Dec 2014 18:42:43 +0000 (18:42 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 16 Dec 2014 18:42:43 +0000 (18:42 +0000)
https://bugs.webkit.org/show_bug.cgi?id=132269

Patch by Tibor Meszaros <tmeszaros.u-szeged@partner.samsung.com> on 2014-12-16
Reviewed by Darin Adler.

Chromium merge from https://codereview.chromium.org/151653004

Source/WebCore:

Tests: fast/dom/document-contentType-DOMParser.html
       fast/dom/document-contentType-createDocument.html
       fast/dom/document-contentType-data-uri.html
       fast/xsl/xslt-contentType.html
       http/tests/dom/document-contentType-meta.html
       http/tests/dom/document-contentType-xhr.html
       http/tests/dom/document-contentType.html

* dom/Document.cpp:
(WebCore::Document::overrideMIMEType):
(WebCore::Document::contentType):
(WebCore::Document::cloneDataFromDocument):
* dom/Document.h:
* dom/Document.idl:
* loader/DocumentLoader.cpp:
(WebCore::DocumentLoader::currentContentType):
* loader/DocumentLoader.h:
* xml/XMLHttpRequest.cpp:
(WebCore::XMLHttpRequest::responseXML):
* xml/XSLTProcessor.cpp:
(WebCore::XSLTProcessor::createDocumentFromSource):

LayoutTests:

* fast/dom/Document/clone-node-expected.txt:
* fast/dom/Document/clone-node.html:
* fast/dom/HTMLDocument/clone-node-quirks-mode-expected.txt:
* fast/dom/HTMLDocument/clone-node-quirks-mode.html:
* fast/dom/document-contentType-DOMParser-expected.txt: Added.
* fast/dom/document-contentType-DOMParser.html: Added.
* fast/dom/document-contentType-createDocument-expected.txt: Added.
* fast/dom/document-contentType-createDocument.html: Added.
* fast/dom/document-contentType-data-uri-expected.txt: Added.
* fast/dom/document-contentType-data-uri.html: Added.
* fast/xsl/xslt-contentType-expected.txt: Added.
* fast/xsl/xslt-contentType.html: Added.
* http/tests/dom/document-contentType-expected.txt: Added.
* http/tests/dom/document-contentType-meta-expected.txt: Added.
* http/tests/dom/document-contentType-meta.html: Added.
* http/tests/dom/document-contentType-xhr-expected.txt: Added.
* http/tests/dom/document-contentType-xhr.html: Added.
* http/tests/dom/document-contentType.html: Added.
* http/tests/dom/resources/dummy.css: Added.
(body):
* http/tests/dom/resources/dummy.html: Added.
* http/tests/dom/resources/dummy.js: Added.
* http/tests/dom/resources/dummy.txt: Added.
* http/tests/dom/resources/dummy.xml: Added.
* http/tests/dom/resources/send-mime-type.php: Added.
* http/tests/dom/resources/square20.bmp: Added.
* http/tests/dom/resources/square20.gif: Added.
* http/tests/dom/resources/square20.jpg: Added.
* http/tests/dom/resources/square20.png: Added.
* resources/js-test.js:
(shouldBeEqualToNumber):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@177366 268f45cc-cd09-0410-ab3c-d52691b4dbfc

38 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/Document/clone-node-expected.txt
LayoutTests/fast/dom/Document/clone-node.html
LayoutTests/fast/dom/HTMLDocument/clone-node-quirks-mode-expected.txt
LayoutTests/fast/dom/HTMLDocument/clone-node-quirks-mode.html
LayoutTests/fast/dom/document-contentType-DOMParser-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/document-contentType-DOMParser.html [new file with mode: 0644]
LayoutTests/fast/dom/document-contentType-createDocument-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/document-contentType-createDocument.html [new file with mode: 0644]
LayoutTests/fast/dom/document-contentType-data-uri-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/document-contentType-data-uri.html [new file with mode: 0644]
LayoutTests/fast/xsl/xslt-contentType-expected.txt [new file with mode: 0644]
LayoutTests/fast/xsl/xslt-contentType.html [new file with mode: 0644]
LayoutTests/http/tests/dom/document-contentType-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/dom/document-contentType-meta-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/dom/document-contentType-meta.html [new file with mode: 0644]
LayoutTests/http/tests/dom/document-contentType-xhr-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/dom/document-contentType-xhr.html [new file with mode: 0644]
LayoutTests/http/tests/dom/document-contentType.html [new file with mode: 0644]
LayoutTests/http/tests/dom/resources/dummy.css [new file with mode: 0644]
LayoutTests/http/tests/dom/resources/dummy.html [new file with mode: 0644]
LayoutTests/http/tests/dom/resources/dummy.js [new file with mode: 0644]
LayoutTests/http/tests/dom/resources/dummy.txt [new file with mode: 0644]
LayoutTests/http/tests/dom/resources/dummy.xml [new file with mode: 0644]
LayoutTests/http/tests/dom/resources/send-mime-type.php [new file with mode: 0644]
LayoutTests/http/tests/dom/resources/square20.bmp [new file with mode: 0644]
LayoutTests/http/tests/dom/resources/square20.gif [new file with mode: 0644]
LayoutTests/http/tests/dom/resources/square20.jpg [new file with mode: 0644]
LayoutTests/http/tests/dom/resources/square20.png [new file with mode: 0644]
LayoutTests/resources/js-test.js
Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/Document.idl
Source/WebCore/loader/DocumentLoader.cpp
Source/WebCore/loader/DocumentLoader.h
Source/WebCore/xml/XMLHttpRequest.cpp
Source/WebCore/xml/XSLTProcessor.cpp

index 6d71809..906255d 100644 (file)
@@ -1,3 +1,44 @@
+2014-12-16  Tibor Meszaros  <tmeszaros.u-szeged@partner.samsung.com>
+
+        Document.contentType implementation
+        https://bugs.webkit.org/show_bug.cgi?id=132269
+
+        Reviewed by Darin Adler.
+
+        Chromium merge from https://codereview.chromium.org/151653004
+
+        * fast/dom/Document/clone-node-expected.txt:
+        * fast/dom/Document/clone-node.html:
+        * fast/dom/HTMLDocument/clone-node-quirks-mode-expected.txt:
+        * fast/dom/HTMLDocument/clone-node-quirks-mode.html:
+        * fast/dom/document-contentType-DOMParser-expected.txt: Added.
+        * fast/dom/document-contentType-DOMParser.html: Added.
+        * fast/dom/document-contentType-createDocument-expected.txt: Added.
+        * fast/dom/document-contentType-createDocument.html: Added.
+        * fast/dom/document-contentType-data-uri-expected.txt: Added.
+        * fast/dom/document-contentType-data-uri.html: Added.
+        * fast/xsl/xslt-contentType-expected.txt: Added.
+        * fast/xsl/xslt-contentType.html: Added.
+        * http/tests/dom/document-contentType-expected.txt: Added.
+        * http/tests/dom/document-contentType-meta-expected.txt: Added.
+        * http/tests/dom/document-contentType-meta.html: Added.
+        * http/tests/dom/document-contentType-xhr-expected.txt: Added.
+        * http/tests/dom/document-contentType-xhr.html: Added.
+        * http/tests/dom/document-contentType.html: Added.
+        * http/tests/dom/resources/dummy.css: Added.
+        (body):
+        * http/tests/dom/resources/dummy.html: Added.
+        * http/tests/dom/resources/dummy.js: Added.
+        * http/tests/dom/resources/dummy.txt: Added.
+        * http/tests/dom/resources/dummy.xml: Added.
+        * http/tests/dom/resources/send-mime-type.php: Added.
+        * http/tests/dom/resources/square20.bmp: Added.
+        * http/tests/dom/resources/square20.gif: Added.
+        * http/tests/dom/resources/square20.jpg: Added.
+        * http/tests/dom/resources/square20.png: Added.
+        * resources/js-test.js:
+        (shouldBeEqualToNumber):
+
 2014-12-16  Alexey Proskuryakov  <ap@apple.com>
 
         media/track/track-language-preference.html and media/track/track-prefer-captions.html time out on Mac
index 70418d2..4b95180 100644 (file)
@@ -6,10 +6,12 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 PASS doc.cloneNode(false).__proto__ is Document.prototype
 PASS className(doc.cloneNode(false)) is "Document"
 PASS doc.cloneNode(true).documentElement.localName is "root"
+PASS doc.cloneNode(true).contentType is "application/xml"
 PASS document.cloneNode(true).compatMode is "CSS1Compat"
 PASS document.cloneNode(false).URL is document.URL
 PASS document.cloneNode(false).baseURI is document.baseURI
 PASS document.cloneNode(false).characterSet is document.characterSet
+PASS document.cloneNode(true).contentType is "text/html"
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 13a098a..aabee58 100644 (file)
@@ -14,10 +14,12 @@ var doc = document.implementation.createDocument('', 'root', null);
 shouldBe('doc.cloneNode(false).__proto__', 'Document.prototype');
 shouldBeEqualToString('className(doc.cloneNode(false))', 'Document');
 shouldBeEqualToString('doc.cloneNode(true).documentElement.localName', 'root');
+shouldBeEqualToString('doc.cloneNode(true).contentType', 'application/xml');
 shouldBeEqualToString('document.cloneNode(true).compatMode', 'CSS1Compat');
 shouldBe('document.cloneNode(false).URL', 'document.URL');
 shouldBe('document.cloneNode(false).baseURI', 'document.baseURI');
 shouldBe('document.cloneNode(false).characterSet', 'document.characterSet');
+shouldBeEqualToString('document.cloneNode(true).contentType', 'text/html');
 
 </script>
 <script src="../../../resources/js-test-post.js"></script>
index 588745e..aa73ab1 100644 (file)
@@ -7,10 +7,12 @@ PASS document.cloneNode(false).__proto__ is HTMLDocument.prototype
 PASS className(document.cloneNode(false)) is "HTMLDocument"
 PASS document.cloneNode(true).title is document.title
 PASS document.cloneNode(true).compatMode is "BackCompat"
+PASS document.cloneNode(true).contentType is "text/html"
 PASS doc.cloneNode(false).__proto__ is HTMLDocument.prototype
 PASS className(doc.cloneNode(false)) is "HTMLDocument"
 PASS doc.cloneNode(true).title is doc.title
 PASS doc.cloneNode(true).compatMode is "CSS1Compat"
+PASS doc.cloneNode(true).contentType is "text/html"
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 91a31d2..a44946c 100644 (file)
@@ -11,12 +11,14 @@ shouldBe('document.cloneNode(false).__proto__', 'HTMLDocument.prototype');
 shouldBeEqualToString('className(document.cloneNode(false))', 'HTMLDocument');
 shouldBe('document.cloneNode(true).title', 'document.title');
 shouldBeEqualToString('document.cloneNode(true).compatMode', 'BackCompat');
+shouldBeEqualToString('document.cloneNode(true).contentType', 'text/html');
 
 var doc = document.implementation.createHTMLDocument('title');
 shouldBe('doc.cloneNode(false).__proto__', 'HTMLDocument.prototype');
 shouldBeEqualToString('className(doc.cloneNode(false))', 'HTMLDocument');
 shouldBe('doc.cloneNode(true).title', 'doc.title');
 shouldBeEqualToString('doc.cloneNode(true).compatMode', 'CSS1Compat');
+shouldBeEqualToString('doc.cloneNode(true).contentType', 'text/html');
 
 </script>
 <script src="../../../resources/js-test-post.js"></script>
diff --git a/LayoutTests/fast/dom/document-contentType-DOMParser-expected.txt b/LayoutTests/fast/dom/document-contentType-DOMParser-expected.txt
new file mode 100644 (file)
index 0000000..c49c3f1
--- /dev/null
@@ -0,0 +1,12 @@
+PASS new DOMParser().parseFromString(htmlContent, "text/html").contentType is "text/html"
+PASS new DOMParser().parseFromString(xmlContent, "application/xml").contentType is "application/xml"
+PASS new DOMParser().parseFromString(xhtmlContent, "application/xhtml+xml").contentType is "application/xhtml+xml"
+PASS new DOMParser().parseFromString(svgImageContent, "image/svg+xml").contentType is "image/svg+xml"
+PASS new DOMParser().parseFromString(xslContent, "text/xsl").contentType threw exception TypeError: Type error.
+PASS new DOMParser().parseFromString(xmlContent, "text/dummy+xml").contentType threw exception TypeError: Type error.
+PASS new DOMParser().parseFromString(xmlContent, "text/XML").contentType threw exception TypeError: Type error.
+PASS new DOMParser().parseFromString(htmlContent, "TEXT/html").contentType threw exception TypeError: Type error.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/document-contentType-DOMParser.html b/LayoutTests/fast/dom/document-contentType-DOMParser.html
new file mode 100644 (file)
index 0000000..7aaf9a8
--- /dev/null
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<head>
+ <title>document.contentType</title>
+ <link rel="help" href="http://dom.spec.whatwg.org/#dom-document-contenttype">
+ <script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+ <script>
+  
+var htmlContent =
+                "<html>" +
+                    "<head>" +
+                        "<noscript>" +
+                            "Scripts must be disabled for the document created using DOMParser.parseFromString()" +
+                        "</noscript>" +
+                    "</head>" +
+                    "<body>" +
+                        "<div id='text'>Sample text content</div>" +
+                        "<script>document.getElementById('text').textContent = 'Modified text content';<\/script>" +
+                    "</body>" +
+                "</html>";
+
+var xmlContent =
+                "<root>" +
+                "</root>";
+
+
+var xhtmlContent =
+                "<!DOCTYPE html>" +
+                "<html xmlns=\"http://www.w3.org/1999/xhtml\">" +
+                    "<head>" +
+                        "<title>Title of document</title>" +
+                        "<noscript>" +
+                            "Scripts must be disabled for the document created using DOMParser.parseFromString()" +
+                        "</noscript>" +
+                    "</head>" +
+                    "<body>" +
+                        "<div id='text'></div>" +
+                        "<script>document.getElementById('text').textContent = 'Newly added text';<\/script>" +
+                    "</body>" +
+                "</html>";
+
+var svgImageContent =
+                "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">" +
+                    "<circle cx=\"100\" cy=\"50\" r=\"40\" stroke=\"black\" stroke-width=\"2\" fill=\"red\"/>" +
+                "</svg>";
+
+var xslContent =
+                "<?xml version=\"1.0\"?>" +
+                "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">" +
+                    "<xsl:template match=\"/\">" +
+                        "<html>" +
+                            "<head>" +
+                                "<title>XML XSL Example</title>" +
+                                "<style type=\"text/css\">" +
+                                    "body" +
+                                    "{" +
+                                        "background-color:red;" +
+                                    "}" +
+                                "</style>" +
+                            "</head>" +
+                            "<body>" +
+                                "<xsl:apply-templates/>" +
+                            "</body>" +
+                        "</html>" +
+                    "</xsl:template>" +
+                    "" +
+                    "<xsl:template match=\"tutorial\">" +
+                        "<span><xsl:value-of select=\"name\"/></span>" +
+                        "<span><xsl:value-of select=\"url\"/></span>" +
+                    "</xsl:template>" +
+                "</xsl:stylesheet>";
+
+shouldBeEqualToString('new DOMParser().parseFromString(htmlContent, "text/html").contentType', 'text/html');
+shouldBeEqualToString('new DOMParser().parseFromString(xmlContent, "application/xml").contentType', 'application/xml');
+shouldBeEqualToString('new DOMParser().parseFromString(xhtmlContent, "application/xhtml+xml").contentType', 'application/xhtml+xml');
+shouldBeEqualToString('new DOMParser().parseFromString(svgImageContent, "image/svg+xml").contentType', 'image/svg+xml');
+shouldThrow('new DOMParser().parseFromString(xslContent, "text/xsl").contentType', "'TypeError: Type error'");
+shouldThrow('new DOMParser().parseFromString(xmlContent, "text/dummy+xml").contentType', "'TypeError: Type error'");
+shouldThrow('new DOMParser().parseFromString(xmlContent, "text/XML").contentType', "'TypeError: Type error'");
+shouldThrow('new DOMParser().parseFromString(htmlContent, "TEXT/html").contentType', "'TypeError: Type error'");
+
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
\ No newline at end of file
diff --git a/LayoutTests/fast/dom/document-contentType-createDocument-expected.txt b/LayoutTests/fast/dom/document-contentType-createDocument-expected.txt
new file mode 100644 (file)
index 0000000..d636ea4
--- /dev/null
@@ -0,0 +1,8 @@
+PASS doc.contentType is "text/html"
+PASS doc.contentType is "application/xml"
+PASS doc.contentType is "application/xml"
+PASS doc.contentType is "image/svg+xml"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/document-contentType-createDocument.html b/LayoutTests/fast/dom/document-contentType-createDocument.html
new file mode 100644 (file)
index 0000000..5728d0d
--- /dev/null
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>document.contentType</title>
+<link rel="help" href="http://dom.spec.whatwg.org/#dom-document-contenttype">
+<script src="../../resources/js-test.js"></script>
+<body>
+<script>
+var doc = document.implementation.createHTMLDocument('f');
+shouldBe('doc.contentType', '"text/html"');
+
+doc = document.implementation.createDocument(null, 'root', null);
+shouldBe('doc.contentType', '"application/xml"');
+
+var foo = document.implementation.createDocumentType("foobar", "", "");
+doc = document.implementation.createDocument(null, null, foo);
+shouldBe('doc.contentType', '"application/xml"');
+
+doc = document.implementation.createDocument('http://www.w3.org/2000/svg', 'svg:svg', null);
+shouldBe('doc.contentType', '"image/svg+xml"');
+</script>
\ No newline at end of file
diff --git a/LayoutTests/fast/dom/document-contentType-data-uri-expected.txt b/LayoutTests/fast/dom/document-contentType-data-uri-expected.txt
new file mode 100644 (file)
index 0000000..37ea2ce
--- /dev/null
@@ -0,0 +1,8 @@
+PASS "application/xml" is "application/xml"
+PASS "image/svg+xml" is "image/svg+xml"
+PASS "text/html" is "text/html"
+PASS "text/xml" is "text/xml"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+   
diff --git a/LayoutTests/fast/dom/document-contentType-data-uri.html b/LayoutTests/fast/dom/document-contentType-data-uri.html
new file mode 100644 (file)
index 0000000..f4311e2
--- /dev/null
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<title>document.contentType</title>
+<link rel="help" href="http://dom.spec.whatwg.org/#dom-document-contenttype">
+<script src="../../resources/js-test.js"></script>
+<body>
+<p>
+<iframe data-mimetype="text/html"></iframe>
+<iframe data-mimetype="text/xml"></iframe>
+<iframe data-mimetype="application/xml"></iframe>
+<iframe data-mimetype="image/svg+xml"></iframe>
+</p>
+<script>
+window.jsTestIsAsync = true;
+var tests = new Array();
+
+window.onmessage = function(e) {
+    if (e.data)
+        tests[--expectedMessagesCount]=e.data;
+    else
+        testFailed("Null message payload");
+
+    if (expectedMessagesCount == 0) {
+        runTests();
+        finishJSTest();
+    }
+};
+
+function runTests(){
+    tests.sort(function(a,b){
+        if (a.obtained > b.obtained)
+            return -1;
+        if (a.obtained < b.obtained)
+            return 1;
+        return 0;
+    });
+
+    for (var i = tests.length - 1; i >= 0; i--) {
+        shouldBe('"' + tests[i].obtained + '"', '"' + tests[i].expected + '"');
+    };
+}
+
+var documentContents = '<script xmlns="http://www.w3.org/1999/xhtml">' +
+    'parent.postMessage(' +
+        '{obtained: document.contentType, expected: "{0}"}, "*");' +
+    '<' + '/script>';
+
+var iframes = document.getElementsByTagName('iframe');
+for (var k = 0, f; f = iframes[k]; k++) {
+    f.src = 'data:' + f.dataset.mimetype + ',' + encodeURIComponent(documentContents.replace('{0}', f.dataset.mimetype));
+}
+
+var expectedMessagesCount = iframes.length;
+
+</script>
+</body>
\ No newline at end of file
diff --git a/LayoutTests/fast/xsl/xslt-contentType-expected.txt b/LayoutTests/fast/xsl/xslt-contentType-expected.txt
new file mode 100644 (file)
index 0000000..482b60f
--- /dev/null
@@ -0,0 +1,9 @@
+PASS doc.contentType is "text/html"
+PASS doc.contentType is "application/xml"
+PASS doc.contentType is "application/xhtml+xml"
+PASS doc.contentType is "application/xml"
+PASS doc.contentType is "application/xml"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/xsl/xslt-contentType.html b/LayoutTests/fast/xsl/xslt-contentType.html
new file mode 100644 (file)
index 0000000..a2073d2
--- /dev/null
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<head>
+       <script src="../../resources/js-test-pre.js"></script>
+</head>
+<body >
+       <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        var xsltp = new XSLTProcessor();
+        var doc;
+
+        function test(method) {
+               try {
+                       var xml = '<?xml version="1.0" encoding="UTF-8"?>';
+               var style = '<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> \
+                                <xsl:output indent="yes" method="'+method+'"/> \
+                            </xsl:stylesheet>';
+
+                var xmlDoc = new DOMParser().parseFromString(xml, "text/xml");
+                var xslDoc = new DOMParser().parseFromString(style, "text/xml");
+    
+                xsltp.importStylesheet(xslDoc);
+                doc = xsltp.transformToDocument(xmlDoc);
+
+                xsltp.reset();
+            } catch(e) {
+              document.write("Exception: " + e);
+            }
+        }
+        
+        function runTests() {
+            test('html');
+            shouldBe('doc.contentType','"text/html"');
+
+            test('xml');
+            shouldBe('doc.contentType','"application/xml"');
+
+            test('text');
+            shouldBe('doc.contentType','"application/xhtml+xml"');
+
+            test('foo');
+            shouldBe('doc.contentType','"application/xml"');
+
+            test('xhtml/foo');
+            shouldBe('doc.contentType','"application/xml"');
+        }
+
+        runTests();
+    </script>
+</body>
+<script src="../../resources/js-test-post.js"></script>
+</html>
diff --git a/LayoutTests/http/tests/dom/document-contentType-expected.txt b/LayoutTests/http/tests/dom/document-contentType-expected.txt
new file mode 100644 (file)
index 0000000..97a03b4
--- /dev/null
@@ -0,0 +1,32 @@
+PASS iframes[0].contentDocument.contentType is "text/css"
+PASS iframes[0].contentDocument.cloneNode(false).contentType is "text/css"
+PASS iframes[1].contentDocument.contentType is "application/x-javascript"
+PASS iframes[1].contentDocument.cloneNode(false).contentType is "application/x-javascript"
+PASS iframes[2].contentDocument.contentType is "text/html"
+PASS iframes[2].contentDocument.cloneNode(false).contentType is "text/html"
+PASS iframes[3].contentDocument.contentType is "text/html"
+PASS iframes[3].contentDocument.cloneNode(false).contentType is "text/html"
+PASS iframes[4].contentDocument.contentType is "text/xml"
+PASS iframes[4].contentDocument.cloneNode(false).contentType is "text/xml"
+PASS iframes[5].contentDocument.contentType is "text/xml"
+PASS iframes[5].contentDocument.cloneNode(false).contentType is "text/xml"
+PASS iframes[6].contentDocument.contentType is "text/html"
+PASS iframes[6].contentDocument.cloneNode(false).contentType is "text/html"
+PASS iframes[7].contentDocument.contentType is "text/html"
+PASS iframes[7].contentDocument.cloneNode(false).contentType is "text/html"
+PASS iframes[8].contentDocument.contentType is "text/plain"
+PASS iframes[8].contentDocument.cloneNode(false).contentType is "text/plain"
+PASS iframes[9].contentDocument.contentType is "application/xml"
+PASS iframes[9].contentDocument.cloneNode(false).contentType is "application/xml"
+PASS iframes[10].contentDocument.contentType is "image/bmp"
+PASS iframes[10].contentDocument.cloneNode(false).contentType is "image/bmp"
+PASS iframes[11].contentDocument.contentType is "image/gif"
+PASS iframes[11].contentDocument.cloneNode(false).contentType is "image/gif"
+PASS iframes[12].contentDocument.contentType is "image/jpeg"
+PASS iframes[12].contentDocument.cloneNode(false).contentType is "image/jpeg"
+PASS iframes[13].contentDocument.contentType is "image/png"
+PASS iframes[13].contentDocument.cloneNode(false).contentType is "image/png"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+             
diff --git a/LayoutTests/http/tests/dom/document-contentType-meta-expected.txt b/LayoutTests/http/tests/dom/document-contentType-meta-expected.txt
new file mode 100644 (file)
index 0000000..3985690
--- /dev/null
@@ -0,0 +1,5 @@
+PASS document.getElementsByTagName("META")[0].content is "text/xml"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/dom/document-contentType-meta.html b/LayoutTests/http/tests/dom/document-contentType-meta.html
new file mode 100644 (file)
index 0000000..a19b75b
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<head>
+ <title>document.contentType</title>
+ <link rel="help" href="http://dom.spec.whatwg.org/#dom-document-contenttype">
+ <meta http-equiv="content-type" content="text/xml">
+ <script src="/js-test-resources/js-test-pre.js"></script>
+</head>
+<body>
+ <script>
+  shouldBeEqualToString('document.getElementsByTagName("META")[0].content', 'text/xml');
+ </script>
+ <script src="/js-test-resources/js-test-post.js"></script>
+</body>
\ No newline at end of file
diff --git a/LayoutTests/http/tests/dom/document-contentType-xhr-expected.txt b/LayoutTests/http/tests/dom/document-contentType-xhr-expected.txt
new file mode 100644 (file)
index 0000000..ca18bb4
--- /dev/null
@@ -0,0 +1,16 @@
+PASS xhr.status is 200
+PASS xhr.responseXML.contentType is "text/html"
+PASS xhr.status is 200
+PASS xhr.responseXML.contentType is "text/xml"
+PASS xhr.status is 200
+PASS xhr.responseXML.contentType is "application/xml"
+PASS xhr.status is 200
+PASS xhr.responseXML.contentType is "text/html"
+PASS xhr.status is 200
+PASS xhr.responseXML.contentType is "text/xml"
+PASS xhr.status is 200
+PASS xhr.responseXML.contentType is "application/xml"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/dom/document-contentType-xhr.html b/LayoutTests/http/tests/dom/document-contentType-xhr.html
new file mode 100644 (file)
index 0000000..9f4e2e9
--- /dev/null
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<title>document.contentType</title>
+<link rel="help" href="http://dom.spec.whatwg.org/#dom-document-contenttype">
+<script src="/js-test-resources/js-test.js"></script>
+<script>
+window.jsTestIsAsync = true;
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+}
+
+var toTest = [
+    { mimeType: "text/html", uri: "resources/send-mime-type.php?m=text/html" },
+    { mimeType: "text/xml", uri: "resources/send-mime-type.php?m=text/xml" },
+    { mimeType: "application/xml", uri: "resources/send-mime-type.php?m=application/xml" },
+    { mimeType: "text/html", uri: "resources/send-mime-type.php?m=text/html;charset=utf-8" },
+    { mimeType: "text/xml", uri: "resources/send-mime-type.php?m=text/xml;charset=utf-8" },
+    { mimeType: "application/xml", uri: "resources/send-mime-type.php?m=application/xml;charset=utf-8" }
+];
+
+function onrequestload(expectedMimeType) {
+    shouldBeEqualToNumber('xhr.status', 200);
+
+    if (xhr.responseXML)
+        shouldBeEqualToString('xhr.responseXML.contentType', expectedMimeType);
+    else
+        testFailed("Null document for mime-type " + expectedMimeType);
+
+    stepTest();
+}
+
+var xhr;
+var testCounter = 0;
+
+function stepTest() {
+    if (testCounter != 6) {
+        var test = toTest[testCounter++];
+
+        xhr = new XMLHttpRequest();
+        xhr.responseType = 'document';
+        xhr.onload = function () { onrequestload(test.mimeType); };
+        xhr.open('GET', test.uri, true);
+        xhr.send(); 
+    } else {
+        finishJSTest();
+    }
+}
+</script>
+
+<body onload="stepTest();">
+</body>
\ No newline at end of file
diff --git a/LayoutTests/http/tests/dom/document-contentType.html b/LayoutTests/http/tests/dom/document-contentType.html
new file mode 100644 (file)
index 0000000..b291076
--- /dev/null
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<title>document.contentType</title>
+<link rel="help" href="http://dom.spec.whatwg.org/#dom-document-contenttype">
+<script src="/js-test-resources/js-test-pre.js"></script>
+<body>
+<p>
+<iframe data-mimetype="text/css" src="resources/dummy.css"></iframe>
+<iframe data-mimetype="application/x-javascript" src="resources/dummy.js"></iframe>
+<iframe data-mimetype="text/html" src="resources/dummy.html"></iframe>
+<iframe data-mimetype="text/html" src="resources/send-mime-type.php"></iframe>
+<iframe data-mimetype="text/xml" src="resources/send-mime-type.php?m=text/xml"></iframe>
+<iframe data-mimetype="text/xml" src="resources/send-mime-type.php?m=text/xml;charset=utf-8"></iframe>
+<iframe data-mimetype="text/html" src="javascript:&quot;hello world&quot;;"></iframe>
+<iframe data-mimetype="text/html" src="about:blank"></iframe>
+<iframe data-mimetype="text/plain" src="resources/dummy.txt"></iframe>
+<iframe data-mimetype="application/xml" src="resources/dummy.xml"></iframe>
+<iframe data-mimetype="image/bmp" src="resources/square20.bmp"></iframe>
+<iframe data-mimetype="image/gif" src="resources/square20.gif"></iframe>
+<iframe data-mimetype="image/jpeg" src="resources/square20.jpg"></iframe>
+<iframe data-mimetype="image/png" src="resources/square20.png"></iframe>
+</p>
+<script>
+var iframes;
+window.onload = function() {
+    iframes = document.getElementsByTagName('iframe');
+    for (var k = 0; iframes[k]; k++) {
+        shouldBeEqualToString('iframes[' + k + '].contentDocument.contentType',
+                              iframes[k].dataset.mimetype);
+        shouldBeEqualToString('iframes[' + k + '].contentDocument.cloneNode(false).contentType',
+                              iframes[k].dataset.mimetype);
+    }
+    wasPostTestScriptParsed = true;
+
+    finishJSTest();
+};
+</script>
+<body>
\ No newline at end of file
diff --git a/LayoutTests/http/tests/dom/resources/dummy.css b/LayoutTests/http/tests/dom/resources/dummy.css
new file mode 100644 (file)
index 0000000..2d91681
--- /dev/null
@@ -0,0 +1 @@
+body {}
\ No newline at end of file
diff --git a/LayoutTests/http/tests/dom/resources/dummy.html b/LayoutTests/http/tests/dom/resources/dummy.html
new file mode 100644 (file)
index 0000000..9733efe
--- /dev/null
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<body>Hello world
\ No newline at end of file
diff --git a/LayoutTests/http/tests/dom/resources/dummy.js b/LayoutTests/http/tests/dom/resources/dummy.js
new file mode 100644 (file)
index 0000000..3589a15
--- /dev/null
@@ -0,0 +1 @@
+var x;
\ No newline at end of file
diff --git a/LayoutTests/http/tests/dom/resources/dummy.txt b/LayoutTests/http/tests/dom/resources/dummy.txt
new file mode 100644 (file)
index 0000000..70c379b
--- /dev/null
@@ -0,0 +1 @@
+Hello world
\ No newline at end of file
diff --git a/LayoutTests/http/tests/dom/resources/dummy.xml b/LayoutTests/http/tests/dom/resources/dummy.xml
new file mode 100644 (file)
index 0000000..5b96d7b
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>Text.me</root>
\ No newline at end of file
diff --git a/LayoutTests/http/tests/dom/resources/send-mime-type.php b/LayoutTests/http/tests/dom/resources/send-mime-type.php
new file mode 100644 (file)
index 0000000..f22a907
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+header("HTTP/1.1 200 OK");
+if (isset($_GET['m']) && $_GET['m'] != "")
+       header("Content-Type: " . $_GET['m']);
+echo "<h1>Hello</h1>"
+?>
\ No newline at end of file
diff --git a/LayoutTests/http/tests/dom/resources/square20.bmp b/LayoutTests/http/tests/dom/resources/square20.bmp
new file mode 100644 (file)
index 0000000..a79e936
Binary files /dev/null and b/LayoutTests/http/tests/dom/resources/square20.bmp differ
diff --git a/LayoutTests/http/tests/dom/resources/square20.gif b/LayoutTests/http/tests/dom/resources/square20.gif
new file mode 100644 (file)
index 0000000..753d775
Binary files /dev/null and b/LayoutTests/http/tests/dom/resources/square20.gif differ
diff --git a/LayoutTests/http/tests/dom/resources/square20.jpg b/LayoutTests/http/tests/dom/resources/square20.jpg
new file mode 100644 (file)
index 0000000..83ed491
Binary files /dev/null and b/LayoutTests/http/tests/dom/resources/square20.jpg differ
diff --git a/LayoutTests/http/tests/dom/resources/square20.png b/LayoutTests/http/tests/dom/resources/square20.png
new file mode 100644 (file)
index 0000000..4d51ac4
Binary files /dev/null and b/LayoutTests/http/tests/dom/resources/square20.png differ
index 787f31d..76f8816 100644 (file)
@@ -424,6 +424,14 @@ function shouldBeEqualToString(a, b)
   shouldBe(a, unevaledString);
 }
 
+function shouldBeEqualToNumber(a, b)
+{
+  if (typeof a !== "string" || typeof b !== "number")
+    debug("WARN: shouldBeEqualToNumber() expects a string and a number arguments");
+  var unevaledString = JSON.stringify(b);
+  shouldBe(a, unevaledString);
+}
+
 function shouldBeEmptyString(a) { shouldBeEqualToString(a, ""); }
 
 function shouldEvaluateTo(actual, expected) {
index c8feeec..87191da 100644 (file)
@@ -1,3 +1,34 @@
+2014-12-16  Tibor Meszaros  <tmeszaros.u-szeged@partner.samsung.com>
+
+        Document.contentType implementation
+        https://bugs.webkit.org/show_bug.cgi?id=132269
+
+        Reviewed by Darin Adler.
+
+        Chromium merge from https://codereview.chromium.org/151653004
+
+        Tests: fast/dom/document-contentType-DOMParser.html
+               fast/dom/document-contentType-createDocument.html
+               fast/dom/document-contentType-data-uri.html
+               fast/xsl/xslt-contentType.html
+               http/tests/dom/document-contentType-meta.html
+               http/tests/dom/document-contentType-xhr.html
+               http/tests/dom/document-contentType.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::overrideMIMEType):
+        (WebCore::Document::contentType):
+        (WebCore::Document::cloneDataFromDocument):
+        * dom/Document.h:
+        * dom/Document.idl:
+        * loader/DocumentLoader.cpp:
+        (WebCore::DocumentLoader::currentContentType):
+        * loader/DocumentLoader.h:
+        * xml/XMLHttpRequest.cpp:
+        (WebCore::XMLHttpRequest::responseXML):
+        * xml/XSLTProcessor.cpp:
+        (WebCore::XSLTProcessor::createDocumentFromSource):
+
 2014-12-16  Anders Carlsson  <andersca@apple.com>
 
         Put some common code in StorageNamespaceProvider
index 537f564..8ebe4b7 100644 (file)
@@ -1376,6 +1376,26 @@ String Document::suggestedMIMEType() const
     return String();
 }
 
+void Document::overrideMIMEType(const String& mimeType)
+{
+    m_overriddenMIMEType = mimeType;
+}
+
+String Document::contentType() const
+{
+    if (!m_overriddenMIMEType.isNull())
+        return m_overriddenMIMEType;
+
+    if (DocumentLoader* documentLoader = loader())
+        return documentLoader->currentContentType();
+
+    String mimeType = suggestedMIMEType();
+    if (!mimeType.isNull())
+        return mimeType;
+
+    return ASCIILiteral("application/xml");
+}
+
 Node* Document::nodeFromPoint(const LayoutPoint& clientPoint, LayoutPoint* localPoint)
 {
     if (!frame() || !view())
@@ -3216,6 +3236,7 @@ void Document::cloneDataFromDocument(const Document& other)
 
     setCompatibilityMode(other.m_compatibilityMode);
     setSecurityOrigin(other.securityOrigin());
+    overrideMIMEType(other.contentType());
     setDecoder(other.decoder());
 }
 
index f328616..e53a7d8 100644 (file)
@@ -465,6 +465,9 @@ public:
 
     String suggestedMIMEType() const;
 
+    void overrideMIMEType(const String&);
+    String contentType() const;
+
     String contentLanguage() const { return m_contentLanguage; }
     void setContentLanguage(const String&);
 
@@ -1408,6 +1411,9 @@ private:
 
     String m_baseTarget;
 
+    // MIME type of the document in case it was cloned or created by XHR.
+    String m_overriddenMIMEType;
+
     std::unique_ptr<DOMImplementation> m_implementation;
 
     RefPtr<CSSStyleSheet> m_elementSheet;
index 51e1b93..107e1cf 100644 (file)
     [ObjCLegacyUnnamedParameters] CSSStyleDeclaration getOverrideStyle([Default=Undefined] optional Element element,
                                                         [Default=Undefined] optional DOMString pseudoElement);
 
+    readonly attribute DOMString contentType;
+
     // DOM Level 3 XPath (XPathEvaluator interface)
     [ObjCLegacyUnnamedParameters, RaisesException] XPathExpression createExpression([Default=Undefined] optional DOMString expression,
                                                     [Default=Undefined] optional XPathNSResolver resolver);
index f9116c0..7c010d2 100644 (file)
@@ -1283,6 +1283,11 @@ const String& DocumentLoader::responseMIMEType() const
     return m_response.mimeType();
 }
 
+const String& DocumentLoader::currentContentType() const
+{
+    return m_writer.mimeType();
+}
+
 #if PLATFORM(IOS)
 // FIXME: This method seems to violate the encapsulation of this class.
 void DocumentLoader::setResponseMIMEType(const String& responseMimeType)
index 7a06ac2..376005d 100644 (file)
@@ -118,7 +118,7 @@ namespace WebCore {
         // FIXME: This method seems to violate the encapsulation of this class.
         WEBCORE_EXPORT void setResponseMIMEType(const String&);
 #endif
-
+        const String& currentContentType() const;
         void replaceRequestURLForSameDocumentNavigation(const URL&);
         bool isStopping() const { return m_isStopping; }
         void stopLoading();
index bf86f03..53947c2 100644 (file)
@@ -206,7 +206,8 @@ Document* XMLHttpRequest::responseXML(ExceptionCode& ec)
         return nullptr;
 
     if (!m_createdDocument) {
-        bool isHTML = equalIgnoringCase(responseMIMEType(), "text/html");
+        String mimeType = responseMIMEType();
+        bool isHTML = equalIgnoringCase(mimeType, "text/html");
 
         // The W3C spec requires the final MIME type to be some valid XML type, or text/html.
         // If it is text/html, then the responseType of "document" must have been supplied explicitly.
@@ -222,6 +223,8 @@ Document* XMLHttpRequest::responseXML(ExceptionCode& ec)
             // FIXME: Set Last-Modified.
             m_responseDocument->setContent(m_responseBuilder.toStringPreserveCapacity());
             m_responseDocument->setSecurityOrigin(securityOrigin());
+            m_responseDocument->overrideMIMEType(mimeType);
+
             if (!m_responseDocument->wellFormed())
                 m_responseDocument = 0;
         }
index 0e27619..f10c0ef 100644 (file)
@@ -76,7 +76,7 @@ PassRefPtr<Document> XSLTProcessor::createDocumentFromSource(const String& sourc
 
     RefPtr<Document> result;
     if (sourceMIMEType == "text/plain") {
-        result = Document::create(frame, sourceIsDocument ? ownerDocument->url() : URL());
+        result = Document::createXHTML(frame, sourceIsDocument ? ownerDocument->url() : URL());
         transformTextStringToXHTMLDocumentString(documentSource);
     } else
         result = DOMImplementation::createDocument(sourceMIMEType, frame, sourceIsDocument ? ownerDocument->url() : URL());