Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1953)

Unified Diff: Source/modules/cachestorage/Cache.cpp

Issue 1124403005: CacheStorage: Implement Cache.addAll() behind a flag (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: fix test failure Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/modules/cachestorage/Cache.h ('k') | Source/modules/cachestorage/Cache.idl » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/modules/cachestorage/Cache.cpp
diff --git a/Source/modules/cachestorage/Cache.cpp b/Source/modules/cachestorage/Cache.cpp
index d2c9e5fb112e1e5d0877272dd31c682680976102..0156b1486464503829001d6b316d76fc824d5144 100644
--- a/Source/modules/cachestorage/Cache.cpp
+++ b/Source/modules/cachestorage/Cache.cpp
@@ -9,6 +9,7 @@
#include "bindings/core/v8/ExceptionState.h"
#include "bindings/core/v8/ScriptPromiseResolver.h"
#include "bindings/core/v8/ScriptState.h"
+#include "bindings/core/v8/V8Binding.h"
#include "bindings/core/v8/V8ThrowException.h"
#include "bindings/modules/v8/V8Response.h"
#include "core/dom/DOMException.h"
@@ -135,45 +136,141 @@ private:
RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver;
};
-ScriptPromise rejectAsNotImplemented(ScriptState* scriptState)
-{
- return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError, "Cache is not implemented"));
-}
+// This class provides Promise.all() for ScriptPromise.
+// TODO(nhiroki): Move this somewhere else so that other components can reuse.
+// TODO(nhiroki): Unfortunately, we have to go through V8 to wait for the fetch
+// promise. It should be better to achieve this only within C++ world.
+class CacheStoragePromiseAll final : public GarbageCollectedFinalized<CacheStoragePromiseAll> {
+public:
+ CacheStoragePromiseAll(Vector<ScriptPromise> promises, PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver)
+ : m_numberOfPendingPromises(promises.size())
+ , m_resolver(resolver)
+ {
+ m_values.resize(promises.size());
+ for (size_t i = 0; i < promises.size(); ++i)
+ promises[i].then(createFulfillFunction(i), createRejectFunction());
+ }
+
+ void onFulfilled(size_t index, const ScriptValue& value)
+ {
+ ASSERT(index < m_values.size());
+ if (m_isSettled)
+ return;
+ m_values[index] = value;
+ if (--m_numberOfPendingPromises > 0)
+ return;
+ m_isSettled = true;
+ m_resolver->resolve(m_values);
+ }
+
+ void onRejected(const ScriptValue& value)
+ {
+ if (m_isSettled)
+ return;
+ m_isSettled = true;
+ m_resolver->reject(value);
+ }
+
+ ScriptPromise promise() { return m_resolver->promise(); }
+
+ DEFINE_INLINE_VIRTUAL_TRACE()
+ {
+ visitor->trace(m_resolver);
+ visitor->trace(m_values);
+ }
+
+private:
+ class AdapterFunction : public ScriptFunction {
+ public:
+ enum ResolveType {
+ Fulfilled,
+ Rejected,
+ };
+
+ static v8::Local<v8::Function> create(ScriptState* scriptState, ResolveType resolveType, size_t index, CacheStoragePromiseAll* promiseAll)
+ {
+ AdapterFunction* self = new AdapterFunction(scriptState, resolveType, index, promiseAll);
+ return self->bindToV8Function();
+ }
+
+ DEFINE_INLINE_VIRTUAL_TRACE()
+ {
+ visitor->trace(m_promiseAll);
+ ScriptFunction::trace(visitor);
+ }
+
+ private:
+ AdapterFunction(ScriptState* scriptState, ResolveType resolveType, size_t index, CacheStoragePromiseAll* promiseAll)
+ : ScriptFunction(scriptState)
+ , m_resolveType(resolveType)
+ , m_index(index)
+ , m_promiseAll(promiseAll) { }
+
+ ScriptValue call(ScriptValue value) override
+ {
+ if (m_resolveType == Fulfilled)
+ m_promiseAll->onFulfilled(m_index, value);
+ else
+ m_promiseAll->onRejected(value);
+ return ScriptValue(scriptState(), m_promiseAll->promise().v8Value());
+ }
+
+ const ResolveType m_resolveType;
+ const size_t m_index;
+ Member<CacheStoragePromiseAll> m_promiseAll;
+ };
+
+ v8::Local<v8::Function> createFulfillFunction(size_t index)
+ {
+ return AdapterFunction::create(m_resolver->scriptState(), AdapterFunction::Fulfilled, index, this);
+ }
+
+ v8::Local<v8::Function> createRejectFunction()
+ {
+ return AdapterFunction::create(m_resolver->scriptState(), AdapterFunction::Rejected, 0, this);
+ }
+
+ size_t m_numberOfPendingPromises;
+ RefPtrWillBeMember<ScriptPromiseResolver> m_resolver;
+ bool m_isSettled = false;
+ Vector<ScriptValue> m_values;
+};
} // namespace
class Cache::FetchResolvedForAdd final : public ScriptFunction {
public:
- static v8::Local<v8::Function> create(ScriptState* scriptState, Cache* cache, Request* request)
+ static v8::Local<v8::Function> create(ScriptState* scriptState, Cache* cache, const HeapVector<Member<Request>>& requests)
{
- FetchResolvedForAdd* self = new FetchResolvedForAdd(scriptState, cache, request);
+ FetchResolvedForAdd* self = new FetchResolvedForAdd(scriptState, cache, requests);
return self->bindToV8Function();
}
ScriptValue call(ScriptValue value) override
{
- Response* response = V8Response::toImplWithTypeCheck(scriptState()->isolate(), value.v8Value());
- ScriptPromise putPromise = m_cache->putImpl(scriptState(), HeapVector<Member<Request>>(1, m_request), HeapVector<Member<Response>>(1, response));
+ NonThrowableExceptionState exceptionState;
+ HeapVector<Member<Response>> responses = toMemberNativeArray<Response, V8Response>(value.v8Value(), m_requests.size(), scriptState()->isolate(), exceptionState);
+ ScriptPromise putPromise = m_cache->putImpl(scriptState(), m_requests, responses);
return ScriptValue(scriptState(), putPromise.v8Value());
}
DEFINE_INLINE_VIRTUAL_TRACE()
{
visitor->trace(m_cache);
- visitor->trace(m_request);
+ visitor->trace(m_requests);
ScriptFunction::trace(visitor);
}
private:
- FetchResolvedForAdd(ScriptState* scriptState, Cache* cache, Request* request)
+ FetchResolvedForAdd(ScriptState* scriptState, Cache* cache, const HeapVector<Member<Request>>& requests)
: ScriptFunction(scriptState)
, m_cache(cache)
- , m_request(request)
+ , m_requests(requests)
{
}
Member<Cache> m_cache;
- Member<Request> m_request;
+ HeapVector<Member<Request>> m_requests;
};
class Cache::BarrierCallbackForPut final : public GarbageCollectedFinalized<BarrierCallbackForPut> {
@@ -298,25 +395,32 @@ ScriptPromise Cache::matchAll(ScriptState* scriptState, const RequestInfo& reque
ScriptPromise Cache::add(ScriptState* scriptState, const RequestInfo& request, ExceptionState& exceptionState)
{
ASSERT(!request.isNull());
- Request* newRequest;
+ HeapVector<Member<Request>> requests;
if (request.isRequest()) {
- newRequest = request.getAsRequest();
+ requests.append(request.getAsRequest());
} else {
- newRequest = Request::create(scriptState, request.getAsUSVString(), exceptionState);
-
+ requests.append(Request::create(scriptState, request.getAsUSVString(), exceptionState));
if (exceptionState.hadException())
return ScriptPromise();
}
- Vector<Request*> requestVector;
- requestVector.append(newRequest);
- return addAllImpl(scriptState, requestVector, exceptionState);
+ return addAllImpl(scriptState, requests, exceptionState);
}
-ScriptPromise Cache::addAll(ScriptState* scriptState, const Vector<ScriptValue>& rawRequests)
+ScriptPromise Cache::addAll(ScriptState* scriptState, const HeapVector<RequestInfo>& rawRequests, ExceptionState& exceptionState)
{
- // FIXME: Implement this.
- return rejectAsNotImplemented(scriptState);
+ HeapVector<Member<Request>> requests;
+ for (RequestInfo request : rawRequests) {
+ if (request.isRequest()) {
+ requests.append(request.getAsRequest());
+ } else {
+ requests.append(Request::create(scriptState, request.getAsUSVString(), exceptionState));
+ if (exceptionState.hadException())
+ return ScriptPromise();
+ }
+ }
+
+ return addAllImpl(scriptState, requests, exceptionState);
}
ScriptPromise Cache::deleteFunction(ScriptState* scriptState, const RequestInfo& request, const CacheQueryOptions& options, ExceptionState& exceptionState)
@@ -394,23 +498,25 @@ ScriptPromise Cache::matchAllImpl(ScriptState* scriptState, const Request* reque
return promise;
}
-ScriptPromise Cache::addAllImpl(ScriptState* scriptState, const Vector<Request*>& requests, ExceptionState& exceptionState)
+ScriptPromise Cache::addAllImpl(ScriptState* scriptState, const HeapVector<Member<Request>>& requests, ExceptionState& exceptionState)
{
- // TODO(gavinp,nhiroki): Implement addAll for more than one element.
- ASSERT(requests.size() == 1);
-
Vector<RequestInfo> requestInfos;
requestInfos.resize(requests.size());
+ Vector<ScriptPromise> promises;
+ promises.resize(requests.size());
for (size_t i = 0; i < requests.size(); ++i) {
if (!requests[i]->url().protocolIsInHTTPFamily())
return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "Add/AddAll does not support schemes other than \"http\" or \"https\""));
if (requests[i]->method() != "GET")
return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "Add/AddAll only supports the GET request method."));
requestInfos[i].setRequest(requests[i]);
+
+ promises[i] = m_scopedFetcher->fetch(scriptState, requestInfos[i], Dictionary(), exceptionState);
}
- ScriptPromise fetchPromise = m_scopedFetcher->fetch(scriptState, requestInfos[0], Dictionary(), exceptionState);
- return fetchPromise.then(FetchResolvedForAdd::create(scriptState, this, requests[0]));
+ RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
+ CacheStoragePromiseAll* promiseAll = new CacheStoragePromiseAll(promises, resolver.get());
+ return promiseAll->promise().then(FetchResolvedForAdd::create(scriptState, this, requests));
}
ScriptPromise Cache::deleteImpl(ScriptState* scriptState, const Request* request, const CacheQueryOptions& options)
« no previous file with comments | « Source/modules/cachestorage/Cache.h ('k') | Source/modules/cachestorage/Cache.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698