Title: [198005] trunk
Revision
198005
Author
youenn.fab...@crf.canon.fr
Date
2016-03-11 04:08:22 -0800 (Fri, 11 Mar 2016)

Log Message

[Fetch API] Use DeferredWrapper directly in FetchBody promise handling
https://bugs.webkit.org/show_bug.cgi?id=155291

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

* web-platform-tests/fetch/api/request/request-consume-empty-expected.txt: Added.
* web-platform-tests/fetch/api/request/request-consume-empty.html: Added.
* web-platform-tests/fetch/api/response/response-consume-empty-expected.txt: Added.
* web-platform-tests/fetch/api/response/response-consume-empty.html: Added.

Source/WebCore:

Moved from typed DOMPromise to DeferredWrapper as there can only be one promise resolved.
Started preparing the handling of blobs translation to other resolved types.

Fixed the case of empty body, in which case promises should resolve with empty objects (strings, buffers...) and not null.

Added Consumer structure to handle asynchronous resolution/rejection of promises.
Added preliminary API to resolve promises based on data stored as a Blob.
FetchBodyOwner will be responsible to do/stop blob loading.

Tests: imported/w3c/web-platform-tests/fetch/api/request/request-consume-empty.html
       imported/w3c/web-platform-tests/fetch/api/response/response-consume-empty.html

