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 |