OLD | NEW |
---|---|
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/ConditionalFeatures.h" | 7 #include "bindings/core/v8/ConditionalFeatures.h" |
8 #include "bindings/core/v8/ExceptionState.h" | 8 #include "bindings/core/v8/ExceptionState.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 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
309 payments::mojom::blink::AndroidPayTokenizationParameter::New()); | 309 payments::mojom::blink::AndroidPayTokenizationParameter::New()); |
310 output->parameters.back()->key = key; | 310 output->parameters.back()->key = key; |
311 output->parameters.back()->value = value; | 311 output->parameters.back()->value = value; |
312 } | 312 } |
313 } | 313 } |
314 } | 314 } |
315 } | 315 } |
316 | 316 |
317 // Parses basic-card data to avoid parsing JSON in the browser. | 317 // Parses basic-card data to avoid parsing JSON in the browser. |
318 void setBasicCardMethodData(const ScriptValue& input, | 318 void setBasicCardMethodData(const ScriptValue& input, |
319 Document& document, | |
320 PaymentMethodDataPtr& output, | 319 PaymentMethodDataPtr& output, |
320 ExecutionContext& executionContext, | |
321 ExceptionState& exceptionState) { | 321 ExceptionState& exceptionState) { |
322 BasicCardRequest basicCard; | 322 BasicCardRequest basicCard; |
323 V8BasicCardRequest::toImpl(input.isolate(), input.v8Value(), basicCard, | 323 V8BasicCardRequest::toImpl(input.isolate(), input.v8Value(), basicCard, |
324 exceptionState); | 324 exceptionState); |
325 if (exceptionState.hadException()) | 325 if (exceptionState.hadException()) |
326 return; | 326 return; |
327 | 327 |
328 if (basicCard.hasSupportedNetworks()) { | 328 if (basicCard.hasSupportedNetworks()) { |
329 using payments::mojom::blink::BasicCardNetwork; | 329 using payments::mojom::blink::BasicCardNetwork; |
330 | 330 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
363 for (const String& type : basicCard.supportedTypes()) { | 363 for (const String& type : basicCard.supportedTypes()) { |
364 for (size_t i = 0; i < arraysize(basicCardTypes); ++i) { | 364 for (size_t i = 0; i < arraysize(basicCardTypes); ++i) { |
365 if (type == basicCardTypes[i].name) { | 365 if (type == basicCardTypes[i].name) { |
366 output->supported_types.push_back(basicCardTypes[i].code); | 366 output->supported_types.push_back(basicCardTypes[i].code); |
367 break; | 367 break; |
368 } | 368 } |
369 } | 369 } |
370 } | 370 } |
371 | 371 |
372 if (output->supported_types.size() != arraysize(basicCardTypes)) { | 372 if (output->supported_types.size() != arraysize(basicCardTypes)) { |
373 document.addConsoleMessage(ConsoleMessage::create( | 373 executionContext.addConsoleMessage(ConsoleMessage::create( |
374 JSMessageSource, WarningMessageLevel, | 374 JSMessageSource, WarningMessageLevel, |
375 "Cannot yet distinguish credit, debit, and prepaid cards.")); | 375 "Cannot yet distinguish credit, debit, and prepaid cards.")); |
376 } | 376 } |
377 } | 377 } |
378 } | 378 } |
379 | 379 |
380 void stringifyAndParseMethodSpecificData(const Vector<String>& supportedMethods, | 380 void stringifyAndParseMethodSpecificData(const Vector<String>& supportedMethods, |
381 const ScriptValue& input, | 381 const ScriptValue& input, |
382 Document& document, | |
383 PaymentMethodDataPtr& output, | 382 PaymentMethodDataPtr& output, |
383 ExecutionContext& executionContext, | |
384 ExceptionState& exceptionState) { | 384 ExceptionState& exceptionState) { |
385 DCHECK(!input.isEmpty()); | 385 DCHECK(!input.isEmpty()); |
386 if (!input.v8Value()->IsObject() || input.v8Value()->IsArray()) { | 386 if (!input.v8Value()->IsObject() || input.v8Value()->IsArray()) { |
387 exceptionState.throwTypeError("Data should be a JSON-serializable object"); | 387 exceptionState.throwTypeError("Data should be a JSON-serializable object"); |
388 return; | 388 return; |
389 } | 389 } |
390 | 390 |
391 v8::Local<v8::String> value; | 391 v8::Local<v8::String> value; |
392 if (!v8::JSON::Stringify(input.context(), input.v8Value().As<v8::Object>()) | 392 if (!v8::JSON::Stringify(input.context(), input.v8Value().As<v8::Object>()) |
393 .ToLocal(&value)) { | 393 .ToLocal(&value)) { |
394 exceptionState.throwTypeError( | 394 exceptionState.throwTypeError( |
395 "Unable to parse payment method specific data"); | 395 "Unable to parse payment method specific data"); |
396 return; | 396 return; |
397 } | 397 } |
398 | 398 |
399 output->stringified_data = | 399 output->stringified_data = |
400 v8StringToWebCoreString<String>(value, DoNotExternalize); | 400 v8StringToWebCoreString<String>(value, DoNotExternalize); |
401 | 401 |
402 // Serialize payment method specific data to be sent to the payment apps. The | 402 // Serialize payment method specific data to be sent to the payment apps. The |
403 // payment apps are responsible for validating and processing their method | 403 // payment apps are responsible for validating and processing their method |
404 // data asynchronously. Do not throw exceptions here. | 404 // data asynchronously. Do not throw exceptions here. |
405 if (supportedMethods.contains("https://android.com/pay")) { | 405 if (supportedMethods.contains("https://android.com/pay")) { |
406 setAndroidPayMethodData(input, output, exceptionState); | 406 setAndroidPayMethodData(input, output, exceptionState); |
407 if (exceptionState.hadException()) | 407 if (exceptionState.hadException()) |
408 exceptionState.clearException(); | 408 exceptionState.clearException(); |
409 } | 409 } |
410 if (RuntimeEnabledFeatures::paymentRequestBasicCardEnabled() && | 410 if (RuntimeEnabledFeatures::paymentRequestBasicCardEnabled() && |
411 supportedMethods.contains("basic-card")) { | 411 supportedMethods.contains("basic-card")) { |
412 setBasicCardMethodData(input, document, output, exceptionState); | 412 setBasicCardMethodData(input, output, executionContext, exceptionState); |
413 if (exceptionState.hadException()) | 413 if (exceptionState.hadException()) |
414 exceptionState.clearException(); | 414 exceptionState.clearException(); |
415 } | 415 } |
416 } | 416 } |
417 | 417 |
418 void validateAndConvertPaymentDetailsModifiers( | 418 void validateAndConvertPaymentDetailsModifiers( |
419 const HeapVector<PaymentDetailsModifier>& input, | 419 const HeapVector<PaymentDetailsModifier>& input, |
420 Document& document, | |
421 Vector<PaymentDetailsModifierPtr>& output, | 420 Vector<PaymentDetailsModifierPtr>& output, |
421 ExecutionContext& executionContext, | |
422 ExceptionState& exceptionState) { | 422 ExceptionState& exceptionState) { |
423 if (input.isEmpty()) { | 423 if (input.isEmpty()) { |
424 exceptionState.throwTypeError( | 424 exceptionState.throwTypeError( |
425 "Must specify at least one payment details modifier"); | 425 "Must specify at least one payment details modifier"); |
426 return; | 426 return; |
427 } | 427 } |
428 | 428 |
429 for (const PaymentDetailsModifier& modifier : input) { | 429 for (const PaymentDetailsModifier& modifier : input) { |
430 output.push_back(payments::mojom::blink::PaymentDetailsModifier::New()); | 430 output.push_back(payments::mojom::blink::PaymentDetailsModifier::New()); |
431 if (modifier.hasTotal()) { | 431 if (modifier.hasTotal()) { |
(...skipping 16 matching lines...) Expand all Loading... | |
448 "Must specify at least one payment method identifier"); | 448 "Must specify at least one payment method identifier"); |
449 return; | 449 return; |
450 } | 450 } |
451 | 451 |
452 output.back()->method_data = | 452 output.back()->method_data = |
453 payments::mojom::blink::PaymentMethodData::New(); | 453 payments::mojom::blink::PaymentMethodData::New(); |
454 output.back()->method_data->supported_methods = modifier.supportedMethods(); | 454 output.back()->method_data->supported_methods = modifier.supportedMethods(); |
455 | 455 |
456 if (modifier.hasData() && !modifier.data().isEmpty()) { | 456 if (modifier.hasData() && !modifier.data().isEmpty()) { |
457 stringifyAndParseMethodSpecificData( | 457 stringifyAndParseMethodSpecificData( |
458 modifier.supportedMethods(), modifier.data(), document, | 458 modifier.supportedMethods(), modifier.data(), |
459 output.back()->method_data, exceptionState); | 459 output.back()->method_data, executionContext, exceptionState); |
460 } else { | 460 } else { |
461 output.back()->method_data->stringified_data = ""; | 461 output.back()->method_data->stringified_data = ""; |
462 } | 462 } |
463 } | 463 } |
464 } | 464 } |
465 | 465 |
466 String getSelectedShippingOption( | 466 String getSelectedShippingOption( |
467 const Vector<PaymentShippingOptionPtr>& shippingOptions) { | 467 const Vector<PaymentShippingOptionPtr>& shippingOptions) { |
468 String result; | 468 String result; |
469 for (const PaymentShippingOptionPtr& shippingOption : shippingOptions) { | 469 for (const PaymentShippingOptionPtr& shippingOption : shippingOptions) { |
470 if (shippingOption->selected) | 470 if (shippingOption->selected) |
471 result = shippingOption->id; | 471 result = shippingOption->id; |
472 } | 472 } |
473 return result; | 473 return result; |
474 } | 474 } |
475 | 475 |
476 void validateAndConvertPaymentDetails(const PaymentDetails& input, | 476 void validateAndConvertPaymentDetails(const PaymentDetails& input, |
477 bool requestShipping, | 477 bool requestShipping, |
478 Document& document, | |
479 PaymentDetailsPtr& output, | 478 PaymentDetailsPtr& output, |
480 String& shippingOptionOutput, | 479 String& shippingOptionOutput, |
480 ExecutionContext& executionContext, | |
481 ExceptionState& exceptionState) { | 481 ExceptionState& exceptionState) { |
482 if (!input.hasTotal()) { | 482 if (!input.hasTotal()) { |
483 exceptionState.throwTypeError("Must specify total"); | 483 exceptionState.throwTypeError("Must specify total"); |
484 return; | 484 return; |
485 } | 485 } |
486 | 486 |
487 validateAndConvertTotal(input.total(), output->total, exceptionState); | 487 validateAndConvertTotal(input.total(), output->total, exceptionState); |
488 if (exceptionState.hadException()) | 488 if (exceptionState.hadException()) |
489 return; | 489 return; |
490 | 490 |
491 if (input.hasDisplayItems()) { | 491 if (input.hasDisplayItems()) { |
492 validateAndConvertDisplayItems(input.displayItems(), output->display_items, | 492 validateAndConvertDisplayItems(input.displayItems(), output->display_items, |
493 exceptionState); | 493 exceptionState); |
494 if (exceptionState.hadException()) | 494 if (exceptionState.hadException()) |
495 return; | 495 return; |
496 } | 496 } |
497 | 497 |
498 if (input.hasShippingOptions() && requestShipping) { | 498 if (input.hasShippingOptions() && requestShipping) { |
499 validateAndConvertShippingOptions(input.shippingOptions(), | 499 validateAndConvertShippingOptions(input.shippingOptions(), |
500 output->shipping_options, exceptionState); | 500 output->shipping_options, exceptionState); |
501 if (exceptionState.hadException()) | 501 if (exceptionState.hadException()) |
502 return; | 502 return; |
503 } | 503 } |
504 | 504 |
505 shippingOptionOutput = getSelectedShippingOption(output->shipping_options); | 505 shippingOptionOutput = getSelectedShippingOption(output->shipping_options); |
506 | 506 |
507 if (input.hasModifiers()) { | 507 if (input.hasModifiers()) { |
508 validateAndConvertPaymentDetailsModifiers( | 508 validateAndConvertPaymentDetailsModifiers( |
509 input.modifiers(), document, output->modifiers, exceptionState); | 509 input.modifiers(), output->modifiers, executionContext, exceptionState); |
510 if (exceptionState.hadException()) | 510 if (exceptionState.hadException()) |
511 return; | 511 return; |
512 } | 512 } |
513 | 513 |
514 if (input.hasError() && !input.error().isNull()) { | 514 if (input.hasError() && !input.error().isNull()) { |
515 String errorMessage; | 515 String errorMessage; |
516 if (!PaymentsValidators::isValidErrorMsgFormat(input.error(), | 516 if (!PaymentsValidators::isValidErrorMsgFormat(input.error(), |
517 &errorMessage)) { | 517 &errorMessage)) { |
518 exceptionState.throwTypeError(errorMessage); | 518 exceptionState.throwTypeError(errorMessage); |
519 return; | 519 return; |
520 } | 520 } |
521 output->error = input.error(); | 521 output->error = input.error(); |
522 } else { | 522 } else { |
523 output->error = ""; | 523 output->error = ""; |
524 } | 524 } |
525 } | 525 } |
526 | 526 |
527 void validateAndConvertPaymentMethodData( | 527 void validateAndConvertPaymentMethodData( |
528 const HeapVector<PaymentMethodData>& input, | 528 const HeapVector<PaymentMethodData>& input, |
529 Document& document, | |
530 Vector<payments::mojom::blink::PaymentMethodDataPtr>& output, | 529 Vector<payments::mojom::blink::PaymentMethodDataPtr>& output, |
530 ExecutionContext& executionContext, | |
531 ExceptionState& exceptionState) { | 531 ExceptionState& exceptionState) { |
532 if (input.isEmpty()) { | 532 if (input.isEmpty()) { |
533 exceptionState.throwTypeError( | 533 exceptionState.throwTypeError( |
534 "Must specify at least one payment method identifier"); | 534 "Must specify at least one payment method identifier"); |
535 return; | 535 return; |
536 } | 536 } |
537 | 537 |
538 for (const PaymentMethodData paymentMethodData : input) { | 538 for (const PaymentMethodData paymentMethodData : input) { |
539 if (paymentMethodData.supportedMethods().isEmpty()) { | 539 if (paymentMethodData.supportedMethods().isEmpty()) { |
540 exceptionState.throwTypeError( | 540 exceptionState.throwTypeError( |
541 "Must specify at least one payment method identifier"); | 541 "Must specify at least one payment method identifier"); |
542 return; | 542 return; |
543 } | 543 } |
544 | 544 |
545 output.push_back(payments::mojom::blink::PaymentMethodData::New()); | 545 output.push_back(payments::mojom::blink::PaymentMethodData::New()); |
546 output.back()->supported_methods = paymentMethodData.supportedMethods(); | 546 output.back()->supported_methods = paymentMethodData.supportedMethods(); |
547 | 547 |
548 if (paymentMethodData.hasData() && !paymentMethodData.data().isEmpty()) { | 548 if (paymentMethodData.hasData() && !paymentMethodData.data().isEmpty()) { |
549 stringifyAndParseMethodSpecificData(paymentMethodData.supportedMethods(), | 549 stringifyAndParseMethodSpecificData( |
550 paymentMethodData.data(), document, | 550 paymentMethodData.supportedMethods(), paymentMethodData.data(), |
551 output.back(), exceptionState); | 551 output.back(), executionContext, exceptionState); |
552 } else { | 552 } else { |
553 output.back()->stringified_data = ""; | 553 output.back()->stringified_data = ""; |
554 } | 554 } |
555 } | 555 } |
556 } | 556 } |
557 | 557 |
558 String getValidShippingType(const String& shippingType) { | 558 String getValidShippingType(const String& shippingType) { |
559 static const char* const validValues[] = { | 559 static const char* const validValues[] = { |
560 "shipping", "delivery", "pickup", | 560 "shipping", "delivery", "pickup", |
561 }; | 561 }; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
621 } | 621 } |
622 | 622 |
623 // Otherwise, paymentrequest is not allowed. (If we reach here and this is | 623 // Otherwise, paymentrequest is not allowed. (If we reach here and this is |
624 // the main frame, then paymentrequest must have been disabled by FP.) | 624 // the main frame, then paymentrequest must have been disabled by FP.) |
625 return false; | 625 return false; |
626 } | 626 } |
627 | 627 |
628 } // namespace | 628 } // namespace |
629 | 629 |
630 PaymentRequest* PaymentRequest::create( | 630 PaymentRequest* PaymentRequest::create( |
631 Document& document, | 631 ScriptState* scriptState, |
632 const HeapVector<PaymentMethodData>& methodData, | 632 const HeapVector<PaymentMethodData>& methodData, |
633 const PaymentDetails& details, | 633 const PaymentDetails& details, |
634 ExceptionState& exceptionState) { | 634 ExceptionState& exceptionState) { |
635 return new PaymentRequest(document, methodData, details, PaymentOptions(), | 635 return new PaymentRequest(scriptState, methodData, details, PaymentOptions(), |
636 exceptionState); | 636 exceptionState); |
637 } | 637 } |
638 | 638 |
639 PaymentRequest* PaymentRequest::create( | 639 PaymentRequest* PaymentRequest::create( |
640 Document& document, | 640 ScriptState* scriptState, |
641 const HeapVector<PaymentMethodData>& methodData, | 641 const HeapVector<PaymentMethodData>& methodData, |
642 const PaymentDetails& details, | 642 const PaymentDetails& details, |
643 const PaymentOptions& options, | 643 const PaymentOptions& options, |
644 ExceptionState& exceptionState) { | 644 ExceptionState& exceptionState) { |
645 return new PaymentRequest(document, methodData, details, options, | 645 return new PaymentRequest(scriptState, methodData, details, options, |
646 exceptionState); | 646 exceptionState); |
647 } | 647 } |
648 | 648 |
649 PaymentRequest::~PaymentRequest() {} | 649 PaymentRequest::~PaymentRequest() {} |
650 | 650 |
651 ScriptPromise PaymentRequest::show(ScriptState* scriptState) { | 651 ScriptPromise PaymentRequest::show() { |
652 if (!m_paymentProvider.is_bound() || m_showResolver) | 652 ScriptState* scriptState = ScriptState::forMainWorld(frame()); |
Marijn Kruisselbrink
2017/02/16 19:50:13
Why is forMainWorld always the correct thing to do
please use gerrit instead
2017/02/16 21:11:24
Undone.
I'm not familiar with these "worlds", mai
haraken
2017/02/17 01:27:31
You're right. It's wrong to assume that this is fo
| |
653 if (!m_paymentProvider.is_bound() || m_showResolver) { | |
653 return ScriptPromise::rejectWithDOMException( | 654 return ScriptPromise::rejectWithDOMException( |
654 scriptState, | 655 scriptState, |
655 DOMException::create(InvalidStateError, "Already called show() once")); | 656 DOMException::create(InvalidStateError, "Already called show() once")); |
657 } | |
656 | 658 |
657 if (!scriptState->domWindow() || !scriptState->domWindow()->frame()) | 659 if (!scriptState->contextIsValid() || !scriptState->domWindow() || |
660 !scriptState->domWindow()->frame()) { | |
658 return ScriptPromise::rejectWithDOMException( | 661 return ScriptPromise::rejectWithDOMException( |
659 scriptState, DOMException::create(InvalidStateError, | 662 scriptState, DOMException::create(InvalidStateError, |
660 "Cannot show the payment request")); | 663 "Cannot show the payment request")); |
664 } | |
661 | 665 |
662 m_paymentProvider->Show(); | 666 m_paymentProvider->Show(); |
663 | 667 |
664 m_showResolver = ScriptPromiseResolver::create(scriptState); | 668 m_showResolver = ScriptPromiseResolver::create(scriptState); |
665 return m_showResolver->promise(); | 669 return m_showResolver->promise(); |
666 } | 670 } |
667 | 671 |
668 ScriptPromise PaymentRequest::abort(ScriptState* scriptState) { | 672 ScriptPromise PaymentRequest::abort() { |
669 if (m_abortResolver) | 673 ScriptState* scriptState = ScriptState::forMainWorld(frame()); |
674 if (!scriptState->contextIsValid()) { | |
675 return ScriptPromise::rejectWithDOMException( | |
676 scriptState, | |
677 DOMException::create(InvalidStateError, "Cannot abort payment")); | |
678 } | |
679 | |
680 if (m_abortResolver) { | |
670 return ScriptPromise::rejectWithDOMException( | 681 return ScriptPromise::rejectWithDOMException( |
671 scriptState, | 682 scriptState, |
672 DOMException::create(InvalidStateError, | 683 DOMException::create(InvalidStateError, |
673 "Cannot abort() again until the previous abort() " | 684 "Cannot abort() again until the previous abort() " |
674 "has resolved or rejected")); | 685 "has resolved or rejected")); |
686 } | |
675 | 687 |
676 if (!m_showResolver) | 688 if (!m_showResolver) { |
677 return ScriptPromise::rejectWithDOMException( | 689 return ScriptPromise::rejectWithDOMException( |
678 scriptState, | 690 scriptState, |
679 DOMException::create(InvalidStateError, | 691 DOMException::create(InvalidStateError, |
680 "Never called show(), so nothing to abort")); | 692 "Never called show(), so nothing to abort")); |
693 } | |
681 | 694 |
682 m_abortResolver = ScriptPromiseResolver::create(scriptState); | 695 m_abortResolver = ScriptPromiseResolver::create(scriptState); |
683 m_paymentProvider->Abort(); | 696 m_paymentProvider->Abort(); |
684 return m_abortResolver->promise(); | 697 return m_abortResolver->promise(); |
685 } | 698 } |
686 | 699 |
687 ScriptPromise PaymentRequest::canMakePayment(ScriptState* scriptState) { | 700 ScriptPromise PaymentRequest::canMakePayment() { |
701 ScriptState* scriptState = ScriptState::forMainWorld(frame()); | |
688 if (!m_paymentProvider.is_bound() || m_canMakePaymentResolver || | 702 if (!m_paymentProvider.is_bound() || m_canMakePaymentResolver || |
689 !scriptState->contextIsValid()) { | 703 !scriptState->contextIsValid()) { |
690 return ScriptPromise::rejectWithDOMException( | 704 return ScriptPromise::rejectWithDOMException( |
691 scriptState, DOMException::create(InvalidStateError, | 705 scriptState, DOMException::create(InvalidStateError, |
692 "Cannot query payment request")); | 706 "Cannot query payment request")); |
693 } | 707 } |
694 | 708 |
695 m_paymentProvider->CanMakePayment(); | 709 m_paymentProvider->CanMakePayment(); |
696 | 710 |
697 m_canMakePaymentResolver = ScriptPromiseResolver::create(scriptState); | 711 m_canMakePaymentResolver = ScriptPromiseResolver::create(scriptState); |
698 return m_canMakePaymentResolver->promise(); | 712 return m_canMakePaymentResolver->promise(); |
699 } | 713 } |
700 | 714 |
701 bool PaymentRequest::hasPendingActivity() const { | 715 bool PaymentRequest::hasPendingActivity() const { |
702 return m_showResolver || m_completeResolver; | 716 return m_showResolver || m_completeResolver; |
703 } | 717 } |
704 | 718 |
705 const AtomicString& PaymentRequest::interfaceName() const { | 719 const AtomicString& PaymentRequest::interfaceName() const { |
706 return EventTargetNames::PaymentRequest; | 720 return EventTargetNames::PaymentRequest; |
707 } | 721 } |
708 | 722 |
709 ExecutionContext* PaymentRequest::getExecutionContext() const { | 723 ExecutionContext* PaymentRequest::getExecutionContext() const { |
710 return ContextLifecycleObserver::getExecutionContext(); | 724 return ContextLifecycleObserver::getExecutionContext(); |
711 } | 725 } |
712 | 726 |
713 ScriptPromise PaymentRequest::complete(ScriptState* scriptState, | 727 ScriptPromise PaymentRequest::complete(PaymentComplete result) { |
714 PaymentComplete result) { | 728 ScriptState* scriptState = ScriptState::forMainWorld(frame()); |
715 if (m_completeResolver) | 729 if (!scriptState->contextIsValid()) { |
730 return ScriptPromise::rejectWithDOMException( | |
731 scriptState, | |
732 DOMException::create(InvalidStateError, "Cannot complete payment")); | |
733 } | |
734 | |
735 if (m_completeResolver) { | |
716 return ScriptPromise::rejectWithDOMException( | 736 return ScriptPromise::rejectWithDOMException( |
717 scriptState, DOMException::create(InvalidStateError, | 737 scriptState, DOMException::create(InvalidStateError, |
718 "Already called complete() once")); | 738 "Already called complete() once")); |
739 } | |
719 | 740 |
720 if (!m_completeTimer.isActive()) | 741 if (!m_completeTimer.isActive()) { |
721 return ScriptPromise::rejectWithDOMException( | 742 return ScriptPromise::rejectWithDOMException( |
722 scriptState, | 743 scriptState, |
723 DOMException::create( | 744 DOMException::create( |
724 InvalidStateError, | 745 InvalidStateError, |
725 "Timed out after 60 seconds, complete() called too late")); | 746 "Timed out after 60 seconds, complete() called too late")); |
747 } | |
726 | 748 |
727 // User has cancelled the transaction while the website was processing it. | 749 // User has cancelled the transaction while the website was processing it. |
728 if (!m_paymentProvider) | 750 if (!m_paymentProvider) { |
729 return ScriptPromise::rejectWithDOMException( | 751 return ScriptPromise::rejectWithDOMException( |
730 scriptState, | 752 scriptState, |
731 DOMException::create(InvalidStateError, "Request cancelled")); | 753 DOMException::create(InvalidStateError, "Request cancelled")); |
754 } | |
732 | 755 |
733 m_completeTimer.stop(); | 756 m_completeTimer.stop(); |
734 | 757 |
735 // The payment provider should respond in PaymentRequest::OnComplete(). | 758 // The payment provider should respond in PaymentRequest::OnComplete(). |
736 m_paymentProvider->Complete(payments::mojom::blink::PaymentComplete(result)); | 759 m_paymentProvider->Complete(payments::mojom::blink::PaymentComplete(result)); |
737 | 760 |
738 m_completeResolver = ScriptPromiseResolver::create(scriptState); | 761 m_completeResolver = ScriptPromiseResolver::create(scriptState); |
739 return m_completeResolver->promise(); | 762 return m_completeResolver->promise(); |
740 } | 763 } |
741 | 764 |
(...skipping 11 matching lines...) Expand all Loading... | |
753 exceptionState); | 776 exceptionState); |
754 if (exceptionState.hadException()) { | 777 if (exceptionState.hadException()) { |
755 m_showResolver->reject( | 778 m_showResolver->reject( |
756 DOMException::create(SyntaxError, exceptionState.message())); | 779 DOMException::create(SyntaxError, exceptionState.message())); |
757 clearResolversAndCloseMojoConnection(); | 780 clearResolversAndCloseMojoConnection(); |
758 return; | 781 return; |
759 } | 782 } |
760 | 783 |
761 PaymentDetailsPtr validatedDetails = | 784 PaymentDetailsPtr validatedDetails = |
762 payments::mojom::blink::PaymentDetails::New(); | 785 payments::mojom::blink::PaymentDetails::New(); |
763 validateAndConvertPaymentDetails( | 786 validateAndConvertPaymentDetails(details, m_options.requestShipping(), |
764 details, m_options.requestShipping(), | 787 validatedDetails, m_shippingOption, |
765 *detailsScriptValue.getScriptState()->domWindow()->document(), | 788 *getExecutionContext(), exceptionState); |
766 validatedDetails, m_shippingOption, exceptionState); | |
767 if (exceptionState.hadException()) { | 789 if (exceptionState.hadException()) { |
768 m_showResolver->reject( | 790 m_showResolver->reject( |
769 DOMException::create(SyntaxError, exceptionState.message())); | 791 DOMException::create(SyntaxError, exceptionState.message())); |
770 clearResolversAndCloseMojoConnection(); | 792 clearResolversAndCloseMojoConnection(); |
771 return; | 793 return; |
772 } | 794 } |
773 | 795 |
774 m_paymentProvider->UpdateWith(std::move(validatedDetails)); | 796 m_paymentProvider->UpdateWith(std::move(validatedDetails)); |
775 } | 797 } |
776 | 798 |
(...skipping 14 matching lines...) Expand all Loading... | |
791 visitor->trace(m_canMakePaymentResolver); | 813 visitor->trace(m_canMakePaymentResolver); |
792 EventTargetWithInlineData::trace(visitor); | 814 EventTargetWithInlineData::trace(visitor); |
793 ContextLifecycleObserver::trace(visitor); | 815 ContextLifecycleObserver::trace(visitor); |
794 } | 816 } |
795 | 817 |
796 void PaymentRequest::onCompleteTimeoutForTesting() { | 818 void PaymentRequest::onCompleteTimeoutForTesting() { |
797 m_completeTimer.stop(); | 819 m_completeTimer.stop(); |
798 onCompleteTimeout(0); | 820 onCompleteTimeout(0); |
799 } | 821 } |
800 | 822 |
801 PaymentRequest::PaymentRequest(Document& document, | 823 PaymentRequest::PaymentRequest(ScriptState* scriptState, |
802 const HeapVector<PaymentMethodData>& methodData, | 824 const HeapVector<PaymentMethodData>& methodData, |
803 const PaymentDetails& details, | 825 const PaymentDetails& details, |
804 const PaymentOptions& options, | 826 const PaymentOptions& options, |
805 ExceptionState& exceptionState) | 827 ExceptionState& exceptionState) |
806 : ContextLifecycleObserver(&document), | 828 : ContextLifecycleObserver(scriptState->getExecutionContext()), |
Marijn Kruisselbrink
2017/02/16 19:50:13
if you're only using the ScriptState to get the Ex
please use gerrit instead
2017/02/16 21:11:24
Did not know that's possible. Doing that now. Than
| |
807 m_options(options), | 829 m_options(options), |
808 m_clientBinding(this), | 830 m_clientBinding(this), |
809 m_completeTimer( | 831 m_completeTimer(TaskRunnerHelper::get(TaskType::MiscPlatformAPI, frame()), |
810 TaskRunnerHelper::get(TaskType::MiscPlatformAPI, document.frame()), | 832 this, |
811 this, | 833 &PaymentRequest::onCompleteTimeout) { |
812 &PaymentRequest::onCompleteTimeout) { | |
813 Vector<payments::mojom::blink::PaymentMethodDataPtr> validatedMethodData; | 834 Vector<payments::mojom::blink::PaymentMethodDataPtr> validatedMethodData; |
814 validateAndConvertPaymentMethodData(methodData, document, validatedMethodData, | 835 validateAndConvertPaymentMethodData(methodData, validatedMethodData, |
815 exceptionState); | 836 *getExecutionContext(), exceptionState); |
816 if (exceptionState.hadException()) | 837 if (exceptionState.hadException()) |
817 return; | 838 return; |
818 | 839 |
819 if (!document.isSecureContext()) { | 840 if (!getExecutionContext()->isSecureContext()) { |
820 exceptionState.throwSecurityError("Must be in a secure context"); | 841 exceptionState.throwSecurityError("Must be in a secure context"); |
821 return; | 842 return; |
822 } | 843 } |
823 | 844 |
824 if (!allowedToUsePaymentRequest(document.frame())) { | 845 if (!allowedToUsePaymentRequest(frame())) { |
825 exceptionState.throwSecurityError( | 846 exceptionState.throwSecurityError( |
826 "Must be in a top-level browsing context or an iframe needs to specify " | 847 "Must be in a top-level browsing context or an iframe needs to specify " |
827 "'allowpaymentrequest' explicitly"); | 848 "'allowpaymentrequest' explicitly"); |
828 return; | 849 return; |
829 } | 850 } |
830 | 851 |
831 PaymentDetailsPtr validatedDetails = | 852 PaymentDetailsPtr validatedDetails = |
832 payments::mojom::blink::PaymentDetails::New(); | 853 payments::mojom::blink::PaymentDetails::New(); |
833 validateAndConvertPaymentDetails(details, m_options.requestShipping(), | 854 validateAndConvertPaymentDetails(details, m_options.requestShipping(), |
834 document, validatedDetails, m_shippingOption, | 855 validatedDetails, m_shippingOption, |
835 exceptionState); | 856 *getExecutionContext(), exceptionState); |
836 if (exceptionState.hadException()) | 857 if (exceptionState.hadException()) |
837 return; | 858 return; |
838 | 859 |
839 if (details.hasError()) { | 860 if (details.hasError()) { |
840 exceptionState.throwTypeError("Error message not allowed in constructor"); | 861 exceptionState.throwTypeError("Error message not allowed in constructor"); |
841 return; | 862 return; |
842 } | 863 } |
843 | 864 |
844 if (m_options.requestShipping()) | 865 if (m_options.requestShipping()) |
845 m_shippingType = getValidShippingType(m_options.shippingType()); | 866 m_shippingType = getValidShippingType(m_options.shippingType()); |
846 | 867 |
847 document.frame()->interfaceProvider()->getInterface( | 868 frame()->interfaceProvider()->getInterface( |
848 mojo::MakeRequest(&m_paymentProvider)); | 869 mojo::MakeRequest(&m_paymentProvider)); |
849 m_paymentProvider.set_connection_error_handler(convertToBaseCallback( | 870 m_paymentProvider.set_connection_error_handler(convertToBaseCallback( |
850 WTF::bind(&PaymentRequest::OnError, wrapWeakPersistent(this), | 871 WTF::bind(&PaymentRequest::OnError, wrapWeakPersistent(this), |
851 PaymentErrorReason::UNKNOWN))); | 872 PaymentErrorReason::UNKNOWN))); |
852 m_paymentProvider->Init( | 873 m_paymentProvider->Init( |
853 m_clientBinding.CreateInterfacePtrAndBind(), | 874 m_clientBinding.CreateInterfacePtrAndBind(), |
854 std::move(validatedMethodData), std::move(validatedDetails), | 875 std::move(validatedMethodData), std::move(validatedDetails), |
855 payments::mojom::blink::PaymentOptions::From(m_options)); | 876 payments::mojom::blink::PaymentOptions::From(m_options)); |
856 } | 877 } |
857 | 878 |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1046 m_completeResolver.clear(); | 1067 m_completeResolver.clear(); |
1047 m_showResolver.clear(); | 1068 m_showResolver.clear(); |
1048 m_abortResolver.clear(); | 1069 m_abortResolver.clear(); |
1049 m_canMakePaymentResolver.clear(); | 1070 m_canMakePaymentResolver.clear(); |
1050 if (m_clientBinding.is_bound()) | 1071 if (m_clientBinding.is_bound()) |
1051 m_clientBinding.Close(); | 1072 m_clientBinding.Close(); |
1052 m_paymentProvider.reset(); | 1073 m_paymentProvider.reset(); |
1053 } | 1074 } |
1054 | 1075 |
1055 } // namespace blink | 1076 } // namespace blink |
OLD | NEW |