Title: [154992] trunk
Revision
154992
Author
[email protected]
Date
2013-09-03 11:45:51 -0700 (Tue, 03 Sep 2013)

Log Message

Support the "json" responseType and JSON response entity in XHR
https://bugs.webkit.org/show_bug.cgi?id=73648

Reviewed by Oliver Hunt.

Source/_javascript_Core: 

Based on the patch written by Jarred Nicholls.

Add JSC::JSONParse. This function will be used in XMLHttpRequest.response of type 'json'.

* _javascript_Core.xcodeproj/project.pbxproj:
* runtime/JSONObject.cpp:
(JSC::JSONParse):
* runtime/JSONObject.h:

Source/WebCore: 

Based on the patch written by Jarred Nicholls.

Implement 'json' type for XMLHttpRequest.response. We cache the result on JSC side as a cached attribute
unlike other response types like 'document' and 'blob' for which the parsed response object is cached
in XMLHttpRequest itself. In the long run, we should do the same for other types of response types.

Also refactored the various code to share the code.

Tests: fast/xmlhttprequest/xmlhttprequest-responsetype-json-invalid.html
       fast/xmlhttprequest/xmlhttprequest-responsetype-json-utf16.html
       fast/xmlhttprequest/xmlhttprequest-responsetype-json-valid.html

* ForwardingHeaders/runtime/JSONObject.h: Added.

* bindings/js/JSXMLHttpRequestCustom.cpp:
(WebCore::JSXMLHttpRequest::visitChildren):
(WebCore::JSXMLHttpRequest::response): Use JSONParse to parse the response text and cache the result.
Call didCacheResponseJSON to set the cache status and clear the original response buffer.

* xml/XMLHttpRequest.cpp:
(WebCore::XMLHttpRequest::XMLHttpRequest): Added m_responseCacheIsValid to invalidate the cache of
a json response.
(WebCore::XMLHttpRequest::responseText):
(WebCore::XMLHttpRequest::didCacheResponseJSON): Added; Updates m_responseCacheIsValid and clears the
response buffer to save memory.
(WebCore::XMLHttpRequest::responseXML):
(WebCore::XMLHttpRequest::setResponseType):
(WebCore::XMLHttpRequest::responseType):
(WebCore::XMLHttpRequest::clearResponseBuffers):
(WebCore::XMLHttpRequest::didReceiveData):

* xml/XMLHttpRequest.h:
(WebCore::XMLHttpRequest::doneWithoutErrors): Extracted from responseXML.
(WebCore::XMLHttpRequest::responseTextIgnoringResponseType): Extracted from responseText.
(WebCore::XMLHttpRequest::responseCacheIsValid): Added.
(WebCore::XMLHttpRequest::shouldDecodeResponse): Extracted from didReceiveData.
Also modified to decode when the response type is ResponseTypeJSON.

* xml/XMLHttpRequest.idl: Added CachedAttribute IDL extention on response property. This cache is
used when the response type is 'json'.

LayoutTests: 

Add regression tests for XMLHttpRequest.response of type 'json'.

Two of these tests (valid & invalid) come from Jarred Nicholls's original patch.

* fast/xmlhttprequest/resources/xmlhttprequest-responsetype-json-utf-16.json: Added.
* fast/xmlhttprequest/resources/xmlhttprequest-responsetype-json.json: Added.
* fast/xmlhttprequest/xmlhttprequest-responsetype-json-invalid-expected.txt: Added.
* fast/xmlhttprequest/xmlhttprequest-responsetype-json-invalid.html: Added.
* fast/xmlhttprequest/xmlhttprequest-responsetype-json-utf16-expected.txt: Added.
* fast/xmlhttprequest/xmlhttprequest-responsetype-json-utf16.html: Added.
* fast/xmlhttprequest/xmlhttprequest-responsetype-json-valid-expected.txt: Added.
* fast/xmlhttprequest/xmlhttprequest-responsetype-json-valid.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (154991 => 154992)


