[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

crogers at google.com crogers at google.com
Wed Dec 22 16:26:42 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 01f283a24c035e0a3cecfc6af4c2c1bacbffbaea
Author: crogers at google.com <crogers at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Nov 23 21:51:00 2010 +0000

    2010-11-23  Chris Rogers  <crogers at google.com>
    
            Reviewed by Alexey Proskuryakov.
    
            Add .responseType and .response to XMLHttpRequest
            https://bugs.webkit.org/show_bug.cgi?id=49633
    
            Tests: fast/xmlhttprequest/xmlhttprequest-responsetype-abort.html
                   fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer.html
                   fast/xmlhttprequest/xmlhttprequest-responsetype-document.html
                   fast/xmlhttprequest/xmlhttprequest-responsetype-text.html
    
            * bindings/js/JSXMLHttpRequestCustom.cpp:
            (WebCore::JSXMLHttpRequest::markChildren):
            (WebCore::JSXMLHttpRequest::open):
            (WebCore::JSXMLHttpRequest::response):
            * bindings/v8/custom/V8XMLHttpRequestCustom.cpp:
            (WebCore::V8XMLHttpRequest::responseAccessorGetter):
            * xml/XMLHttpRequest.cpp:
            (WebCore::XMLHttpRequest::XMLHttpRequest):
            (WebCore::XMLHttpRequest::responseText):
            (WebCore::XMLHttpRequest::responseXML):
            (WebCore::XMLHttpRequest::responseBlob):
            (WebCore::XMLHttpRequest::responseArrayBuffer):
            (WebCore::XMLHttpRequest::setResponseType):
            (WebCore::XMLHttpRequest::responseType):
            (WebCore::XMLHttpRequest::setAsBlob):
            (WebCore::XMLHttpRequest::open):
            (WebCore::XMLHttpRequest::clearResponse):
            (WebCore::XMLHttpRequest::didFinishLoading):
            (WebCore::XMLHttpRequest::didReceiveData):
            * xml/XMLHttpRequest.h:
            (WebCore::XMLHttpRequest::asBlob):
            (WebCore::XMLHttpRequest::optionalResponseXML):
            (WebCore::XMLHttpRequest::optionalResponseBlob):
            (WebCore::XMLHttpRequest::responseTypeCode):
            (WebCore::XMLHttpRequest::optionalResponseArrayBuffer):
            * xml/XMLHttpRequest.idl:
    2010-11-23  Chris Rogers  <crogers at google.com>
    
            Reviewed by Alexey Proskuryakov.
    
            Add .responseType and .response to XMLHttpRequest
            https://bugs.webkit.org/show_bug.cgi?id=49633
    
            * fast/xmlhttprequest/xmlhttprequest-responsetype-abort-expected.txt: Added.
            * fast/xmlhttprequest/xmlhttprequest-responsetype-abort.html: Added.
            * fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer-expected.txt: Added.
            * fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer.html: Added.
            * fast/xmlhttprequest/xmlhttprequest-responsetype-document-expected.txt: Added.
            * fast/xmlhttprequest/xmlhttprequest-responsetype-document.html: Added.
            * fast/xmlhttprequest/xmlhttprequest-responsetype-text-expected.txt: Added.
            * fast/xmlhttprequest/xmlhttprequest-responsetype-text.html: Added.
            * http/tests/resources/balls-of-the-orient.aif: Added.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@72626 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 499d4db..bdb1b24 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,20 @@
+2010-11-23  Chris Rogers  <crogers at google.com>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Add .responseType and .response to XMLHttpRequest
+        https://bugs.webkit.org/show_bug.cgi?id=49633
+
+        * fast/xmlhttprequest/xmlhttprequest-responsetype-abort-expected.txt: Added.
+        * fast/xmlhttprequest/xmlhttprequest-responsetype-abort.html: Added.
+        * fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer-expected.txt: Added.
+        * fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer.html: Added.
+        * fast/xmlhttprequest/xmlhttprequest-responsetype-document-expected.txt: Added.
+        * fast/xmlhttprequest/xmlhttprequest-responsetype-document.html: Added.
+        * fast/xmlhttprequest/xmlhttprequest-responsetype-text-expected.txt: Added.
+        * fast/xmlhttprequest/xmlhttprequest-responsetype-text.html: Added.
+        * http/tests/resources/balls-of-the-orient.aif: Added.
+
 2010-11-23  Abhishek Arya  <inferno at chromium.org>
 
         Reviewed by Adam Barth.
diff --git a/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-abort-expected.txt b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-abort-expected.txt
new file mode 100644
index 0000000..0d18b8c
--- /dev/null
+++ b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-abort-expected.txt
@@ -0,0 +1,13 @@
+Tests aborting XMLHttpRequest 'arraybuffer' loading with the .responseType and .response attributes.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS responseType property exists.
+PASS response property exists.
+PASS xhr.responseType has been correctly set to 'arraybuffer'.
+PASS abort() was called.
+PASS 'arraybuffer' .response does not exist after aborted load.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-abort.html b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-abort.html
new file mode 100644
index 0000000..53fc0d6
--- /dev/null
+++ b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-abort.html
@@ -0,0 +1,79 @@
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css"/>
+<script src="../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+description("Tests aborting XMLHttpRequest 'arraybuffer' loading with the .responseType and .response attributes.");
+
+var xhr = 0;
+
+function abort() {
+    testPassed("abort() was called.");
+
+    // For aborted 'arraybuffer' the .response should not yet exist.
+    if (!xhr.response)
+        testPassed("'arraybuffer' .response does not exist after aborted load.");
+    else
+        testFailed("'arraybuffer' .response should not exist after aborted load.");
+
+    xhr = null;
+    finishJSTest();
+}
+
+function load() {
+    testFailed("onload() should not be called since loading was aborted.");
+
+    xhr = null;
+    finishJSTest();
+}
+
+function runTest() {
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+
+    xhr = new XMLHttpRequest();
+    xhr.onload = load;
+    xhr.onabort = abort;
+    xhr.open("GET", "../../http/tests/resources/balls-of-the-orient.aif", true);
+        
+    try {
+        if ("responseType" in xhr)
+            testPassed("responseType property exists.");
+
+        if ("response" in xhr)
+            testPassed("response property exists.");
+
+        // Make sure we can set responseType to "arraybuffer" before send() is called.
+        try {
+            xhr.responseType = "arraybuffer";
+            if (xhr.responseType == "arraybuffer")
+                testPassed("xhr.responseType has been correctly set to 'arraybuffer'.");
+        } catch(e) {
+            testFailed("unable to set xhr.responseType to 'arraybuffer' " + e + ".");
+        }
+    } catch(e) {
+        testFailed("Caught exception " + e + ".");
+    }
+
+    xhr.send(null);
+    xhr.abort();
+    window.jsTestIsAsync = true;
+}
+
+runTest();
+successfullyParsed = true;
+
+</script>
+
+<script src="../js/resources/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer-expected.txt b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer-expected.txt
new file mode 100644
index 0000000..c0f64eb
--- /dev/null
+++ b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer-expected.txt
@@ -0,0 +1,31 @@
+Tests XMLHttpRequest 'arraybuffer' loading with the .responseType and .response attributes.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS 'arraybuffer' .response does not exist when .readyState is 1.
+PASS responseType property exists.
+PASS response property exists.
+PASS xhr.responseType is initially set to default value of empty string.
+PASS xhr.responseType has been correctly set to ''.
+PASS xhr.responseType has been correctly set to 'text'.
+PASS xhr.responseType has been correctly set to 'document'.
+PASS xhr.responseType has been correctly set to 'arraybuffer'.
+PASS exception correctly thrown when xhr.responseType is set to invalid value : Error: SYNTAX_ERR: DOM Exception 12.
+PASS 'arraybuffer' .response does not exist when .readyState is 2.
+PASS 'arraybuffer' .response does not exist when .readyState is 3.
+PASS 'arraybuffer' .response exists when .readyState is 4.
+PASS DONE LOADING
+PASS received response object : [object ArrayBuffer].
+PASS exception correctly thrown when xhr.responseType is set to valid value too late in the loading process : Error: INVALID_STATE_ERR: DOM Exception 11.
+response length : 670184.
+bytes at offset 0 : 46 4f 52 4d 0 a 39 e0 
+bytes at offset 356874 : a 91 f 5f 8 2f e fd 
+bytes at offset 670166 : 8 be 3 c 6 91 2 8 
+checksum : 84637740
+PASS exception correctly thrown when xhr.responseText is accessed but responseType is 'arraybuffer' : Error: INVALID_STATE_ERR: DOM Exception 11.
+PASS exception correctly thrown when xhr.responseXML is accessed but responseType is 'arraybuffer' : Error: INVALID_STATE_ERR: DOM Exception 11.
+PASS xhr.response.foo is 'bar'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer.html b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer.html
new file mode 100644
index 0000000..423b284
--- /dev/null
+++ b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer.html
@@ -0,0 +1,164 @@
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css"/>
+<script src="../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+description("Tests XMLHttpRequest 'arraybuffer' loading with the .responseType and .response attributes.");
+
+var xhr = 0;
+var lastState = 0;
+
+function stateChange() {
+    // Protect against race-condition where .onreadystatechange sometimes will be called multiple times for the same state.
+    if (xhr.readyState == lastState)
+        return;
+    lastState = xhr.readyState;
+    
+    if (xhr.readyState == XMLHttpRequest.DONE) {
+        // Check that .response exists when .readyState is DONE
+        if (xhr.response)
+            testPassed("'arraybuffer' .response exists when .readyState is " + xhr.readyState + ".");
+        else
+            testFailed("'arraybuffer' .response should exist when .readyState is " + xhr.readyState + ".");
+    } else {
+        // Otherwise, for 'arraybuffer' the .response should not yet exist.
+        if (!xhr.response)
+            testPassed("'arraybuffer' .response does not exist when .readyState is " + xhr.readyState + ".");
+        else
+            testFailed("'arraybuffer' .response should not exist when .readyState is " + xhr.readyState + ".");
+    }
+}
+
+function logBytesAtOffset(buffer8, offset) {
+    var s = "bytes at offset " + offset + " : ";
+    for (var i = 0; i < 8; ++i)
+        s += buffer8[i + offset].toString(16) + ' ';
+    
+    debug(s);
+}
+
+function load() {
+    testPassed('DONE LOADING');
+    testPassed('received response object : ' + xhr.response + ".");
+
+    // Make sure exception is thrown if responseType is set too late in the loading process.
+    try {
+        xhr.responseType = "text";
+    } catch(e) {
+        testPassed("exception correctly thrown when xhr.responseType is set to valid value too late in the loading process : " + e + ".");
+    }
+
+    var buffer = xhr.response;
+
+    // Interpret the ArrayBuffer as Uint8Array.
+    var buffer8 = new Uint8Array(buffer);
+    buffer8.set(buffer);
+
+    var totalLength = buffer8.length;
+    debug('response length : ' + totalLength + ".");
+    
+    // Log the bytes at the start, in the middle, and near the end:
+    logBytesAtOffset(buffer8, 0);
+    logBytesAtOffset(buffer8, 0x5720A);
+    logBytesAtOffset(buffer8, 0xA39D6);
+    
+    // Calculate checksum.
+    var sum = 0;
+    for (var i = 0; i < totalLength; ++i) {
+        sum += buffer8[i];
+    }
+    
+    debug('checksum : ' + sum);
+
+    // Check that xhr.responseText throws an exception:
+    try {
+        var x = xhr.responseText;
+    } catch(e) {
+        testPassed("exception correctly thrown when xhr.responseText is accessed but responseType is 'arraybuffer' : " + e + ".");
+    }
+
+    // Check that xhr.responseXML throws an exception:
+    try {
+        var x = xhr.responseXML;
+    } catch(e) {
+        testPassed("exception correctly thrown when xhr.responseXML is accessed but responseType is 'arraybuffer' : " + e + ".");
+    }
+    
+    // Test .response garbage collection.
+    xhr.response.foo = "bar";
+    gc();
+    shouldBe("xhr.response.foo", "'bar'");    
+
+    xhr = null;
+    finishJSTest();
+}
+
+function runTest() {
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+
+    xhr = new XMLHttpRequest();
+    xhr.onreadystatechange = stateChange;
+    xhr.onload = load;
+    xhr.open("GET", "../../http/tests/resources/balls-of-the-orient.aif", true);
+        
+    try {
+        if ("responseType" in xhr)
+            testPassed("responseType property exists.");
+
+        if ("response" in xhr)
+            testPassed("response property exists.");
+            
+        if (xhr.responseType == "")
+            testPassed("xhr.responseType is initially set to default value of empty string.");
+
+        // Make sure we can set responseType to valid values before send() is called.
+        try {
+            xhr.responseType = "";
+            if (xhr.responseType == "")
+                testPassed("xhr.responseType has been correctly set to ''.");
+
+            xhr.responseType = "text";
+            if (xhr.responseType == "text")
+                testPassed("xhr.responseType has been correctly set to 'text'.");
+
+            xhr.responseType = "document";
+            if (xhr.responseType == "document")
+                testPassed("xhr.responseType has been correctly set to 'document'.");
+
+            xhr.responseType = "arraybuffer";
+            if (xhr.responseType == "arraybuffer")
+                testPassed("xhr.responseType has been correctly set to 'arraybuffer'.");
+        } catch(e) {
+            testFailed("unable to set xhr.responseType to a valid value " + e + ".");
+        }
+
+        // Make sure exception is thrown if responseType is set to invalid value.
+        try {
+            xhr.responseType = "dkjdfkjdfkj";
+        } catch(e) {
+            testPassed("exception correctly thrown when xhr.responseType is set to invalid value : " + e + ".");
+        }
+    } catch(e) {
+        testFailed("Caught exception " + e + ".");
+    }
+
+    xhr.send(null);
+    window.jsTestIsAsync = true;
+}
+
+runTest();
+successfullyParsed = true;
+
+</script>
+
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-document-expected.txt b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-document-expected.txt
new file mode 100644
index 0000000..690d6bb
--- /dev/null
+++ b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-document-expected.txt
@@ -0,0 +1,16 @@
+Tests XMLHttpRequest 'document' loading with the .responseType and .response attributes.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS responseType property exists.
+PASS response property exists.
+PASS xhr.responseType has been correctly set to 'document'.
+PASS DONE LOADING
+PASS received response object of type : object.
+PASS exception correctly thrown when xhr.responseType is set to valid value too late in the loading process : Error: INVALID_STATE_ERR: DOM Exception 11.
+PASS xhr.response is a Document.
+PASS xhr.response == xhr.responseXML.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-document.html b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-document.html
new file mode 100644
index 0000000..ac1dfe9
--- /dev/null
+++ b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-document.html
@@ -0,0 +1,105 @@
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css"/>
+<script src="../js/resources/js-test-pre.js"></script>
+<style type="text/css">
+.box {
+  display: box;
+  border: 1px solid black;
+  margin-bottom: 0.5em;
+}
+.boxheader {
+  font-weight: bold;
+  color: maroon;
+}
+pre {
+  margin-left: 2em;
+}
+</style>
+</head>
+<body>
+
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+description("Tests XMLHttpRequest 'document' loading with the .responseType and .response attributes.");
+
+var xhr = 0;
+
+function load() {
+    testPassed('DONE LOADING');
+    testPassed('received response object of type : ' + typeof xhr.response + ".");
+
+    // Make sure exception is thrown if responseType is set too late in the loading process.
+    // .responseType was previously set to "document".  Let's try setting it to "arraybuffer".
+    try {
+        xhr.responseType = "arraybuffer";
+    } catch(e) {
+        testPassed("exception correctly thrown when xhr.responseType is set to valid value too late in the loading process : " + e + ".");
+    }
+
+    // Check that .response is a Document
+    if (xhr.response.documentElement.tagName == 'doc')
+        testPassed("xhr.response is a Document.");
+    else
+        testFailed("xhr.response should be a Document.");
+    
+    // .response is really just an alias to .responseXML when .responseType is set to "document".
+    // Make sure they're the same.
+    if (xhr.response == xhr.responseXML)
+        testPassed("xhr.response == xhr.responseXML.");
+    else
+        testFailed("xhr.response == xhr.responseXML.");
+
+    xhr = null;
+    finishJSTest();
+}
+
+function runTest() {
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+
+    xhr = new XMLHttpRequest();
+    xhr.onload = load;
+    xhr.open("GET", "resources/xmlhttprequest-get-data.xml", true);
+        
+    try {
+        if ("responseType" in xhr)
+            testPassed("responseType property exists.");
+        else
+            testFailed("responseType property does not exist.");
+        
+
+        if ("response" in xhr)
+            testPassed("response property exists.");
+        else
+            testFailed("response property does not exist.");
+
+        // Make sure we can set responseType to "document" before send() is called.
+        try {
+            xhr.responseType = "document";
+            if (xhr.responseType == "document")
+                testPassed("xhr.responseType has been correctly set to 'document'.");
+        } catch(e) {
+            testFailed("unable to set xhr.responseType to 'document' " + e + ".");
+        }
+    } catch(e) {
+        testFailed("Caught exception " + e + ".");
+    }
+
+    xhr.send(null);
+    window.jsTestIsAsync = true;
+}
+
+runTest();
+successfullyParsed = true;
+
+</script>
+
+<script src="../js/resources/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-text-expected.txt b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-text-expected.txt
new file mode 100644
index 0000000..88bdeb5
--- /dev/null
+++ b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-text-expected.txt
@@ -0,0 +1,25 @@
+Tests XMLHttpRequest 'text' loading with the .responseType and .response attributes.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+responseText
+<?xml version="1.0"?>
+<!DOCTYPE doc [
+<!ATTLIST d id ID #IMPLIED>
+]>
+<doc>
+  <foo xmlns="foobar">One</foo> <x:bar xmlns:x="barfoo">Two</x:bar>
+  <d id="id3">Three</d>
+</doc>
+
+PASS responseType property exists.
+PASS response property exists.
+PASS xhr.responseType has been correctly set to 'text'.
+PASS DONE LOADING
+PASS received response object of type : string.
+PASS exception correctly thrown when xhr.responseType is set to valid value too late in the loading process : Error: INVALID_STATE_ERR: DOM Exception 11.
+PASS xhr.response == xhr.responseText.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-text.html b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-text.html
new file mode 100644
index 0000000..bacea94
--- /dev/null
+++ b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-text.html
@@ -0,0 +1,108 @@
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css"/>
+<script src="../js/resources/js-test-pre.js"></script>
+<style type="text/css">
+.box {
+  display: box;
+  border: 1px solid black;
+  margin-bottom: 0.5em;
+}
+.boxheader {
+  font-weight: bold;
+  color: maroon;
+}
+pre {
+  margin-left: 2em;
+}
+</style>
+</head>
+<body>
+
+<div id="description"></div>
+
+<div class="box"><span class="boxheader">responseText</span>
+<pre id="id1">@@No result@@</pre>
+</div>
+<br>
+
+<div id="console"></div>
+
+<script>
+description("Tests XMLHttpRequest 'text' loading with the .responseType and .response attributes.");
+
+var xhr = 0;
+
+function load() {
+    testPassed('DONE LOADING');
+    testPassed('received response object of type : ' + typeof xhr.response + ".");
+
+    // Make sure exception is thrown if responseType is set too late in the loading process.
+    // .responseType was previously set to "text".  Let's try setting it to "arraybuffer".
+    try {
+        xhr.responseType = "arraybuffer";
+    } catch(e) {
+        testPassed("exception correctly thrown when xhr.responseType is set to valid value too late in the loading process : " + e + ".");
+    }
+
+    // Get .responseText
+    document.getElementById("id1").firstChild.nodeValue = xhr.responseText;
+
+    // .response is really just an alias to .responseText when .responseType is set to "text".
+    // Make sure they're the same.
+    if (xhr.response == xhr.responseText)
+        testPassed("xhr.response == xhr.responseText.");
+    else
+        testFailed("xhr.response == xhr.responseText.");
+
+    xhr = null;
+    finishJSTest();
+}
+
+function runTest() {
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+
+    xhr = new XMLHttpRequest();
+    xhr.onload = load;
+    xhr.open("GET", "resources/xmlhttprequest-get-data.xml", true);
+        
+    try {
+        if ("responseType" in xhr)
+            testPassed("responseType property exists.");
+        else
+            testFailed("responseType property does not exist.");
+        
+
+        if ("response" in xhr)
+            testPassed("response property exists.");
+        else
+            testFailed("response property does not exist.");
+
+        // Make sure we can set responseType to "text" before send() is called.
+        try {
+            xhr.responseType = "text";
+            if (xhr.responseType == "text")
+                testPassed("xhr.responseType has been correctly set to 'text'.");
+        } catch(e) {
+            testFailed("unable to set xhr.responseType to 'text' " + e + ".");
+        }
+    } catch(e) {
+        testFailed("Caught exception " + e + ".");
+    }
+
+    xhr.send(null);
+    window.jsTestIsAsync = true;
+}
+
+runTest();
+successfullyParsed = true;
+
+</script>
+
+<script src="../js/resources/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/LayoutTests/http/tests/resources/balls-of-the-orient.aif b/LayoutTests/http/tests/resources/balls-of-the-orient.aif
new file mode 100644
index 0000000..eabe5bf
Binary files /dev/null and b/LayoutTests/http/tests/resources/balls-of-the-orient.aif differ
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 0a238e4..d10ea40 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,42 @@
+2010-11-23  Chris Rogers  <crogers at google.com>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Add .responseType and .response to XMLHttpRequest
+        https://bugs.webkit.org/show_bug.cgi?id=49633
+
+        Tests: fast/xmlhttprequest/xmlhttprequest-responsetype-abort.html
+               fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer.html
+               fast/xmlhttprequest/xmlhttprequest-responsetype-document.html
+               fast/xmlhttprequest/xmlhttprequest-responsetype-text.html
+
+        * bindings/js/JSXMLHttpRequestCustom.cpp:
+        (WebCore::JSXMLHttpRequest::markChildren):
+        (WebCore::JSXMLHttpRequest::open):
+        (WebCore::JSXMLHttpRequest::response):
+        * bindings/v8/custom/V8XMLHttpRequestCustom.cpp:
+        (WebCore::V8XMLHttpRequest::responseAccessorGetter):
+        * xml/XMLHttpRequest.cpp:
+        (WebCore::XMLHttpRequest::XMLHttpRequest):
+        (WebCore::XMLHttpRequest::responseText):
+        (WebCore::XMLHttpRequest::responseXML):
+        (WebCore::XMLHttpRequest::responseBlob):
+        (WebCore::XMLHttpRequest::responseArrayBuffer):
+        (WebCore::XMLHttpRequest::setResponseType):
+        (WebCore::XMLHttpRequest::responseType):
+        (WebCore::XMLHttpRequest::setAsBlob):
+        (WebCore::XMLHttpRequest::open):
+        (WebCore::XMLHttpRequest::clearResponse):
+        (WebCore::XMLHttpRequest::didFinishLoading):
+        (WebCore::XMLHttpRequest::didReceiveData):
+        * xml/XMLHttpRequest.h:
+        (WebCore::XMLHttpRequest::asBlob):
+        (WebCore::XMLHttpRequest::optionalResponseXML):
+        (WebCore::XMLHttpRequest::optionalResponseBlob):
+        (WebCore::XMLHttpRequest::responseTypeCode):
+        (WebCore::XMLHttpRequest::optionalResponseArrayBuffer):
+        * xml/XMLHttpRequest.idl:
+
 2010-11-23  Abhishek Arya  <inferno at chromium.org>
 
         Reviewed by Adam Barth.
diff --git a/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp b/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp
index 58d324d..b237aac 100644
--- a/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp
+++ b/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp
@@ -29,6 +29,7 @@
 #include "config.h"
 #include "JSXMLHttpRequest.h"
 
+#include "ArrayBuffer.h"
 #include "Blob.h"
 #include "DOMFormData.h"
 #include "DOMWindow.h"
@@ -38,6 +39,7 @@
 #include "FrameLoader.h"
 #include "HTMLDocument.h"
 #include "InspectorInstrumentation.h"
+#include "JSArrayBuffer.h"
 #include "JSBlob.h"
 #include "JSDOMFormData.h"
 #include "JSDOMWindowCustom.h"
@@ -59,6 +61,19 @@ void JSXMLHttpRequest::markChildren(MarkStack& markStack)
     if (XMLHttpRequestUpload* upload = m_impl->optionalUpload())
         markDOMObjectWrapper(markStack, *Heap::heap(this)->globalData(), upload);
 
+    if (Document* responseDocument = m_impl->optionalResponseXML())
+        markDOMObjectWrapper(markStack, *Heap::heap(this)->globalData(), responseDocument);
+
+#if ENABLE(3D_CANVAS) || ENABLE(BLOB)
+    if (ArrayBuffer* responseArrayBuffer = m_impl->optionalResponseArrayBuffer())
+        markDOMObjectWrapper(markStack, *Heap::heap(this)->globalData(), responseArrayBuffer);
+#endif
+
+#if ENABLE(XHR_RESPONSE_BLOB)
+    if (Blob* responseBlob = m_impl->optionalResponseBlob())
+        markDOMObjectWrapper(markStack, *Heap::heap(this)->globalData(), responseBlob);
+#endif
+
     m_impl->markJSEventListeners(markStack);
 }
 
