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

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

Issue 2697123003: Use ExecutionContext instead of Document in PaymentRequest constructor. (Closed)
Patch Set: Use ScriptState Created 3 years, 10 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
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 <stddef.h>
8 #include <utility>
7 #include "bindings/core/v8/ConditionalFeatures.h" 9 #include "bindings/core/v8/ConditionalFeatures.h"
8 #include "bindings/core/v8/ExceptionState.h" 10 #include "bindings/core/v8/ExceptionState.h"
9 #include "bindings/core/v8/ScriptPromiseResolver.h" 11 #include "bindings/core/v8/ScriptPromiseResolver.h"
10 #include "bindings/core/v8/ScriptState.h" 12 #include "bindings/core/v8/ScriptState.h"
11 #include "bindings/core/v8/V8StringResource.h" 13 #include "bindings/core/v8/V8StringResource.h"
12 #include "bindings/modules/v8/V8AndroidPayMethodData.h" 14 #include "bindings/modules/v8/V8AndroidPayMethodData.h"
13 #include "bindings/modules/v8/V8BasicCardRequest.h" 15 #include "bindings/modules/v8/V8BasicCardRequest.h"
14 #include "bindings/modules/v8/V8PaymentDetails.h" 16 #include "bindings/modules/v8/V8PaymentDetails.h"
15 #include "core/EventTypeNames.h" 17 #include "core/EventTypeNames.h"
16 #include "core/dom/DOMException.h" 18 #include "core/dom/DOMException.h"
(...skipping 17 matching lines...) Expand all
34 #include "modules/payments/PaymentResponse.h" 36 #include "modules/payments/PaymentResponse.h"
35 #include "modules/payments/PaymentShippingOption.h" 37 #include "modules/payments/PaymentShippingOption.h"
36 #include "modules/payments/PaymentsValidators.h" 38 #include "modules/payments/PaymentsValidators.h"
37 #include "mojo/public/cpp/bindings/interface_request.h" 39 #include "mojo/public/cpp/bindings/interface_request.h"
38 #include "platform/RuntimeEnabledFeatures.h" 40 #include "platform/RuntimeEnabledFeatures.h"
39 #include "platform/mojo/MojoHelper.h" 41 #include "platform/mojo/MojoHelper.h"
40 #include "public/platform/InterfaceProvider.h" 42 #include "public/platform/InterfaceProvider.h"
41 #include "public/platform/Platform.h" 43 #include "public/platform/Platform.h"
42 #include "public/platform/WebTraceLocation.h" 44 #include "public/platform/WebTraceLocation.h"
43 #include "wtf/HashSet.h" 45 #include "wtf/HashSet.h"
44 #include <stddef.h>
45 #include <utility>
46 46
47 using payments::mojom::blink::CanMakePaymentQueryResult; 47 using payments::mojom::blink::CanMakePaymentQueryResult;
48 using payments::mojom::blink::PaymentAddressPtr; 48 using payments::mojom::blink::PaymentAddressPtr;
49 using payments::mojom::blink::PaymentCurrencyAmount; 49 using payments::mojom::blink::PaymentCurrencyAmount;
50 using payments::mojom::blink::PaymentCurrencyAmountPtr; 50 using payments::mojom::blink::PaymentCurrencyAmountPtr;
51 using payments::mojom::blink::PaymentDetailsModifierPtr; 51 using payments::mojom::blink::PaymentDetailsModifierPtr;
52 using payments::mojom::blink::PaymentDetailsPtr; 52 using payments::mojom::blink::PaymentDetailsPtr;
53 using payments::mojom::blink::PaymentErrorReason; 53 using payments::mojom::blink::PaymentErrorReason;
54 using payments::mojom::blink::PaymentItemPtr; 54 using payments::mojom::blink::PaymentItemPtr;
55 using payments::mojom::blink::PaymentMethodDataPtr; 55 using payments::mojom::blink::PaymentMethodDataPtr;
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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(ScriptState* scriptState) {
652 if (!m_paymentProvider.is_bound() || m_showResolver) 652 if (!m_paymentProvider.is_bound() || m_showResolver) {
653 return ScriptPromise::rejectWithDOMException( 653 return ScriptPromise::rejectWithDOMException(
654 scriptState, 654 scriptState,
655 DOMException::create(InvalidStateError, "Already called show() once")); 655 DOMException::create(InvalidStateError, "Already called show() once"));
656 }
656 657
657 if (!scriptState->domWindow() || !scriptState->domWindow()->frame()) 658 if (!scriptState->contextIsValid() || !scriptState->domWindow() ||
659 !scriptState->domWindow()->frame()) {
658 return ScriptPromise::rejectWithDOMException( 660 return ScriptPromise::rejectWithDOMException(
659 scriptState, DOMException::create(InvalidStateError, 661 scriptState, DOMException::create(InvalidStateError,
660 "Cannot show the payment request")); 662 "Cannot show the payment request"));
663 }
661 664
662 m_paymentProvider->Show(); 665 m_paymentProvider->Show();
663 666
664 m_showResolver = ScriptPromiseResolver::create(scriptState); 667 m_showResolver = ScriptPromiseResolver::create(scriptState);
665 return m_showResolver->promise(); 668 return m_showResolver->promise();
666 } 669 }
667 670
668 ScriptPromise PaymentRequest::abort(ScriptState* scriptState) { 671 ScriptPromise PaymentRequest::abort(ScriptState* scriptState) {
669 if (m_abortResolver) 672 if (!scriptState->contextIsValid()) {
673 return ScriptPromise::rejectWithDOMException(
674 scriptState,
675 DOMException::create(InvalidStateError, "Cannot abort payment"));
676 }
677
678 if (m_abortResolver) {
670 return ScriptPromise::rejectWithDOMException( 679 return ScriptPromise::rejectWithDOMException(
671 scriptState, 680 scriptState,
672 DOMException::create(InvalidStateError, 681 DOMException::create(InvalidStateError,
673 "Cannot abort() again until the previous abort() " 682 "Cannot abort() again until the previous abort() "
674 "has resolved or rejected")); 683 "has resolved or rejected"));
684 }
675 685
676 if (!m_showResolver) 686 if (!m_showResolver) {
677 return ScriptPromise::rejectWithDOMException( 687 return ScriptPromise::rejectWithDOMException(
678 scriptState, 688 scriptState,
679 DOMException::create(InvalidStateError, 689 DOMException::create(InvalidStateError,
680 "Never called show(), so nothing to abort")); 690 "Never called show(), so nothing to abort"));
691 }
681 692
682 m_abortResolver = ScriptPromiseResolver::create(scriptState); 693 m_abortResolver = ScriptPromiseResolver::create(scriptState);
683 m_paymentProvider->Abort(); 694 m_paymentProvider->Abort();
684 return m_abortResolver->promise(); 695 return m_abortResolver->promise();
685 } 696 }
686 697
687 ScriptPromise PaymentRequest::canMakePayment(ScriptState* scriptState) { 698 ScriptPromise PaymentRequest::canMakePayment(ScriptState* scriptState) {
688 if (!m_paymentProvider.is_bound() || m_canMakePaymentResolver || 699 if (!m_paymentProvider.is_bound() || m_canMakePaymentResolver ||
689 !scriptState->contextIsValid()) { 700 !scriptState->contextIsValid()) {
690 return ScriptPromise::rejectWithDOMException( 701 return ScriptPromise::rejectWithDOMException(
(...skipping 14 matching lines...) Expand all
705 const AtomicString& PaymentRequest::interfaceName() const { 716 const AtomicString& PaymentRequest::interfaceName() const {
706 return EventTargetNames::PaymentRequest; 717 return EventTargetNames::PaymentRequest;
707 } 718 }
708 719
709 ExecutionContext* PaymentRequest::getExecutionContext() const { 720 ExecutionContext* PaymentRequest::getExecutionContext() const {
710 return ContextLifecycleObserver::getExecutionContext(); 721 return ContextLifecycleObserver::getExecutionContext();
711 } 722 }
712 723
713 ScriptPromise PaymentRequest::complete(ScriptState* scriptState, 724 ScriptPromise PaymentRequest::complete(ScriptState* scriptState,
714 PaymentComplete result) { 725 PaymentComplete result) {
715 if (m_completeResolver) 726 if (!scriptState->contextIsValid()) {
727 return ScriptPromise::rejectWithDOMException(
728 scriptState,
729 DOMException::create(InvalidStateError, "Cannot complete payment"));
730 }
731
732 if (m_completeResolver) {
716 return ScriptPromise::rejectWithDOMException( 733 return ScriptPromise::rejectWithDOMException(
717 scriptState, DOMException::create(InvalidStateError, 734 scriptState, DOMException::create(InvalidStateError,
718 "Already called complete() once")); 735 "Already called complete() once"));
736 }
719 737
720 if (!m_completeTimer.isActive()) 738 if (!m_completeTimer.isActive()) {
721 return ScriptPromise::rejectWithDOMException( 739 return ScriptPromise::rejectWithDOMException(
722 scriptState, 740 scriptState,
723 DOMException::create( 741 DOMException::create(
724 InvalidStateError, 742 InvalidStateError,
725 "Timed out after 60 seconds, complete() called too late")); 743 "Timed out after 60 seconds, complete() called too late"));
744 }
726 745
727 // User has cancelled the transaction while the website was processing it. 746 // User has cancelled the transaction while the website was processing it.
728 if (!m_paymentProvider) 747 if (!m_paymentProvider) {
729 return ScriptPromise::rejectWithDOMException( 748 return ScriptPromise::rejectWithDOMException(
730 scriptState, 749 scriptState,
731 DOMException::create(InvalidStateError, "Request cancelled")); 750 DOMException::create(InvalidStateError, "Request cancelled"));
751 }
732 752
733 m_completeTimer.stop(); 753 m_completeTimer.stop();
734 754
735 // The payment provider should respond in PaymentRequest::OnComplete(). 755 // The payment provider should respond in PaymentRequest::OnComplete().
736 m_paymentProvider->Complete(payments::mojom::blink::PaymentComplete(result)); 756 m_paymentProvider->Complete(payments::mojom::blink::PaymentComplete(result));
737 757
738 m_completeResolver = ScriptPromiseResolver::create(scriptState); 758 m_completeResolver = ScriptPromiseResolver::create(scriptState);
739 return m_completeResolver->promise(); 759 return m_completeResolver->promise();
740 } 760 }
741 761
(...skipping 11 matching lines...) Expand all
753 exceptionState); 773 exceptionState);
754 if (exceptionState.hadException()) { 774 if (exceptionState.hadException()) {
755 m_showResolver->reject( 775 m_showResolver->reject(
756 DOMException::create(SyntaxError, exceptionState.message())); 776 DOMException::create(SyntaxError, exceptionState.message()));
757 clearResolversAndCloseMojoConnection(); 777 clearResolversAndCloseMojoConnection();
758 return; 778 return;
759 } 779 }
760 780
761 PaymentDetailsPtr validatedDetails = 781 PaymentDetailsPtr validatedDetails =
762 payments::mojom::blink::PaymentDetails::New(); 782 payments::mojom::blink::PaymentDetails::New();
763 validateAndConvertPaymentDetails( 783 validateAndConvertPaymentDetails(details, m_options.requestShipping(),
764 details, m_options.requestShipping(), 784 validatedDetails, m_shippingOption,
765 *detailsScriptValue.getScriptState()->domWindow()->document(), 785 *getExecutionContext(), exceptionState);
766 validatedDetails, m_shippingOption, exceptionState);
767 if (exceptionState.hadException()) { 786 if (exceptionState.hadException()) {
768 m_showResolver->reject( 787 m_showResolver->reject(
769 DOMException::create(SyntaxError, exceptionState.message())); 788 DOMException::create(SyntaxError, exceptionState.message()));
770 clearResolversAndCloseMojoConnection(); 789 clearResolversAndCloseMojoConnection();
771 return; 790 return;
772 } 791 }
773 792
774 m_paymentProvider->UpdateWith(std::move(validatedDetails)); 793 m_paymentProvider->UpdateWith(std::move(validatedDetails));
775 } 794 }
776 795
(...skipping 14 matching lines...) Expand all
791 visitor->trace(m_canMakePaymentResolver); 810 visitor->trace(m_canMakePaymentResolver);
792 EventTargetWithInlineData::trace(visitor); 811 EventTargetWithInlineData::trace(visitor);
793 ContextLifecycleObserver::trace(visitor); 812 ContextLifecycleObserver::trace(visitor);
794 } 813 }
795 814
796 void PaymentRequest::onCompleteTimeoutForTesting() { 815 void PaymentRequest::onCompleteTimeoutForTesting() {
797 m_completeTimer.stop(); 816 m_completeTimer.stop();
798 onCompleteTimeout(0); 817 onCompleteTimeout(0);
799 } 818 }
800 819
801 PaymentRequest::PaymentRequest(Document& document, 820 PaymentRequest::PaymentRequest(ScriptState* scriptState,
802 const HeapVector<PaymentMethodData>& methodData, 821 const HeapVector<PaymentMethodData>& methodData,
803 const PaymentDetails& details, 822 const PaymentDetails& details,
804 const PaymentOptions& options, 823 const PaymentOptions& options,
805 ExceptionState& exceptionState) 824 ExceptionState& exceptionState)
806 : ContextLifecycleObserver(&document), 825 : ContextLifecycleObserver(scriptState->getExecutionContext()),
807 m_options(options), 826 m_options(options),
808 m_clientBinding(this), 827 m_clientBinding(this),
809 m_completeTimer( 828 m_completeTimer(TaskRunnerHelper::get(TaskType::MiscPlatformAPI, frame()),
810 TaskRunnerHelper::get(TaskType::MiscPlatformAPI, document.frame()), 829 this,
811 this, 830 &PaymentRequest::onCompleteTimeout) {
812 &PaymentRequest::onCompleteTimeout) {
813 Vector<payments::mojom::blink::PaymentMethodDataPtr> validatedMethodData; 831 Vector<payments::mojom::blink::PaymentMethodDataPtr> validatedMethodData;
814 validateAndConvertPaymentMethodData(methodData, document, validatedMethodData, 832 validateAndConvertPaymentMethodData(methodData, validatedMethodData,
815 exceptionState); 833 *getExecutionContext(), exceptionState);
816 if (exceptionState.hadException()) 834 if (exceptionState.hadException())
817 return; 835 return;
818 836
819 if (!document.isSecureContext()) { 837 if (!getExecutionContext()->isSecureContext()) {
820 exceptionState.throwSecurityError("Must be in a secure context"); 838 exceptionState.throwSecurityError("Must be in a secure context");
821 return; 839 return;
822 } 840 }
823 841
824 if (!allowedToUsePaymentRequest(document.frame())) { 842 if (!allowedToUsePaymentRequest(frame())) {
825 exceptionState.throwSecurityError( 843 exceptionState.throwSecurityError(
826 "Must be in a top-level browsing context or an iframe needs to specify " 844 "Must be in a top-level browsing context or an iframe needs to specify "
827 "'allowpaymentrequest' explicitly"); 845 "'allowpaymentrequest' explicitly");
828 return; 846 return;
829 } 847 }
830 848
831 PaymentDetailsPtr validatedDetails = 849 PaymentDetailsPtr validatedDetails =
832 payments::mojom::blink::PaymentDetails::New(); 850 payments::mojom::blink::PaymentDetails::New();
833 validateAndConvertPaymentDetails(details, m_options.requestShipping(), 851 validateAndConvertPaymentDetails(details, m_options.requestShipping(),
834 document, validatedDetails, m_shippingOption, 852 validatedDetails, m_shippingOption,
835 exceptionState); 853 *getExecutionContext(), exceptionState);
836 if (exceptionState.hadException()) 854 if (exceptionState.hadException())
837 return; 855 return;
838 856
839 if (details.hasError()) { 857 if (details.hasError()) {
840 exceptionState.throwTypeError("Error message not allowed in constructor"); 858 exceptionState.throwTypeError("Error message not allowed in constructor");
841 return; 859 return;
842 } 860 }
843 861
844 if (m_options.requestShipping()) 862 if (m_options.requestShipping())
845 m_shippingType = getValidShippingType(m_options.shippingType()); 863 m_shippingType = getValidShippingType(m_options.shippingType());
846 864
847 document.frame()->interfaceProvider()->getInterface( 865 frame()->interfaceProvider()->getInterface(
848 mojo::MakeRequest(&m_paymentProvider)); 866 mojo::MakeRequest(&m_paymentProvider));
849 m_paymentProvider.set_connection_error_handler(convertToBaseCallback( 867 m_paymentProvider.set_connection_error_handler(convertToBaseCallback(
850 WTF::bind(&PaymentRequest::OnError, wrapWeakPersistent(this), 868 WTF::bind(&PaymentRequest::OnError, wrapWeakPersistent(this),
851 PaymentErrorReason::UNKNOWN))); 869 PaymentErrorReason::UNKNOWN)));
852 m_paymentProvider->Init( 870 m_paymentProvider->Init(
853 m_clientBinding.CreateInterfacePtrAndBind(), 871 m_clientBinding.CreateInterfacePtrAndBind(),
854 std::move(validatedMethodData), std::move(validatedDetails), 872 std::move(validatedMethodData), std::move(validatedDetails),
855 payments::mojom::blink::PaymentOptions::From(m_options)); 873 payments::mojom::blink::PaymentOptions::From(m_options));
856 } 874 }
857 875
858 void PaymentRequest::contextDestroyed(ExecutionContext*) { 876 void PaymentRequest::contextDestroyed(ExecutionContext*) {
859 clearResolversAndCloseMojoConnection(); 877 clearResolversAndCloseMojoConnection();
860 } 878 }
861 879
862 void PaymentRequest::OnShippingAddressChange(PaymentAddressPtr address) { 880 void PaymentRequest::OnShippingAddressChange(PaymentAddressPtr address) {
863 DCHECK(m_showResolver); 881 DCHECK(m_showResolver);
864 DCHECK(!m_completeResolver); 882 DCHECK(!m_completeResolver);
865 883
866 String errorMessage; 884 String errorMessage;
867 if (!PaymentsValidators::isValidShippingAddress(address, &errorMessage)) { 885 if (!PaymentsValidators::isValidShippingAddress(address, &errorMessage)) {
868 m_showResolver->reject(DOMException::create(SyntaxError, errorMessage)); 886 m_showResolver->reject(DOMException::create(SyntaxError, errorMessage));
869 clearResolversAndCloseMojoConnection(); 887 clearResolversAndCloseMojoConnection();
870 return; 888 return;
871 } 889 }
872 890
873 m_shippingAddress = new PaymentAddress(std::move(address)); 891 m_shippingAddress = new PaymentAddress(std::move(address));
874 PaymentRequestUpdateEvent* event = PaymentRequestUpdateEvent::create( 892 PaymentRequestUpdateEvent* event =
875 getExecutionContext(), EventTypeNames::shippingaddresschange); 893 PaymentRequestUpdateEvent::create(ScriptState::forMainWorld(frame()),
894 EventTypeNames::shippingaddresschange);
876 event->setTarget(this); 895 event->setTarget(this);
877 event->setPaymentDetailsUpdater(this); 896 event->setPaymentDetailsUpdater(this);
878 bool success = getExecutionContext()->getEventQueue()->enqueueEvent(event); 897 bool success = getExecutionContext()->getEventQueue()->enqueueEvent(event);
879 DCHECK(success); 898 DCHECK(success);
880 ALLOW_UNUSED_LOCAL(success); 899 ALLOW_UNUSED_LOCAL(success);
881 } 900 }
882 901
883 void PaymentRequest::OnShippingOptionChange(const String& shippingOptionId) { 902 void PaymentRequest::OnShippingOptionChange(const String& shippingOptionId) {
884 DCHECK(m_showResolver); 903 DCHECK(m_showResolver);
885 DCHECK(!m_completeResolver); 904 DCHECK(!m_completeResolver);
886 m_shippingOption = shippingOptionId; 905 m_shippingOption = shippingOptionId;
887 PaymentRequestUpdateEvent* event = PaymentRequestUpdateEvent::create( 906 PaymentRequestUpdateEvent* event = PaymentRequestUpdateEvent::create(
888 getExecutionContext(), EventTypeNames::shippingoptionchange); 907 ScriptState::forMainWorld(frame()), EventTypeNames::shippingoptionchange);
please use gerrit instead 2017/02/19 18:53:02 Is it OK to use the main world when notifying the
Marijn Kruisselbrink 2017/02/21 19:08:56 Even though each world has it's own Window and Doc
889 event->setTarget(this); 908 event->setTarget(this);
890 event->setPaymentDetailsUpdater(this); 909 event->setPaymentDetailsUpdater(this);
891 bool success = getExecutionContext()->getEventQueue()->enqueueEvent(event); 910 bool success = getExecutionContext()->getEventQueue()->enqueueEvent(event);
892 DCHECK(success); 911 DCHECK(success);
893 ALLOW_UNUSED_LOCAL(success); 912 ALLOW_UNUSED_LOCAL(success);
894 } 913 }
895 914
896 void PaymentRequest::OnPaymentResponse(PaymentResponsePtr response) { 915 void PaymentRequest::OnPaymentResponse(PaymentResponsePtr response) {
897 DCHECK(m_showResolver); 916 DCHECK(m_showResolver);
898 DCHECK(!m_completeResolver); 917 DCHECK(!m_completeResolver);
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 m_completeResolver.clear(); 1065 m_completeResolver.clear();
1047 m_showResolver.clear(); 1066 m_showResolver.clear();
1048 m_abortResolver.clear(); 1067 m_abortResolver.clear();
1049 m_canMakePaymentResolver.clear(); 1068 m_canMakePaymentResolver.clear();
1050 if (m_clientBinding.is_bound()) 1069 if (m_clientBinding.is_bound())
1051 m_clientBinding.Close(); 1070 m_clientBinding.Close();
1052 m_paymentProvider.reset(); 1071 m_paymentProvider.reset();
1053 } 1072 }
1054 1073
1055 } // namespace blink 1074 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698