| 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 "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 |
| OLD | NEW |