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

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

Issue 2444493002: Overwrite the HeapVector of ShippingOptions for more clear code. (Closed)
Patch Set: Rebase Created 4 years, 1 month 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 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 222
223 void validateDisplayItems(const HeapVector<PaymentItem>& items, 223 void validateDisplayItems(const HeapVector<PaymentItem>& items,
224 ExceptionState& exceptionState) { 224 ExceptionState& exceptionState) {
225 for (const auto& item : items) { 225 for (const auto& item : items) {
226 validateShippingOptionOrPaymentItem(item, exceptionState); 226 validateShippingOptionOrPaymentItem(item, exceptionState);
227 if (exceptionState.hadException()) 227 if (exceptionState.hadException())
228 return; 228 return;
229 } 229 }
230 } 230 }
231 231
232 // Returns false if |options| should be ignored, even if an exception was not 232 void validateShippingOptions(HeapVector<PaymentShippingOption>& options,
233 // thrown. TODO(rouslan): Clear shipping options instead of ignoring them when
234 // http://crbug.com/601193 is fixed.
235 bool validateShippingOptions(const HeapVector<PaymentShippingOption>& options,
236 ExceptionState& exceptionState) { 233 ExceptionState& exceptionState) {
237 HashSet<String> uniqueIds; 234 HashSet<String> uniqueIds;
238 for (const auto& option : options) { 235 for (const auto& option : options) {
239 if (!option.hasId() || option.id().isEmpty()) { 236 if (!option.hasId() || option.id().isEmpty()) {
240 exceptionState.throwTypeError("ShippingOption id required"); 237 exceptionState.throwTypeError("ShippingOption id required");
241 return false; 238 return;
242 } 239 }
243 240
244 if (uniqueIds.contains(option.id())) 241 if (uniqueIds.contains(option.id())) {
245 return false; 242 options.clear();
243 return;
244 }
246 245
247 uniqueIds.add(option.id()); 246 uniqueIds.add(option.id());
248 247
249 validateShippingOptionOrPaymentItem(option, exceptionState); 248 validateShippingOptionOrPaymentItem(option, exceptionState);
250 if (exceptionState.hadException()) 249 if (exceptionState.hadException())
251 return false; 250 return;
252 } 251 }
253
254 return true;
255 } 252 }
256 253
257 void validatePaymentDetailsModifiers( 254 void validatePaymentDetailsModifiers(
258 const HeapVector<PaymentDetailsModifier>& modifiers, 255 const HeapVector<PaymentDetailsModifier>& modifiers,
259 ExceptionState& exceptionState) { 256 ExceptionState& exceptionState) {
260 if (modifiers.isEmpty()) { 257 if (modifiers.isEmpty()) {
261 exceptionState.throwTypeError( 258 exceptionState.throwTypeError(
262 "Must specify at least one payment details modifier"); 259 "Must specify at least one payment details modifier");
263 return; 260 return;
264 } 261 }
(...skipping 28 matching lines...) Expand all
293 } 290 }
294 291
295 if (modifier.hasAdditionalDisplayItems()) { 292 if (modifier.hasAdditionalDisplayItems()) {
296 validateDisplayItems(modifier.additionalDisplayItems(), exceptionState); 293 validateDisplayItems(modifier.additionalDisplayItems(), exceptionState);
297 if (exceptionState.hadException()) 294 if (exceptionState.hadException())
298 return; 295 return;
299 } 296 }
300 } 297 }
301 } 298 }
302 299
303 // Returns false if the shipping options should be ignored without throwing an 300 void validatePaymentDetails(PaymentDetails& details,
304 // exception.
305 bool validatePaymentDetails(const PaymentDetails& details,
306 ExceptionState& exceptionState) { 301 ExceptionState& exceptionState) {
307 bool keepShippingOptions = true;
308 if (!details.hasTotal()) { 302 if (!details.hasTotal()) {
309 exceptionState.throwTypeError("Must specify total"); 303 exceptionState.throwTypeError("Must specify total");
310 return keepShippingOptions; 304 return;
311 } 305 }
312 306
313 validateShippingOptionOrPaymentItem(details.total(), exceptionState); 307 validateShippingOptionOrPaymentItem(details.total(), exceptionState);
314 if (exceptionState.hadException()) 308 if (exceptionState.hadException())
315 return keepShippingOptions; 309 return;
316 310
317 if (details.total().amount().value()[0] == '-') { 311 if (details.total().amount().value()[0] == '-') {
318 exceptionState.throwTypeError("Total amount value should be non-negative"); 312 exceptionState.throwTypeError("Total amount value should be non-negative");
319 return keepShippingOptions; 313 return;
320 } 314 }
321 315
322 if (details.hasDisplayItems()) { 316 if (details.hasDisplayItems()) {
323 validateDisplayItems(details.displayItems(), exceptionState); 317 validateDisplayItems(details.displayItems(), exceptionState);
324 if (exceptionState.hadException()) 318 if (exceptionState.hadException())
325 return keepShippingOptions; 319 return;
326 } 320 }
327 321
328 if (details.hasShippingOptions()) { 322 if (details.hasShippingOptions()) {
329 keepShippingOptions = 323 HeapVector<PaymentShippingOption> options = details.shippingOptions();
330 validateShippingOptions(details.shippingOptions(), exceptionState); 324 validateShippingOptions(options, exceptionState);
325 details.setShippingOptions(options);
331 326
332 if (exceptionState.hadException()) 327 if (exceptionState.hadException())
333 return keepShippingOptions; 328 return;
334 } 329 }
335 330
336 if (details.hasModifiers()) { 331 if (details.hasModifiers()) {
337 validatePaymentDetailsModifiers(details.modifiers(), exceptionState); 332 validatePaymentDetailsModifiers(details.modifiers(), exceptionState);
338 if (exceptionState.hadException()) 333 if (exceptionState.hadException())
339 return keepShippingOptions; 334 return;
340 } 335 }
341 336
342 String errorMessage; 337 String errorMessage;
343 if (!PaymentsValidators::isValidErrorMsgFormat(details.error(), 338 if (!PaymentsValidators::isValidErrorMsgFormat(details.error(),
344 &errorMessage)) { 339 &errorMessage)) {
345 exceptionState.throwTypeError(errorMessage); 340 exceptionState.throwTypeError(errorMessage);
346 } 341 }
347
348 return keepShippingOptions;
349 } 342 }
350 343
351 void validateAndConvertPaymentMethodData( 344 void validateAndConvertPaymentMethodData(
352 const HeapVector<PaymentMethodData>& paymentMethodData, 345 const HeapVector<PaymentMethodData>& paymentMethodData,
353 Vector<PaymentRequest::MethodData>* methodData, 346 Vector<PaymentRequest::MethodData>* methodData,
354 ExceptionState& exceptionState) { 347 ExceptionState& exceptionState) {
355 if (paymentMethodData.isEmpty()) { 348 if (paymentMethodData.isEmpty()) {
356 exceptionState.throwTypeError( 349 exceptionState.throwTypeError(
357 "Must specify at least one payment method identifier"); 350 "Must specify at least one payment method identifier");
358 return; 351 return;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 static const char* const validValues[] = { 410 static const char* const validValues[] = {
418 "shipping", "delivery", "pickup", 411 "shipping", "delivery", "pickup",
419 }; 412 };
420 for (size_t i = 0; i < WTF_ARRAY_LENGTH(validValues); i++) { 413 for (size_t i = 0; i < WTF_ARRAY_LENGTH(validValues); i++) {
421 if (shippingType == validValues[i]) 414 if (shippingType == validValues[i])
422 return shippingType; 415 return shippingType;
423 } 416 }
424 return validValues[0]; 417 return validValues[0];
425 } 418 }
426 419
427 mojom::blink::PaymentDetailsPtr maybeKeepShippingOptions(
428 mojom::blink::PaymentDetailsPtr details,
429 bool keep) {
430 if (!keep)
431 details->shipping_options.resize(0);
432
433 return details;
434 }
435
436 bool allowedToUsePaymentRequest(const Frame* frame) { 420 bool allowedToUsePaymentRequest(const Frame* frame) {
437 // To determine whether a Document object |document| is allowed to use the 421 // To determine whether a Document object |document| is allowed to use the
438 // feature indicated by attribute name |allowpaymentrequest|, run these steps: 422 // feature indicated by attribute name |allowpaymentrequest|, run these steps:
439 423
440 // 1. If |document| has no browsing context, then return false. 424 // 1. If |document| has no browsing context, then return false.
441 if (!frame) 425 if (!frame)
442 return false; 426 return false;
443 427
444 // 2. If |document|'s browsing context is a top-level browsing context, then 428 // 2. If |document|'s browsing context is a top-level browsing context, then
445 // return true. 429 // return true.
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 V8PaymentDetails::toImpl(detailsScriptValue.isolate(), 568 V8PaymentDetails::toImpl(detailsScriptValue.isolate(),
585 detailsScriptValue.v8Value(), details, 569 detailsScriptValue.v8Value(), details,
586 exceptionState); 570 exceptionState);
587 if (exceptionState.hadException()) { 571 if (exceptionState.hadException()) {
588 m_showResolver->reject( 572 m_showResolver->reject(
589 DOMException::create(SyntaxError, exceptionState.message())); 573 DOMException::create(SyntaxError, exceptionState.message()));
590 clearResolversAndCloseMojoConnection(); 574 clearResolversAndCloseMojoConnection();
591 return; 575 return;
592 } 576 }
593 577
594 bool keepShippingOptions = validatePaymentDetails(details, exceptionState); 578 validatePaymentDetails(details, exceptionState);
595 if (exceptionState.hadException()) { 579 if (exceptionState.hadException()) {
596 m_showResolver->reject( 580 m_showResolver->reject(
597 DOMException::create(SyntaxError, exceptionState.message())); 581 DOMException::create(SyntaxError, exceptionState.message()));
598 clearResolversAndCloseMojoConnection(); 582 clearResolversAndCloseMojoConnection();
599 return; 583 return;
600 } 584 }
601 585
602 if (m_options.requestShipping()) { 586 if (m_options.requestShipping())
603 if (keepShippingOptions) 587 m_shippingOption = getSelectedShippingOption(details);
604 m_shippingOption = getSelectedShippingOption(details);
605 else
606 m_shippingOption = String();
607 }
608 588
609 m_paymentProvider->UpdateWith(maybeKeepShippingOptions( 589 m_paymentProvider->UpdateWith(mojom::blink::PaymentDetails::From(details));
610 mojom::blink::PaymentDetails::From(details), keepShippingOptions));
611 } 590 }
612 591
613 void PaymentRequest::onUpdatePaymentDetailsFailure(const String& error) { 592 void PaymentRequest::onUpdatePaymentDetailsFailure(const String& error) {
614 if (m_showResolver) 593 if (m_showResolver)
615 m_showResolver->reject(DOMException::create(AbortError, error)); 594 m_showResolver->reject(DOMException::create(AbortError, error));
616 if (m_completeResolver) 595 if (m_completeResolver)
617 m_completeResolver->reject(DOMException::create(AbortError, error)); 596 m_completeResolver->reject(DOMException::create(AbortError, error));
618 clearResolversAndCloseMojoConnection(); 597 clearResolversAndCloseMojoConnection();
619 } 598 }
620 599
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 return; 633 return;
655 } 634 }
656 635
657 if (!allowedToUsePaymentRequest(scriptState->domWindow()->frame())) { 636 if (!allowedToUsePaymentRequest(scriptState->domWindow()->frame())) {
658 exceptionState.throwSecurityError( 637 exceptionState.throwSecurityError(
659 "Must be in a top-level browsing context or an iframe needs to specify " 638 "Must be in a top-level browsing context or an iframe needs to specify "
660 "'allowpaymentrequest' explicitly"); 639 "'allowpaymentrequest' explicitly");
661 return; 640 return;
662 } 641 }
663 642
664 bool keepShippingOptions = validatePaymentDetails(details, exceptionState); 643 PaymentDetails fixedDetails = details;
644 validatePaymentDetails(fixedDetails, exceptionState);
665 if (exceptionState.hadException()) 645 if (exceptionState.hadException())
666 return; 646 return;
667 647
668 if (details.hasError() && !details.error().isEmpty()) { 648 if (fixedDetails.hasError() && !fixedDetails.error().isEmpty()) {
669 exceptionState.throwTypeError("Error value should be empty"); 649 exceptionState.throwTypeError("Error value should be empty");
670 return; 650 return;
671 } 651 }
672 652
673 if (m_options.requestShipping()) { 653 if (m_options.requestShipping()) {
674 if (keepShippingOptions) 654 m_shippingOption = getSelectedShippingOption(fixedDetails);
675 m_shippingOption = getSelectedShippingOption(details);
676 m_shippingType = getValidShippingType(m_options.shippingType()); 655 m_shippingType = getValidShippingType(m_options.shippingType());
656 } else {
657 fixedDetails.setShippingOptions(HeapVector<PaymentShippingOption>());
677 } 658 }
678 659
679 scriptState->domWindow()->frame()->interfaceProvider()->getInterface( 660 scriptState->domWindow()->frame()->interfaceProvider()->getInterface(
680 mojo::GetProxy(&m_paymentProvider)); 661 mojo::GetProxy(&m_paymentProvider));
681 m_paymentProvider.set_connection_error_handler(convertToBaseCallback( 662 m_paymentProvider.set_connection_error_handler(convertToBaseCallback(
682 WTF::bind(&PaymentRequest::OnError, wrapWeakPersistent(this), 663 WTF::bind(&PaymentRequest::OnError, wrapWeakPersistent(this),
683 mojom::blink::PaymentErrorReason::UNKNOWN))); 664 mojom::blink::PaymentErrorReason::UNKNOWN)));
684 m_paymentProvider->Init( 665 m_paymentProvider->Init(m_clientBinding.CreateInterfacePtrAndBind(),
685 m_clientBinding.CreateInterfacePtrAndBind(), 666 ConvertPaymentMethodData(validatedMethodData),
686 ConvertPaymentMethodData(validatedMethodData), 667 mojom::blink::PaymentDetails::From(fixedDetails),
687 maybeKeepShippingOptions( 668 mojom::blink::PaymentOptions::From(m_options));
688 mojom::blink::PaymentDetails::From(details),
689 keepShippingOptions && m_options.requestShipping()),
690 mojom::blink::PaymentOptions::From(m_options));
691 } 669 }
692 670
693 void PaymentRequest::contextDestroyed() { 671 void PaymentRequest::contextDestroyed() {
694 clearResolversAndCloseMojoConnection(); 672 clearResolversAndCloseMojoConnection();
695 } 673 }
696 674
697 void PaymentRequest::OnShippingAddressChange( 675 void PaymentRequest::OnShippingAddressChange(
698 mojom::blink::PaymentAddressPtr address) { 676 mojom::blink::PaymentAddressPtr address) {
699 DCHECK(m_showResolver); 677 DCHECK(m_showResolver);
700 DCHECK(!m_completeResolver); 678 DCHECK(!m_completeResolver);
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
857 m_completeTimer.stop(); 835 m_completeTimer.stop();
858 m_completeResolver.clear(); 836 m_completeResolver.clear();
859 m_showResolver.clear(); 837 m_showResolver.clear();
860 m_abortResolver.clear(); 838 m_abortResolver.clear();
861 if (m_clientBinding.is_bound()) 839 if (m_clientBinding.is_bound())
862 m_clientBinding.Close(); 840 m_clientBinding.Close();
863 m_paymentProvider.reset(); 841 m_paymentProvider.reset();
864 } 842 }
865 843
866 } // namespace blink 844 } // 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