d6c18b82e579b4c29b5be6444efd7c471e788b2e
[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 "NotImplemented.h"
32 #include "PaymentRequest.h"
33 #include <wtf/IsoMallocInlines.h>
34 #include <wtf/RunLoop.h>
35
36 namespace WebCore {
37
38 WTF_MAKE_ISO_ALLOCATED_IMPL(PaymentResponse);
39
40 PaymentResponse::PaymentResponse(ScriptExecutionContext* context, PaymentRequest& request)
41     : ActiveDOMObject { context }
42     , m_request { makeWeakPtr(request) }
43 {
44     suspendIfNeeded();
45 }
46
47 void PaymentResponse::finishConstruction()
48 {
49     ASSERT(!hasPendingActivity());
50     m_pendingActivity = makePendingActivity(*this);
51 }
52
53 PaymentResponse::~PaymentResponse()
54 {
55     ASSERT(!hasPendingActivity());
56     ASSERT(!hasRetryPromise());
57 }
58
59 void PaymentResponse::setDetailsFunction(DetailsFunction&& detailsFunction)
60 {
61     m_detailsFunction = WTFMove(detailsFunction);
62     m_cachedDetails = { };
63 }
64
65 void PaymentResponse::complete(Optional<PaymentComplete>&& result, DOMPromiseDeferred<void>&& promise)
66 {
67     if (m_state == State::Stopped || !m_request) {
68         promise.reject(Exception { AbortError });
69         return;
70     }
71
72     if (m_state == State::Completed || m_retryPromise) {
73         promise.reject(Exception { InvalidStateError });
74         return;
75     }
76
77     ASSERT(hasPendingActivity());
78     ASSERT(m_state == State::Created);
79     m_pendingActivity = nullptr;
80     m_state = State::Completed;
81
82     promise.settle(m_request->complete(WTFMove(result)));
83 }
84
85 void PaymentResponse::retry(PaymentValidationErrors&& errors, DOMPromiseDeferred<void>&& promise)
86 {
87     if (m_state == State::Stopped || !m_request) {
88         promise.reject(Exception { AbortError });
89         return;
90     }
91
92     if (m_state == State::Completed || m_retryPromise) {
93         promise.reject(Exception { InvalidStateError });
94         return;
95     }
96
97     ASSERT(hasPendingActivity());
98     ASSERT(m_state == State::Created);
99
100     auto exception = m_request->retry(WTFMove(errors));
101     if (exception.hasException()) {
102         promise.reject(exception.releaseException());
103         return;
104     }
105
106     m_retryPromise = WTFMove(promise);
107 }
108
109 void PaymentResponse::abortWithException(Exception&& exception)
110 {
111     settleRetryPromise(WTFMove(exception));
112     m_pendingActivity = nullptr;
113     m_state = State::Completed;
114 }
115
116 void PaymentResponse::settleRetryPromise(ExceptionOr<void>&& result)
117 {
118     if (!m_retryPromise)
119         return;
120
121     ASSERT(hasPendingActivity());
122     ASSERT(m_state == State::Created);
123     std::exchange(m_retryPromise, WTF::nullopt)->settle(WTFMove(result));
124 }
125
126 bool PaymentResponse::canSuspendForDocumentSuspension() const
127 {
128     ASSERT(m_state != State::Stopped);
129     return !hasPendingActivity();
130 }
131
132 void PaymentResponse::stop()
133 {
134     settleRetryPromise(Exception { AbortError });
135     m_pendingActivity = nullptr;
136     m_state = State::Stopped;
137 }
138
139 } // namespace WebCore
140
141 #endif // ENABLE(PAYMENT_REQUEST)