@@ -77,7 +92,7 @@ JSValue JSXMLHttpRequest::open(ExecState* exec)
 
         if (exec->argumentCount() >= 4 && !exec->argument(3).isUndefined()) {
             String user = valueToStringWithNullCheck(exec, exec->argument(3));
-            
+
             if (exec->argumentCount() >= 5 && !exec->argument(4).isUndefined()) {
                 String password = valueToStringWithNullCheck(exec, exec->argument(4));
                 impl()->open(method, url, async, user, password, ec);
@@ -136,6 +151,56 @@ JSValue JSXMLHttpRequest::responseText(ExecState* exec) const
     return jsOwnedStringOrNull(exec, text);
 }
 
+JSValue JSXMLHttpRequest::response(ExecState* exec) const
+{
+    switch (impl()->responseTypeCode()) {
+    case XMLHttpRequest::ResponseTypeDefault:
+    case XMLHttpRequest::ResponseTypeText:
+        return responseText(exec);
+
+    case XMLHttpRequest::ResponseTypeDocument:
+        {
+            ExceptionCode ec = 0;
+            Document* document = impl()->responseXML(ec);
+            if (ec) {
+                setDOMException(exec, ec);
+                return jsUndefined();
+            }
+            return toJS(exec, globalObject(), document);
+        }
+
+    case XMLHttpRequest::ResponseTypeBlob:
+#if ENABLE(XHR_RESPONSE_BLOB)
+        {
+            ExceptionCode ec = 0;
+            Blob* blob = impl()->responseBlob(ec);
+            if (ec) {
+                setDOMException(exec, ec);
+                return jsUndefined();
+            }
+            return toJS(exec, globalObject(), blob);
+        }
+#else
+        return jsUndefined();
+#endif
+
+#if ENABLE(3D_CANVAS) || ENABLE(BLOB)
+    case XMLHttpRequest::ResponseTypeArrayBuffer:
+        {
+            ExceptionCode ec = 0;
+            ArrayBuffer* arrayBuffer = impl()->responseArrayBuffer(ec);
+            if (ec) {
+                setDOMException(exec, ec);
+                return jsUndefined();
+            }
+            return toJS(exec, globalObject(), arrayBuffer);
+        }
+#endif
+    }
+
+    return jsUndefined();
+}
+
 EncodedJSValue JSC_HOST_CALL JSXMLHttpRequestConstructor::constructJSXMLHttpRequest(ExecState* exec)
 {
     JSXMLHttpRequestConstructor* jsConstructor = static_cast<JSXMLHttpRequestConstructor*>(exec->callee());
diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
index 393e544..5c56cfb 100644
--- a/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
@@ -31,8 +31,10 @@
 #include "config.h"
 #include "V8XMLHttpRequest.h"
 
+#include "ArrayBuffer.h"
 #include "Frame.h"
 #include "InspectorInstrumentation.h"
+#include "V8ArrayBuffer.h"
 #include "V8Binding.h"
 #include "V8Blob.h"
 #include "V8DOMFormData.h"
@@ -57,6 +59,59 @@ v8::Handle<v8::Value> V8XMLHttpRequest::responseTextAccessorGetter(v8::Local<v8:
     return v8String(text);
 }
 
+v8::Handle<v8::Value> V8XMLHttpRequest::responseAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+    INC_STATS("DOM.XMLHttpRequest.response._get");
+    XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(info.Holder());
+
+    switch (xmlHttpRequest->responseTypeCode()) {
+    case XMLHttpRequest::ResponseTypeDefault:
+    case XMLHttpRequest::ResponseTypeText:
+        return responseTextAccessorGetter(name, info);
+
+    case XMLHttpRequest::ResponseTypeDocument:
+        {
+            ExceptionCode ec = 0;
+            Document* document = xmlHttpRequest->responseXML(ec);
+            if (ec) {
+                V8Proxy::setDOMException(ec);
+                return v8::Undefined();
+            }
+            return toV8(document);
+        }
+
+    case XMLHttpRequest::ResponseTypeBlob:
+#if ENABLE(XHR_RESPONSE_BLOB)
+        {
+            ExceptionCode ec = 0;
+            Blob* blob = xmlHttpRequest->responseBlob(ec);
+            if (ec) {
+                V8Proxy::setDOMException(ec);
+                return v8::Undefined();
+            }
+            return toV8(blob);
+        }
+#else
+        return v8::Undefined();
+#endif
+
+#if ENABLE(3D_CANVAS) || ENABLE(BLOB)
+    case XMLHttpRequest::ResponseTypeArrayBuffer:
+        {
+            ExceptionCode ec = 0;
+            ArrayBuffer* arrayBuffer = xmlHttpRequest->responseArrayBuffer(ec);
+            if (ec) {
+                V8Proxy::setDOMException(ec);
+                return v8::Undefined();
+            }
+            return toV8(arrayBuffer);
+        }
+#endif
+    }
+
+    return v8::Undefined();
+}
+
 v8::Handle<v8::Value> V8XMLHttpRequest::openCallback(const v8::Arguments& args)
 {
     INC_STATS("DOM.XMLHttpRequest.open()");
diff --git a/WebCore/xml/XMLHttpRequest.cpp b/WebCore/xml/XMLHttpRequest.cpp
index 782e159..6103703 100644
--- a/WebCore/xml/XMLHttpRequest.cpp
+++ b/WebCore/xml/XMLHttpRequest.cpp
@@ -22,6 +22,7 @@
 #include "config.h"
 #include "XMLHttpRequest.h"
 
+#include "ArrayBuffer.h"
 #include "Blob.h"
 #include "MemoryCache.h"
 #include "CrossOriginAccessControl.h"
@@ -40,6 +41,7 @@
 #include "ResourceRequest.h"
 #include "SecurityOrigin.h"
 #include "Settings.h"
+#include "SharedBuffer.h"
 #include "TextResourceDecoder.h"
 #include "ThreadableLoader.h"
 #include "XMLHttpRequestException.h"
@@ -169,9 +171,6 @@ XMLHttpRequest::XMLHttpRequest(ScriptExecutionContext* context)
     : ActiveDOMObject(context, this)
     , m_async(true)
     , m_includeCredentials(false)
-#if ENABLE(XHR_RESPONSE_BLOB)
-    , m_asBlob(false)
-#endif
     , m_state(UNSENT)
     , m_createdDocument(false)
     , m_error(false)
@@ -182,6 +181,7 @@ XMLHttpRequest::XMLHttpRequest(ScriptExecutionContext* context)
     , m_lastSendLineNumber(0)
     , m_exceptionCode(0)
     , m_progressEventThrottle(this)
+    , m_responseTypeCode(ResponseTypeDefault)
 {
     initializeXMLHttpRequestStaticData();
 #ifndef NDEBUG
@@ -222,25 +222,19 @@ XMLHttpRequest::State XMLHttpRequest::readyState() const
 
 String XMLHttpRequest::responseText(ExceptionCode& ec)
 {
-#if ENABLE(XHR_RESPONSE_BLOB)
-    if (m_asBlob)
+    if (responseTypeCode() != ResponseTypeDefault && responseTypeCode() != ResponseTypeText) {
         ec = INVALID_STATE_ERR;
-#else
-    UNUSED_PARAM(ec);
-#endif
+        return "";
+    }
     return m_responseBuilder.toStringPreserveCapacity();
 }
 
 Document* XMLHttpRequest::responseXML(ExceptionCode& ec)
 {
-#if ENABLE(XHR_RESPONSE_BLOB)
-    if (m_asBlob) {
+    if (responseTypeCode() != ResponseTypeDefault && responseTypeCode() != ResponseTypeText && responseTypeCode() != ResponseTypeDocument) {
         ec = INVALID_STATE_ERR;
         return 0;
     }
-#else
-    UNUSED_PARAM(ec);
-#endif
 
     if (m_state != DONE)
         return 0;
@@ -269,7 +263,7 @@ Document* XMLHttpRequest::responseXML(ExceptionCode& ec)
 #if ENABLE(XHR_RESPONSE_BLOB)
 Blob* XMLHttpRequest::responseBlob(ExceptionCode& ec) const
 {
-    if (!m_asBlob) {
+    if (responseTypeCode() != ResponseTypeBlob) {
         ec = INVALID_STATE_ERR;
         return 0;
     }
@@ -277,6 +271,71 @@ Blob* XMLHttpRequest::responseBlob(ExceptionCode& ec) const
 }
 #endif
 
+#if ENABLE(3D_CANVAS) || ENABLE(BLOB)
+ArrayBuffer* XMLHttpRequest::responseArrayBuffer(ExceptionCode& ec)
+{
+    if (m_responseTypeCode != ResponseTypeArrayBuffer) {
+        ec = INVALID_STATE_ERR;
+        return 0;
+    }
+
+    if (m_state != DONE)
+        return 0;
+
+    if (!m_responseArrayBuffer.get() && m_binaryResponseBuilder.get() && m_binaryResponseBuilder->size() > 0) {
+        m_responseArrayBuffer = ArrayBuffer::create(const_cast<char*>(m_binaryResponseBuilder->data()), static_cast<unsigned>(m_binaryResponseBuilder->size()));
+        m_binaryResponseBuilder.clear();
+    }
+
+    if (m_responseArrayBuffer.get())
+        return m_responseArrayBuffer.get();
+
+    return 0;
+}
+#endif
+
+void XMLHttpRequest::setResponseType(const String& responseType, ExceptionCode& ec)
+{
+    if (m_state != OPENED || m_loader) {
+        ec = INVALID_STATE_ERR;
+        return;
+    }
+
+    if (responseType == "")
+        m_responseTypeCode = ResponseTypeDefault;
+    else if (responseType == "text")
+        m_responseTypeCode = ResponseTypeText;
+    else if (responseType == "document")
+        m_responseTypeCode = ResponseTypeDocument;
+    else if (responseType == "blob") {
+#if ENABLE(XHR_RESPONSE_BLOB)
+        m_responseTypeCode = ResponseTypeBlob;
+#endif
+    } else if (responseType == "arraybuffer") {
+#if ENABLE(3D_CANVAS) || ENABLE(BLOB)
+        m_responseTypeCode = ResponseTypeArrayBuffer;
+#endif
+    } else
+        ec = SYNTAX_ERR;
+}
+
+String XMLHttpRequest::responseType()
+{
+    switch (m_responseTypeCode) {
+    case ResponseTypeDefault:
+        return "";
+    case ResponseTypeText:
+        return "text";
+    case ResponseTypeDocument:
+        return "document";
+    case ResponseTypeBlob:
+        return "blob";
+    case ResponseTypeArrayBuffer:
+        return "arraybuffer";
+    }
+    return "";
+}
+
 XMLHttpRequestUpload* XMLHttpRequest::upload()
 {
     if (!m_upload)
@@ -328,8 +387,8 @@ void XMLHttpRequest::setAsBlob(bool value, ExceptionCode& ec)
         ec = INVALID_STATE_ERR;
         return;
     }
-
-    m_asBlob = value;
+    
+    m_responseTypeCode = value ? ResponseTypeBlob : ResponseTypeDefault;
 }
 #endif
 
@@ -344,9 +403,7 @@ void XMLHttpRequest::open(const String& method, const KURL& url, bool async, Exc
     State previousState = m_state;
     m_state = UNSENT;
     m_error = false;
-#if ENABLE(XHR_RESPONSE_BLOB)
-    m_asBlob = false;
-#endif
+    m_responseTypeCode = ResponseTypeDefault;
     m_uploadComplete = false;
 
     // clear stuff from possible previous load
@@ -666,6 +723,10 @@ void XMLHttpRequest::clearResponse()
 #if ENABLE(XHR_RESPONSE_BLOB)
     m_responseBlob = 0;
 #endif
+#if ENABLE(3D_CANVAS) || ENABLE(BLOB)
+    m_binaryResponseBuilder.clear();
+    m_responseArrayBuffer.clear();
+#endif
 }
 
 void XMLHttpRequest::clearRequest()
@@ -920,9 +981,9 @@ void XMLHttpRequest::didFinishLoading(unsigned long identifier)
         m_responseBuilder.append(m_decoder->flush());
 
     m_responseBuilder.shrinkToFit();
-
+    
 #if ENABLE(XHR_RESPONSE_BLOB)
-    // FIXME: Set m_responseBlob to something here in the m_asBlob case.
+    // FIXME: Set m_responseBlob to something here in the ResponseTypeBlob case.
 #endif
 
 #if ENABLE(INSPECTOR)
@@ -976,7 +1037,9 @@ void XMLHttpRequest::didReceiveData(const char* data, int len)
     if (m_state < HEADERS_RECEIVED)
         changeState(HEADERS_RECEIVED);
 
-    if (!m_decoder) {
+    bool useDecoder = responseTypeCode() == ResponseTypeDefault || responseTypeCode() == ResponseTypeText || responseTypeCode() == ResponseTypeDocument;
+
+    if (useDecoder && !m_decoder) {
         if (!m_responseEncoding.isEmpty())
             m_decoder = TextResourceDecoder::create("text/plain", m_responseEncoding);
         // allow TextResourceDecoder to look inside the m_response if it's XML or HTML
@@ -996,7 +1059,16 @@ void XMLHttpRequest::didReceiveData(const char* data, int len)
     if (len == -1)
         len = strlen(data);
 
-    m_responseBuilder.append(m_decoder->decode(data, len));
+    if (useDecoder)
+        m_responseBuilder.append(m_decoder->decode(data, len));
+#if ENABLE(3D_CANVAS) || ENABLE(BLOB)
+    else if (responseTypeCode() == ResponseTypeArrayBuffer) {
+        // Buffer binary data.
+        if (!m_binaryResponseBuilder)
+            m_binaryResponseBuilder = SharedBuffer::create();
+        m_binaryResponseBuilder->append(data, len);
+    }
+#endif
 
     if (!m_error) {
         long long expectedLength = m_response.expectedContentLength();
diff --git a/WebCore/xml/XMLHttpRequest.h b/WebCore/xml/XMLHttpRequest.h
index 1b983e6..098e19f 100644
--- a/WebCore/xml/XMLHttpRequest.h
+++ b/WebCore/xml/XMLHttpRequest.h
@@ -34,10 +34,12 @@
 
 namespace WebCore {
 
+class ArrayBuffer;
 class Blob;
 class Document;
 class DOMFormData;
 class ResourceRequest;
+class SharedBuffer;
 class TextResourceDecoder;
 class ThreadableLoader;
 
@@ -54,6 +56,14 @@ public:
         LOADING = 3,
         DONE = 4
     };
+    
+    enum ResponseTypeCode {
+        ResponseTypeDefault,
+        ResponseTypeText, 
+        ResponseTypeDocument,
+        ResponseTypeBlob,
+        ResponseTypeArrayBuffer
+    };
 
     virtual XMLHttpRequest* toXMLHttpRequest() { return this; }
 
@@ -72,7 +82,7 @@ public:
     bool withCredentials() const { return m_includeCredentials; }
     void setWithCredentials(bool, ExceptionCode&);
 #if ENABLE(XHR_RESPONSE_BLOB)
-    bool asBlob() const { return m_asBlob; }
+    bool asBlob() const { return responseTypeCode() == ResponseTypeBlob; }
     void setAsBlob(bool, ExceptionCode&);
 #endif
     void open(const String& method, const KURL&, ExceptionCode&);
@@ -91,9 +101,22 @@ public:
     String getResponseHeader(const AtomicString& name, ExceptionCode&) const;
     String responseText(ExceptionCode&);
     Document* responseXML(ExceptionCode&);
+    Document* optionalResponseXML() const { return m_responseXML.get(); }
 #if ENABLE(XHR_RESPONSE_BLOB)
     Blob* responseBlob(ExceptionCode&) const;
+    Blob* optionalResponseBlob() const { return m_responseBlob.get(); }
+#endif
+
+    void setResponseType(const String&, ExceptionCode&);
+    String responseType();
+    ResponseTypeCode responseTypeCode() const { return m_responseTypeCode; }
+    
+#if ENABLE(3D_CANVAS) || ENABLE(BLOB)
+    // response attribute has custom getter.
+    ArrayBuffer* responseArrayBuffer(ExceptionCode&);
+    ArrayBuffer* optionalResponseArrayBuffer() const { return m_responseArrayBuffer.get(); }
 #endif
+
     void setLastSendLineNumber(unsigned lineNumber) { m_lastSendLineNumber = lineNumber; }
     void setLastSendURL(const String& url) { m_lastSendURL = url; }
 
@@ -164,7 +187,6 @@ private:
     bool m_async;
     bool m_includeCredentials;
 #if ENABLE(XHR_RESPONSE_BLOB)
-    bool m_asBlob;
     RefPtr<Blob> m_responseBlob;
 #endif
 
@@ -179,6 +201,11 @@ private:
     StringBuilder m_responseBuilder;
     mutable bool m_createdDocument;
     mutable RefPtr<Document> m_responseXML;
+    
+#if ENABLE(3D_CANVAS) || ENABLE(BLOB)
+    RefPtr<SharedBuffer> m_binaryResponseBuilder;
+    mutable RefPtr<ArrayBuffer> m_responseArrayBuffer;
+#endif
 
     bool m_error;
 
@@ -197,6 +224,9 @@ private:
     EventTargetData m_eventTargetData;
 
     XMLHttpRequestProgressEventThrottle m_progressEventThrottle;
+
+    // An enum corresponding to the allowed string values for the responseType attribute.
+    ResponseTypeCode m_responseTypeCode;
 };
 
 } // namespace WebCore
diff --git a/WebCore/xml/XMLHttpRequest.idl b/WebCore/xml/XMLHttpRequest.idl
index 59997f8..2b0b177 100644
--- a/WebCore/xml/XMLHttpRequest.idl
+++ b/WebCore/xml/XMLHttpRequest.idl
@@ -95,6 +95,12 @@ module xml {
         readonly attribute [EnabledAtRuntime] Blob responseBlob
             getter raises(DOMException);
 #endif
+
+        attribute DOMString responseType
+            setter raises(DOMException);
+        readonly attribute [CustomGetter] Object response
+            getter raises(DOMException);
+
         readonly attribute unsigned short status
             getter raises(DOMException);
         readonly attribute DOMString statusText

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list