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

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

Issue 2427633004: Don't overwrite PaymentDetails (Closed)
Patch Set: Created 4 years, 2 months 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/JSONValuesForV8.h" 8 #include "bindings/core/v8/JSONValuesForV8.h"
9 #include "bindings/core/v8/ScriptPromiseResolver.h" 9 #include "bindings/core/v8/ScriptPromiseResolver.h"
10 #include "bindings/core/v8/ScriptState.h" 10 #include "bindings/core/v8/ScriptState.h"
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 216
217 void validateDisplayItems(const HeapVector<PaymentItem>& items, 217 void validateDisplayItems(const HeapVector<PaymentItem>& items,
218 ExceptionState& exceptionState) { 218 ExceptionState& exceptionState) {
219 for (const auto& item : items) { 219 for (const auto& item : items) {
220 validateShippingOptionOrPaymentItem(item, exceptionState); 220 validateShippingOptionOrPaymentItem(item, exceptionState);
221 if (exceptionState.hadException()) 221 if (exceptionState.hadException())
222 return; 222 return;
223 } 223 }
224 } 224 }
225 225
226 void validateAndFixupShippingOptions(HeapVector<PaymentShippingOption>& options, 226 // Returns false if |options| should be ignored without throwing an exception.
227 ExceptionState& exceptionState) { 227 bool validateShippingOptions(const HeapVector<PaymentShippingOption>& options,
228 ExceptionState& exceptionState) {
228 HashSet<String> uniqueIds; 229 HashSet<String> uniqueIds;
229 for (const auto& option : options) { 230 for (const auto& option : options) {
230 if (!option.hasId() || option.id().isEmpty()) { 231 if (!option.hasId() || option.id().isEmpty()) {
231 exceptionState.throwTypeError("ShippingOption id required"); 232 exceptionState.throwTypeError("ShippingOption id required");
232 return; 233 return true;
233 } 234 }
234 235
235 if (uniqueIds.contains(option.id())) { 236 if (uniqueIds.contains(option.id()))
236 options = HeapVector<PaymentShippingOption>(); 237 return false;
237 return; 238
238 }
239 uniqueIds.add(option.id()); 239 uniqueIds.add(option.id());
240 240
241 validateShippingOptionOrPaymentItem(option, exceptionState); 241 validateShippingOptionOrPaymentItem(option, exceptionState);
242 if (exceptionState.hadException()) 242 if (exceptionState.hadException())
243 return; 243 return true;
244 } 244 }
245
246 return true;
245 } 247 }
246 248
247 void validatePaymentDetailsModifiers( 249 void validatePaymentDetailsModifiers(
248 const HeapVector<PaymentDetailsModifier>& modifiers, 250 const HeapVector<PaymentDetailsModifier>& modifiers,
249 ExceptionState& exceptionState) { 251 ExceptionState& exceptionState) {
250 if (modifiers.isEmpty()) { 252 if (modifiers.isEmpty()) {
251 exceptionState.throwTypeError( 253 exceptionState.throwTypeError(
252 "Must specify at least one payment details modifier"); 254 "Must specify at least one payment details modifier");
253 return; 255 return;
254 } 256 }
(...skipping 28 matching lines...) Expand all
283 } 285 }
284 286
285 if (modifier.hasAdditionalDisplayItems()) { 287 if (modifier.hasAdditionalDisplayItems()) {
286 validateDisplayItems(modifier.additionalDisplayItems(), exceptionState); 288 validateDisplayItems(modifier.additionalDisplayItems(), exceptionState);
287 if (exceptionState.hadException()) 289 if (exceptionState.hadException())
288 return; 290 return;
289 } 291 }
290 } 292 }
291 } 293 }
292 294
293 void validateAndFixupPaymentDetails(PaymentDetails& details, 295 // Returns false if the shipping options should be ignored without throwing an
294 ExceptionState& exceptionState) { 296 // exception.
Mathieu 2016/10/18 14:13:00 It took me a few passes to understand this pattern
please use gerrit instead 2016/10/19 15:44:34 Done.
297 bool validatePaymentDetails(const PaymentDetails& details,
298 ExceptionState& exceptionState) {
295 if (!details.hasTotal()) { 299 if (!details.hasTotal()) {
296 exceptionState.throwTypeError("Must specify total"); 300 exceptionState.throwTypeError("Must specify total");
297 return; 301 return true;
298 } 302 }
299 303
300 validateShippingOptionOrPaymentItem(details.total(), exceptionState); 304 validateShippingOptionOrPaymentItem(details.total(), exceptionState);
301 if (exceptionState.hadException()) 305 if (exceptionState.hadException())
302 return; 306 return true;
303 307
304 if (details.total().amount().value()[0] == '-') { 308 if (details.total().amount().value()[0] == '-') {
305 exceptionState.throwTypeError("Total amount value should be non-negative"); 309 exceptionState.throwTypeError("Total amount value should be non-negative");
306 return; 310 return true;
307 } 311 }
308 312
309 if (details.hasDisplayItems()) { 313 if (details.hasDisplayItems()) {
310 validateDisplayItems(details.displayItems(), exceptionState); 314 validateDisplayItems(details.displayItems(), exceptionState);
311 if (exceptionState.hadException()) 315 if (exceptionState.hadException())
312 return; 316 return true;
313 } 317 }
314 318
315 if (details.hasShippingOptions()) { 319 if (details.hasShippingOptions()) {
316 HeapVector<PaymentShippingOption> fixedShippingOptions = 320 if (!validateShippingOptions(details.shippingOptions(), exceptionState))
317 details.shippingOptions(); 321 return false;
318 validateAndFixupShippingOptions(fixedShippingOptions, exceptionState); 322
319 details.setShippingOptions(fixedShippingOptions);
320 if (exceptionState.hadException()) 323 if (exceptionState.hadException())
321 return; 324 return true;
322 } 325 }
323 326
324 if (details.hasModifiers()) { 327 if (details.hasModifiers()) {
325 validatePaymentDetailsModifiers(details.modifiers(), exceptionState); 328 validatePaymentDetailsModifiers(details.modifiers(), exceptionState);
326 } 329 }
327 330
328 String errorMessage; 331 String errorMessage;
329 if (!PaymentsValidators::isValidErrorMsgFormat(details.error(), 332 if (!PaymentsValidators::isValidErrorMsgFormat(details.error(),
330 &errorMessage)) { 333 &errorMessage)) {
331 exceptionState.throwTypeError(errorMessage); 334 exceptionState.throwTypeError(errorMessage);
332 return;
333 } 335 }
336
337 return true;
334 } 338 }
335 339
336 void validateAndConvertPaymentMethodData( 340 void validateAndConvertPaymentMethodData(
337 const HeapVector<PaymentMethodData>& paymentMethodData, 341 const HeapVector<PaymentMethodData>& paymentMethodData,
338 Vector<PaymentRequest::MethodData>* methodData, 342 Vector<PaymentRequest::MethodData>* methodData,
339 ExceptionState& exceptionState) { 343 ExceptionState& exceptionState) {
340 if (paymentMethodData.isEmpty()) { 344 if (paymentMethodData.isEmpty()) {
341 exceptionState.throwTypeError( 345 exceptionState.throwTypeError(
342 "Must specify at least one payment method identifier"); 346 "Must specify at least one payment method identifier");
343 return; 347 return;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 static const char* const validValues[] = { 406 static const char* const validValues[] = {
403 "shipping", "delivery", "pickup", 407 "shipping", "delivery", "pickup",
404 }; 408 };
405 for (size_t i = 0; i < WTF_ARRAY_LENGTH(validValues); i++) { 409 for (size_t i = 0; i < WTF_ARRAY_LENGTH(validValues); i++) {
406 if (shippingType == validValues[i]) 410 if (shippingType == validValues[i])
407 return shippingType; 411 return shippingType;
408 } 412 }
409 return validValues[0]; 413 return validValues[0];
410 } 414 }
411 415
416 mojom::blink::PaymentDetailsPtr maybeKeepShippingOptions(
417 mojom::blink::PaymentDetailsPtr details,
418 bool keep) {
419 if (!keep)
420 details->shipping_options.resize(0);
421
422 return details;
423 }
424
412 } // namespace 425 } // namespace
413 426
414 PaymentRequest* PaymentRequest::create( 427 PaymentRequest* PaymentRequest::create(
415 ScriptState* scriptState, 428 ScriptState* scriptState,
416 const HeapVector<PaymentMethodData>& methodData, 429 const HeapVector<PaymentMethodData>& methodData,
417 const PaymentDetails& details, 430 const PaymentDetails& details,
418 ExceptionState& exceptionState) { 431 ExceptionState& exceptionState) {
419 return new PaymentRequest(scriptState, methodData, details, PaymentOptions(), 432 return new PaymentRequest(scriptState, methodData, details, PaymentOptions(),
420 exceptionState); 433 exceptionState);
421 } 434 }
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 V8PaymentDetails::toImpl(detailsScriptValue.isolate(), 532 V8PaymentDetails::toImpl(detailsScriptValue.isolate(),
520 detailsScriptValue.v8Value(), details, 533 detailsScriptValue.v8Value(), details,
521 exceptionState); 534 exceptionState);
522 if (exceptionState.hadException()) { 535 if (exceptionState.hadException()) {
523 m_showResolver->reject( 536 m_showResolver->reject(
524 DOMException::create(SyntaxError, exceptionState.message())); 537 DOMException::create(SyntaxError, exceptionState.message()));
525 clearResolversAndCloseMojoConnection(); 538 clearResolversAndCloseMojoConnection();
526 return; 539 return;
527 } 540 }
528 541
529 validateAndFixupPaymentDetails(details, exceptionState); 542 bool keepShippingOptions = validatePaymentDetails(details, exceptionState);
530 if (exceptionState.hadException()) { 543 if (exceptionState.hadException()) {
531 m_showResolver->reject( 544 m_showResolver->reject(
532 DOMException::create(SyntaxError, exceptionState.message())); 545 DOMException::create(SyntaxError, exceptionState.message()));
533 clearResolversAndCloseMojoConnection(); 546 clearResolversAndCloseMojoConnection();
534 return; 547 return;
535 } 548 }
536 549
537 if (m_options.requestShipping()) 550 if (m_options.requestShipping()) {
538 m_shippingOption = getSelectedShippingOption(details); 551 if (keepShippingOptions)
552 m_shippingOption = getSelectedShippingOption(details);
553 else
554 m_shippingOption = String();
555 }
539 556
540 m_paymentProvider->UpdateWith(mojom::blink::PaymentDetails::From(details)); 557 m_paymentProvider->UpdateWith(maybeKeepShippingOptions(
558 mojom::blink::PaymentDetails::From(details), keepShippingOptions));
541 } 559 }
542 560
543 void PaymentRequest::onUpdatePaymentDetailsFailure(const String& error) { 561 void PaymentRequest::onUpdatePaymentDetailsFailure(const String& error) {
544 if (m_showResolver) 562 if (m_showResolver)
545 m_showResolver->reject(DOMException::create(AbortError, error)); 563 m_showResolver->reject(DOMException::create(AbortError, error));
546 if (m_completeResolver) 564 if (m_completeResolver)
547 m_completeResolver->reject(DOMException::create(AbortError, error)); 565 m_completeResolver->reject(DOMException::create(AbortError, error));
548 clearResolversAndCloseMojoConnection(); 566 clearResolversAndCloseMojoConnection();
549 } 567 }
550 568
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 return; 602 return;
585 } 603 }
586 604
587 if (!scriptState->domWindow()->frame() || 605 if (!scriptState->domWindow()->frame() ||
588 !scriptState->domWindow()->frame()->isMainFrame()) { 606 !scriptState->domWindow()->frame()->isMainFrame()) {
589 exceptionState.throwSecurityError( 607 exceptionState.throwSecurityError(
590 "Must be in a top-level browsing context"); 608 "Must be in a top-level browsing context");
591 return; 609 return;
592 } 610 }
593 611
594 PaymentDetails fixedDetails(details); 612 bool keepShippingOptions = validatePaymentDetails(details, exceptionState);
595 validateAndFixupPaymentDetails(fixedDetails, exceptionState);
596 if (exceptionState.hadException()) 613 if (exceptionState.hadException())
597 return; 614 return;
598 615
599 if (fixedDetails.hasError() && !fixedDetails.error().isEmpty()) { 616 if (details.hasError() && !details.error().isEmpty()) {
600 exceptionState.throwTypeError("Error value should be empty"); 617 exceptionState.throwTypeError("Error value should be empty");
601 return; 618 return;
602 } 619 }
603 620
604 if (m_options.requestShipping()) { 621 if (m_options.requestShipping()) {
605 m_shippingOption = getSelectedShippingOption(fixedDetails); 622 if (keepShippingOptions)
623 m_shippingOption = getSelectedShippingOption(details);
606 m_shippingType = getValidShippingType(m_options.shippingType()); 624 m_shippingType = getValidShippingType(m_options.shippingType());
607 } 625 }
608 626
609 scriptState->domWindow()->frame()->interfaceProvider()->getInterface( 627 scriptState->domWindow()->frame()->interfaceProvider()->getInterface(
610 mojo::GetProxy(&m_paymentProvider)); 628 mojo::GetProxy(&m_paymentProvider));
611 m_paymentProvider.set_connection_error_handler(convertToBaseCallback( 629 m_paymentProvider.set_connection_error_handler(convertToBaseCallback(
612 WTF::bind(&PaymentRequest::OnError, wrapWeakPersistent(this), 630 WTF::bind(&PaymentRequest::OnError, wrapWeakPersistent(this),
613 mojom::blink::PaymentErrorReason::UNKNOWN))); 631 mojom::blink::PaymentErrorReason::UNKNOWN)));
614 m_paymentProvider->Init( 632 m_paymentProvider->Init(
615 m_clientBinding.CreateInterfacePtrAndBind(), 633 m_clientBinding.CreateInterfacePtrAndBind(),
616 mojo::WTFArray<mojom::blink::PaymentMethodDataPtr>::From( 634 mojo::WTFArray<mojom::blink::PaymentMethodDataPtr>::From(
617 validatedMethodData), 635 validatedMethodData),
618 mojom::blink::PaymentDetails::From(fixedDetails), 636 maybeKeepShippingOptions(mojom::blink::PaymentDetails::From(details),
637 keepShippingOptions),
619 mojom::blink::PaymentOptions::From(m_options)); 638 mojom::blink::PaymentOptions::From(m_options));
620 } 639 }
621 640
622 void PaymentRequest::contextDestroyed() { 641 void PaymentRequest::contextDestroyed() {
623 clearResolversAndCloseMojoConnection(); 642 clearResolversAndCloseMojoConnection();
624 } 643 }
625 644
626 void PaymentRequest::OnShippingAddressChange( 645 void PaymentRequest::OnShippingAddressChange(
627 mojom::blink::PaymentAddressPtr address) { 646 mojom::blink::PaymentAddressPtr address) {
628 DCHECK(m_showResolver); 647 DCHECK(m_showResolver);
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
786 m_completeTimer.stop(); 805 m_completeTimer.stop();
787 m_completeResolver.clear(); 806 m_completeResolver.clear();
788 m_showResolver.clear(); 807 m_showResolver.clear();
789 m_abortResolver.clear(); 808 m_abortResolver.clear();
790 if (m_clientBinding.is_bound()) 809 if (m_clientBinding.is_bound())
791 m_clientBinding.Close(); 810 m_clientBinding.Close();
792 m_paymentProvider.reset(); 811 m_paymentProvider.reset();
793 } 812 }
794 813
795 } // namespace blink 814 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698