diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/modules/payments/payment_request.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/modules/payments/payment_request.cc | 404 |
1 files changed, 213 insertions, 191 deletions
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request.cc b/chromium/third_party/blink/renderer/modules/payments/payment_request.cc index e16c732ce23..34f940dabdc 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_request.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payment_request.cc @@ -57,6 +57,7 @@ #include "third_party/blink/renderer/platform/uuid.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -88,53 +89,53 @@ using ::payments::mojom::blink::PaymentValidationErrorsPtr; namespace mojo { template <> -struct TypeConverter<PaymentCurrencyAmountPtr, blink::PaymentCurrencyAmount> { +struct TypeConverter<PaymentCurrencyAmountPtr, blink::PaymentCurrencyAmount*> { static PaymentCurrencyAmountPtr Convert( - const blink::PaymentCurrencyAmount& input) { + const blink::PaymentCurrencyAmount* input) { PaymentCurrencyAmountPtr output = PaymentCurrencyAmount::New(); - output->currency = input.currency().UpperASCII(); - output->value = input.value(); + output->currency = input->currency().UpperASCII(); + output->value = input->value(); return output; } }; template <> -struct TypeConverter<PaymentItemPtr, blink::PaymentItem> { - static PaymentItemPtr Convert(const blink::PaymentItem& input) { +struct TypeConverter<PaymentItemPtr, blink::PaymentItem*> { + static PaymentItemPtr Convert(const blink::PaymentItem* input) { PaymentItemPtr output = payments::mojom::blink::PaymentItem::New(); - output->label = input.label(); - output->amount = PaymentCurrencyAmount::From(input.amount()); - output->pending = input.pending(); + output->label = input->label(); + output->amount = PaymentCurrencyAmount::From(input->amount()); + output->pending = input->pending(); return output; } }; template <> -struct TypeConverter<PaymentShippingOptionPtr, blink::PaymentShippingOption> { +struct TypeConverter<PaymentShippingOptionPtr, blink::PaymentShippingOption*> { static PaymentShippingOptionPtr Convert( - const blink::PaymentShippingOption& input) { + const blink::PaymentShippingOption* input) { PaymentShippingOptionPtr output = payments::mojom::blink::PaymentShippingOption::New(); - output->id = input.id(); - output->label = input.label(); - output->amount = PaymentCurrencyAmount::From(input.amount()); - output->selected = input.hasSelected() && input.selected(); + output->id = input->id(); + output->label = input->label(); + output->amount = PaymentCurrencyAmount::From(input->amount()); + output->selected = input->hasSelected() && input->selected(); return output; } }; template <> -struct TypeConverter<PaymentOptionsPtr, blink::PaymentOptions> { - static PaymentOptionsPtr Convert(const blink::PaymentOptions& input) { +struct TypeConverter<PaymentOptionsPtr, blink::PaymentOptions*> { + static PaymentOptionsPtr Convert(const blink::PaymentOptions* input) { PaymentOptionsPtr output = payments::mojom::blink::PaymentOptions::New(); - output->request_payer_name = input.requestPayerName(); - output->request_payer_email = input.requestPayerEmail(); - output->request_payer_phone = input.requestPayerPhone(); - output->request_shipping = input.requestShipping(); + output->request_payer_name = input->requestPayerName(); + output->request_payer_email = input->requestPayerEmail(); + output->request_payer_phone = input->requestPayerPhone(); + output->request_shipping = input->requestShipping(); - if (input.shippingType() == "delivery") + if (input->shippingType() == "delivery") output->shipping_type = PaymentShippingType::DELIVERY; - else if (input.shippingType() == "pickup") + else if (input->shippingType() == "pickup") output->shipping_type = PaymentShippingType::PICKUP; else output->shipping_type = PaymentShippingType::SHIPPING; @@ -145,57 +146,58 @@ struct TypeConverter<PaymentOptionsPtr, blink::PaymentOptions> { template <> struct TypeConverter<PaymentValidationErrorsPtr, - blink::PaymentValidationErrors> { + blink::PaymentValidationErrors*> { static PaymentValidationErrorsPtr Convert( - const blink::PaymentValidationErrors& input) { + const blink::PaymentValidationErrors* input) { PaymentValidationErrorsPtr output = payments::mojom::blink::PaymentValidationErrors::New(); - output->payer = input.hasPayer() ? PayerErrors::From(input.payer()) - : PayerErrors::From(blink::PayerErrors()); + output->payer = input->hasPayer() + ? PayerErrors::From(input->payer()) + : PayerErrors::From(blink::PayerErrors::Create()); output->shipping_address = - input.hasShippingAddress() - ? AddressErrors::From(input.shippingAddress()) - : AddressErrors::From(blink::AddressErrors()); + input->hasShippingAddress() + ? AddressErrors::From(input->shippingAddress()) + : AddressErrors::From(blink::AddressErrors::Create()); return output; } }; template <> -struct TypeConverter<PayerErrorsPtr, blink::PayerErrors> { - static PayerErrorsPtr Convert(const blink::PayerErrors& input) { +struct TypeConverter<PayerErrorsPtr, blink::PayerErrors*> { + static PayerErrorsPtr Convert(const blink::PayerErrors* input) { PayerErrorsPtr output = payments::mojom::blink::PayerErrors::New(); - output->email = input.hasEmail() ? input.email() : g_empty_string; - output->name = input.hasName() ? input.name() : g_empty_string; - output->phone = input.hasPhone() ? input.phone() : g_empty_string; + output->email = input->hasEmail() ? input->email() : g_empty_string; + output->name = input->hasName() ? input->name() : g_empty_string; + output->phone = input->hasPhone() ? input->phone() : g_empty_string; return output; } }; template <> -struct TypeConverter<AddressErrorsPtr, blink::AddressErrors> { - static AddressErrorsPtr Convert(const blink::AddressErrors& input) { +struct TypeConverter<AddressErrorsPtr, blink::AddressErrors*> { + static AddressErrorsPtr Convert(const blink::AddressErrors* input) { AddressErrorsPtr output = payments::mojom::blink::AddressErrors::New(); output->address_line = - input.hasAddressLine() ? input.addressLine() : g_empty_string; - output->city = input.hasCity() ? input.city() : g_empty_string; - output->country = input.hasCountry() ? input.country() : g_empty_string; - output->dependent_locality = input.hasDependentLocality() - ? input.dependentLocality() + input->hasAddressLine() ? input->addressLine() : g_empty_string; + output->city = input->hasCity() ? input->city() : g_empty_string; + output->country = input->hasCountry() ? input->country() : g_empty_string; + output->dependent_locality = input->hasDependentLocality() + ? input->dependentLocality() : g_empty_string; output->language_code = - input.hasLanguageCode() ? input.languageCode() : g_empty_string; + input->hasLanguageCode() ? input->languageCode() : g_empty_string; output->organization = - input.hasOrganization() ? input.organization() : g_empty_string; - output->phone = input.hasPhone() ? input.phone() : g_empty_string; + input->hasOrganization() ? input->organization() : g_empty_string; + output->phone = input->hasPhone() ? input->phone() : g_empty_string; output->postal_code = - input.hasPostalCode() ? input.postalCode() : g_empty_string; + input->hasPostalCode() ? input->postalCode() : g_empty_string; output->recipient = - input.hasRecipient() ? input.recipient() : g_empty_string; - output->region = input.hasRegion() ? input.region() : g_empty_string; + input->hasRecipient() ? input->recipient() : g_empty_string; + output->region = input->hasRegion() ? input->region() : g_empty_string; output->region_code = - input.hasRegionCode() ? input.regionCode() : g_empty_string; + input->hasRegionCode() ? input->regionCode() : g_empty_string; output->sorting_code = - input.hasSortingCode() ? input.sortingCode() : g_empty_string; + input->hasSortingCode() ? input->sortingCode() : g_empty_string; return output; } }; @@ -212,65 +214,66 @@ constexpr TimeDelta kCompleteTimeout = TimeDelta::FromSeconds(60); // Validates ShippingOption or PaymentItem, which happen to have identical // fields, except for "id", which is present only in ShippingOption. template <typename T> -void ValidateShippingOptionOrPaymentItem(const T& item, +void ValidateShippingOptionOrPaymentItem(const T* item, const String& item_name, ExecutionContext& execution_context, ExceptionState& exception_state) { - DCHECK(item.hasLabel()); - DCHECK(item.hasAmount()); - DCHECK(item.amount().hasValue()); - DCHECK(item.amount().hasCurrency()); + DCHECK(item->hasLabel()); + DCHECK(item->hasAmount()); + DCHECK(item->amount()->hasValue()); + DCHECK(item->amount()->hasCurrency()); - if (item.label().length() > PaymentRequest::kMaxStringLength) { + if (item->label().length() > PaymentRequest::kMaxStringLength) { exception_state.ThrowTypeError("The label for " + item_name + " cannot be longer than 1024 characters"); return; } - if (item.amount().currency().length() > PaymentRequest::kMaxStringLength) { + if (item->amount()->currency().length() > PaymentRequest::kMaxStringLength) { exception_state.ThrowTypeError("The currency code for " + item_name + " cannot be longer than 1024 characters"); return; } - if (item.amount().value().length() > PaymentRequest::kMaxStringLength) { + if (item->amount()->value().length() > PaymentRequest::kMaxStringLength) { exception_state.ThrowTypeError("The amount value for " + item_name + " cannot be longer than 1024 characters"); return; } String error_message; - if (!PaymentsValidators::IsValidAmountFormat(item.amount().value(), item_name, - &error_message)) { + if (!PaymentsValidators::IsValidAmountFormat(item->amount()->value(), + item_name, &error_message)) { exception_state.ThrowTypeError(error_message); return; } - if (item.label().IsEmpty()) { + if (item->label().IsEmpty()) { execution_context.AddConsoleMessage(ConsoleMessage::Create( kJSMessageSource, kErrorMessageLevel, "Empty " + item_name + " label may be confusing the user")); return; } - if (!PaymentsValidators::IsValidCurrencyCodeFormat(item.amount().currency(), + if (!PaymentsValidators::IsValidCurrencyCodeFormat(item->amount()->currency(), &error_message)) { exception_state.ThrowRangeError(error_message); return; } } -void ValidateAndConvertDisplayItems(const HeapVector<PaymentItem>& input, - const String& item_names, - Vector<PaymentItemPtr>& output, - ExecutionContext& execution_context, - ExceptionState& exception_state) { +void ValidateAndConvertDisplayItems( + const HeapVector<Member<PaymentItem>>& input, + const String& item_names, + Vector<PaymentItemPtr>& output, + ExecutionContext& execution_context, + ExceptionState& exception_state) { if (input.size() > PaymentRequest::kMaxListSize) { exception_state.ThrowTypeError("At most 1024 " + item_names + " allowed"); return; } - for (const PaymentItem& item : input) { + for (PaymentItem* item : input) { ValidateShippingOptionOrPaymentItem(item, item_names, execution_context, exception_state); if (exception_state.HadException()) @@ -285,7 +288,7 @@ void ValidateAndConvertDisplayItems(const HeapVector<PaymentItem>& input, // to clear |output| when an exception is thrown, because the caller takes care // of deleting |output|. void ValidateAndConvertShippingOptions( - const HeapVector<PaymentShippingOption>& input, + const HeapVector<Member<PaymentShippingOption>>& input, Vector<PaymentShippingOptionPtr>& output, String& shipping_option_output, ExecutionContext& execution_context, @@ -296,43 +299,43 @@ void ValidateAndConvertShippingOptions( } HashSet<String> unique_ids; - for (const PaymentShippingOption& option : input) { + for (PaymentShippingOption* option : input) { ValidateShippingOptionOrPaymentItem(option, "shippingOptions", execution_context, exception_state); if (exception_state.HadException()) return; - DCHECK(option.hasId()); - if (option.id().length() > PaymentRequest::kMaxStringLength) { + DCHECK(option->hasId()); + if (option->id().length() > PaymentRequest::kMaxStringLength) { exception_state.ThrowTypeError( "Shipping option ID cannot be longer than 1024 characters"); return; } - if (option.id().IsEmpty()) { + if (option->id().IsEmpty()) { execution_context.AddConsoleMessage(ConsoleMessage::Create( kJSMessageSource, kWarningMessageLevel, "Empty shipping option ID may be hard to debug")); return; } - if (unique_ids.Contains(option.id())) { + if (unique_ids.Contains(option->id())) { exception_state.ThrowTypeError( "Cannot have duplicate shipping option identifiers"); return; } - if (option.selected()) - shipping_option_output = option.id(); + if (option->selected()) + shipping_option_output = option->id(); - unique_ids.insert(option.id()); + unique_ids.insert(option->id()); output.push_back( payments::mojom::blink::PaymentShippingOption::From(option)); } } -void ValidateAndConvertTotal(const PaymentItem& input, +void ValidateAndConvertTotal(const PaymentItem* input, const String& item_name, PaymentItemPtr& output, ExecutionContext& execution_context, @@ -342,49 +345,50 @@ void ValidateAndConvertTotal(const PaymentItem& input, if (exception_state.HadException()) return; - if (input.amount().value()[0] == '-') { + if (input->amount()->value()[0] == '-') { exception_state.ThrowTypeError("Total amount value should be non-negative"); return; } - output = payments::mojom::blink::PaymentItem::From(input); + output = payments::mojom::blink::PaymentItem::From( + const_cast<PaymentItem*>(input)); } // Parses Android Pay data to avoid parsing JSON in the browser. void SetAndroidPayMethodData(const ScriptValue& input, PaymentMethodDataPtr& output, ExceptionState& exception_state) { - AndroidPayMethodData android_pay; + AndroidPayMethodData* android_pay = AndroidPayMethodData::Create(); V8AndroidPayMethodData::ToImpl(input.GetIsolate(), input.V8Value(), android_pay, exception_state); if (exception_state.HadException()) return; - if (android_pay.hasEnvironment() && android_pay.environment() == "TEST") + if (android_pay->hasEnvironment() && android_pay->environment() == "TEST") output->environment = payments::mojom::blink::AndroidPayEnvironment::TEST; - if (android_pay.hasMerchantName() && - android_pay.merchantName().length() > PaymentRequest::kMaxStringLength) { + if (android_pay->hasMerchantName() && + android_pay->merchantName().length() > PaymentRequest::kMaxStringLength) { exception_state.ThrowTypeError( "Android Pay merchant name cannot be longer than 1024 characters"); return; } - output->merchant_name = android_pay.merchantName(); + output->merchant_name = android_pay->merchantName(); - if (android_pay.hasMerchantId() && - android_pay.merchantId().length() > PaymentRequest::kMaxStringLength) { + if (android_pay->hasMerchantId() && + android_pay->merchantId().length() > PaymentRequest::kMaxStringLength) { exception_state.ThrowTypeError( "Android Pay merchant id cannot be longer than 1024 characters"); return; } - output->merchant_id = android_pay.merchantId(); + output->merchant_id = android_pay->merchantId(); // 0 means the merchant did not specify or it was an invalid value output->min_google_play_services_version = 0; - if (android_pay.hasMinGooglePlayServicesVersion()) { + if (android_pay->hasMinGooglePlayServicesVersion()) { bool ok = false; int min_google_play_services_version = - android_pay.minGooglePlayServicesVersion().ToIntStrict(&ok); + android_pay->minGooglePlayServicesVersion().ToIntStrict(&ok); if (ok) { output->min_google_play_services_version = min_google_play_services_version; @@ -393,10 +397,10 @@ void SetAndroidPayMethodData(const ScriptValue& input, // 0 means the merchant did not specify or it was an invalid value output->api_version = 0; - if (android_pay.hasApiVersion()) - output->api_version = android_pay.apiVersion(); + if (android_pay->hasApiVersion()) + output->api_version = android_pay->apiVersion(); - if (android_pay.hasAllowedCardNetworks()) { + if (android_pay->hasAllowedCardNetworks()) { using ::payments::mojom::blink::AndroidPayCardNetwork; const struct { @@ -408,7 +412,7 @@ void SetAndroidPayMethodData(const ScriptValue& input, {AndroidPayCardNetwork::VISA, "VISA"}}; for (const String& allowed_card_network : - android_pay.allowedCardNetworks()) { + android_pay->allowedCardNetworks()) { for (size_t i = 0; i < arraysize(kAndroidPayNetwork); ++i) { if (allowed_card_network == kAndroidPayNetwork[i].name) { output->allowed_card_networks.push_back(kAndroidPayNetwork[i].code); @@ -418,12 +422,12 @@ void SetAndroidPayMethodData(const ScriptValue& input, } } - if (android_pay.hasPaymentMethodTokenizationParameters()) { - const blink::AndroidPayTokenization& tokenization = - android_pay.paymentMethodTokenizationParameters(); + if (android_pay->hasPaymentMethodTokenizationParameters()) { + const blink::AndroidPayTokenization* tokenization = + android_pay->paymentMethodTokenizationParameters(); output->tokenization_type = payments::mojom::blink::AndroidPayTokenization::UNSPECIFIED; - if (tokenization.hasTokenizationType()) { + if (tokenization->hasTokenizationType()) { using ::payments::mojom::blink::AndroidPayTokenization; const struct { @@ -434,7 +438,7 @@ void SetAndroidPayMethodData(const ScriptValue& input, {AndroidPayTokenization::NETWORK_TOKEN, "NETWORK_TOKEN"}}; for (size_t i = 0; i < arraysize(kAndroidPayTokenization); ++i) { - if (tokenization.tokenizationType() == + if (tokenization->tokenizationType() == kAndroidPayTokenization[i].name) { output->tokenization_type = kAndroidPayTokenization[i].code; break; @@ -442,9 +446,9 @@ void SetAndroidPayMethodData(const ScriptValue& input, } } - if (tokenization.hasParameters()) { + if (tokenization->hasParameters()) { const Vector<String>& keys = - tokenization.parameters().GetPropertyNames(exception_state); + tokenization->parameters().GetPropertyNames(exception_state); if (exception_state.HadException()) return; if (keys.size() > PaymentRequest::kMaxListSize) { @@ -454,7 +458,7 @@ void SetAndroidPayMethodData(const ScriptValue& input, } String value; for (const String& key : keys) { - if (!DictionaryHelper::Get(tokenization.parameters(), key, value)) + if (!DictionaryHelper::Get(tokenization->parameters(), key, value)) continue; if (key.length() > PaymentRequest::kMaxStringLength) { exception_state.ThrowTypeError( @@ -558,7 +562,7 @@ bool IsValidMethodFormat(const String& identifier) { } void ValidateAndConvertPaymentDetailsModifiers( - const HeapVector<PaymentDetailsModifier>& input, + const HeapVector<Member<PaymentDetailsModifier>>& input, Vector<PaymentDetailsModifierPtr>& output, ExecutionContext& execution_context, ExceptionState& exception_state) { @@ -567,18 +571,18 @@ void ValidateAndConvertPaymentDetailsModifiers( return; } - for (const PaymentDetailsModifier& modifier : input) { + for (const PaymentDetailsModifier* modifier : input) { output.push_back(payments::mojom::blink::PaymentDetailsModifier::New()); - if (modifier.hasTotal()) { - ValidateAndConvertTotal(modifier.total(), "modifier total", + if (modifier->hasTotal()) { + ValidateAndConvertTotal(modifier->total(), "modifier total", output.back()->total, execution_context, exception_state); if (exception_state.HadException()) return; } - if (modifier.hasAdditionalDisplayItems()) { - ValidateAndConvertDisplayItems(modifier.additionalDisplayItems(), + if (modifier->hasAdditionalDisplayItems()) { + ValidateAndConvertDisplayItems(modifier->additionalDisplayItems(), "additional display items in modifier", output.back()->additional_display_items, execution_context, exception_state); @@ -586,22 +590,22 @@ void ValidateAndConvertPaymentDetailsModifiers( return; } - if (!IsValidMethodFormat(modifier.supportedMethod())) { + if (!IsValidMethodFormat(modifier->supportedMethod())) { exception_state.ThrowRangeError( "Invalid payment method identifier format"); return; } - CountPaymentRequestNetworkNameInSupportedMethod(modifier.supportedMethod(), + CountPaymentRequestNetworkNameInSupportedMethod(modifier->supportedMethod(), execution_context); output.back()->method_data = payments::mojom::blink::PaymentMethodData::New(); - output.back()->method_data->supported_method = modifier.supportedMethod(); + output.back()->method_data->supported_method = modifier->supportedMethod(); - if (modifier.hasData() && !modifier.data().IsEmpty()) { + if (modifier->hasData() && !modifier->data().IsEmpty()) { StringifyAndParseMethodSpecificData( - modifier.supportedMethod(), modifier.data(), + modifier->supportedMethod(), modifier->data(), output.back()->method_data, exception_state); } else { output.back()->method_data->stringified_data = ""; @@ -609,14 +613,14 @@ void ValidateAndConvertPaymentDetailsModifiers( } } -void ValidateAndConvertPaymentDetailsBase(const PaymentDetailsBase& input, - const PaymentOptions& options, +void ValidateAndConvertPaymentDetailsBase(const PaymentDetailsBase* input, + const PaymentOptions* options, PaymentDetailsPtr& output, String& shipping_option_output, ExecutionContext& execution_context, ExceptionState& exception_state) { - if (input.hasDisplayItems()) { - ValidateAndConvertDisplayItems(input.displayItems(), "display items", + if (input->hasDisplayItems()) { + ValidateAndConvertDisplayItems(input->displayItems(), "display items", output->display_items, execution_context, exception_state); if (exception_state.HadException()) @@ -625,9 +629,9 @@ void ValidateAndConvertPaymentDetailsBase(const PaymentDetailsBase& input, // If requestShipping is specified and there are shipping options to validate, // proceed with validation. - if (options.requestShipping() && input.hasShippingOptions()) { + if (options->requestShipping() && input->hasShippingOptions()) { ValidateAndConvertShippingOptions( - input.shippingOptions(), output->shipping_options, + input->shippingOptions(), output->shipping_options, shipping_option_output, execution_context, exception_state); if (exception_state.HadException()) return; @@ -635,21 +639,21 @@ void ValidateAndConvertPaymentDetailsBase(const PaymentDetailsBase& input, shipping_option_output = String(); } - if (input.hasModifiers()) { + if (input->hasModifiers()) { ValidateAndConvertPaymentDetailsModifiers( - input.modifiers(), output->modifiers, execution_context, + input->modifiers(), output->modifiers, execution_context, exception_state); } } -void ValidateAndConvertPaymentDetailsInit(const PaymentDetailsInit& input, - const PaymentOptions& options, +void ValidateAndConvertPaymentDetailsInit(const PaymentDetailsInit* input, + const PaymentOptions* options, PaymentDetailsPtr& output, String& shipping_option_output, ExecutionContext& execution_context, ExceptionState& exception_state) { - DCHECK(input.hasTotal()); - ValidateAndConvertTotal(input.total(), "total", output->total, + DCHECK(input->hasTotal()); + ValidateAndConvertTotal(input->total(), "total", output->total, execution_context, exception_state); if (exception_state.HadException()) return; @@ -659,8 +663,8 @@ void ValidateAndConvertPaymentDetailsInit(const PaymentDetailsInit& input, execution_context, exception_state); } -void ValidateAndConvertPaymentDetailsUpdate(const PaymentDetailsUpdate& input, - const PaymentOptions& options, +void ValidateAndConvertPaymentDetailsUpdate(const PaymentDetailsUpdate* input, + const PaymentOptions* options, PaymentDetailsPtr& output, String& shipping_option_output, ExecutionContext& execution_context, @@ -671,38 +675,38 @@ void ValidateAndConvertPaymentDetailsUpdate(const PaymentDetailsUpdate& input, if (exception_state.HadException()) return; - if (input.hasTotal()) { - ValidateAndConvertTotal(input.total(), "total", output->total, + if (input->hasTotal()) { + ValidateAndConvertTotal(input->total(), "total", output->total, execution_context, exception_state); if (exception_state.HadException()) return; } - if (input.hasError()) { + if (input->hasError()) { String error_message; - if (!PaymentsValidators::IsValidErrorMsgFormat(input.error(), + if (!PaymentsValidators::IsValidErrorMsgFormat(input->error(), &error_message)) { exception_state.ThrowTypeError(error_message); return; } - output->error = input.error(); + output->error = input->error(); } - if (input.hasShippingAddressErrors()) { + if (input->hasShippingAddressErrors()) { String error_message; if (!PaymentsValidators::IsValidAddressErrorsFormat( - input.shippingAddressErrors(), &error_message)) { + input->shippingAddressErrors(), &error_message)) { exception_state.ThrowTypeError(error_message); return; } output->shipping_address_errors = payments::mojom::blink::AddressErrors::From( - input.shippingAddressErrors()); + input->shippingAddressErrors()); } } void ValidateAndConvertPaymentMethodData( - const HeapVector<PaymentMethodData>& input, + const HeapVector<Member<PaymentMethodData>>& input, Vector<payments::mojom::blink::PaymentMethodDataPtr>& output, HashSet<String>& method_names, ExecutionContext& execution_context, @@ -718,26 +722,26 @@ void ValidateAndConvertPaymentMethodData( return; } - for (const PaymentMethodData payment_method_data : input) { - if (!IsValidMethodFormat(payment_method_data.supportedMethod())) { + for (const PaymentMethodData* payment_method_data : input) { + if (!IsValidMethodFormat(payment_method_data->supportedMethod())) { exception_state.ThrowRangeError( "Invalid payment method identifier format"); return; } - method_names.insert(payment_method_data.supportedMethod()); + method_names.insert(payment_method_data->supportedMethod()); CountPaymentRequestNetworkNameInSupportedMethod( - payment_method_data.supportedMethod(), execution_context); + payment_method_data->supportedMethod(), execution_context); output.push_back(payments::mojom::blink::PaymentMethodData::New()); - output.back()->supported_method = payment_method_data.supportedMethod(); + output.back()->supported_method = payment_method_data->supportedMethod(); - if (payment_method_data.hasData() && - !payment_method_data.data().IsEmpty()) { - StringifyAndParseMethodSpecificData(payment_method_data.supportedMethod(), - payment_method_data.data(), - output.back(), exception_state); + if (payment_method_data->hasData() && + !payment_method_data->data().IsEmpty()) { + StringifyAndParseMethodSpecificData( + payment_method_data->supportedMethod(), payment_method_data->data(), + output.back(), exception_state); } else { output.back()->stringified_data = ""; } @@ -772,21 +776,22 @@ void WarnIgnoringQueryQuotaForCanMakePayment( PaymentRequest* PaymentRequest::Create( ExecutionContext* execution_context, - const HeapVector<PaymentMethodData>& method_data, - const PaymentDetailsInit& details, + const HeapVector<Member<PaymentMethodData>>& method_data, + const PaymentDetailsInit* details, ExceptionState& exception_state) { - return new PaymentRequest(execution_context, method_data, details, - PaymentOptions(), exception_state); + return MakeGarbageCollected<PaymentRequest>(execution_context, method_data, + details, PaymentOptions::Create(), + exception_state); } PaymentRequest* PaymentRequest::Create( ExecutionContext* execution_context, - const HeapVector<PaymentMethodData>& method_data, - const PaymentDetailsInit& details, - const PaymentOptions& options, + const HeapVector<Member<PaymentMethodData>>& method_data, + const PaymentDetailsInit* details, + const PaymentOptions* options, ExceptionState& exception_state) { - return new PaymentRequest(execution_context, method_data, details, options, - exception_state); + return MakeGarbageCollected<PaymentRequest>( + execution_context, method_data, details, options, exception_state); } PaymentRequest::~PaymentRequest() = default; @@ -874,7 +879,7 @@ bool PaymentRequest::HasPendingActivity() const { } const AtomicString& PaymentRequest::InterfaceName() const { - return EventTargetNames::PaymentRequest; + return event_target_names::kPaymentRequest; } ExecutionContext* PaymentRequest::GetExecutionContext() const { @@ -882,7 +887,7 @@ ExecutionContext* PaymentRequest::GetExecutionContext() const { } ScriptPromise PaymentRequest::Retry(ScriptState* script_state, - const PaymentValidationErrors& errors) { + const PaymentValidationErrors* errors) { if (!script_state->ContextIsValid() || !LocalDOMWindow::From(script_state) || !LocalDOMWindow::From(script_state)->GetFrame()) { return ScriptPromise::RejectWithDOMException( @@ -923,7 +928,8 @@ ScriptPromise PaymentRequest::Retry(ScriptState* script_state, // The payment provider should respond in PaymentRequest::OnPaymentResponse(). payment_provider_->Retry( - payments::mojom::blink::PaymentValidationErrors::From(errors)); + payments::mojom::blink::PaymentValidationErrors::From( + const_cast<PaymentValidationErrors*>(errors))); retry_resolver_ = ScriptPromiseResolver::Create(script_state); @@ -976,11 +982,12 @@ ScriptPromise PaymentRequest::Complete(ScriptState* script_state, } void PaymentRequest::OnUpdatePaymentDetails( + const AtomicString& event_type, const ScriptValue& details_script_value) { if (!GetPendingAcceptPromiseResolver() || !payment_provider_) return; - PaymentDetailsUpdate details; + PaymentDetailsUpdate* details = PaymentDetailsUpdate::Create(); ExceptionState exception_state(v8::Isolate::GetCurrent(), ExceptionState::kConstructionContext, "PaymentDetailsUpdate"); @@ -994,7 +1001,7 @@ void PaymentRequest::OnUpdatePaymentDetails( return; } - if (!details.hasTotal()) { + if (!details->hasTotal()) { resolver->Reject( DOMException::Create(DOMExceptionCode::kSyntaxError, "Total required")); ClearResolversAndCloseMojoConnection(); @@ -1012,7 +1019,21 @@ void PaymentRequest::OnUpdatePaymentDetails( return; } - if (!options_.requestShipping()) + // TODO(https://crbug.com/902291): We should make shippingOptions optional. + if (options_->requestShipping() && !details->hasShippingOptions()) { + if (event_type == event_type_names::kShippingaddresschange) { + UseCounter::Count( + GetExecutionContext(), + WebFeature::kUpdateWithoutShippingOptionOnShippingAddressChange); + } + if (event_type == event_type_names::kShippingoptionchange) { + UseCounter::Count( + GetExecutionContext(), + WebFeature::kUpdateWithoutShippingOptionOnShippingOptionChange); + } + } + + if (!options_->requestShipping()) validated_details->shipping_options.clear(); payment_provider_->UpdateWith(std::move(validated_details)); @@ -1049,11 +1070,12 @@ void PaymentRequest::OnCompleteTimeoutForTesting() { OnCompleteTimeout(nullptr); } -PaymentRequest::PaymentRequest(ExecutionContext* execution_context, - const HeapVector<PaymentMethodData>& method_data, - const PaymentDetailsInit& details, - const PaymentOptions& options, - ExceptionState& exception_state) +PaymentRequest::PaymentRequest( + ExecutionContext* execution_context, + const HeapVector<Member<PaymentMethodData>>& method_data, + const PaymentDetailsInit* details, + const PaymentOptions* options, + ExceptionState& exception_state) : ContextLifecycleObserver(execution_context), options_(options), client_binding_(this), @@ -1070,8 +1092,8 @@ PaymentRequest::PaymentRequest(ExecutionContext* execution_context, return; } - if (details.hasId() && - details.id().length() > PaymentRequest::kMaxStringLength) { + if (details->hasId() && + details->id().length() > PaymentRequest::kMaxStringLength) { exception_state.ThrowTypeError("ID cannot be longer than 1024 characters"); return; } @@ -1079,7 +1101,7 @@ PaymentRequest::PaymentRequest(ExecutionContext* execution_context, PaymentDetailsPtr validated_details = payments::mojom::blink::PaymentDetails::New(); validated_details->id = id_ = - details.hasId() ? details.id() : CreateCanonicalUUIDString(); + details->hasId() ? details->id() : CreateCanonicalUUIDString(); Vector<payments::mojom::blink::PaymentMethodDataPtr> validated_method_data; ValidateAndConvertPaymentMethodData(method_data, validated_method_data, @@ -1094,8 +1116,8 @@ PaymentRequest::PaymentRequest(ExecutionContext* execution_context, if (exception_state.HadException()) return; - if (options_.requestShipping()) - shipping_type_ = options_.shippingType(); + if (options_->requestShipping()) + shipping_type_ = options_->shippingType(); else validated_details->shipping_options.clear(); @@ -1110,10 +1132,10 @@ PaymentRequest::PaymentRequest(ExecutionContext* execution_context, payments::mojom::blink::PaymentRequestClientPtr client; client_binding_.Bind(mojo::MakeRequest(&client)); - payment_provider_->Init( - std::move(client), std::move(validated_method_data), - std::move(validated_details), - payments::mojom::blink::PaymentOptions::From(options_)); + payment_provider_->Init(std::move(client), std::move(validated_method_data), + std::move(validated_details), + payments::mojom::blink::PaymentOptions::From( + const_cast<PaymentOptions*>(options_.Get()))); } void PaymentRequest::ContextDestroyed(ExecutionContext*) { @@ -1132,10 +1154,10 @@ void PaymentRequest::OnShippingAddressChange(PaymentAddressPtr address) { return; } - shipping_address_ = new PaymentAddress(std::move(address)); + shipping_address_ = MakeGarbageCollected<PaymentAddress>(std::move(address)); PaymentRequestUpdateEvent* event = PaymentRequestUpdateEvent::Create( - GetExecutionContext(), EventTypeNames::shippingaddresschange); + GetExecutionContext(), event_type_names::kShippingaddresschange); event->SetTarget(this); event->SetPaymentDetailsUpdater(this); DispatchEvent(*event); @@ -1154,7 +1176,7 @@ void PaymentRequest::OnShippingOptionChange(const String& shipping_option_id) { shipping_option_ = shipping_option_id; PaymentRequestUpdateEvent* event = PaymentRequestUpdateEvent::Create( - GetExecutionContext(), EventTypeNames::shippingoptionchange); + GetExecutionContext(), event_type_names::kShippingoptionchange); event->SetTarget(this); event->SetPaymentDetailsUpdater(this); DispatchEvent(*event); @@ -1174,7 +1196,7 @@ void PaymentRequest::OnPayerDetailChange( DCHECK(!complete_resolver_); PaymentRequestUpdateEvent* event = PaymentRequestUpdateEvent::Create( - GetExecutionContext(), EventTypeNames::payerdetailchange); + GetExecutionContext(), event_type_names::kPayerdetailchange); event->SetTarget(payment_response_); event->SetPaymentDetailsUpdater(this); payment_response_->UpdatePayerDetail(std::move(detail)); @@ -1186,7 +1208,7 @@ void PaymentRequest::OnPaymentResponse(PaymentResponsePtr response) { DCHECK(!complete_resolver_); ScriptPromiseResolver* resolver = GetPendingAcceptPromiseResolver(); - if (options_.requestShipping()) { + if (options_->requestShipping()) { if (!response->shipping_address || response->shipping_option.IsEmpty()) { resolver->Reject(DOMException::Create(DOMExceptionCode::kSyntaxError)); ClearResolversAndCloseMojoConnection(); @@ -1202,8 +1224,8 @@ void PaymentRequest::OnPaymentResponse(PaymentResponsePtr response) { return; } - shipping_address_ = - new PaymentAddress(std::move(response->shipping_address)); + shipping_address_ = MakeGarbageCollected<PaymentAddress>( + std::move(response->shipping_address)); shipping_option_ = response->shipping_option; } else { if (response->shipping_address || !response->shipping_option.IsNull()) { @@ -1214,12 +1236,12 @@ void PaymentRequest::OnPaymentResponse(PaymentResponsePtr response) { } DCHECK(response->payer); - if ((options_.requestPayerName() && response->payer->name.IsEmpty()) || - (options_.requestPayerEmail() && response->payer->email.IsEmpty()) || - (options_.requestPayerPhone() && response->payer->phone.IsEmpty()) || - (!options_.requestPayerName() && !response->payer->name.IsNull()) || - (!options_.requestPayerEmail() && !response->payer->email.IsNull()) || - (!options_.requestPayerPhone() && !response->payer->phone.IsNull())) { + if ((options_->requestPayerName() && response->payer->name.IsEmpty()) || + (options_->requestPayerEmail() && response->payer->email.IsEmpty()) || + (options_->requestPayerPhone() && response->payer->phone.IsEmpty()) || + (!options_->requestPayerName() && !response->payer->name.IsNull()) || + (!options_->requestPayerEmail() && !response->payer->email.IsNull()) || + (!options_->requestPayerPhone() && !response->payer->phone.IsNull())) { resolver->Reject(DOMException::Create(DOMExceptionCode::kSyntaxError)); ClearResolversAndCloseMojoConnection(); return; @@ -1238,9 +1260,9 @@ void PaymentRequest::OnPaymentResponse(PaymentResponsePtr response) { // connection to display a success or failure message to the user. retry_resolver_.Clear(); } else if (accept_resolver_) { - payment_response_ = new PaymentResponse(accept_resolver_->GetScriptState(), - std::move(response), - shipping_address_.Get(), this, id_); + payment_response_ = MakeGarbageCollected<PaymentResponse>( + accept_resolver_->GetScriptState(), std::move(response), + shipping_address_.Get(), this, id_); accept_resolver_->Resolve(payment_response_); // Do not close the mojo connection here. The merchant website should call |