--- trunk/LayoutTests/ChangeLog	2013-09-03 18:30:08 UTC (rev 154991)
+++ trunk/LayoutTests/ChangeLog	2013-09-03 18:45:51 UTC (rev 154992)
@@ -1,3 +1,23 @@
+2013-09-02  Ryosuke Niwa  <[email protected]>
+
+        Support the "json" responseType and JSON response entity in XHR
+        https://bugs.webkit.org/show_bug.cgi?id=73648
+
+        Reviewed by Oliver Hunt.
+
+        Add regression tests for XMLHttpRequest.response of type 'json'.
+
+        Two of these tests (valid & invalid) come from Jarred Nicholls's original patch.
+
+        * fast/xmlhttprequest/resources/xmlhttprequest-responsetype-json-utf-16.json: Added.
+        * fast/xmlhttprequest/resources/xmlhttprequest-responsetype-json.json: Added.
+        * fast/xmlhttprequest/xmlhttprequest-responsetype-json-invalid-expected.txt: Added.
+        * fast/xmlhttprequest/xmlhttprequest-responsetype-json-invalid.html: Added.
+        * fast/xmlhttprequest/xmlhttprequest-responsetype-json-utf16-expected.txt: Added.
+        * fast/xmlhttprequest/xmlhttprequest-responsetype-json-utf16.html: Added.
+        * fast/xmlhttprequest/xmlhttprequest-responsetype-json-valid-expected.txt: Added.
+        * fast/xmlhttprequest/xmlhttprequest-responsetype-json-valid.html: Added.
+
 2013-09-03  Commit Queue  <[email protected]>
 
         Unreviewed, rolling out r154881.

Added: trunk/LayoutTests/fast/xmlhttprequest/resources/xmlhttprequest-responsetype-json-utf-16.json


(Binary files differ)
Property changes on: trunk/LayoutTests/fast/xmlhttprequest/resources/xmlhttprequest-responsetype-json-utf-16.json ___________________________________________________________________

Added: svn:mime-type

Added: trunk/LayoutTests/fast/xmlhttprequest/resources/xmlhttprequest-responsetype-json.json (0 => 154992)


--- trunk/LayoutTests/fast/xmlhttprequest/resources/xmlhttprequest-responsetype-json.json	                        (rev 0)
+++ trunk/LayoutTests/fast/xmlhttprequest/resources/xmlhttprequest-responsetype-json.json	2013-09-03 18:45:51 UTC (rev 154992)
@@ -0,0 +1,5 @@
+{
+    "a": ["b", 1, {"c": "d"}],
+    "e": 2,
+    "f": "g"
+}

Added: trunk/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-json-invalid-expected.txt (0 => 154992)


--- trunk/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-json-invalid-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-json-invalid-expected.txt	2013-09-03 18:45:51 UTC (rev 154992)
@@ -0,0 +1,10 @@
+Tests XMLHttpRequest.responseType of "json" with an invalid payload.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS xhr.response is null
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-json-invalid.html (0 => 154992)


--- trunk/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-json-invalid.html	                        (rev 0)
+++ trunk/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-json-invalid.html	2013-09-03 18:45:51 UTC (rev 154992)
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+window.jsTestIsAsync = true;
+description('Tests XMLHttpRequest.responseType of "json" with an invalid payload.');
+
+var xhr = new XMLHttpRequest();
+var url = '';
+
+xhr.open('GET', url);
+xhr.responseType = 'json';
+xhr._onload_ = function() {
+    shouldBeNull('xhr.response');
+    finishJSTest();
+};
+xhr._onerror_ = function() {
+    testFailed('An error occurred while loading "' + url + '"');
+    finishJSTest();
+};
+xhr.send(null);
+</script>
+<script src=""
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-json-utf16-expected.txt (0 => 154992)


