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 <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 Loading... | |
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 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(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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |