Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "modules/cachestorage/Cache.h" | 6 #include "modules/cachestorage/Cache.h" |
| 7 | 7 |
| 8 #include "bindings/core/v8/CallbackPromiseAdapter.h" | 8 #include "bindings/core/v8/CallbackPromiseAdapter.h" |
| 9 #include "bindings/core/v8/ExceptionState.h" | 9 #include "bindings/core/v8/ExceptionState.h" |
| 10 #include "bindings/core/v8/ScriptPromiseResolver.h" | 10 #include "bindings/core/v8/ScriptPromiseResolver.h" |
| 11 #include "bindings/core/v8/ScriptState.h" | 11 #include "bindings/core/v8/ScriptState.h" |
| 12 #include "bindings/core/v8/V8Binding.h" | |
| 12 #include "bindings/core/v8/V8ThrowException.h" | 13 #include "bindings/core/v8/V8ThrowException.h" |
| 13 #include "bindings/modules/v8/V8Response.h" | 14 #include "bindings/modules/v8/V8Response.h" |
| 14 #include "core/dom/DOMException.h" | 15 #include "core/dom/DOMException.h" |
| 15 #include "modules/cachestorage/CacheStorageError.h" | 16 #include "modules/cachestorage/CacheStorageError.h" |
| 16 #include "modules/fetch/BodyStreamBuffer.h" | 17 #include "modules/fetch/BodyStreamBuffer.h" |
| 17 #include "modules/fetch/GlobalFetch.h" | 18 #include "modules/fetch/GlobalFetch.h" |
| 18 #include "modules/fetch/Request.h" | 19 #include "modules/fetch/Request.h" |
| 19 #include "modules/fetch/Response.h" | 20 #include "modules/fetch/Response.h" |
| 20 #include "public/platform/WebServiceWorkerCache.h" | 21 #include "public/platform/WebServiceWorkerCache.h" |
| 21 | 22 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 128 { | 129 { |
| 129 OwnPtr<WebServiceWorkerCacheError> reason = adoptPtr(rawReason); | 130 OwnPtr<WebServiceWorkerCacheError> reason = adoptPtr(rawReason); |
| 130 m_resolver->reject(CacheStorageError::createException(*reason)); | 131 m_resolver->reject(CacheStorageError::createException(*reason)); |
| 131 m_resolver.clear(); | 132 m_resolver.clear(); |
| 132 } | 133 } |
| 133 | 134 |
| 134 private: | 135 private: |
| 135 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver; | 136 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver; |
| 136 }; | 137 }; |
| 137 | 138 |
| 138 ScriptPromise rejectAsNotImplemented(ScriptState* scriptState) | |
| 139 { | |
| 140 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError, "Cache is not implemented")); | |
| 141 } | |
| 142 | |
| 143 } // namespace | 139 } // namespace |
| 144 | 140 |
| 145 class Cache::FetchResolvedForAdd final : public ScriptFunction { | 141 class Cache::FetchResolvedForAdd final : public ScriptFunction { |
| 146 public: | 142 public: |
| 147 static v8::Local<v8::Function> create(ScriptState* scriptState, Cache* cache , Request* request) | 143 static v8::Local<v8::Function> create(ScriptState* scriptState, Cache* cache , const HeapVector<Member<Request>>& requests) |
| 148 { | 144 { |
| 149 FetchResolvedForAdd* self = new FetchResolvedForAdd(scriptState, cache, request); | 145 FetchResolvedForAdd* self = new FetchResolvedForAdd(scriptState, cache, requests); |
| 150 return self->bindToV8Function(); | 146 return self->bindToV8Function(); |
| 151 } | 147 } |
| 152 | 148 |
| 153 ScriptValue call(ScriptValue value) override | 149 ScriptValue call(ScriptValue value) override |
| 154 { | 150 { |
| 155 Response* response = V8Response::toImplWithTypeCheck(scriptState()->isol ate(), value.v8Value()); | 151 NonThrowableExceptionState exceptionState; |
| 156 ScriptPromise putPromise = m_cache->putImpl(scriptState(), HeapVector<Me mber<Request>>(1, m_request), HeapVector<Member<Response>>(1, response)); | 152 HeapVector<Member<Response>> responses = toMemberNativeArray<Response, V 8Response>(value.v8Value(), m_requests.size(), scriptState()->isolate(), excepti onState); |
| 153 ScriptPromise putPromise = m_cache->putImpl(scriptState(), m_requests, r esponses); | |
| 157 return ScriptValue(scriptState(), putPromise.v8Value()); | 154 return ScriptValue(scriptState(), putPromise.v8Value()); |
| 158 } | 155 } |
| 159 | 156 |
| 160 DEFINE_INLINE_VIRTUAL_TRACE() | 157 DEFINE_INLINE_VIRTUAL_TRACE() |
| 161 { | 158 { |
| 162 visitor->trace(m_cache); | 159 visitor->trace(m_cache); |
| 163 visitor->trace(m_request); | 160 visitor->trace(m_requests); |
| 164 ScriptFunction::trace(visitor); | 161 ScriptFunction::trace(visitor); |
| 165 } | 162 } |
| 166 | 163 |
| 167 private: | 164 private: |
| 168 FetchResolvedForAdd(ScriptState* scriptState, Cache* cache, Request* request ) | 165 FetchResolvedForAdd(ScriptState* scriptState, Cache* cache, const HeapVector <Member<Request>>& requests) |
| 169 : ScriptFunction(scriptState) | 166 : ScriptFunction(scriptState) |
| 170 , m_cache(cache) | 167 , m_cache(cache) |
| 171 , m_request(request) | 168 , m_requests(requests) |
| 172 { | 169 { |
| 173 } | 170 } |
| 174 | 171 |
| 175 Member<Cache> m_cache; | 172 Member<Cache> m_cache; |
| 176 Member<Request> m_request; | 173 HeapVector<Member<Request>> m_requests; |
| 177 }; | 174 }; |
| 178 | 175 |
| 179 class Cache::BarrierCallbackForPut final : public GarbageCollectedFinalized<Barr ierCallbackForPut> { | 176 class Cache::BarrierCallbackForPut final : public GarbageCollectedFinalized<Barr ierCallbackForPut> { |
| 180 public: | 177 public: |
| 181 BarrierCallbackForPut(int numberOfOperations, Cache* cache, PassRefPtrWillBe RawPtr<ScriptPromiseResolver> resolver) | 178 BarrierCallbackForPut(int numberOfOperations, Cache* cache, PassRefPtrWillBe RawPtr<ScriptPromiseResolver> resolver) |
| 182 : m_numberOfRemainingOperations(numberOfOperations) | 179 : m_numberOfRemainingOperations(numberOfOperations) |
| 183 , m_cache(cache) | 180 , m_cache(cache) |
| 184 , m_resolver(resolver) | 181 , m_resolver(resolver) |
| 185 { | 182 { |
| 186 ASSERT(0 < m_numberOfRemainingOperations); | 183 ASSERT(0 < m_numberOfRemainingOperations); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 285 return matchAllImpl(scriptState, request.getAsRequest(), options); | 282 return matchAllImpl(scriptState, request.getAsRequest(), options); |
| 286 Request* newRequest = Request::create(scriptState, request.getAsUSVString(), exceptionState); | 283 Request* newRequest = Request::create(scriptState, request.getAsUSVString(), exceptionState); |
| 287 if (exceptionState.hadException()) | 284 if (exceptionState.hadException()) |
| 288 return ScriptPromise(); | 285 return ScriptPromise(); |
| 289 return matchAllImpl(scriptState, newRequest, options); | 286 return matchAllImpl(scriptState, newRequest, options); |
| 290 } | 287 } |
| 291 | 288 |
| 292 ScriptPromise Cache::add(ScriptState* scriptState, const RequestInfo& request, E xceptionState& exceptionState) | 289 ScriptPromise Cache::add(ScriptState* scriptState, const RequestInfo& request, E xceptionState& exceptionState) |
| 293 { | 290 { |
| 294 ASSERT(!request.isNull()); | 291 ASSERT(!request.isNull()); |
| 295 Request* newRequest; | 292 HeapVector<Member<Request>> requests; |
| 296 if (request.isRequest()) { | 293 if (request.isRequest()) { |
| 297 newRequest = request.getAsRequest(); | 294 requests.append(request.getAsRequest()); |
| 298 } else { | 295 } else { |
| 299 newRequest = Request::create(scriptState, request.getAsUSVString(), exce ptionState); | 296 requests.append(Request::create(scriptState, request.getAsUSVString(), e xceptionState)); |
| 300 | |
| 301 if (exceptionState.hadException()) | 297 if (exceptionState.hadException()) |
| 302 return ScriptPromise(); | 298 return ScriptPromise(); |
| 303 } | 299 } |
| 304 | 300 |
| 305 Vector<Request*> requestVector; | 301 return addAllImpl(scriptState, requests, exceptionState); |
| 306 requestVector.append(newRequest); | |
| 307 return addAllImpl(scriptState, requestVector, exceptionState); | |
| 308 } | 302 } |
| 309 | 303 |
| 310 ScriptPromise Cache::addAll(ScriptState* scriptState, const Vector<ScriptValue>& rawRequests) | 304 ScriptPromise Cache::addAll(ScriptState* scriptState, const HeapVector<RequestIn fo>& rawRequests, ExceptionState& exceptionState) |
| 311 { | 305 { |
| 312 // FIXME: Implement this. | 306 HeapVector<Member<Request>> requests; |
| 313 return rejectAsNotImplemented(scriptState); | 307 for (RequestInfo request : rawRequests) { |
| 308 if (request.isRequest()) { | |
| 309 requests.append(request.getAsRequest()); | |
| 310 } else { | |
| 311 requests.append(Request::create(scriptState, request.getAsUSVString( ), exceptionState)); | |
| 312 if (exceptionState.hadException()) | |
| 313 return ScriptPromise(); | |
| 314 } | |
| 315 } | |
| 316 | |
| 317 return addAllImpl(scriptState, requests, exceptionState); | |
| 314 } | 318 } |
| 315 | 319 |
| 316 ScriptPromise Cache::deleteFunction(ScriptState* scriptState, const RequestInfo& request, const CacheQueryOptions& options, ExceptionState& exceptionState) | 320 ScriptPromise Cache::deleteFunction(ScriptState* scriptState, const RequestInfo& request, const CacheQueryOptions& options, ExceptionState& exceptionState) |
| 317 { | 321 { |
| 318 ASSERT(!request.isNull()); | 322 ASSERT(!request.isNull()); |
| 319 if (request.isRequest()) | 323 if (request.isRequest()) |
| 320 return deleteImpl(scriptState, request.getAsRequest(), options); | 324 return deleteImpl(scriptState, request.getAsRequest(), options); |
| 321 Request* newRequest = Request::create(scriptState, request.getAsUSVString(), exceptionState); | 325 Request* newRequest = Request::create(scriptState, request.getAsUSVString(), exceptionState); |
| 322 if (exceptionState.hadException()) | 326 if (exceptionState.hadException()) |
| 323 return ScriptPromise(); | 327 return ScriptPromise(); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 381 { | 385 { |
| 382 WebServiceWorkerRequest webRequest; | 386 WebServiceWorkerRequest webRequest; |
| 383 request->populateWebServiceWorkerRequest(webRequest); | 387 request->populateWebServiceWorkerRequest(webRequest); |
| 384 | 388 |
| 385 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState); | 389 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState); |
| 386 const ScriptPromise promise = resolver->promise(); | 390 const ScriptPromise promise = resolver->promise(); |
| 387 m_webCache->dispatchMatchAll(new CacheWithResponsesCallbacks(resolver), webR equest, toWebQueryParams(options)); | 391 m_webCache->dispatchMatchAll(new CacheWithResponsesCallbacks(resolver), webR equest, toWebQueryParams(options)); |
| 388 return promise; | 392 return promise; |
| 389 } | 393 } |
| 390 | 394 |
| 391 ScriptPromise Cache::addAllImpl(ScriptState* scriptState, const Vector<Request*> & requests, ExceptionState& exceptionState) | 395 // This class provides Promise.all() for ScriptPromise. |
| 396 class ScriptPromiseAll final : public GarbageCollectedFinalized<ScriptPromiseAll > { | |
|
jkarlin
2015/06/26 19:40:28
I'm sad that we have to go through V8 to wait on t
nhiroki
2015/07/02 09:31:54
Done.
| |
| 397 public: | |
| 398 class AdapterFunction : public ScriptFunction { | |
| 399 public: | |
| 400 enum ResolveType { | |
| 401 Fulfilled, | |
| 402 Rejected, | |
| 403 }; | |
| 404 | |
| 405 static v8::Local<v8::Function> create(ScriptState* scriptState, ResolveT ype resolveType, size_t index, ScriptPromiseAll* promiseAll) | |
| 406 { | |
| 407 AdapterFunction* self = new AdapterFunction(scriptState, resolveType , index, promiseAll); | |
| 408 return self->bindToV8Function(); | |
| 409 } | |
| 410 | |
| 411 DEFINE_INLINE_VIRTUAL_TRACE() | |
| 412 { | |
| 413 visitor->trace(m_promiseAll); | |
| 414 ScriptFunction::trace(visitor); | |
| 415 } | |
| 416 | |
| 417 private: | |
| 418 AdapterFunction(ScriptState* scriptState, ResolveType resolveType, size_ t index, ScriptPromiseAll* promiseAll) | |
| 419 : ScriptFunction(scriptState) | |
| 420 , m_resolveType(resolveType) | |
| 421 , m_index(index) | |
| 422 , m_promiseAll(promiseAll) { } | |
| 423 | |
| 424 ScriptValue call(ScriptValue value) override | |
| 425 { | |
| 426 if (m_resolveType == Fulfilled) { | |
| 427 m_promiseAll->onFulfilled(m_index, value); | |
| 428 } else { | |
| 429 m_promiseAll->onRejected(value); | |
| 430 } | |
| 431 return ScriptValue(scriptState(), m_promiseAll->promise().v8Value()) ; | |
| 432 } | |
| 433 | |
| 434 const ResolveType m_resolveType; | |
| 435 const size_t m_index; | |
| 436 Member<ScriptPromiseAll> m_promiseAll; | |
| 437 }; | |
| 438 | |
| 439 ScriptPromiseAll(Vector<ScriptPromise> promises, PassRefPtrWillBeRawPtr<Scri ptPromiseResolver> resolver) | |
| 440 : m_numberOfPendingPromises(promises.size()) | |
| 441 , m_resolver(resolver) | |
| 442 { | |
| 443 m_values.resize(promises.size()); | |
| 444 for (size_t i = 0; i < promises.size(); ++i) | |
| 445 promises[i].then(createFulfillFunction(i), createRejectFunction()); | |
| 446 } | |
| 447 | |
| 448 void onFulfilled(size_t index, const ScriptValue& value) | |
| 449 { | |
| 450 ASSERT(index < m_values.size()); | |
| 451 if (m_isResolvedOrRejected) | |
| 452 return; | |
| 453 m_values[index] = value; | |
| 454 if (--m_numberOfPendingPromises > 0) | |
| 455 return; | |
| 456 m_isResolvedOrRejected = true; | |
| 457 m_resolver->resolve(m_values); | |
| 458 } | |
| 459 | |
| 460 void onRejected(const ScriptValue& value) | |
| 461 { | |
| 462 if (m_isResolvedOrRejected) | |
| 463 return; | |
| 464 m_isResolvedOrRejected = true; | |
| 465 m_resolver->reject(value); | |
| 466 } | |
| 467 | |
| 468 v8::Local<v8::Function> createFulfillFunction(size_t index) | |
|
jkarlin
2015/06/26 19:40:28
The create functions should be private
nhiroki
2015/07/02 09:31:54
Done.
| |
| 469 { | |
| 470 return AdapterFunction::create(m_resolver->scriptState(), AdapterFunctio n::Fulfilled, index, this); | |
| 471 } | |
| 472 | |
| 473 v8::Local<v8::Function> createRejectFunction() | |
| 474 { | |
| 475 return AdapterFunction::create(m_resolver->scriptState(), AdapterFunctio n::Rejected, 0, this); | |
| 476 } | |
| 477 | |
| 478 ScriptPromise promise() { return m_resolver->promise(); } | |
| 479 | |
| 480 DEFINE_INLINE_VIRTUAL_TRACE() | |
| 481 { | |
| 482 visitor->trace(m_resolver); | |
| 483 visitor->trace(m_values); | |
| 484 } | |
| 485 | |
| 486 private: | |
| 487 size_t m_numberOfPendingPromises; | |
| 488 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver; | |
| 489 bool m_isResolvedOrRejected = false; | |
|
jkarlin
2015/06/26 19:40:28
I believe 'settled' is the term for a promise that
nhiroki
2015/07/02 09:31:54
Done.
| |
| 490 Vector<ScriptValue> m_values; | |
| 491 }; | |
| 492 | |
| 493 ScriptPromise Cache::addAllImpl(ScriptState* scriptState, const HeapVector<Membe r<Request>>& requests, ExceptionState& exceptionState) | |
| 392 { | 494 { |
| 393 // TODO(gavinp,nhiroki): Implement addAll for more than one element. | |
| 394 ASSERT(requests.size() == 1); | |
| 395 | |
| 396 Vector<RequestInfo> requestInfos; | 495 Vector<RequestInfo> requestInfos; |
| 397 requestInfos.resize(requests.size()); | 496 requestInfos.resize(requests.size()); |
| 497 Vector<ScriptPromise> promises; | |
| 498 promises.resize(requests.size()); | |
| 398 for (size_t i = 0; i < requests.size(); ++i) { | 499 for (size_t i = 0; i < requests.size(); ++i) { |
| 399 if (!requests[i]->url().protocolIsInHTTPFamily()) | 500 if (!requests[i]->url().protocolIsInHTTPFamily()) |
| 400 return ScriptPromise::reject(scriptState, V8ThrowException::createTy peError(scriptState->isolate(), "Add/AddAll does not support schemes other than \"http\" or \"https\"")); | 501 return ScriptPromise::reject(scriptState, V8ThrowException::createTy peError(scriptState->isolate(), "Add/AddAll does not support schemes other than \"http\" or \"https\"")); |
| 401 if (requests[i]->method() != "GET") | 502 if (requests[i]->method() != "GET") |
| 402 return ScriptPromise::reject(scriptState, V8ThrowException::createTy peError(scriptState->isolate(), "Add/AddAll only supports the GET request method .")); | 503 return ScriptPromise::reject(scriptState, V8ThrowException::createTy peError(scriptState->isolate(), "Add/AddAll only supports the GET request method .")); |
| 403 requestInfos[i].setRequest(requests[i]); | 504 requestInfos[i].setRequest(requests[i]); |
| 505 | |
| 506 promises[i] = m_scopedFetcher->fetch(scriptState, requestInfos[i], Dicti onary(), exceptionState); | |
| 404 } | 507 } |
| 405 | 508 |
| 406 ScriptPromise fetchPromise = m_scopedFetcher->fetch(scriptState, requestInfo s[0], Dictionary(), exceptionState); | 509 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState); |
| 407 return fetchPromise.then(FetchResolvedForAdd::create(scriptState, this, requ ests[0])); | 510 ScriptPromiseAll* promiseAll = new ScriptPromiseAll(promises, resolver.get() ); |
| 511 return promiseAll->promise().then(FetchResolvedForAdd::create(scriptState, t his, requests)); | |
| 408 } | 512 } |
| 409 | 513 |
| 410 ScriptPromise Cache::deleteImpl(ScriptState* scriptState, const Request* request , const CacheQueryOptions& options) | 514 ScriptPromise Cache::deleteImpl(ScriptState* scriptState, const Request* request , const CacheQueryOptions& options) |
| 411 { | 515 { |
| 412 WebVector<WebServiceWorkerCache::BatchOperation> batchOperations(size_t(1)); | 516 WebVector<WebServiceWorkerCache::BatchOperation> batchOperations(size_t(1)); |
| 413 batchOperations[0].operationType = WebServiceWorkerCache::OperationTypeDelet e; | 517 batchOperations[0].operationType = WebServiceWorkerCache::OperationTypeDelet e; |
| 414 request->populateWebServiceWorkerRequest(batchOperations[0].request); | 518 request->populateWebServiceWorkerRequest(batchOperations[0].request); |
| 415 batchOperations[0].matchParams = toWebQueryParams(options); | 519 batchOperations[0].matchParams = toWebQueryParams(options); |
| 416 | 520 |
| 417 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState); | 521 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 479 m_webCache->dispatchKeys(new CacheWithRequestsCallbacks(resolver), 0, toWebQ ueryParams(options)); | 583 m_webCache->dispatchKeys(new CacheWithRequestsCallbacks(resolver), 0, toWebQ ueryParams(options)); |
| 480 return promise; | 584 return promise; |
| 481 } | 585 } |
| 482 | 586 |
| 483 WebServiceWorkerCache* Cache::webCache() const | 587 WebServiceWorkerCache* Cache::webCache() const |
| 484 { | 588 { |
| 485 return m_webCache.get(); | 589 return m_webCache.get(); |
| 486 } | 590 } |
| 487 | 591 |
| 488 } // namespace blink | 592 } // namespace blink |
| OLD | NEW |