* Modules/fetch/FetchBody.cpp:
(WebCore::FetchBody::processIfEmptyOrDisturbed): Fixed empty body case.
(WebCore::FetchBody::arrayBuffer):
(WebCore::FetchBody::blob):
(WebCore::FetchBody::json):
(WebCore::FetchBody::text):
(WebCore::FetchBody::consume):
(WebCore::FetchBody::consumeText):
(WebCore::FetchBody::loadingType):
(WebCore::FetchBody::consumeBlob):
(WebCore::FetchBody::resolveAsJSON):
(WebCore::FetchBody::loadingFailed):
(WebCore::FetchBody::loadedAsBlob):
* Modules/fetch/FetchBody.h:
(WebCore::FetchBody::formData):
(WebCore::FetchBody::Consumer::Consumer):
* Modules/fetch/FetchBody.idl:
* Modules/fetch/FetchBodyOwner.h:
(WebCore::FetchBodyOwner::arrayBuffer):
(WebCore::FetchBodyOwner::blob):
(WebCore::FetchBodyOwner::formData):
(WebCore::FetchBodyOwner::json):
(WebCore::FetchBodyOwner::text):
(WebCore::FetchBodyOwner::loadBlob):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (198004 => 198005)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2016-03-11 11:13:25 UTC (rev 198004)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2016-03-11 12:08:22 UTC (rev 198005)
@@ -1,3 +1,15 @@
+2016-03-11  Youenn Fablet  <youenn.fab...@crf.canon.fr>
+
+        [Fetch API] Use DeferredWrapper directly in FetchBody promise handling
+        https://bugs.webkit.org/show_bug.cgi?id=155291
+
+        Reviewed by Darin Adler.
+
+        * web-platform-tests/fetch/api/request/request-consume-empty-expected.txt: Added.
+        * web-platform-tests/fetch/api/request/request-consume-empty.html: Added.
+        * web-platform-tests/fetch/api/response/response-consume-empty-expected.txt: Added.
+        * web-platform-tests/fetch/api/response/response-consume-empty.html: Added.
+
 2016-03-09  Chris Dumez  <cdu...@apple.com>
 
         focus() / blur() should be on HTMLElement / SVGElement, not Element

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-consume-empty-expected.txt (0 => 198005)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-consume-empty-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-consume-empty-expected.txt	2016-03-11 12:08:22 UTC (rev 198005)
@@ -0,0 +1,7 @@
+
+PASS Consume request's body as text 
+PASS Consume request's body as blob 
+PASS Consume request's body as arrayBuffer 
+PASS Consume request's body as json 
+FAIL Consume request's body as formData promise_test: Unhandled rejection with value: undefined
+

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-consume-empty.html (0 => 198005)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-consume-empty.html	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-consume-empty.html	2016-03-11 12:08:22 UTC (rev 198005)
@@ -0,0 +1,81 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Request consume empty bodies</title>
+    <meta name="help" href=""
+    <meta name="help" href=""
+    <meta name="author" title="Canon Research France" href=""
+    <script src=""
+    <script src=""
+  </head>
+  <body>
+    <script>
+    function checkBodyText(request) {
+      return request.text().then( function(bodyAsText) {
+        assert_equals(bodyAsText, "", "Resolved value should be empty");
+        assert_false(request.bodyUsed);
+      });
+    }
+
+    function checkBodyBlob(request) {
+      return request.blob().then(function(bodyAsBlob) {
+        var promise = new Promise(function (resolve, reject) {
+          var reader = new FileReader();
+          reader._onload_ = function(evt) {
+            resolve(reader.result)
+          };
+          reader._onerror_ = function() {
+            reject("Blob's reader failed");
+          };
+          reader.readAsText(bodyAsBlob);
+        });
+        return promise.then(function(body) {
+          assert_equals(body, "", "Resolved value should be empty");
+          assert_false(request.bodyUsed);
+        });
+      });
+    }
+
+    function checkBodyArrayBuffer(request) {
+      return request.arrayBuffer().then( function(bodyAsArrayBuffer) {
+        assert_equals(bodyAsArrayBuffer.byteLength, 0, "Resolved value should be empty");
+        assert_false(request.bodyUsed);
+      });
+    }
+
+    function checkBodyJSON(request) {
+      return request.json().then(
+        (bodyAsJSON) => {
+          assert_unreached("JSON parsing should fail");
+        },
+        () => {
+          assert_false(request.bodyUsed);
+        });
+    }
+
+    function checkBodyFormData(request) {
+      return request.formData().then(function(bodyAsFormData) {
+        assert_true(bodyAsFormData instanceof FormData, "Should receive a FormData");
+        assert_false(request.bodyUsed);
+     });
+    }
+
+    function checkRequestBody(bodyType, checkFunction) {
+      promise_test(function(test) {
+        var request = new Request("", {"method": "POST"});
+        assert_false(request.bodyUsed);
+        return checkFunction(request);
+      }, "Consume request's body as " + bodyType);
+    }
+
+    var formData = new FormData();
+    checkRequestBody("text", checkBodyText);
+    checkRequestBody("blob", checkBodyBlob);
+    checkRequestBody("arrayBuffer", checkBodyArrayBuffer);
+    checkRequestBody("json", checkBodyJSON);
+    checkRequestBody("formData", checkBodyFormData);
+
+    </script>
+  </body>
+</html>

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume-empty-expected.txt (0 => 198005)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume-empty-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume-empty-expected.txt	2016-03-11 12:08:22 UTC (rev 198005)
@@ -0,0 +1,7 @@
+
+PASS Consume response's body as text 
+PASS Consume response's body as blob 
+PASS Consume response's body as arrayBuffer 
+PASS Consume response's body as json 
+FAIL Consume response's body as formData promise_test: Unhandled rejection with value: undefined
+

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume-empty.html (0 => 198005)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume-empty.html	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume-empty.html	2016-03-11 12:08:22 UTC (rev 198005)
@@ -0,0 +1,81 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Response consume empty bodies</title>
+    <meta name="help" href=""
+    <meta name="help" href=""
+    <meta name="author" title="Canon Research France" href=""
+    <script src=""
+    <script src=""
+  </head>
+  <body>
+    <script>
+    function checkBodyText(response) {
+      return response.text().then( function(bodyAsText) {
+        assert_equals(bodyAsText, "", "Resolved value should be empty");
+        assert_false(response.bodyUsed);
+      });
+    }
+
+    function checkBodyBlob(response) {
+      return response.blob().then(function(bodyAsBlob) {
+        var promise = new Promise(function (resolve, reject) {
+          var reader = new FileReader();
+          reader._onload_ = function(evt) {
+            resolve(reader.result)
+          };
+          reader._onerror_ = function() {
+            reject("Blob's reader failed");
+          };
+          reader.readAsText(bodyAsBlob);
+        });
+        return promise.then(function(body) {
+          assert_equals(body, "", "Resolved value should be empty");
+          assert_false(response.bodyUsed);
+        });
+      });
+    }
+
+    function checkBodyArrayBuffer(response) {
+      return response.arrayBuffer().then( function(bodyAsArrayBuffer) {
+        assert_equals(bodyAsArrayBuffer.byteLength, 0, "Resolved value should be empty");
+        assert_false(response.bodyUsed);
+      });
+    }
+
+    function checkBodyJSON(response) {
+      return response.json().then(
+        (bodyAsJSON) => {
+          assert_unreached("JSON parsing should fail");
+        },
+        () => {
+          assert_false(response.bodyUsed);
+        });
+    }
+
+    function checkBodyFormData(response) {
+      return response.formData().then(function(bodyAsFormData) {
+        assert_true(bodyAsFormData instanceof FormData, "Should receive a FormData");
+        assert_false(response.bodyUsed);
+     });
+    }
+
+    function checkResponseBody(bodyType, checkFunction) {
+      promise_test(function(test) {
+        var response = new Response();
+        assert_false(response.bodyUsed);
+        return checkFunction(response);
+      }, "Consume response's body as " + bodyType);
+    }
+
+    var formData = new FormData();
+    checkResponseBody("text", checkBodyText);
+    checkResponseBody("blob", checkBodyBlob);
+    checkResponseBody("arrayBuffer", checkBodyArrayBuffer);
+    checkResponseBody("json", checkBodyJSON);
+    checkResponseBody("formData", checkBodyFormData);
+
+    </script>
+  </body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (198004 => 198005)