--- trunk/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-json-utf16-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-json-utf16-expected.txt	2013-09-03 18:45:51 UTC (rev 154992)
@@ -0,0 +1,10 @@
+Tests XMLHttpRequest.responseType of "json" fails to parse if the payload was encoded with UTF-16.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+FAIL jsonXHR.response should be null. Was [object Object].
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-json-utf16.html (0 => 154992)


--- trunk/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-json-utf16.html	                        (rev 0)
+++ trunk/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-json-utf16.html	2013-09-03 18:45:51 UTC (rev 154992)
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+window.jsTestIsAsync = true;
+description('Tests XMLHttpRequest.responseType of "json" fails to parse if the payload was encoded with UTF-16.');
+
+var jsonXHR = new XMLHttpRequest();
+var textXHR = new XMLHttpRequest();
+var jsonUrl = 'resources/xmlhttprequest-responsetype-json-utf-16.json';
+
+jsonXHR.open('GET', jsonUrl);
+jsonXHR.responseType = 'json';
+jsonXHR._onload_ = function() {
+    shouldBeNull('jsonXHR.response');
+    finishJSTest();
+};
+jsonXHR._onerror_ = function() {
+    testFailed('An error occurred while loading "' + jsonUrl + '"');
+    finishJSTest();
+};
+jsonXHR.send(null);
+</script>
+<script src=""
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-json-valid-expected.txt (0 => 154992)


--- trunk/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-json-valid-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-json-valid-expected.txt	2013-09-03 18:45:51 UTC (rev 154992)
@@ -0,0 +1,14 @@
+Tests XMLHttpRequest.responseType of "json" with a valid payload.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS jsonXHR.response is null
+PASS jsonXHR.response is non-null.
+PASS jsonXHR.response is jsonXHR.response
+PASS JSON.stringify(jsonXHR.response) is JSON.stringify(JSON.parse(textXHR.responseText))
+PASS jsonXHR.open("GET", jsonUrl); jsonXHR.response is null
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-json-valid.html (0 => 154992)


--- trunk/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-json-valid.html	                        (rev 0)
+++ trunk/LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-json-valid.html	2013-09-03 18:45:51 UTC (rev 154992)
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+window.jsTestIsAsync = true;
+description('Tests XMLHttpRequest.responseType of "json" with a valid payload.');
+
+var jsonXHR = new XMLHttpRequest();
+var textXHR = new XMLHttpRequest();
+var jsonUrl = 'resources/xmlhttprequest-responsetype-json.json';
+var response;
+var responseText;
+
+jsonXHR.open('GET', jsonUrl);
+jsonXHR.responseType = 'json';
+jsonXHR._onload_ = function() {
+    shouldBeNonNull('jsonXHR.response');
+    shouldBe('jsonXHR.response', 'jsonXHR.response');
+
+    textXHR.open('GET', jsonUrl);
+    textXHR._onload_ = function() {
+        shouldBe('JSON.stringify(jsonXHR.response)', 'JSON.stringify(JSON.parse(textXHR.responseText))');
+
+        // When calling open() to reuse an XHR instance, the cached response
+        // should have been cleared.
+        shouldBeNull('jsonXHR.open("GET", jsonUrl); jsonXHR.response');
+
+        finishJSTest();
+    };
+    textXHR._onerror_ = function() {
+        testFailed('An error occurred while loading "' + jsonUrl + '"');
+        finishJSTest();
+    };
+    textXHR.send(null);
+};
+jsonXHR._onerror_ = function() {
+    testFailed('An error occurred while loading "' + jsonUrl + '"');
+    finishJSTest();
+};
+
+shouldBeNull('jsonXHR.response');
+jsonXHR.send(null);
+</script>
+<script src=""
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+</body>
+</html>
\ No newline at end of file

Modified: trunk/Source/_javascript_Core/ChangeLog (154991 => 154992)


