98b5d6cf24097a0cc8e18e1ccdd0b319682fddfd
[WebKit-https.git] / Source / WebCore / Modules / paymentrequest / PaymentResponse.cpp
1 /*
2  * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "PaymentResponse.h"
28
29 #if ENABLE(PAYMENT_REQUEST)
30
31 #include "JSDOMPromiseDeferred.h"
32 #include "NotImplemented.h"
33 #include "PaymentRequest.h"
34 #include <wtf/IsoMallocInlines.h>
35 #include <wtf/RunLoop.h>
36
37 namespace WebCore {
38
39 WTF_MAKE_ISO_ALLOCATED_IMPL(PaymentResponse);
40
41 PaymentResponse::PaymentResponse(ScriptExecutionContext* context, PaymentRequest& request)
42     : ActiveDOMObject { context }
43     , m_request { makeWeakPtr(request) }
44 {
45     suspendIfNeeded();
46 }
47
48 void PaymentResponse::finishConstruction()
49 {
50     ASSERT(!hasPendingActivity());
51     m_pendingActivity = makePendingActivity(*this);
52 }
53
54 PaymentResponse::~PaymentResponse()
55 {
56     ASSERT(!hasPendingActivity());
57     ASSERT(!hasRetryPromise());
58 }
59
60 void PaymentResponse::setDetailsFunction(DetailsFunction&& detailsFunction)
61 {
62     m_detailsFunction = WTFMove(detailsFunction);
63     m_cachedDetails = { };
64 }
65
66 void PaymentResponse::complete(Optional<PaymentComplete>&& result, DOMPromiseDeferred<void>&& promise)
67 {
68     if (m_state == State::Stopped || !m_request) {
69         promise.reject(Exception { AbortError });
70         return;
71     }
72
73     if (m_state == State::Completed || m_retryPromise) {
74         promise.reject(Exception { InvalidStateError });
75         return;
76     }
77
78     ASSERT(hasPendingActivity());
79     ASSERT(m_state == State::Created);
80     m_pendingActivity = nullptr;
81     m_state = State::Completed;
82
83     promise.settle(m_request->complete(WTFMove(result)));
84 }
85
86 void PaymentResponse::retry(PaymentValidationErrors&& errors, DOMPromiseDeferred<void>&& promise)
87 {
88     if (m_state == State::Stopped || !m_request) {
89         promise.reject(Exception { AbortError });
90         return;
91     }
92
93     if (m_state == State::Completed || m_retryPromise) {
94         promise.reject(Exception { InvalidStateError });
95         return;
96     }
97
98     ASSERT(hasPendingActivity());
99     ASSERT(m_state == State::Created);
100
101     auto exception = m_request->retry(WTFMove(errors));
102     if (exception.hasException()) {
103         promise.reject(exception.releaseException());
104         return;
105     }
106
107     m_retryPromise = WTF::makeUnique<DOMPromiseDeferred<void>>(WTFMove(promise));
108 }
109
110 void PaymentResponse::abortWithException(Exception&& exception)
111 {
112     settleRetryPromise(WTFMove(exception));
113     m_pendingActivity = nullptr;
114     m_state = State::Completed;
115 }
116
117 void PaymentResponse::settleRetryPromise(ExceptionOr<void>&& result)
118 {
119     if (!m_retryPromise)
120         return;
121
122     ASSERT(hasPendingActivity());
123     ASSERT(m_state == State::Created);
124     m_retryPromise->settle(WTFMove(result));
125     m_retryPromise = nullptr;
126 }
127
128 bool PaymentResponse::canSuspendForDocumentSuspension() const
129 {
130     ASSERT(m_state != State::Stopped);
131     return !hasPendingActivity();
132 }
133
134 void PaymentResponse::stop()
135 {
136     settleRetryPromise(Exception { AbortError });
137     m_pendingActivity = nullptr;
138     m_state = State::Stopped;
139 }
140
141 } // namespace WebCore
142
143 #endif // ENABLE(PAYMENT_REQUEST)