Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: third_party/WebKit/Source/modules/payments/PaymentRequest.cpp

Issue 2470463002: Add data parameter to payment details modifier. (Closed)
Patch Set: Rebase Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/payments/PaymentRequest.h" 5 #include "modules/payments/PaymentRequest.h"
6 6
7 #include "bindings/core/v8/ExceptionState.h" 7 #include "bindings/core/v8/ExceptionState.h"
8 #include "bindings/core/v8/ScriptPromiseResolver.h" 8 #include "bindings/core/v8/ScriptPromiseResolver.h"
9 #include "bindings/core/v8/ScriptState.h" 9 #include "bindings/core/v8/ScriptState.h"
10 #include "bindings/core/v8/V8StringResource.h" 10 #include "bindings/core/v8/V8StringResource.h"
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 PaymentShippingOptionPtr output = PaymentShippingOption::New(); 91 PaymentShippingOptionPtr output = PaymentShippingOption::New();
92 output->id = input.id(); 92 output->id = input.id();
93 output->label = input.label(); 93 output->label = input.label();
94 output->amount = PaymentCurrencyAmount::From(input.amount()); 94 output->amount = PaymentCurrencyAmount::From(input.amount());
95 output->selected = input.hasSelected() && input.selected(); 95 output->selected = input.hasSelected() && input.selected();
96 return output; 96 return output;
97 } 97 }
98 }; 98 };
99 99
100 template <> 100 template <>
101 struct TypeConverter<PaymentDetailsModifierPtr, blink::PaymentDetailsModifier> {
102 static PaymentDetailsModifierPtr Convert(
103 const blink::PaymentDetailsModifier& input) {
104 PaymentDetailsModifierPtr output = PaymentDetailsModifier::New();
105 output->supported_methods = input.supportedMethods();
106
107 if (input.hasTotal())
108 output->total = PaymentItem::From(input.total());
109
110 if (input.hasAdditionalDisplayItems()) {
111 for (size_t i = 0; i < input.additionalDisplayItems().size(); ++i) {
112 output->additional_display_items.append(
113 PaymentItem::From(input.additionalDisplayItems()[i]));
114 }
115 }
116 return output;
117 }
118 };
119
120 template <>
121 struct TypeConverter<PaymentDetailsPtr, blink::PaymentDetails> {
122 static PaymentDetailsPtr Convert(const blink::PaymentDetails& input) {
123 PaymentDetailsPtr output = PaymentDetails::New();
124 output->total = PaymentItem::From(input.total());
125
126 if (input.hasDisplayItems()) {
127 for (size_t i = 0; i < input.displayItems().size(); ++i) {
128 output->display_items.append(
129 PaymentItem::From(input.displayItems()[i]));
130 }
131 }
132
133 if (input.hasShippingOptions()) {
134 for (size_t i = 0; i < input.shippingOptions().size(); ++i) {
135 output->shipping_options.append(
136 PaymentShippingOption::From(input.shippingOptions()[i]));
137 }
138 }
139
140 if (input.hasModifiers()) {
141 for (size_t i = 0; i < input.modifiers().size(); ++i) {
142 output->modifiers.append(
143 PaymentDetailsModifier::From(input.modifiers()[i]));
144 }
145 }
146
147 if (input.hasError())
148 output->error = input.error();
149 else
150 output->error = emptyString();
151
152 return output;
153 }
154 };
155
156 template <>
157 struct TypeConverter<PaymentOptionsPtr, blink::PaymentOptions> { 101 struct TypeConverter<PaymentOptionsPtr, blink::PaymentOptions> {
158 static PaymentOptionsPtr Convert(const blink::PaymentOptions& input) { 102 static PaymentOptionsPtr Convert(const blink::PaymentOptions& input) {
159 PaymentOptionsPtr output = PaymentOptions::New(); 103 PaymentOptionsPtr output = PaymentOptions::New();
160 output->request_payer_name = input.requestPayerName(); 104 output->request_payer_name = input.requestPayerName();
161 output->request_payer_email = input.requestPayerEmail(); 105 output->request_payer_email = input.requestPayerEmail();
162 output->request_payer_phone = input.requestPayerPhone(); 106 output->request_payer_phone = input.requestPayerPhone();
163 output->request_shipping = input.requestShipping(); 107 output->request_shipping = input.requestShipping();
164 108
165 if (input.shippingType() == "delivery") 109 if (input.shippingType() == "delivery")
166 output->shipping_type = PaymentShippingType::DELIVERY; 110 output->shipping_type = PaymentShippingType::DELIVERY;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 return; 177 return;
234 } 178 }
235 179
236 if (!PaymentsValidators::isValidAmountFormat(item.amount().value(), 180 if (!PaymentsValidators::isValidAmountFormat(item.amount().value(),
237 &errorMessage)) { 181 &errorMessage)) {
238 exceptionState.throwTypeError(errorMessage); 182 exceptionState.throwTypeError(errorMessage);
239 return; 183 return;
240 } 184 }
241 } 185 }
242 186
243 void validateDisplayItems(const HeapVector<PaymentItem>& items, 187 void validateAndConvertDisplayItems(const HeapVector<PaymentItem>& input,
244 ExceptionState& exceptionState) { 188 Vector<PaymentItemPtr>& output,
245 for (const auto& item : items) { 189 ExceptionState& exceptionState) {
190 output.resize(input.size());
191 for (size_t i = 0; i < input.size(); ++i) {
192 const PaymentItem& item = input[i];
palmer 2016/11/29 00:24:55 Nit: If you want, you could declare |i| and |item|
please use gerrit instead 2016/11/29 16:19:52 I prefer to be explicit, if there's enough space o
Kevin Bailey 2016/11/29 17:27:59 Does HeapVector<> support range-based loops?
please use gerrit instead 2016/11/29 19:26:52 Yes it does. Vector used to not have .append() met
246 validateShippingOptionOrPaymentItem(item, exceptionState); 193 validateShippingOptionOrPaymentItem(item, exceptionState);
247 if (exceptionState.hadException()) 194 if (exceptionState.hadException())
248 return; 195 return;
196 output[i] = payments::mojom::blink::PaymentItem::From(item);
249 } 197 }
250 } 198 }
251 199
252 // Returns false if |options| should be ignored, even if an exception was not 200 void validateAndConvertShippingOptions(
253 // thrown. TODO(rouslan): Clear shipping options instead of ignoring them when 201 const HeapVector<PaymentShippingOption>& input,
254 // http://crbug.com/601193 is fixed. 202 Vector<PaymentShippingOptionPtr>& output,
255 bool validateShippingOptions(const HeapVector<PaymentShippingOption>& options, 203 ExceptionState& exceptionState) {
256 ExceptionState& exceptionState) { 204 output.resize(input.size());
257 HashSet<String> uniqueIds; 205 HashSet<String> uniqueIds;
258 for (const auto& option : options) { 206 for (size_t i = 0; i < input.size(); ++i) {
207 const PaymentShippingOption& option = input[i];
palmer 2016/11/29 00:24:55 Here, too.
please use gerrit instead 2016/11/29 16:19:52 Acknowledged.
259 if (!option.hasId() || option.id().isEmpty()) { 208 if (!option.hasId() || option.id().isEmpty()) {
260 exceptionState.throwTypeError("ShippingOption id required"); 209 exceptionState.throwTypeError("ShippingOption id required");
haraken 2016/11/29 01:58:25 Don't we need to clear output?
please use gerrit instead 2016/11/29 16:19:52 No need to clear output when throwing an exception
261 return false; 210 return;
262 } 211 }
263 212
264 if (uniqueIds.contains(option.id())) 213 if (uniqueIds.contains(option.id())) {
265 return false; 214 output.clear();
215 return;
216 }
266 217
267 uniqueIds.add(option.id()); 218 uniqueIds.add(option.id());
268 219
269 validateShippingOptionOrPaymentItem(option, exceptionState); 220 validateShippingOptionOrPaymentItem(option, exceptionState);
270 if (exceptionState.hadException()) 221 if (exceptionState.hadException())
271 return false; 222 return;
haraken 2016/11/29 01:58:25 Ditto.
please use gerrit instead 2016/11/29 16:19:52 Acknowledged.
223
224 output[i] = payments::mojom::blink::PaymentShippingOption::From(input[i]);
272 } 225 }
273
274 return true;
275 } 226 }
276 227
277 void validatePaymentDetailsModifiers( 228 void validateAndConvertTotal(const PaymentItem& input,
278 const HeapVector<PaymentDetailsModifier>& modifiers, 229 PaymentItemPtr& output,
279 ExceptionState& exceptionState) { 230 ExceptionState& exceptionState) {
280 if (modifiers.isEmpty()) { 231 validateShippingOptionOrPaymentItem(input, exceptionState);
281 exceptionState.throwTypeError( 232 if (exceptionState.hadException())
282 "Must specify at least one payment details modifier"); 233 return;
234
235 if (input.amount().value()[0] == '-') {
236 exceptionState.throwTypeError("Total amount value should be non-negative");
283 return; 237 return;
284 } 238 }
285 239
286 for (const auto& modifier : modifiers) { 240 output = payments::mojom::blink::PaymentItem::From(input);
287 if (modifier.supportedMethods().isEmpty()) {
288 exceptionState.throwTypeError(
289 "Must specify at least one payment method identifier");
290 return;
291 }
292
293 if (modifier.hasTotal()) {
294 validateShippingOptionOrPaymentItem(modifier.total(), exceptionState);
295 if (exceptionState.hadException())
296 return;
297
298 if (modifier.total().amount().value()[0] == '-') {
299 exceptionState.throwTypeError(
300 "Total amount value should be non-negative");
301 return;
302 }
303 }
304
305 if (modifier.hasAdditionalDisplayItems()) {
306 validateDisplayItems(modifier.additionalDisplayItems(), exceptionState);
307 if (exceptionState.hadException())
308 return;
309 }
310 }
311 } 241 }
312 242
313 // Returns false if the shipping options should be ignored without throwing an 243 void maybeSetAndroidPayMethodData(const ScriptValue& input,
314 // exception. 244 PaymentMethodDataPtr& output,
315 bool validatePaymentDetails(const PaymentDetails& details, 245 ExceptionState& exceptionState) {
316 ExceptionState& exceptionState) {
317 bool keepShippingOptions = true;
318 if (!details.hasTotal()) {
319 exceptionState.throwTypeError("Must specify total");
320 return keepShippingOptions;
321 }
322
323 validateShippingOptionOrPaymentItem(details.total(), exceptionState);
324 if (exceptionState.hadException())
325 return keepShippingOptions;
326
327 if (details.total().amount().value()[0] == '-') {
328 exceptionState.throwTypeError("Total amount value should be non-negative");
329 return keepShippingOptions;
330 }
331
332 if (details.hasDisplayItems()) {
333 validateDisplayItems(details.displayItems(), exceptionState);
334 if (exceptionState.hadException())
335 return keepShippingOptions;
336 }
337
338 if (details.hasShippingOptions()) {
339 keepShippingOptions =
340 validateShippingOptions(details.shippingOptions(), exceptionState);
341
342 if (exceptionState.hadException())
343 return keepShippingOptions;
344 }
345
346 if (details.hasModifiers()) {
347 validatePaymentDetailsModifiers(details.modifiers(), exceptionState);
348 if (exceptionState.hadException())
349 return keepShippingOptions;
350 }
351
352 String errorMessage;
353 if (!PaymentsValidators::isValidErrorMsgFormat(details.error(),
354 &errorMessage)) {
355 exceptionState.throwTypeError(errorMessage);
356 }
357
358 return keepShippingOptions;
359 }
360
361 void maybeSetAndroidPayMethodData(
362 const ScriptValue& input,
363 payments::mojom::blink::PaymentMethodDataPtr& output,
364 ExceptionState& exceptionState) {
365 AndroidPayMethodData androidPay; 246 AndroidPayMethodData androidPay;
366 TrackExceptionState trackExceptionState; 247 TrackExceptionState trackExceptionState;
367 V8AndroidPayMethodData::toImpl(input.isolate(), input.v8Value(), androidPay, 248 V8AndroidPayMethodData::toImpl(input.isolate(), input.v8Value(), androidPay,
368 trackExceptionState); 249 trackExceptionState);
369 if (trackExceptionState.hadException()) 250 if (trackExceptionState.hadException())
370 return; 251 return;
371 252
372 if (androidPay.hasEnvironment() && androidPay.environment() == "TEST") 253 if (androidPay.hasEnvironment() && androidPay.environment() == "TEST")
373 output->environment = payments::mojom::blink::AndroidPayEnvironment::TEST; 254 output->environment = payments::mojom::blink::AndroidPayEnvironment::TEST;
374 255
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 payments::mojom::blink::AndroidPayTokenizationParameter::New(); 302 payments::mojom::blink::AndroidPayTokenizationParameter::New();
422 output->parameters[numberOfParameters]->key = keys[i]; 303 output->parameters[numberOfParameters]->key = keys[i];
423 output->parameters[numberOfParameters]->value = value; 304 output->parameters[numberOfParameters]->value = value;
424 ++numberOfParameters; 305 ++numberOfParameters;
425 } 306 }
426 output->parameters.resize(numberOfParameters); 307 output->parameters.resize(numberOfParameters);
427 } 308 }
428 } 309 }
429 } 310 }
430 311
312 void stringifyAndParseMethodSpecificData(const ScriptValue& input,
313 PaymentMethodDataPtr& output,
314 ExceptionState& exceptionState) {
315 String stringifiedData = "";
haraken 2016/11/29 01:58:25 '= ""' won't be needed.
please use gerrit instead 2016/11/29 16:19:52 Removed.
316 if (!input.isEmpty()) {
317 if (!input.v8Value()->IsObject() || input.v8Value()->IsArray()) {
318 exceptionState.throwTypeError(
319 "Data should be a JSON-serializable object");
320 return;
321 }
322
323 v8::Local<v8::String> value;
324 if (!v8::JSON::Stringify(input.context(), input.v8Value().As<v8::Object>())
325 .ToLocal(&value)) {
326 exceptionState.throwTypeError(
327 "Unable to parse payment method specific data");
328 return;
329 }
330
331 stringifiedData = v8StringToWebCoreString<String>(value, DoNotExternalize);
332 }
333
334 output->stringified_data = stringifiedData;
335 maybeSetAndroidPayMethodData(input, output, exceptionState);
336 }
337
338 void validateAndConvertPaymentDetailsModifiers(
339 const HeapVector<PaymentDetailsModifier>& input,
340 Vector<PaymentDetailsModifierPtr>& output,
341 ExceptionState& exceptionState) {
342 if (input.isEmpty()) {
343 exceptionState.throwTypeError(
344 "Must specify at least one payment details modifier");
345 return;
346 }
347
348 output.resize(input.size());
349 for (size_t i = 0; i < input.size(); ++i) {
350 const PaymentDetailsModifier& modifier = input[i];
palmer 2016/11/29 00:24:55 Here, too.
please use gerrit instead 2016/11/29 16:19:52 Acknowledged.
351 output[i] = payments::mojom::blink::PaymentDetailsModifier::New();
352 if (modifier.hasTotal()) {
353 validateAndConvertTotal(modifier.total(), output[i]->total,
354 exceptionState);
355 if (exceptionState.hadException())
356 return;
haraken 2016/11/29 01:58:25 Ditto. Do you need to clear output?
please use gerrit instead 2016/11/29 16:19:52 Acknowledged.
357 }
358
359 if (modifier.hasAdditionalDisplayItems()) {
360 validateAndConvertDisplayItems(modifier.additionalDisplayItems(),
361 output[i]->additional_display_items,
362 exceptionState);
363 if (exceptionState.hadException())
364 return;
365 }
366
367 if (modifier.supportedMethods().isEmpty()) {
368 exceptionState.throwTypeError(
369 "Must specify at least one payment method identifier");
370 return;
371 }
372
373 output[i]->method_data = payments::mojom::blink::PaymentMethodData::New();
374 output[i]->method_data->supported_methods = modifier.supportedMethods();
375
376 if (modifier.hasData()) {
377 stringifyAndParseMethodSpecificData(
378 modifier.data(), output[i]->method_data, exceptionState);
379 if (exceptionState.hadException())
380 return;
381 } else {
382 output[i]->method_data->stringified_data = "";
383 }
384 }
385 }
386
387 String getSelectedShippingOption(
388 const Vector<PaymentShippingOptionPtr>& shippingOptions) {
389 for (int i = shippingOptions.size() - 1; i >= 0; --i) {
palmer 2016/11/29 00:24:55 If this is a wtf::Vector, you should IWYU, and it
please use gerrit instead 2016/11/29 16:19:52 Switched to looping over all elements in the natur
Kevin Bailey 2016/11/29 17:27:59 I can appreciate the concern in case this size goe
please use gerrit instead 2016/11/29 19:26:52 The concern was compiler warning, which should be
390 if (shippingOptions[i]->selected)
391 return shippingOptions[i]->id;
392 }
393 return String();
394 }
395
396 void validateAndConvertPaymentDetails(const PaymentDetails& input,
397 bool requestShipping,
398 PaymentDetailsPtr& output,
399 String& shippingOptionOutput,
400 ExceptionState& exceptionState) {
401 if (!input.hasTotal()) {
402 exceptionState.throwTypeError("Must specify total");
403 return;
404 }
405
406 validateAndConvertTotal(input.total(), output->total, exceptionState);
407 if (exceptionState.hadException())
408 return;
409
410 if (input.hasDisplayItems()) {
411 validateAndConvertDisplayItems(input.displayItems(), output->display_items,
412 exceptionState);
413 if (exceptionState.hadException())
414 return;
415 }
416
417 if (input.hasShippingOptions() && requestShipping) {
418 validateAndConvertShippingOptions(input.shippingOptions(),
419 output->shipping_options, exceptionState);
420 if (exceptionState.hadException())
421 return;
422 }
423
424 shippingOptionOutput = getSelectedShippingOption(output->shipping_options);
425
426 if (input.hasModifiers()) {
427 validateAndConvertPaymentDetailsModifiers(
428 input.modifiers(), output->modifiers, exceptionState);
429 if (exceptionState.hadException())
430 return;
431 }
432
433 if (input.hasError() && !input.error().isNull()) {
434 String errorMessage;
435 if (!PaymentsValidators::isValidErrorMsgFormat(input.error(),
436 &errorMessage)) {
437 exceptionState.throwTypeError(errorMessage);
438 return;
439 }
440 output->error = input.error();
441 } else {
442 output->error = "";
443 }
444 }
445
431 void validateAndConvertPaymentMethodData( 446 void validateAndConvertPaymentMethodData(
432 const HeapVector<PaymentMethodData>& input, 447 const HeapVector<PaymentMethodData>& input,
433 Vector<payments::mojom::blink::PaymentMethodDataPtr>& output, 448 Vector<payments::mojom::blink::PaymentMethodDataPtr>& output,
434 ExceptionState& exceptionState) { 449 ExceptionState& exceptionState) {
435 if (input.isEmpty()) { 450 if (input.isEmpty()) {
436 exceptionState.throwTypeError( 451 exceptionState.throwTypeError(
437 "Must specify at least one payment method identifier"); 452 "Must specify at least one payment method identifier");
438 return; 453 return;
439 } 454 }
440 455
441 output.resize(input.size()); 456 output.resize(input.size());
442 for (size_t i = 0; i < input.size(); ++i) { 457 for (size_t i = 0; i < input.size(); ++i) {
443 const auto& paymentMethodData = input[i]; 458 const auto& paymentMethodData = input[i];
444 if (paymentMethodData.supportedMethods().isEmpty()) { 459 if (paymentMethodData.supportedMethods().isEmpty()) {
445 exceptionState.throwTypeError( 460 exceptionState.throwTypeError(
446 "Must specify at least one payment method identifier"); 461 "Must specify at least one payment method identifier");
447 return; 462 return;
448 } 463 }
449 464
450 String stringifiedData = "";
451 if (paymentMethodData.hasData() && !paymentMethodData.data().isEmpty()) {
452 if (!paymentMethodData.data().v8Value()->IsObject() ||
453 paymentMethodData.data().v8Value()->IsArray()) {
454 exceptionState.throwTypeError(
455 "Data should be a JSON-serializable object");
456 return;
457 }
458
459 v8::Local<v8::String> value;
460 if (!v8::JSON::Stringify(
461 paymentMethodData.data().context(),
462 paymentMethodData.data().v8Value().As<v8::Object>())
463 .ToLocal(&value)) {
464 exceptionState.throwTypeError(
465 "Unable to parse payment method specific data");
466 return;
467 }
468 stringifiedData =
469 v8StringToWebCoreString<String>(value, DoNotExternalize);
470 }
471
472 output[i] = payments::mojom::blink::PaymentMethodData::New(); 465 output[i] = payments::mojom::blink::PaymentMethodData::New();
473 output[i]->supported_methods = paymentMethodData.supportedMethods(); 466 output[i]->supported_methods = paymentMethodData.supportedMethods();
474 output[i]->stringified_data = stringifiedData; 467
475 maybeSetAndroidPayMethodData(paymentMethodData.data(), output[i], 468 if (paymentMethodData.hasData()) {
476 exceptionState); 469 stringifyAndParseMethodSpecificData(paymentMethodData.data(), output[i],
477 if (exceptionState.hadException()) 470 exceptionState);
478 return; 471 if (exceptionState.hadException())
472 return;
473 } else {
474 output[i]->stringified_data = "";
475 }
479 } 476 }
480 } 477 }
481 478
482 String getSelectedShippingOption(const PaymentDetails& details) {
483 String result;
484 if (!details.hasShippingOptions())
485 return result;
486
487 for (int i = details.shippingOptions().size() - 1; i >= 0; --i) {
488 if (details.shippingOptions()[i].hasSelected() &&
489 details.shippingOptions()[i].selected()) {
490 return details.shippingOptions()[i].id();
491 }
492 }
493
494 return result;
495 }
496
497 String getValidShippingType(const String& shippingType) { 479 String getValidShippingType(const String& shippingType) {
498 static const char* const validValues[] = { 480 static const char* const validValues[] = {
499 "shipping", "delivery", "pickup", 481 "shipping", "delivery", "pickup",
500 }; 482 };
501 for (size_t i = 0; i < WTF_ARRAY_LENGTH(validValues); i++) { 483 for (size_t i = 0; i < WTF_ARRAY_LENGTH(validValues); i++) {
502 if (shippingType == validValues[i]) 484 if (shippingType == validValues[i])
503 return shippingType; 485 return shippingType;
504 } 486 }
505 return validValues[0]; 487 return validValues[0];
506 } 488 }
507 489
508 PaymentDetailsPtr maybeKeepShippingOptions(PaymentDetailsPtr details,
509 bool keep) {
510 if (!keep)
511 details->shipping_options.resize(0);
512
513 return details;
514 }
515
516 bool allowedToUsePaymentRequest(const Frame* frame) { 490 bool allowedToUsePaymentRequest(const Frame* frame) {
517 // To determine whether a Document object |document| is allowed to use the 491 // To determine whether a Document object |document| is allowed to use the
518 // feature indicated by attribute name |allowpaymentrequest|, run these steps: 492 // feature indicated by attribute name |allowpaymentrequest|, run these steps:
519 493
520 // 1. If |document| has no browsing context, then return false. 494 // 1. If |document| has no browsing context, then return false.
521 if (!frame) 495 if (!frame)
522 return false; 496 return false;
523 497
524 // 2. If |document|'s browsing context is a top-level browsing context, then 498 // 2. If |document|'s browsing context is a top-level browsing context, then
525 // return true. 499 // return true.
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 V8PaymentDetails::toImpl(detailsScriptValue.isolate(), 639 V8PaymentDetails::toImpl(detailsScriptValue.isolate(),
666 detailsScriptValue.v8Value(), details, 640 detailsScriptValue.v8Value(), details,
667 exceptionState); 641 exceptionState);
668 if (exceptionState.hadException()) { 642 if (exceptionState.hadException()) {
669 m_showResolver->reject( 643 m_showResolver->reject(
670 DOMException::create(SyntaxError, exceptionState.message())); 644 DOMException::create(SyntaxError, exceptionState.message()));
671 clearResolversAndCloseMojoConnection(); 645 clearResolversAndCloseMojoConnection();
672 return; 646 return;
673 } 647 }
674 648
675 bool keepShippingOptions = validatePaymentDetails(details, exceptionState); 649 PaymentDetailsPtr validatedDetails =
650 payments::mojom::blink::PaymentDetails::New();
651 validateAndConvertPaymentDetails(details, m_options.requestShipping(),
652 validatedDetails, m_shippingOption,
653 exceptionState);
676 if (exceptionState.hadException()) { 654 if (exceptionState.hadException()) {
677 m_showResolver->reject( 655 m_showResolver->reject(
678 DOMException::create(SyntaxError, exceptionState.message())); 656 DOMException::create(SyntaxError, exceptionState.message()));
679 clearResolversAndCloseMojoConnection(); 657 clearResolversAndCloseMojoConnection();
680 return; 658 return;
681 } 659 }
682 660
683 if (m_options.requestShipping()) { 661 m_paymentProvider->UpdateWith(std::move(validatedDetails));
684 if (keepShippingOptions)
685 m_shippingOption = getSelectedShippingOption(details);
686 else
687 m_shippingOption = String();
688 }
689
690 m_paymentProvider->UpdateWith(maybeKeepShippingOptions(
691 payments::mojom::blink::PaymentDetails::From(details),
692 keepShippingOptions));
693 } 662 }
694 663
695 void PaymentRequest::onUpdatePaymentDetailsFailure(const String& error) { 664 void PaymentRequest::onUpdatePaymentDetailsFailure(const String& error) {
696 if (m_showResolver) 665 if (m_showResolver)
697 m_showResolver->reject(DOMException::create(AbortError, error)); 666 m_showResolver->reject(DOMException::create(AbortError, error));
698 if (m_completeResolver) 667 if (m_completeResolver)
699 m_completeResolver->reject(DOMException::create(AbortError, error)); 668 m_completeResolver->reject(DOMException::create(AbortError, error));
700 clearResolversAndCloseMojoConnection(); 669 clearResolversAndCloseMojoConnection();
701 } 670 }
702 671
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 708
740 if (!allowedToUsePaymentRequest(scriptState->domWindow()->frame())) { 709 if (!allowedToUsePaymentRequest(scriptState->domWindow()->frame())) {
741 exceptionState.throwSecurityError( 710 exceptionState.throwSecurityError(
742 RuntimeEnabledFeatures::paymentRequestIFrameEnabled() 711 RuntimeEnabledFeatures::paymentRequestIFrameEnabled()
743 ? "Must be in a top-level browsing context or an iframe needs to " 712 ? "Must be in a top-level browsing context or an iframe needs to "
744 "specify 'allowpaymentrequest' explicitly" 713 "specify 'allowpaymentrequest' explicitly"
745 : "Must be in a top-level browsing context"); 714 : "Must be in a top-level browsing context");
746 return; 715 return;
747 } 716 }
748 717
749 bool keepShippingOptions = validatePaymentDetails(details, exceptionState); 718 PaymentDetailsPtr validatedDetails =
719 payments::mojom::blink::PaymentDetails::New();
720 validateAndConvertPaymentDetails(details, m_options.requestShipping(),
721 validatedDetails, m_shippingOption,
722 exceptionState);
750 if (exceptionState.hadException()) 723 if (exceptionState.hadException())
751 return; 724 return;
752 725
753 if (details.hasError() && !details.error().isEmpty()) { 726 if (!validatedDetails->error.isEmpty()) {
754 exceptionState.throwTypeError("Error value should be empty"); 727 exceptionState.throwTypeError("Error value should be empty");
755 return; 728 return;
756 } 729 }
757 730
758 if (m_options.requestShipping()) { 731 if (m_options.requestShipping())
759 if (keepShippingOptions)
760 m_shippingOption = getSelectedShippingOption(details);
761 m_shippingType = getValidShippingType(m_options.shippingType()); 732 m_shippingType = getValidShippingType(m_options.shippingType());
762 }
763 733
764 scriptState->domWindow()->frame()->interfaceProvider()->getInterface( 734 scriptState->domWindow()->frame()->interfaceProvider()->getInterface(
765 mojo::GetProxy(&m_paymentProvider)); 735 mojo::GetProxy(&m_paymentProvider));
766 m_paymentProvider.set_connection_error_handler(convertToBaseCallback( 736 m_paymentProvider.set_connection_error_handler(convertToBaseCallback(
767 WTF::bind(&PaymentRequest::OnError, wrapWeakPersistent(this), 737 WTF::bind(&PaymentRequest::OnError, wrapWeakPersistent(this),
768 PaymentErrorReason::UNKNOWN))); 738 PaymentErrorReason::UNKNOWN)));
769 m_paymentProvider->Init( 739 m_paymentProvider->Init(
770 m_clientBinding.CreateInterfacePtrAndBind(), 740 m_clientBinding.CreateInterfacePtrAndBind(),
771 std::move(validatedMethodData), 741 std::move(validatedMethodData), std::move(validatedDetails),
772 maybeKeepShippingOptions(
773 payments::mojom::blink::PaymentDetails::From(details),
774 keepShippingOptions && m_options.requestShipping()),
775 payments::mojom::blink::PaymentOptions::From(m_options)); 742 payments::mojom::blink::PaymentOptions::From(m_options));
776 } 743 }
777 744
778 void PaymentRequest::contextDestroyed() { 745 void PaymentRequest::contextDestroyed() {
779 clearResolversAndCloseMojoConnection(); 746 clearResolversAndCloseMojoConnection();
780 } 747 }
781 748
782 void PaymentRequest::OnShippingAddressChange(PaymentAddressPtr address) { 749 void PaymentRequest::OnShippingAddressChange(PaymentAddressPtr address) {
783 DCHECK(m_showResolver); 750 DCHECK(m_showResolver);
784 DCHECK(!m_completeResolver); 751 DCHECK(!m_completeResolver);
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 m_completeResolver.clear(); 939 m_completeResolver.clear();
973 m_showResolver.clear(); 940 m_showResolver.clear();
974 m_abortResolver.clear(); 941 m_abortResolver.clear();
975 m_canMakeActivePaymentResolver.clear(); 942 m_canMakeActivePaymentResolver.clear();
976 if (m_clientBinding.is_bound()) 943 if (m_clientBinding.is_bound())
977 m_clientBinding.Close(); 944 m_clientBinding.Close();
978 m_paymentProvider.reset(); 945 m_paymentProvider.reset();
979 } 946 }
980 947
981 } // namespace blink 948 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698