| Index: third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
|
| diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
|
| index 2d04ec27bc3e4ba93a43130cd4a9bda9dbb7a1e1..c0f9454193ec6c0e6a358ac4e9af61c1f50a8df9 100644
|
| --- a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
|
| +++ b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
|
| @@ -8,6 +8,7 @@
|
| #include "bindings/core/v8/JSONValuesForV8.h"
|
| #include "bindings/core/v8/ScriptPromiseResolver.h"
|
| #include "bindings/core/v8/ScriptState.h"
|
| +#include "bindings/modules/v8/V8PaymentDetails.h"
|
| #include "core/EventTypeNames.h"
|
| #include "core/dom/DOMException.h"
|
| #include "core/dom/ExceptionCode.h"
|
| @@ -15,6 +16,7 @@
|
| #include "core/events/EventQueue.h"
|
| #include "modules/EventTargetModulesNames.h"
|
| #include "modules/payments/PaymentItem.h"
|
| +#include "modules/payments/PaymentRequestUpdateEvent.h"
|
| #include "modules/payments/PaymentResponse.h"
|
| #include "modules/payments/PaymentsValidators.h"
|
| #include "modules/payments/ShippingAddress.h"
|
| @@ -145,6 +147,26 @@ void validateShippingOptionsOrPaymentItems(HeapVector<T> items, ExceptionState&
|
| }
|
| }
|
|
|
| +void validatePaymentDetails(const PaymentDetails& details, ExceptionState& exceptionState)
|
| +{
|
| + if (!details.hasItems()) {
|
| + exceptionState.throwTypeError("Must specify items");
|
| + return;
|
| + }
|
| +
|
| + if (details.items().isEmpty()) {
|
| + exceptionState.throwTypeError("Must specify at least one item");
|
| + return;
|
| + }
|
| +
|
| + validateShippingOptionsOrPaymentItems(details.items(), exceptionState);
|
| + if (exceptionState.hadException())
|
| + return;
|
| +
|
| + if (details.hasShippingOptions())
|
| + validateShippingOptionsOrPaymentItems(details.shippingOptions(), exceptionState);
|
| +}
|
| +
|
| } // namespace
|
|
|
| PaymentRequest* PaymentRequest::create(ScriptState* scriptState, const Vector<String>& supportedMethods, const PaymentDetails& details, ExceptionState& exceptionState)
|
| @@ -209,12 +231,52 @@ ScriptPromise PaymentRequest::complete(ScriptState* scriptState, bool success)
|
| if (m_completeResolver)
|
| return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "Already called complete() once"));
|
|
|
| - m_completeResolver = ScriptPromiseResolver::create(scriptState);
|
| + // The payment provider should respond in PaymentRequest::OnComplete().
|
| m_paymentProvider->Complete(success);
|
|
|
| + m_completeResolver = ScriptPromiseResolver::create(scriptState);
|
| return m_completeResolver->promise();
|
| }
|
|
|
| +void PaymentRequest::onUpdatePaymentDetails(const ScriptValue& detailsScriptValue)
|
| +{
|
| + if (!m_showResolver || !m_paymentProvider)
|
| + return;
|
| +
|
| + PaymentDetails details;
|
| + TrackExceptionState exceptionState;
|
| + V8PaymentDetails::toImpl(detailsScriptValue.isolate(), detailsScriptValue.v8Value(), details, exceptionState);
|
| + if (exceptionState.hadException()) {
|
| + m_showResolver->reject(DOMException::create(SyntaxError, exceptionState.message()));
|
| + clearResolversAndCloseMojoConnection();
|
| + return;
|
| + }
|
| +
|
| + validatePaymentDetails(details, exceptionState);
|
| + if (exceptionState.hadException()) {
|
| + m_showResolver->reject(DOMException::create(SyntaxError, exceptionState.message()));
|
| + clearResolversAndCloseMojoConnection();
|
| + return;
|
| + }
|
| +
|
| + // Set the currently selected option if only one option was passed.
|
| + if (details.hasShippingOptions() && details.shippingOptions().size() == 1)
|
| + m_shippingOption = details.shippingOptions().begin()->id();
|
| + else
|
| + m_shippingOption = String();
|
| +
|
| + m_paymentProvider->UpdateWith(mojom::blink::PaymentDetails::From(details));
|
| +}
|
| +
|
| +void PaymentRequest::onUpdatePaymentDetailsFailure(const ScriptValue& error)
|
| +{
|
| + if (m_showResolver)
|
| + m_showResolver->reject(error);
|
| + if (m_completeResolver)
|
| + m_completeResolver->reject(error);
|
| + clearResolversAndCloseMojoConnection();
|
| +}
|
| +
|
| DEFINE_TRACE(PaymentRequest)
|
| {
|
| visitor->trace(m_details);
|
| @@ -228,8 +290,6 @@ DEFINE_TRACE(PaymentRequest)
|
|
|
| PaymentRequest::PaymentRequest(ScriptState* scriptState, const Vector<String>& supportedMethods, const PaymentDetails& details, const PaymentOptions& options, const ScriptValue& data, ExceptionState& exceptionState)
|
| : ContextLifecycleObserver(scriptState->getExecutionContext())
|
| - , m_supportedMethods(supportedMethods)
|
| - , m_details(details)
|
| , m_options(options)
|
| , m_clientBinding(this)
|
| {
|
| @@ -244,26 +304,12 @@ PaymentRequest::PaymentRequest(ScriptState* scriptState, const Vector<String>& s
|
| exceptionState.throwTypeError("Must specify at least one payment method identifier");
|
| return;
|
| }
|
| + m_supportedMethods = supportedMethods;
|
|
|
| - if (!details.hasItems()) {
|
| - exceptionState.throwTypeError("Must specify items");
|
| - return;
|
| - }
|
| -
|
| - if (details.items().isEmpty()) {
|
| - exceptionState.throwTypeError("Must specify at least one item");
|
| - return;
|
| - }
|
| -
|
| - validateShippingOptionsOrPaymentItems(details.items(), exceptionState);
|
| + validatePaymentDetails(details, exceptionState);
|
| if (exceptionState.hadException())
|
| return;
|
| -
|
| - if (details.hasShippingOptions()) {
|
| - validateShippingOptionsOrPaymentItems(details.shippingOptions(), exceptionState);
|
| - if (exceptionState.hadException())
|
| - return;
|
| - }
|
| + m_details = details;
|
|
|
| if (!data.isEmpty()) {
|
| RefPtr<JSONValue> value = toJSONValue(data.context(), data.v8Value());
|
| @@ -300,7 +346,7 @@ PaymentRequest::PaymentRequest(ScriptState* scriptState, const Vector<String>& s
|
|
|
| void PaymentRequest::contextDestroyed()
|
| {
|
| - cleanUp();
|
| + clearResolversAndCloseMojoConnection();
|
| }
|
|
|
| void PaymentRequest::OnShippingAddressChange(mojom::blink::ShippingAddressPtr address)
|
| @@ -311,14 +357,17 @@ void PaymentRequest::OnShippingAddressChange(mojom::blink::ShippingAddressPtr ad
|
| String errorMessage;
|
| if (!PaymentsValidators::isValidShippingAddress(address, &errorMessage)) {
|
| m_showResolver->reject(DOMException::create(SyntaxError, errorMessage));
|
| - cleanUp();
|
| + clearResolversAndCloseMojoConnection();
|
| return;
|
| }
|
|
|
| m_shippingAddress = new ShippingAddress(std::move(address));
|
| - Event* event = Event::create(EventTypeNames::shippingaddresschange);
|
| + PaymentRequestUpdateEvent* event = PaymentRequestUpdateEvent::create(EventTypeNames::shippingaddresschange);
|
| event->setTarget(this);
|
| - getExecutionContext()->getEventQueue()->enqueueEvent(event);
|
| + event->setPaymentDetailsUpdater(this);
|
| + bool success = getExecutionContext()->getEventQueue()->enqueueEvent(event);
|
| + DCHECK(success);
|
| + ALLOW_UNUSED_LOCAL(success);
|
| }
|
|
|
| void PaymentRequest::OnShippingOptionChange(const String& shippingOptionId)
|
| @@ -326,9 +375,12 @@ void PaymentRequest::OnShippingOptionChange(const String& shippingOptionId)
|
| DCHECK(m_showResolver);
|
| DCHECK(!m_completeResolver);
|
| m_shippingOption = shippingOptionId;
|
| - Event* event = Event::create(EventTypeNames::shippingoptionchange);
|
| + PaymentRequestUpdateEvent* event = PaymentRequestUpdateEvent::create(EventTypeNames::shippingoptionchange);
|
| event->setTarget(this);
|
| - getExecutionContext()->getEventQueue()->enqueueEvent(event);
|
| + event->setPaymentDetailsUpdater(this);
|
| + bool success = getExecutionContext()->getEventQueue()->enqueueEvent(event);
|
| + DCHECK(success);
|
| + ALLOW_UNUSED_LOCAL(success);
|
| }
|
|
|
| void PaymentRequest::OnPaymentResponse(mojom::blink::PaymentResponsePtr response)
|
| @@ -340,7 +392,7 @@ void PaymentRequest::OnPaymentResponse(mojom::blink::PaymentResponsePtr response
|
| String errorMessage;
|
| if (!PaymentsValidators::isValidShippingAddress(response->shipping_address, &errorMessage)) {
|
| m_showResolver->reject(DOMException::create(SyntaxError, errorMessage));
|
| - cleanUp();
|
| + clearResolversAndCloseMojoConnection();
|
| return;
|
| }
|
|
|
| @@ -349,6 +401,11 @@ void PaymentRequest::OnPaymentResponse(mojom::blink::PaymentResponsePtr response
|
| }
|
|
|
| m_showResolver->resolve(new PaymentResponse(std::move(response), this));
|
| +
|
| + // Do not close the mojo connection here. The merchant website should call
|
| + // PaymentResponse::complete(boolean), which will be forwarded over the mojo
|
| + // connection to display a success or failure message to the user.
|
| + m_showResolver.clear();
|
| }
|
|
|
| void PaymentRequest::OnError()
|
| @@ -357,17 +414,17 @@ void PaymentRequest::OnError()
|
| m_completeResolver->reject(DOMException::create(SyntaxError, "Request cancelled"));
|
| if (m_showResolver)
|
| m_showResolver->reject(DOMException::create(SyntaxError, "Request cancelled"));
|
| - cleanUp();
|
| + clearResolversAndCloseMojoConnection();
|
| }
|
|
|
| void PaymentRequest::OnComplete()
|
| {
|
| DCHECK(m_completeResolver);
|
| m_completeResolver->resolve();
|
| - cleanUp();
|
| + clearResolversAndCloseMojoConnection();
|
| }
|
|
|
| -void PaymentRequest::cleanUp()
|
| +void PaymentRequest::clearResolversAndCloseMojoConnection()
|
| {
|
| m_completeResolver.clear();
|
| m_showResolver.clear();
|
|
|