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

Side by Side Diff: third_party/WebKit/Source/modules/serviceworkers/RespondWithObserver.cpp

Issue 2877543003: [ServiceWorker] Allow waitUntil to be called multiple times asynchronously (Closed)
Patch Set: Address comments from falken@ Created 3 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 unified diff | Download patch
OLDNEW
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 "modules/serviceworkers/RespondWithObserver.h" 5 #include "modules/serviceworkers/RespondWithObserver.h"
6 6
7 #include <v8.h> 7 #include <v8.h>
8 8
9 #include "bindings/core/v8/ScriptFunction.h" 9 #include "bindings/core/v8/ScriptFunction.h"
10 #include "bindings/core/v8/ScriptPromise.h" 10 #include "bindings/core/v8/ScriptPromise.h"
11 #include "bindings/core/v8/ScriptValue.h" 11 #include "bindings/core/v8/ScriptValue.h"
12 #include "bindings/core/v8/V8BindingForCore.h" 12 #include "bindings/core/v8/V8BindingForCore.h"
13 #include "core/dom/ExecutionContext.h" 13 #include "core/dom/ExecutionContext.h"
14 #include "modules/serviceworkers/WaitUntilObserver.h" 14 #include "modules/serviceworkers/WaitUntilObserver.h"
15 #include "public/platform/modules/serviceworker/WebServiceWorkerResponse.h" 15 #include "public/platform/modules/serviceworker/WebServiceWorkerResponse.h"
16 16
17 namespace blink { 17 namespace blink {
18 18
19 class RespondWithObserver::ThenFunction final : public ScriptFunction {
20 public:
21 enum ResolveType {
22 kFulfilled,
23 kRejected,
24 };
25
26 static v8::Local<v8::Function> CreateFunction(ScriptState* script_state,
27 RespondWithObserver* observer,
28 ResolveType type) {
29 ThenFunction* self = new ThenFunction(script_state, observer, type);
30 return self->BindToV8Function();
31 }
32
33 DEFINE_INLINE_VIRTUAL_TRACE() {
34 visitor->Trace(observer_);
35 ScriptFunction::Trace(visitor);
36 }
37
38 private:
39 ThenFunction(ScriptState* script_state,
40 RespondWithObserver* observer,
41 ResolveType type)
42 : ScriptFunction(script_state),
43 observer_(observer),
44 resolve_type_(type) {}
45
46 ScriptValue Call(ScriptValue value) override {
47 DCHECK(observer_);
48 DCHECK(resolve_type_ == kFulfilled || resolve_type_ == kRejected);
49 if (resolve_type_ == kRejected) {
50 observer_->ResponseWasRejected(
51 kWebServiceWorkerResponseErrorPromiseRejected);
52 value =
53 ScriptPromise::Reject(value.GetScriptState(), value).GetScriptValue();
54 } else {
55 observer_->ResponseWasFulfilled(value);
56 }
57 observer_ = nullptr;
58 return value;
59 }
60
61 Member<RespondWithObserver> observer_;
62 ResolveType resolve_type_;
63 };
64
65 void RespondWithObserver::ContextDestroyed(ExecutionContext*) { 19 void RespondWithObserver::ContextDestroyed(ExecutionContext*) {
66 if (observer_) { 20 if (observer_) {
67 DCHECK_EQ(kPending, state_); 21 DCHECK_EQ(kPending, state_);
68 observer_.Clear(); 22 observer_.Clear();
69 } 23 }
70 state_ = kDone; 24 state_ = kDone;
71 } 25 }
72 26
73 void RespondWithObserver::WillDispatchEvent() { 27 void RespondWithObserver::WillDispatchEvent() {
74 event_dispatch_time_ = WTF::CurrentTime(); 28 event_dispatch_time_ = WTF::CurrentTime();
75 } 29 }
76 30
77 void RespondWithObserver::DidDispatchEvent( 31 void RespondWithObserver::DidDispatchEvent(
78 DispatchEventResult dispatch_result) { 32 DispatchEventResult dispatch_result) {
79 DCHECK(GetExecutionContext()); 33 DCHECK(GetExecutionContext());
80 if (state_ != kInitial) 34 if (state_ != kInitial)
81 return; 35 return;
82 36
83 if (dispatch_result != DispatchEventResult::kNotCanceled) { 37 if (dispatch_result == DispatchEventResult::kNotCanceled) {
84 observer_->IncrementPendingActivity(); 38 OnNoResponse();
85 ResponseWasRejected(kWebServiceWorkerResponseErrorDefaultPrevented); 39 } else {
86 return; 40 OnResponseRejected(kWebServiceWorkerResponseErrorDefaultPrevented);
87 } 41 }
88 42
89 OnNoResponse();
90 state_ = kDone; 43 state_ = kDone;
91 observer_.Clear(); 44 observer_.Clear();
92 } 45 }
93 46
94 void RespondWithObserver::RespondWith(ScriptState* script_state, 47 void RespondWithObserver::RespondWith(ScriptState* script_state,
95 ScriptPromise script_promise, 48 ScriptPromise script_promise,
96 ExceptionState& exception_state) { 49 ExceptionState& exception_state) {
97 if (state_ != kInitial) { 50 if (state_ != kInitial) {
98 exception_state.ThrowDOMException( 51 exception_state.ThrowDOMException(
99 kInvalidStateError, "The event has already been responded to."); 52 kInvalidStateError, "The event has already been responded to.");
100 return; 53 return;
101 } 54 }
102 55
103 state_ = kPending; 56 state_ = kPending;
104 observer_->IncrementPendingActivity(); 57 observer_->WaitUntil(
105 script_promise.Then(ThenFunction::CreateFunction(script_state, this, 58 script_state, script_promise, exception_state,
106 ThenFunction::kFulfilled), 59 WTF::Bind(&RespondWithObserver::ResponseWasFulfilled,
107 ThenFunction::CreateFunction(script_state, this, 60 WrapPersistent(this)),
108 ThenFunction::kRejected)); 61 WTF::Bind(&RespondWithObserver::ResponseWasRejected, WrapPersistent(this),
62 kWebServiceWorkerResponseErrorPromiseRejected));
109 } 63 }
110 64
111 void RespondWithObserver::ResponseWasRejected( 65 void RespondWithObserver::ResponseWasRejected(
112 WebServiceWorkerResponseError error) { 66 WebServiceWorkerResponseError error,
67 const ScriptValue& value) {
113 OnResponseRejected(error); 68 OnResponseRejected(error);
114 state_ = kDone; 69 state_ = kDone;
115 observer_->DecrementPendingActivity();
116 observer_.Clear(); 70 observer_.Clear();
117 } 71 }
118 72
119 void RespondWithObserver::ResponseWasFulfilled(const ScriptValue& value) { 73 void RespondWithObserver::ResponseWasFulfilled(const ScriptValue& value) {
120 OnResponseFulfilled(value); 74 OnResponseFulfilled(value);
121 state_ = kDone; 75 state_ = kDone;
122 observer_->DecrementPendingActivity();
123 observer_.Clear(); 76 observer_.Clear();
124 } 77 }
125 78
126 RespondWithObserver::RespondWithObserver(ExecutionContext* context, 79 RespondWithObserver::RespondWithObserver(ExecutionContext* context,
127 int event_id, 80 int event_id,
128 WaitUntilObserver* observer) 81 WaitUntilObserver* observer)
129 : ContextLifecycleObserver(context), 82 : ContextLifecycleObserver(context),
130 event_id_(event_id), 83 event_id_(event_id),
131 state_(kInitial), 84 state_(kInitial),
132 observer_(observer) {} 85 observer_(observer) {}
133 86
134 DEFINE_TRACE(RespondWithObserver) { 87 DEFINE_TRACE(RespondWithObserver) {
135 visitor->Trace(observer_); 88 visitor->Trace(observer_);
136 ContextLifecycleObserver::Trace(visitor); 89 ContextLifecycleObserver::Trace(visitor);
137 } 90 }
138 91
139 } // namespace blink 92 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698