--- trunk/Source/WebCore/ChangeLog	2016-03-11 11:13:25 UTC (rev 198004)
+++ trunk/Source/WebCore/ChangeLog	2016-03-11 12:08:22 UTC (rev 198005)
@@ -1,3 +1,47 @@
+2016-03-11  Youenn Fablet  <youenn.fab...@crf.canon.fr>
+
+        [Fetch API] Use DeferredWrapper directly in FetchBody promise handling
+        https://bugs.webkit.org/show_bug.cgi?id=155291
+
+        Reviewed by Darin Adler.
+
+        Moved from typed DOMPromise to DeferredWrapper as there can only be one promise resolved.
+        Started preparing the handling of blobs translation to other resolved types.
+
+        Fixed the case of empty body, in which case promises should resolve with empty objects (strings, buffers...) and not null.
+
+        Added Consumer structure to handle asynchronous resolution/rejection of promises.
+        Added preliminary API to resolve promises based on data stored as a Blob.
+        FetchBodyOwner will be responsible to do/stop blob loading.
+
+        Tests: imported/w3c/web-platform-tests/fetch/api/request/request-consume-empty.html
+               imported/w3c/web-platform-tests/fetch/api/response/response-consume-empty.html
+
+        * Modules/fetch/FetchBody.cpp:
+        (WebCore::FetchBody::processIfEmptyOrDisturbed): Fixed empty body case.
+        (WebCore::FetchBody::arrayBuffer):
+        (WebCore::FetchBody::blob):
+        (WebCore::FetchBody::json):
+        (WebCore::FetchBody::text):
+        (WebCore::FetchBody::consume):
+        (WebCore::FetchBody::consumeText):
+        (WebCore::FetchBody::loadingType):
+        (WebCore::FetchBody::consumeBlob):
+        (WebCore::FetchBody::resolveAsJSON):
+        (WebCore::FetchBody::loadingFailed):
+        (WebCore::FetchBody::loadedAsBlob):
+        * Modules/fetch/FetchBody.h:
+        (WebCore::FetchBody::formData):
+        (WebCore::FetchBody::Consumer::Consumer):
+        * Modules/fetch/FetchBody.idl:
+        * Modules/fetch/FetchBodyOwner.h:
+        (WebCore::FetchBodyOwner::arrayBuffer):
+        (WebCore::FetchBodyOwner::blob):
+        (WebCore::FetchBodyOwner::formData):
+        (WebCore::FetchBodyOwner::json):
+        (WebCore::FetchBodyOwner::text):
+        (WebCore::FetchBodyOwner::loadBlob):
+
 2016-03-11  Yoav Weiss  <y...@yoav.ws>
 
         Avoid applying link tags with an invalid media attribute