--- trunk/Source/_javascript_Core/ChangeLog	2013-09-03 18:30:08 UTC (rev 154991)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-09-03 18:45:51 UTC (rev 154992)
@@ -1,3 +1,19 @@
+2013-09-02  Ryosuke Niwa  <[email protected]>
+
+        Support the "json" responseType and JSON response entity in XHR
+        https://bugs.webkit.org/show_bug.cgi?id=73648
+
+        Reviewed by Oliver Hunt.
+
+        Based on the patch written by Jarred Nicholls.
+
+        Add JSC::JSONParse. This function will be used in XMLHttpRequest.response of type 'json'.
+
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * runtime/JSONObject.cpp:
+        (JSC::JSONParse):
+        * runtime/JSONObject.h:
+
 2013-09-02  Filip Pizlo  <[email protected]>
 
         CodeBlock::jettison() should be implicit

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (154991 => 154992)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2013-09-03 18:30:08 UTC (rev 154991)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2013-09-03 18:45:51 UTC (rev 154992)
@@ -957,7 +957,7 @@
 		A7E5AB3A1799E4B200D2833D /* X86Disassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7E5AB361799E4B200D2833D /* X86Disassembler.cpp */; };
 		A7F2996B17A0BB670010417A /* FTLFail.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7F2996917A0BB670010417A /* FTLFail.cpp */; };
 		A7F2996C17A0BB670010417A /* FTLFail.h in Headers */ = {isa = PBXBuildFile; fileRef = A7F2996A17A0BB670010417A /* FTLFail.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		A7F9935F0FD7325100A0B2D0 /* JSONObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A7F9935D0FD7325100A0B2D0 /* JSONObject.h */; };
+		A7F9935F0FD7325100A0B2D0 /* JSONObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A7F9935D0FD7325100A0B2D0 /* JSONObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		A7F993600FD7325100A0B2D0 /* JSONObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7F9935E0FD7325100A0B2D0 /* JSONObject.cpp */; };
 		A7FB60A4103F7DC20017A286 /* PropertyDescriptor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7FB60A3103F7DC20017A286 /* PropertyDescriptor.cpp */; };
 		A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FB604B103F5EAB0017A286 /* PropertyDescriptor.h */; settings = {ATTRIBUTES = (Private, ); }; };

Modified: trunk/Source/_javascript_Core/runtime/JSONObject.cpp (154991 => 154992)


--- trunk/Source/_javascript_Core/runtime/JSONObject.cpp	2013-09-03 18:30:08 UTC (rev 154991)
+++ trunk/Source/_javascript_Core/runtime/JSONObject.cpp	2013-09-03 18:45:51 UTC (rev 154992)
@@ -819,6 +819,19 @@
     return JSValue::encode(result);
 }
 
+JSValue JSONParse(ExecState* exec, const String& json)
+{
+    LocalScope scope(exec->vm());
+
+    if (json.is8Bit()) {
+        LiteralParser<LChar> jsonParser(exec, json.characters8(), json.length(), StrictJSON);
+        return jsonParser.tryLiteralParse();
+    }
+
+    LiteralParser<UChar> jsonParser(exec, json.characters16(), json.length(), StrictJSON);
+    return jsonParser.tryLiteralParse();
+}
+
 String JSONStringify(ExecState* exec, JSValue value, unsigned indent)
 {
     LocalScope scope(exec->vm());

Modified: trunk/Source/_javascript_Core/runtime/JSONObject.h (154991 => 154992)


--- trunk/Source/_javascript_Core/runtime/JSONObject.h	2013-09-03 18:30:08 UTC (rev 154991)
+++ trunk/Source/_javascript_Core/runtime/JSONObject.h	2013-09-03 18:45:51 UTC (rev 154992)
@@ -60,6 +60,7 @@
 
     };
 
+    JS_EXPORT_PRIVATE JSValue JSONParse(ExecState*, const String&);
     String JSONStringify(ExecState*, JSValue, unsigned indent);
 
 } // namespace JSC

Modified: trunk/Source/WebCore/ChangeLog (154991 => 154992)


