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

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

Issue 2427633004: Don't overwrite PaymentDetails (Closed)
Patch Set: Clarify the intent of the code. Add a TODO depending on GC fix. 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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 217
218 void validateDisplayItems(const HeapVector<PaymentItem>& items, 218 void validateDisplayItems(const HeapVector<PaymentItem>& items,
219 ExceptionState& exceptionState) { 219 ExceptionState& exceptionState) {
220 for (const auto& item : items) { 220 for (const auto& item : items) {
221 validateShippingOptionOrPaymentItem(item, exceptionState); 221 validateShippingOptionOrPaymentItem(item, exceptionState);
222 if (exceptionState.hadException()) 222 if (exceptionState.hadException())
223 return; 223 return;
224 } 224 }
225 } 225 }
226 226
227 void validateAndFixupShippingOptions(HeapVector<PaymentShippingOption>& options, 227 // Returns false if |options| should be ignored, even if an exception was not
228 ExceptionState& exceptionState) { 228 // thrown. TODO(rouslan): Clear shipping options instead of ignoring them when
229 // http://crbug.com/601193 is fixed.
230 bool validateShippingOptions(const HeapVector<PaymentShippingOption>& options,
231 ExceptionState& exceptionState) {
229 HashSet<String> uniqueIds; 232 HashSet<String> uniqueIds;
230 for (const auto& option : options) { 233 for (const auto& option : options) {
231 if (!option.hasId() || option.id().isEmpty()) { 234 if (!option.hasId() || option.id().isEmpty()) {
232 exceptionState.throwTypeError("ShippingOption id required"); 235 exceptionState.throwTypeError("ShippingOption id required");
233 return; 236 return false;
234 } 237 }
235 238
236 if (uniqueIds.contains(option.id())) { 239 if (uniqueIds.contains(option.id()))
237 options = HeapVector<PaymentShippingOption>(); 240 return false;
238 return; 241
239 }
240 uniqueIds.add(option.id()); 242 uniqueIds.add(option.id());
241 243
242 validateShippingOptionOrPaymentItem(option, exceptionState); 244 validateShippingOptionOrPaymentItem(option, exceptionState);
243 if (exceptionState.hadException()) 245 if (exceptionState.hadException())
244 return; 246 return false;
245 } 247 }
248
249 return true;
246 } 250 }
247 251
248 void validatePaymentDetailsModifiers( 252 void validatePaymentDetailsModifiers(
249 const HeapVector<PaymentDetailsModifier>& modifiers, 253 const HeapVector<PaymentDetailsModifier>& modifiers,
250 ExceptionState& exceptionState) { 254 ExceptionState& exceptionState) {
251 if (modifiers.isEmpty()) { 255 if (modifiers.isEmpty()) {
252 exceptionState.throwTypeError( 256 exceptionState.throwTypeError(
253 "Must specify at least one payment details modifier"); 257 "Must specify at least one payment details modifier");
254 return; 258 return;
255 } 259 }
(...skipping 28 matching lines...) Expand all
284 } 288 }
285 289
286 if (modifier.hasAdditionalDisplayItems()) { 290 if (modifier.hasAdditionalDisplayItems()) {
287 validateDisplayItems(modifier.additionalDisplayItems(), exceptionState); 291 validateDisplayItems(modifier.additionalDisplayItems(), exceptionState);
288 if (exceptionState.hadException()) 292 if (exceptionState.hadException())
289 return; 293 return;
290 } 294 }
291 } 295 }
292 } 296 }
293 297
294 void validateAndFixupPaymentDetails(PaymentDetails& details, 298 // Returns false if the shipping options should be ignored without throwing an
295 ExceptionState& exceptionState) { 299 // exception.
300 bool validatePaymentDetails(const PaymentDetails& details,
301 ExceptionState& exceptionState) {
302 bool keepShippingOptions = true;
296 if (!details.hasTotal()) { 303 if (!details.hasTotal()) {
297 exceptionState.throwTypeError("Must specify total"); 304 exceptionState.throwTypeError("Must specify total");
298 return; 305 return keepShippingOptions;
299 } 306 }
300 307
301 validateShippingOptionOrPaymentItem(details.total(), exceptionState); 308 validateShippingOptionOrPaymentItem(details.total(), exceptionState);
302 if (exceptionState.hadException()) 309 if (exceptionState.hadException())
303 return; 310 return keepShippingOptions;
304 311
305 if (details.total().amount().value()[0] == '-') { 312 if (details.total().amount().value()[0] == '-') {
306 exceptionState.throwTypeError("Total amount value should be non-negative"); 313 exceptionState.throwTypeError("Total amount value should be non-negative");
307 return; 314 return keepShippingOptions;
308 } 315 }
309 316
310 if (details.hasDisplayItems()) { 317 if (details.hasDisplayItems()) {
311 validateDisplayItems(details.displayItems(), exceptionState); 318 validateDisplayItems(details.displayItems(), exceptionState);
312 if (exceptionState.hadException()) 319 if (exceptionState.hadException())
313 return; 320 return keepShippingOptions;
314 } 321 }
315 322
316 if (details.hasShippingOptions()) { 323 if (details.hasShippingOptions()) {
317 HeapVector<PaymentShippingOption> fixedShippingOptions = 324 keepShippingOptions =
318 details.shippingOptions(); 325 validateShippingOptions(details.shippingOptions(), exceptionState);
319 validateAndFixupShippingOptions(fixedShippingOptions, exceptionState); 326
320 details.setShippingOptions(fixedShippingOptions);
321 if (exceptionState.hadException()) 327 if (exceptionState.hadException())
322 return; 328 return keepShippingOptions;
323 } 329 }
324 330
325 if (details.hasModifiers()) { 331 if (details.hasModifiers()) {
326 validatePaymentDetailsModifiers(details.modifiers(), exceptionState); 332 validatePaymentDetailsModifiers(details.modifiers(), exceptionState);
333 if (exceptionState.hadException())
334 return keepShippingOptions;
327 } 335 }
328 336
329 String errorMessage; 337 String errorMessage;
330 if (!PaymentsValidators::isValidErrorMsgFormat(details.error(), 338 if (!PaymentsValidators::isValidErrorMsgFormat(details.error(),
331 &errorMessage)) { 339 &errorMessage)) {
332 exceptionState.throwTypeError(errorMessage); 340 exceptionState.throwTypeError(errorMessage);
333 return;
334 } 341 }
342
343 return keepShippingOptions;
335 } 344 }
336 345
337 void validateAndConvertPaymentMethodData( 346 void validateAndConvertPaymentMethodData(
338 const HeapVector<PaymentMethodData>& paymentMethodData, 347 const HeapVector<PaymentMethodData>& paymentMethodData,
339 Vector<PaymentRequest::MethodData>* methodData, 348 Vector<PaymentRequest::MethodData>* methodData,
340 ExceptionState& exceptionState) { 349 ExceptionState& exceptionState) {
341 if (paymentMethodData.isEmpty()) { 350 if (paymentMethodData.isEmpty()) {
342 exceptionState.throwTypeError( 351 exceptionState.throwTypeError(
343 "Must specify at least one payment method identifier"); 352 "Must specify at least one payment method identifier");
344 return; 353 return;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 static const char* const validValues[] = { 412 static const char* const validValues[] = {
404 "shipping", "delivery", "pickup", 413 "shipping", "delivery", "pickup",
405 }; 414 };
406 for (size_t i = 0; i < WTF_ARRAY_LENGTH(validValues); i++) { 415 for (size_t i = 0; i < WTF_ARRAY_LENGTH(validValues); i++) {
407 if (shippingType == validValues[i]) 416 if (shippingType == validValues[i])
408 return shippingType; 417 return shippingType;
409 } 418 }
410 return validValues[0]; 419 return validValues[0];
411 } 420 }
412 421
422 mojom::blink::PaymentDetailsPtr maybeKeepShippingOptions(
423 mojom::blink::PaymentDetailsPtr details,
424 bool keep) {
425 if (!keep)
426 details->shipping_options.resize(0);
427
428 return details;
429 }
430
413 } // namespace 431 } // namespace
414 432
415 PaymentRequest* PaymentRequest::create( 433 PaymentRequest* PaymentRequest::create(
416 ScriptState* scriptState, 434 ScriptState* scriptState,
417 const HeapVector<PaymentMethodData>& methodData, 435 const HeapVector<PaymentMethodData>& methodData,
418 const PaymentDetails& details, 436 const PaymentDetails& details,
419 ExceptionState& exceptionState) { 437 ExceptionState& exceptionState) {
420 return new PaymentRequest(scriptState, methodData, details, PaymentOptions(), 438 return new PaymentRequest(scriptState, methodData, details, PaymentOptions(),
421 exceptionState); 439 exceptionState);
422 } 440 }
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 V8PaymentDetails::toImpl(detailsScriptValue.isolate(), 538 V8PaymentDetails::toImpl(detailsScriptValue.isolate(),
521 detailsScriptValue.v8Value(), details, 539 detailsScriptValue.v8Value(), details,
522 exceptionState); 540 exceptionState);
523 if (exceptionState.hadException()) { 541 if (exceptionState.hadException()) {
524 m_showResolver->reject( 542 m_showResolver->reject(
525 DOMException::create(SyntaxError, exceptionState.message())); 543 DOMException::create(SyntaxError, exceptionState.message()));
526 clearResolversAndCloseMojoConnection(); 544 clearResolversAndCloseMojoConnection();
527 return; 545 return;
528 } 546 }
529 547
530 validateAndFixupPaymentDetails(details, exceptionState); 548 bool keepShippingOptions = validatePaymentDetails(details, exceptionState);
531 if (exceptionState.hadException()) { 549 if (exceptionState.hadException()) {
532 m_showResolver->reject( 550 m_showResolver->reject(
533 DOMException::create(SyntaxError, exceptionState.message())); 551 DOMException::create(SyntaxError, exceptionState.message()));
534 clearResolversAndCloseMojoConnection(); 552 clearResolversAndCloseMojoConnection();
535 return; 553 return;
536 } 554 }
537 555
538 if (m_options.requestShipping()) 556 if (m_options.requestShipping()) {
539 m_shippingOption = getSelectedShippingOption(details); 557 if (keepShippingOptions)
558 m_shippingOption = getSelectedShippingOption(details);
559 else
560 m_shippingOption = String();
561 }
540 562
541 m_paymentProvider->UpdateWith(mojom::blink::PaymentDetails::From(details)); 563 m_paymentProvider->UpdateWith(maybeKeepShippingOptions(
564 mojom::blink::PaymentDetails::From(details), keepShippingOptions));
542 } 565 }
543 566
544 void PaymentRequest::onUpdatePaymentDetailsFailure(const String& error) { 567 void PaymentRequest::onUpdatePaymentDetailsFailure(const String& error) {
545 if (m_showResolver) 568 if (m_showResolver)
546 m_showResolver->reject(DOMException::create(AbortError, error)); 569 m_showResolver->reject(DOMException::create(AbortError, error));
547 if (m_completeResolver) 570 if (m_completeResolver)
548 m_completeResolver->reject(DOMException::create(AbortError, error)); 571 m_completeResolver->reject(DOMException::create(AbortError, error));
549 clearResolversAndCloseMojoConnection(); 572 clearResolversAndCloseMojoConnection();
550 } 573 }
551 574
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 return; 608 return;
586 } 609 }
587 610
588 if (!scriptState->domWindow()->frame() || 611 if (!scriptState->domWindow()->frame() ||
589 !scriptState->domWindow()->frame()->isMainFrame()) { 612 !scriptState->domWindow()->frame()->isMainFrame()) {
590 exceptionState.throwSecurityError( 613 exceptionState.throwSecurityError(
591 "Must be in a top-level browsing context"); 614 "Must be in a top-level browsing context");
592 return; 615 return;
593 } 616 }
594 617
595 PaymentDetails fixedDetails(details); 618 bool keepShippingOptions = validatePaymentDetails(details, exceptionState);
596 validateAndFixupPaymentDetails(fixedDetails, exceptionState);
597 if (exceptionState.hadException()) 619 if (exceptionState.hadException())
598 return; 620 return;
599 621
600 if (fixedDetails.hasError() && !fixedDetails.error().isEmpty()) { 622 if (details.hasError() && !details.error().isEmpty()) {
601 exceptionState.throwTypeError("Error value should be empty"); 623 exceptionState.throwTypeError("Error value should be empty");
602 return; 624 return;
603 } 625 }
604 626
605 if (m_options.requestShipping()) { 627 if (m_options.requestShipping()) {
606 m_shippingOption = getSelectedShippingOption(fixedDetails); 628 if (keepShippingOptions)
629 m_shippingOption = getSelectedShippingOption(details);
607 m_shippingType = getValidShippingType(m_options.shippingType()); 630 m_shippingType = getValidShippingType(m_options.shippingType());
608 } 631 }
609 632
610 scriptState->domWindow()->frame()->interfaceProvider()->getInterface( 633 scriptState->domWindow()->frame()->interfaceProvider()->getInterface(
611 mojo::GetProxy(&m_paymentProvider)); 634 mojo::GetProxy(&m_paymentProvider));
612 m_paymentProvider.set_connection_error_handler(convertToBaseCallback( 635 m_paymentProvider.set_connection_error_handler(convertToBaseCallback(
613 WTF::bind(&PaymentRequest::OnError, wrapWeakPersistent(this), 636 WTF::bind(&PaymentRequest::OnError, wrapWeakPersistent(this),
614 mojom::blink::PaymentErrorReason::UNKNOWN))); 637 mojom::blink::PaymentErrorReason::UNKNOWN)));
615 m_paymentProvider->Init( 638 m_paymentProvider->Init(
616 m_clientBinding.CreateInterfacePtrAndBind(), 639 m_clientBinding.CreateInterfacePtrAndBind(),
617 mojo::WTFArray<mojom::blink::PaymentMethodDataPtr>::From( 640 mojo::WTFArray<mojom::blink::PaymentMethodDataPtr>::From(
618 validatedMethodData), 641 validatedMethodData),
619 mojom::blink::PaymentDetails::From(fixedDetails), 642 maybeKeepShippingOptions(mojom::blink::PaymentDetails::From(details),
643 keepShippingOptions),
620 mojom::blink::PaymentOptions::From(m_options)); 644 mojom::blink::PaymentOptions::From(m_options));
621 } 645 }
622 646
623 void PaymentRequest::contextDestroyed() { 647 void PaymentRequest::contextDestroyed() {
624 clearResolversAndCloseMojoConnection(); 648 clearResolversAndCloseMojoConnection();
625 } 649 }
626 650
627 void PaymentRequest::OnShippingAddressChange( 651 void PaymentRequest::OnShippingAddressChange(
628 mojom::blink::PaymentAddressPtr address) { 652 mojom::blink::PaymentAddressPtr address) {
629 DCHECK(m_showResolver); 653 DCHECK(m_showResolver);
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 m_completeTimer.stop(); 811 m_completeTimer.stop();
788 m_completeResolver.clear(); 812 m_completeResolver.clear();
789 m_showResolver.clear(); 813 m_showResolver.clear();
790 m_abortResolver.clear(); 814 m_abortResolver.clear();
791 if (m_clientBinding.is_bound()) 815 if (m_clientBinding.is_bound())
792 m_clientBinding.Close(); 816 m_clientBinding.Close();
793 m_paymentProvider.reset(); 817 m_paymentProvider.reset();
794 } 818 }
795 819
796 } // namespace blink 820 } // 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