Modified: trunk/Source/WebCore/Modules/fetch/FetchBody.cpp (198004 => 198005)


--- trunk/Source/WebCore/Modules/fetch/FetchBody.cpp	2016-03-11 11:13:25 UTC (rev 198004)
+++ trunk/Source/WebCore/Modules/fetch/FetchBody.cpp	2016-03-11 12:08:22 UTC (rev 198005)
@@ -31,8 +31,10 @@
 
 #if ENABLE(FETCH_API)
 
+#include "DOMRequestState.h"
 #include "Dictionary.h"
 #include "ExceptionCode.h"
+#include "FetchBodyOwner.h"
 #include "HTTPParsers.h"
 #include "JSBlob.h"
 #include "JSDOMFormData.h"
@@ -82,98 +84,138 @@
     return FetchBody(WTFMove(*body));
 }
 
-template<typename T> inline bool FetchBody::processIfEmptyOrDisturbed(DOMPromise<T, ExceptionCode>& promise)
+bool FetchBody::processIfEmptyOrDisturbed(Consumer::Type type, DeferredWrapper& promise)
 {
     if (m_type == Type::None) {
-        promise.resolve(T());
-        return true;
+        switch (type) {
+        case Consumer::Type::Text:
+            promise.resolve(String());
+            return true;
+        case Consumer::Type::Blob:
+            promise.resolve<RefPtr<Blob>>(Blob::create());
+            return true;
+        case Consumer::Type::JSON:
+            promise.reject<ExceptionCode>(SYNTAX_ERR);
+            return true;
+        case Consumer::Type::ArrayBuffer:
+            promise.resolve(ArrayBuffer::create(nullptr, 0));
+            return true;
+        default:
+            ASSERT_NOT_REACHED();
+            promise.reject<ExceptionCode>(0);
+            return true;
+        };
     }
 
     if (m_isDisturbed) {
-        promise.reject(TypeError);
+        promise.reject<ExceptionCode>(TypeError);
         return true;
     }
     m_isDisturbed = true;
     return false;
 }
 
-void FetchBody::arrayBuffer(ArrayBufferPromise&& promise)
+void FetchBody::arrayBuffer(FetchBodyOwner& owner, DeferredWrapper&& promise)
 {
-    if (processIfEmptyOrDisturbed(promise))
+    if (processIfEmptyOrDisturbed(Consumer::Type::ArrayBuffer, promise))
         return;
-
-    if (m_type == Type::Text) {
-        // FIXME: Ideally we would like to have an ArrayBuffer directly from m_text.
-        Vector<char> data = ""
-        RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(data.data(), data.size());
-        promise.resolve(buffer);
-        return;
-    }
-    // FIXME: Support other types.
-    promise.reject(0);
+    consume(owner, Consumer::Type::ArrayBuffer, WTFMove(promise));
 }
 
-void FetchBody::formData(FormDataPromise&& promise)
+void FetchBody::blob(FetchBodyOwner& owner, DeferredWrapper&& promise)
 {
-    if (m_type == Type::None || m_isDisturbed) {
-        promise.reject(TypeError);
+    if (processIfEmptyOrDisturbed(Consumer::Type::Blob, promise))
         return;
-    }
-    m_isDisturbed = true;
 
-    // FIXME: Support other types.
-    promise.reject(0);
+    consume(owner, Consumer::Type::Blob, WTFMove(promise));
 }
 