--- trunk/Source/WebCore/ChangeLog	2013-09-03 18:30:08 UTC (rev 154991)
+++ trunk/Source/WebCore/ChangeLog	2013-09-03 18:45:51 UTC (rev 154992)
@@ -1,3 +1,51 @@
+2013-09-02  Ryosuke Niwa  <[email protected]>
+
+        Support the "json" responseType and JSON response entity in XHR
+        https://bugs.webkit.org/show_bug.cgi?id=73648
+
+        Reviewed by Oliver Hunt.
+
+        Based on the patch written by Jarred Nicholls.
+
+        Implement 'json' type for XMLHttpRequest.response. We cache the result on JSC side as a cached attribute
+        unlike other response types like 'document' and 'blob' for which the parsed response object is cached
+        in XMLHttpRequest itself. In the long run, we should do the same for other types of response types.
+
+        Also refactored the various code to share the code.
+
+        Tests: fast/xmlhttprequest/xmlhttprequest-responsetype-json-invalid.html
+               fast/xmlhttprequest/xmlhttprequest-responsetype-json-utf16.html
+               fast/xmlhttprequest/xmlhttprequest-responsetype-json-valid.html
+
+        * ForwardingHeaders/runtime/JSONObject.h: Added.
+
+        * bindings/js/JSXMLHttpRequestCustom.cpp:
+        (WebCore::JSXMLHttpRequest::visitChildren):
+        (WebCore::JSXMLHttpRequest::response): Use JSONParse to parse the response text and cache the result.
+        Call didCacheResponseJSON to set the cache status and clear the original response buffer.
+
+        * xml/XMLHttpRequest.cpp:
+        (WebCore::XMLHttpRequest::XMLHttpRequest): Added m_responseCacheIsValid to invalidate the cache of
+        a json response.
+        (WebCore::XMLHttpRequest::responseText):
+        (WebCore::XMLHttpRequest::didCacheResponseJSON): Added; Updates m_responseCacheIsValid and clears the
+        response buffer to save memory.
+        (WebCore::XMLHttpRequest::responseXML):
+        (WebCore::XMLHttpRequest::setResponseType):
+        (WebCore::XMLHttpRequest::responseType):
+        (WebCore::XMLHttpRequest::clearResponseBuffers):
+        (WebCore::XMLHttpRequest::didReceiveData):
+
+        * xml/XMLHttpRequest.h:
+        (WebCore::XMLHttpRequest::doneWithoutErrors): Extracted from responseXML.
+        (WebCore::XMLHttpRequest::responseTextIgnoringResponseType): Extracted from responseText.
+        (WebCore::XMLHttpRequest::responseCacheIsValid): Added.
+        (WebCore::XMLHttpRequest::shouldDecodeResponse): Extracted from didReceiveData.
+        Also modified to decode when the response type is ResponseTypeJSON.
+
+        * xml/XMLHttpRequest.idl: Added CachedAttribute IDL extention on response property. This cache is
+        used when the response type is 'json'.
+
 2013-09-03  Commit Queue  <[email protected]>
 
         Unreviewed, rolling out r154881.

Added: trunk/Source/WebCore/ForwardingHeaders/runtime/JSONObject.h (0 => 154992)


--- trunk/Source/WebCore/ForwardingHeaders/runtime/JSONObject.h	                        (rev 0)
+++ trunk/Source/WebCore/ForwardingHeaders/runtime/JSONObject.h	2013-09-03 18:45:51 UTC (rev 154992)
@@ -0,0 +1,4 @@
+#ifndef WebCore_FWD_JSONObject_h
+#define WebCore_FWD_JSONObject_h
+#include <_javascript_Core/JSONObject.h>
+#endif

Modified: trunk/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp (154991 => 154992)


--- trunk/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp	2013-09-03 18:30:08 UTC (rev 154991)
+++ trunk/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp	2013-09-03 18:45:51 UTC (rev 154992)
@@ -50,6 +50,7 @@
 #include <runtime/Error.h>
 #include <runtime/JSArrayBuffer.h>
 #include <runtime/JSArrayBufferView.h>
