Chromium Code Reviews| 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 |