-void FetchBody::blob(BlobPromise&& promise)
+void FetchBody::json(FetchBodyOwner& owner, DeferredWrapper&& promise)
 {
-    if (processIfEmptyOrDisturbed(promise))
+    if (processIfEmptyOrDisturbed(Consumer::Type::JSON, promise))
         return;
 
-    if (m_type == Type::Blob) {
-        promise.resolve(m_blob);
-        return;
-    }
     if (m_type == Type::Text) {
-        String contentType = Blob::normalizedContentType(extractMIMETypeFromMediaType(m_mimeType));
-        promise.resolve(Blob::create(extractFromText(), contentType));
+        resolveAsJSON(owner.scriptExecutionContext(), m_text, WTFMove(promise));
         return;
     }
-
-    // FIXME: Support other types.
-    promise.reject(0);
+    consume(owner, Consumer::Type::JSON, WTFMove(promise));
 }
 
-void FetchBody::text(TextPromise&& promise)
+void FetchBody::text(FetchBodyOwner& owner, DeferredWrapper&& promise)
 {
-    if (processIfEmptyOrDisturbed(promise))
+    if (processIfEmptyOrDisturbed(Consumer::Type::Text, promise))
         return;
 
     if (m_type == Type::Text) {
         promise.resolve(m_text);
         return;
     }
-    // FIXME: Support other types.
-    promise.reject(0);
+    consume(owner, Consumer::Type::Text, WTFMove(promise));
 }
 
-void FetchBody::json(JSC::ExecState& state, JSONPromise&& promise)
+void FetchBody::consume(FetchBodyOwner& owner, Consumer::Type type, DeferredWrapper&& promise)
 {
-    if (processIfEmptyOrDisturbed(promise))
-        return;
-
     if (m_type == Type::Text) {
-        JSC::JSValue value = JSC::JSONParse(&state, m_text);
-        if (!value)
-            promise.reject(SYNTAX_ERR);
-        else
-            promise.resolve(value);
+        consumeText(type, WTFMove(promise));
         return;
     }
+    if (m_type == Type::Blob) {
+        consumeBlob(owner, type, WTFMove(promise));
+        return;
+    }
+
     // FIXME: Support other types.
-    promise.reject(0);
+    promise.reject<ExceptionCode>(0);
 }
 
+void FetchBody::consumeText(Consumer::Type type, DeferredWrapper&& promise)
+{
+    ASSERT(type == Consumer::Type::ArrayBuffer || type == Consumer::Type::Blob);
+
+    if (type == Consumer::Type::ArrayBuffer) {
+        Vector<char> data = ""
+        promise.resolve<RefPtr<ArrayBuffer>>(ArrayBuffer::create(data.data(), data.size()));
+        return;
+    }
+    String contentType = Blob::normalizedContentType(extractMIMETypeFromMediaType(m_mimeType));
+    promise.resolve<RefPtr<Blob>>(Blob::create(extractFromText(), contentType));
+}
+
+FetchLoadingType FetchBody::loadingType(Consumer::Type type)
+{
+    switch (type) {
+    case Consumer::Type::JSON:
+    case Consumer::Type::Text:
+        return FetchLoadingType::Text;
+    case Consumer::Type::Blob:
+        return FetchLoadingType::Blob;
+    case Consumer::Type::ArrayBuffer:
+        return FetchLoadingType::ArrayBuffer;
+    default:
+        ASSERT_NOT_REACHED();
+        return FetchLoadingType::ArrayBuffer;
+    };
+}
+
+void FetchBody::consumeBlob(FetchBodyOwner& owner, Consumer::Type type, DeferredWrapper&& promise)
+{
+    ASSERT(m_blob);
+
+    m_consumer = Consumer({type, WTFMove(promise)});
+    owner.loadBlob(*m_blob, loadingType(type));
+}
+
+void FetchBody::resolveAsJSON(ScriptExecutionContext* context, const String& data, DeferredWrapper&& promise)
+{
+    DOMRequestState state(context);
+    JSC::JSValue value = JSC::JSONParse(state.exec(), data);
+    if (!value)
+        promise.reject<ExceptionCode>(SYNTAX_ERR);
+    else
+        promise.resolve(value);
+}
+
 Vector<char> FetchBody::extractFromText() const
 {
     ASSERT(m_type == Type::Text);
@@ -184,6 +226,20 @@
     return value;
 }
 