+#include <runtime/JSONObject.h>
 
 using namespace JSC;
 
@@ -75,6 +76,9 @@
     if (Blob* responseBlob = thisObject->m_impl->optionalResponseBlob())
         visitor.addOpaqueRoot(responseBlob);
 
+    if (thisObject->m_response)
+        visitor.append(&thisObject->m_response);
+
     thisObject->m_impl->visitJSEventListeners(visitor);
 }
 
@@ -168,6 +172,26 @@
     case XMLHttpRequest::ResponseTypeText:
         return responseText(exec);
 
+    case XMLHttpRequest::ResponseTypeJSON:
+        {
+            // FIXME: Use CachedAttribute for other types as well.
+            if (m_response && impl()->responseCacheIsValid())
+                return m_response.get();
+
+            if (!impl()->doneWithoutErrors())
+                return jsNull();
+
+            JSValue value = JSONParse(exec, impl()->responseTextIgnoringResponseType());
+            if (!value)
+                value = jsNull();
+            JSXMLHttpRequest* jsRequest = const_cast<JSXMLHttpRequest*>(this);
+            jsRequest->m_response.set(exec->vm(), jsRequest, value);
+
+            impl()->didCacheResponseJSON();
+
+            return value;
+        }
+
     case XMLHttpRequest::ResponseTypeDocument:
         {
             ExceptionCode ec = 0;

Modified: trunk/Source/WebCore/xml/XMLHttpRequest.cpp (154991 => 154992)


--- trunk/Source/WebCore/xml/XMLHttpRequest.cpp	2013-09-03 18:30:08 UTC (rev 154991)
+++ trunk/Source/WebCore/xml/XMLHttpRequest.cpp	2013-09-03 18:45:51 UTC (rev 154992)
@@ -192,6 +192,7 @@
     , m_exceptionCode(0)
     , m_progressEventThrottle(this)
     , m_responseTypeCode(ResponseTypeDefault)
+    , m_responseCacheIsValid(false)
 {
     initializeXMLHttpRequestStaticData();
 #ifndef NDEBUG
@@ -238,9 +239,16 @@
         ec = INVALID_STATE_ERR;
         return "";
     }
-    return m_responseBuilder.toStringPreserveCapacity();
+    return responseTextIgnoringResponseType();
 }
 
+void XMLHttpRequest::didCacheResponseJSON()
+{
+    ASSERT(m_responseTypeCode == ResponseTypeJSON && doneWithoutErrors());
+    m_responseCacheIsValid = true;
+    m_responseBuilder.clear();
+}
+
 Document* XMLHttpRequest::responseXML(ExceptionCode& ec)
 {
     if (m_responseTypeCode != ResponseTypeDefault && m_responseTypeCode != ResponseTypeDocument) {
@@ -248,7 +256,7 @@
         return 0;
     }
 
-    if (m_error || m_state != DONE)
+    if (!doneWithoutErrors())
         return 0;
 
     if (!m_createdDocument) {
@@ -362,6 +370,8 @@
         m_responseTypeCode = ResponseTypeDefault;
     else if (responseType == "text")
         m_responseTypeCode = ResponseTypeText;
+    else if (responseType == "json")
+        m_responseTypeCode = ResponseTypeJSON;
     else if (responseType == "document")
         m_responseTypeCode = ResponseTypeDocument;
     else if (responseType == "blob")
@@ -379,6 +389,8 @@
         return "";
     case ResponseTypeText:
         return "text";
+    case ResponseTypeJSON:
+        return "json";
     case ResponseTypeDocument:
         return "document";
     case ResponseTypeBlob:
@@ -887,6 +899,7 @@
     m_responseBlob = 0;
     m_binaryResponseBuilder.clear();
     m_responseArrayBuffer.clear();
+    m_responseCacheIsValid = false;
 }
 
 void XMLHttpRequest::clearRequest()
@@ -1189,7 +1202,7 @@
     if (m_state < HEADERS_RECEIVED)
         changeState(HEADERS_RECEIVED);
 
-    bool useDecoder = m_responseTypeCode == ResponseTypeDefault || m_responseTypeCode == ResponseTypeText || m_responseTypeCode == ResponseTypeDocument;
+    bool useDecoder = shouldDecodeResponse();
 
     if (useDecoder && !m_decoder) {
         if (!m_responseEncoding.isEmpty())

Modified: trunk/Source/WebCore/xml/XMLHttpRequest.h (154991 => 154992)


--- trunk/Source/WebCore/xml/XMLHttpRequest.h	2013-09-03 18:30:08 UTC (rev 154991)
+++ trunk/Source/WebCore/xml/XMLHttpRequest.h	2013-09-03 18:45:51 UTC (rev 154992)
@@ -68,11 +68,15 @@
     
     enum ResponseTypeCode {
         ResponseTypeDefault,
-        ResponseTypeText, 
+        ResponseTypeText,
+        ResponseTypeJSON,
         ResponseTypeDocument,
+
+        // Binary format
         ResponseTypeBlob,
         ResponseTypeArrayBuffer
     };
+    static const ResponseTypeCode FirstBinaryResponseType = ResponseTypeBlob;
 
 #if ENABLE(XHR_TIMEOUT)
     virtual void didTimeout();
@@ -101,9 +105,11 @@
     void abort();
     void setRequestHeader(const AtomicString& name, const String& value, ExceptionCode&);
     void overrideMimeType(const String& override);
+    bool doneWithoutErrors() const { return !m_error && m_state == DONE; }
     String getAllResponseHeaders(ExceptionCode&) const;
     String getResponseHeader(const AtomicString& name, ExceptionCode&) const;
     String responseText(ExceptionCode&);
+    String responseTextIgnoringResponseType() const { return m_responseBuilder.toStringPreserveCapacity(); }
     Document* responseXML(ExceptionCode&);
     Document* optionalResponseXML() const { return m_responseDocument.get(); }
     Blob* responseBlob();
@@ -113,6 +119,9 @@
     void setTimeout(unsigned long timeout, ExceptionCode&);
 #endif
 
+    bool responseCacheIsValid() const { return m_responseCacheIsValid; }
+    void didCacheResponseJSON();
+
     void sendFromInspector(PassRefPtr<FormData>, ExceptionCode&);
 
     // Expose HTTP validation methods for other untrusted requests.
@@ -200,6 +209,8 @@
     void networkError();
     void abortError();
 
+    bool shouldDecodeResponse() const { return m_responseTypeCode < FirstBinaryResponseType; }
+
     OwnPtr<XMLHttpRequestUpload> m_upload;
 
     KURL m_url;
@@ -249,6 +260,7 @@
 
     // An enum corresponding to the allowed string values for the responseType attribute.
     ResponseTypeCode m_responseTypeCode;
+    bool m_responseCacheIsValid;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/xml/XMLHttpRequest.idl (154991 => 154992)


--- trunk/Source/WebCore/xml/XMLHttpRequest.idl	2013-09-03 18:30:08 UTC (rev 154991)
+++ trunk/Source/WebCore/xml/XMLHttpRequest.idl	2013-09-03 18:45:51 UTC (rev 154992)
@@ -31,8 +31,7 @@
     "arraybuffer",
     "blob",
     "document",
-//    FIXME: enable once support for json responseText is completed. (bug #73648)
-//    "json",
+    "json",
     "text"
 };
 
@@ -87,7 +86,7 @@
     [GetterRaisesException] readonly attribute Document responseXML;
 
     [SetterRaisesException] attribute XMLHttpRequestResponseType responseType;
-    [GetterRaisesException, CustomGetter] readonly attribute Object response;
+    [GetterRaisesException, CachedAttribute, CustomGetter] readonly attribute Object response;
 
     [GetterRaisesException] readonly attribute unsigned short status;
     [GetterRaisesException] readonly attribute DOMString statusText;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to