+void FetchBody::loadingFailed()
+{
+    ASSERT(m_consumer);
+    m_consumer->promise.reject<ExceptionCode>(0);
+    m_consumer = Nullopt;
 }
 
+void FetchBody::loadedAsBlob(Blob& blob)
+{
+    ASSERT(m_consumer);
+    m_consumer->promise.resolve(&blob);
+    m_consumer = Nullopt;
+}
+
+}
+
 #endif // ENABLE(FETCH_API)

Modified: trunk/Source/WebCore/Modules/fetch/FetchBody.h (198004 => 198005)


--- trunk/Source/WebCore/Modules/fetch/FetchBody.h	2016-03-11 11:13:25 UTC (rev 198004)
+++ trunk/Source/WebCore/Modules/fetch/FetchBody.h	2016-03-11 12:08:22 UTC (rev 198005)
@@ -36,33 +36,23 @@
 #include "JSDOMPromise.h"
 
 namespace JSC {
-class ArrayBuffer;
 class ExecState;
 class JSValue;
 };
 
 namespace WebCore {
 
-class Dictionary;
-typedef int ExceptionCode;
+class FetchBodyOwner;
+enum class FetchLoadingType;
 
 class FetchBody {
 public:
-    typedef DOMPromise<RefPtr<JSC::ArrayBuffer>, ExceptionCode> ArrayBufferPromise;
-    void arrayBuffer(ArrayBufferPromise&&);
+    void arrayBuffer(FetchBodyOwner&, DeferredWrapper&&);
+    void blob(FetchBodyOwner&, DeferredWrapper&&);
+    void json(FetchBodyOwner&, DeferredWrapper&&);
+    void text(FetchBodyOwner&, DeferredWrapper&&);
+    void formData(FetchBodyOwner&, DeferredWrapper&& promise) { promise.reject<ExceptionCode>(0); }
 
-    typedef DOMPromise<RefPtr<DOMFormData>, ExceptionCode> FormDataPromise;
-    void formData(FormDataPromise&&);
-
-    typedef DOMPromise<RefPtr<Blob>, ExceptionCode> BlobPromise;
-    void blob(BlobPromise&&);
-
-    typedef DOMPromise<JSC::JSValue, ExceptionCode> JSONPromise;
-    void json(JSC::ExecState&, JSONPromise&&);
-
-    typedef DOMPromise<String, ExceptionCode> TextPromise;
-    void text(TextPromise&&);
-
     bool isDisturbed() const { return m_isDisturbed; }
     bool isEmpty() const { return m_type == Type::None; }
 
@@ -73,16 +63,30 @@
     static FetchBody extractFromBody(FetchBody*);
     FetchBody() = default;
 
+    void loadingFailed();
+    void loadedAsBlob(Blob&);
+
 private:
-    template<typename T> bool processIfEmptyOrDisturbed(DOMPromise<T, ExceptionCode>&);
-
     enum class Type { None, Text, Blob, FormData };
 
     FetchBody(Ref<Blob>&&);
     FetchBody(Ref<DOMFormData>&&);
     FetchBody(String&&);
 
+    struct Consumer {
+        enum class Type { Text, Blob, JSON, ArrayBuffer };
+
+        Type type;
+        DeferredWrapper promise;
+    };
+    void consume(FetchBodyOwner&, Consumer::Type, DeferredWrapper&&);
+
     Vector<char> extractFromText() const;
+    bool processIfEmptyOrDisturbed(Consumer::Type, DeferredWrapper&);
+    void consumeText(Consumer::Type, DeferredWrapper&&);
+    void consumeBlob(FetchBodyOwner&, Consumer::Type, DeferredWrapper&&);
+    void resolveAsJSON(ScriptExecutionContext*, const String&, DeferredWrapper&&);
+    static FetchLoadingType loadingType(Consumer::Type);
 
     Type m_type = Type::None;
     String m_mimeType;
@@ -92,6 +96,8 @@
     RefPtr<Blob> m_blob;
     RefPtr<DOMFormData> m_formData;
     String m_text;
+
+    Optional<Consumer> m_consumer;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/fetch/FetchBody.idl (198004 => 198005)


--- trunk/Source/WebCore/Modules/fetch/FetchBody.idl	2016-03-11 11:13:25 UTC (rev 198004)
+++ trunk/Source/WebCore/Modules/fetch/FetchBody.idl	2016-03-11 12:08:22 UTC (rev 198005)
@@ -37,6 +37,6 @@
     [NewObject] Promise arrayBuffer();
     [NewObject] Promise blob();
     [NewObject] Promise formData();
-    [CallWith=ScriptState, NewObject] Promise json();
+    [NewObject] Promise json();
     [NewObject] Promise text();
 };

Modified: trunk/Source/WebCore/Modules/fetch/FetchBodyOwner.h (198004 => 198005)


--- trunk/Source/WebCore/Modules/fetch/FetchBodyOwner.h	2016-03-11 11:13:25 UTC (rev 198004)
+++ trunk/Source/WebCore/Modules/fetch/FetchBodyOwner.h	2016-03-11 12:08:22 UTC (rev 198005)
@@ -36,18 +36,22 @@
 
 namespace WebCore {
 
+enum class FetchLoadingType { Text, ArrayBuffer, Blob };
+
 class FetchBodyOwner : public RefCounted<FetchBodyOwner>, public ActiveDOMObject {
 public:
     FetchBodyOwner(ScriptExecutionContext&, FetchBody&&);
 
     // Exposed Body API
     bool isDisturbed() const { return m_body.isDisturbed(); }
-    void arrayBuffer(FetchBody::ArrayBufferPromise&& promise) { m_body.arrayBuffer(WTFMove(promise)); }
-    void formData(FetchBody::FormDataPromise&& promise) { m_body.formData(WTFMove(promise)); }
-    void blob(FetchBody::BlobPromise&& promise) { m_body.blob(WTFMove(promise)); }
-    void json(JSC::ExecState& state, FetchBody::JSONPromise&& promise) { m_body.json(state, WTFMove(promise)); }
-    void text(FetchBody::TextPromise&& promise) { m_body.text(WTFMove(promise)); }
+    void arrayBuffer(DeferredWrapper&& promise) { m_body.arrayBuffer(*this, WTFMove(promise)); }
+    void blob(DeferredWrapper&& promise) { m_body.blob(*this, WTFMove(promise)); }
+    void formData(DeferredWrapper&& promise) { m_body.formData(*this, WTFMove(promise)); }
+    void json(DeferredWrapper&& promise) { m_body.json(*this, WTFMove(promise)); }
+    void text(DeferredWrapper&& promise) { m_body.text(*this, WTFMove(promise)); }
 
+    void loadBlob(Blob&, FetchLoadingType);
+
 protected:
     FetchBody m_body;
 };
@@ -59,6 +63,17 @@
     suspendIfNeeded();
 }
 
+inline void FetchBodyOwner::loadBlob(Blob& blob, FetchLoadingType type)
+{
+    if (type == FetchLoadingType::Blob) {
+        // FIXME: Clone blob.
+        m_body.loadedAsBlob(blob);
+        return;
+    }
+    // FIXME: Implement blob loading.
+    m_body.loadingFailed();
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(FETCH_API)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to