Changeset 228195 in webkit
- Timestamp:
- Feb 6, 2018, 2:49:53 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r228187 r228195 1 2018-02-06 Andy Estes <aestes@apple.com> 2 3 [Payment Request] show() should take an optional PaymentDetailsUpdate promise 4 https://bugs.webkit.org/show_bug.cgi?id=182538 5 <rdar://problem/36754552> 6 7 Reviewed by Tim Horton. 8 9 * http/tests/paymentrequest/payment-request-show-method.https-expected.txt: 10 * http/tests/paymentrequest/payment-request-show-method.https.html: 11 1 12 2018-02-06 Daniel Bates <dabates@apple.com> 2 13 -
trunk/LayoutTests/http/tests/paymentrequest/payment-request-show-method.https-expected.txt
r223962 r228195 5 5 PASS If payment method consultation produces no supported method of payment, then return a promise rejected with a "NotSupportedError" DOMException. 6 6 PASS If the user aborts the payment request algorithm, then return a promise rejected with an "AbortError" DOMException. 7 PASS A request is updated when show()'s detail promise resolves. 8 PASS Change events do not occur until show()'s detail promise resolves. 7 9 -
trunk/LayoutTests/http/tests/paymentrequest/payment-request-show-method.https.html
r224402 r228195 76 76 await promise_rejects(t, "AbortError", acceptPromise); 77 77 }, `If the user aborts the payment request algorithm, then return a promise rejected with an "AbortError" DOMException.`); 78 79 user_activation_test(async t => { 80 const request = new PaymentRequest(defaultMethods, defaultDetails); 81 const expectedLabel = "Updated Total"; 82 const expectedAmount = "2.00"; 83 const details = { 84 total: { 85 label: expectedLabel, 86 amount: { 87 currency: "USD", 88 value: expectedAmount, 89 }, 90 }, 91 }; 92 const acceptPromise = request.show(details); 93 internals.mockPaymentCoordinator.changePaymentMethod({ type: 'credit' }); 94 internals.mockPaymentCoordinator.acceptPayment(); 95 const result = await acceptPromise; 96 assert_equals(internals.mockPaymentCoordinator.total.label, expectedLabel); 97 assert_equals(internals.mockPaymentCoordinator.total.amount, expectedAmount); 98 result.complete("success"); 99 }, `A request is updated when show()'s detail promise resolves.`); 100 101 user_activation_test(async t => { 102 const request = new PaymentRequest(defaultMethods, defaultDetails); 103 const expectedLabel = "Updated Total"; 104 const expectedAmount = "2.00"; 105 106 var shippingAddressChanged = false; 107 const shippingAddressChangedPromise = new Promise((resolve) => { 108 request.onshippingaddresschange = () => { 109 shippingAddressChanged = true; 110 resolve(); 111 }; 112 }); 113 114 const detailsPromise = new Promise((resolve) => { 115 const details = { 116 total: { 117 label: expectedLabel, 118 amount: { 119 currency: "USD", 120 value: expectedAmount, 121 }, 122 }, 123 }; 124 125 request.onmerchantvalidation = (event) => { 126 const sessionPromise = new Promise((resolve) => resolve({ })); 127 event.complete(sessionPromise); 128 sessionPromise.then(() => window.setTimeout(() => { 129 assert_equals(shippingAddressChanged, false, "shippingaddresschange does not fire before the details promise resolves."); 130 resolve(details); 131 })); 132 }; 133 }); 134 135 request.show(detailsPromise).catch(() => {}); 136 await shippingAddressChangedPromise; 137 }, `Change events do not occur until show()'s detail promise resolves.`); 78 138 </script> -
trunk/Source/WebCore/ChangeLog
r228191 r228195 1 2018-02-06 Andy Estes <aestes@apple.com> 2 3 [Payment Request] show() should take an optional PaymentDetailsUpdate promise 4 https://bugs.webkit.org/show_bug.cgi?id=182538 5 <rdar://problem/36754552> 6 7 Reviewed by Tim Horton. 8 9 Taught show() to take an optional promise for a PaymentDetailsUpdate. 10 11 Added test cases to http/tests/paymentrequest/payment-request-show-method.https.html. 12 13 * Modules/applepay/paymentrequest/ApplePayPaymentHandler.cpp: 14 (WebCore::ApplePayPaymentHandler::detailsUpdated): 15 16 Changed to take a PaymentRequest::UpdateReason instead of a eventType string. 17 18 (WebCore::ApplePayPaymentHandler::shippingAddressUpdated): 19 (WebCore::ApplePayPaymentHandler::shippingOptionUpdated): 20 (WebCore::ApplePayPaymentHandler::paymentMethodUpdated): 21 (WebCore::ApplePayPaymentHandler::didAuthorizePayment): 22 (WebCore::ApplePayPaymentHandler::didSelectShippingMethod): 23 (WebCore::ApplePayPaymentHandler::didSelectShippingContact): 24 (WebCore::ApplePayPaymentHandler::didSelectPaymentMethod): 25 26 Asserted that only one of the PaymentSession delegates is executing at a time. 27 28 * Modules/applepay/paymentrequest/ApplePayPaymentHandler.h: 29 * Modules/paymentrequest/PaymentHandler.h: 30 31 Changed detailsUpdated to take a PaymentRequest::UpdateReason instead of a eventType string. 32 33 * Modules/paymentrequest/PaymentRequest.cpp: 34 (WebCore::PaymentRequest::show): 35 36 If there is a details promise, call updateWith() with UpdateReason::ShowDetailsResolved. 37 38 (WebCore::PaymentRequest::shippingAddressChanged): 39 (WebCore::PaymentRequest::shippingOptionChanged): 40 (WebCore::PaymentRequest::paymentMethodChanged): 41 42 Used whenDetailsSettled() to ensure that update events do not start before the show() 43 details promise settles. 44 45 (WebCore::PaymentRequest::updateWith): 46 (WebCore::PaymentRequest::settleDetailsPromise): 47 48 Changed to use a PaymentRequest::UpdateReason instead of a eventType string. 49 50 (WebCore::PaymentRequest::whenDetailsSettled): 51 52 If there is a details promise, wait for it to settle before executing the callback. 53 54 * Modules/paymentrequest/PaymentRequest.h: 55 56 Defined enum class UpdateReason. 57 58 * Modules/paymentrequest/PaymentRequest.idl: 59 60 Updated show() to take an optional Promise<PaymentDetailsUpdate>. 61 62 * Modules/paymentrequest/PaymentRequestUpdateEvent.cpp: 63 (WebCore::PaymentRequestUpdateEvent::updateWith): 64 65 Map the event type to a PaymentRequest::UpdateReason. 66 1 67 2018-02-06 Dean Jackson <dino@apple.com> 2 68 -
trunk/Source/WebCore/Modules/applepay/paymentrequest/ApplePayPaymentHandler.cpp
r226766 r228195 1 1 /* 2 * Copyright (C) 2017 Apple Inc. All rights reserved.2 * Copyright (C) 2017-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 308 308 } 309 309 310 ExceptionOr<void> ApplePayPaymentHandler::detailsUpdated(const AtomicString& eventType, const String& error) 311 { 312 if (eventType == eventNames().shippingaddresschangeEvent) 310 ExceptionOr<void> ApplePayPaymentHandler::detailsUpdated(PaymentRequest::UpdateReason reason, const String& error) 311 { 312 using Reason = PaymentRequest::UpdateReason; 313 switch (reason) { 314 case Reason::ShowDetailsResolved: 315 return { }; 316 case Reason::ShippingAddressChanged: 313 317 return shippingAddressUpdated(error); 314 315 if (eventType == eventNames().shippingoptionchangeEvent) 318 case Reason::ShippingOptionChanged: 316 319 return shippingOptionUpdated(); 320 case Reason::PaymentMethodChanged: 321 return paymentMethodUpdated(); 322 } 317 323 318 324 ASSERT_NOT_REACHED(); … … 339 345 ExceptionOr<void> ApplePayPaymentHandler::shippingAddressUpdated(const String& error) 340 346 { 347 ASSERT(m_isUpdating); 348 m_isUpdating = false; 349 341 350 ShippingContactUpdate update; 342 351 … … 359 368 ExceptionOr<void> ApplePayPaymentHandler::shippingOptionUpdated() 360 369 { 370 ASSERT(m_isUpdating); 371 m_isUpdating = false; 372 361 373 ShippingMethodUpdate update; 362 374 … … 372 384 ExceptionOr<void> ApplePayPaymentHandler::paymentMethodUpdated() 373 385 { 386 ASSERT(m_isUpdating); 387 m_isUpdating = false; 388 374 389 PaymentMethodUpdate update; 375 390 … … 428 443 void ApplePayPaymentHandler::didAuthorizePayment(const Payment& payment) 429 444 { 445 ASSERT(!m_isUpdating); 446 430 447 auto applePayPayment = payment.toApplePayPayment(version()); 431 448 auto& execState = *document().execState(); … … 438 455 void ApplePayPaymentHandler::didSelectShippingMethod(const ApplePaySessionPaymentRequest::ShippingMethod& shippingMethod) 439 456 { 457 ASSERT(!m_isUpdating); 458 m_isUpdating = true; 459 440 460 m_paymentRequest->shippingOptionChanged(shippingMethod.identifier); 441 461 } … … 443 463 void ApplePayPaymentHandler::didSelectShippingContact(const PaymentContact& shippingContact) 444 464 { 465 ASSERT(!m_isUpdating); 466 m_isUpdating = true; 467 445 468 m_paymentRequest->shippingAddressChanged(convert(shippingContact.toApplePayPaymentContact(version()))); 446 469 } … … 448 471 void ApplePayPaymentHandler::didSelectPaymentMethod(const PaymentMethod& paymentMethod) 449 472 { 473 ASSERT(!m_isUpdating); 474 m_isUpdating = true; 475 450 476 m_selectedPaymentMethodType = paymentMethod.toApplePayPaymentMethod().type; 451 paymentMethodUpdated();477 m_paymentRequest->paymentMethodChanged(); 452 478 } 453 479 -
trunk/Source/WebCore/Modules/applepay/paymentrequest/ApplePayPaymentHandler.h
r226766 r228195 1 1 /* 2 * Copyright (C) 2017 Apple Inc. All rights reserved.2 * Copyright (C) 2017-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 64 64 void hide() final; 65 65 void canMakePayment(WTF::Function<void(bool)>&& completionHandler) final; 66 ExceptionOr<void> detailsUpdated( const AtomicString& eventType, const String& error) final;66 ExceptionOr<void> detailsUpdated(PaymentRequest::UpdateReason, const String& error) final; 67 67 ExceptionOr<void> merchantValidationCompleted(JSC::JSValue&&) final; 68 68 void complete(std::optional<PaymentComplete>&&) final; … … 81 81 std::optional<ApplePayRequest> m_applePayRequest; 82 82 std::optional<ApplePayPaymentMethodType> m_selectedPaymentMethodType; 83 bool m_isUpdating { false }; 83 84 }; 84 85 -
trunk/Source/WebCore/Modules/paymentrequest/PaymentHandler.h
r226766 r228195 1 1 /* 2 * Copyright (C) 2017 Apple Inc. All rights reserved.2 * Copyright (C) 2017-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 50 50 virtual void hide() = 0; 51 51 virtual void canMakePayment(WTF::Function<void(bool)>&& completionHandler) = 0; 52 virtual ExceptionOr<void> detailsUpdated( const AtomicString& eventType, const String& error) = 0;52 virtual ExceptionOr<void> detailsUpdated(PaymentRequest::UpdateReason, const String& error) = 0; 53 53 virtual ExceptionOr<void> merchantValidationCompleted(JSC::JSValue&&) = 0; 54 54 virtual void complete(std::optional<PaymentComplete>&&) = 0; -
trunk/Source/WebCore/Modules/paymentrequest/PaymentRequest.cpp
r227277 r228195 1 1 /* 2 * Copyright (C) 2017 Apple Inc. All rights reserved.2 * Copyright (C) 2017-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 381 381 382 382 // https://www.w3.org/TR/payment-request/#show()-method 383 void PaymentRequest::show(Document& document, ShowPromise&& promise)383 void PaymentRequest::show(Document& document, RefPtr<DOMPromise>&& detailsPromise, ShowPromise&& promise) 384 384 { 385 385 if (!document.frame()) { … … 443 443 m_activePaymentHandler = WTFMove(selectedPaymentHandler); 444 444 setPendingActivity(this); // unsetPendingActivity() is called below in stop() 445 446 if (!detailsPromise) 447 return; 448 449 exception = updateWith(UpdateReason::ShowDetailsResolved, detailsPromise.releaseNonNull()); 450 ASSERT(!exception.hasException()); 445 451 } 446 452 … … 532 538 void PaymentRequest::shippingAddressChanged(Ref<PaymentAddress>&& shippingAddress) 533 539 { 534 ASSERT(m_state == State::Interactive); 535 m_shippingAddress = WTFMove(shippingAddress); 536 if (m_isUpdating) 537 return; 538 dispatchEvent(PaymentRequestUpdateEvent::create(eventNames().shippingaddresschangeEvent, *this)); 540 whenDetailsSettled([this, protectedThis = makeRefPtr(this), shippingAddress = makeRefPtr(shippingAddress.get())]() mutable { 541 m_shippingAddress = WTFMove(shippingAddress); 542 dispatchEvent(PaymentRequestUpdateEvent::create(eventNames().shippingaddresschangeEvent, *this)); 543 }); 539 544 } 540 545 541 546 void PaymentRequest::shippingOptionChanged(const String& shippingOption) 542 547 { 543 ASSERT(m_state == State::Interactive); 544 m_shippingOption = shippingOption; 545 if (m_isUpdating) 546 return; 547 dispatchEvent(PaymentRequestUpdateEvent::create(eventNames().shippingoptionchangeEvent, *this)); 548 } 549 550 ExceptionOr<void> PaymentRequest::updateWith(Event& event, Ref<DOMPromise>&& promise) 548 whenDetailsSettled([this, protectedThis = makeRefPtr(this), shippingOption]() mutable { 549 m_shippingOption = shippingOption; 550 dispatchEvent(PaymentRequestUpdateEvent::create(eventNames().shippingoptionchangeEvent, *this)); 551 }); 552 } 553 554 void PaymentRequest::paymentMethodChanged() 555 { 556 whenDetailsSettled([this, protectedThis = makeRefPtr(this)] { 557 m_activePaymentHandler->detailsUpdated(UpdateReason::PaymentMethodChanged, { }); 558 }); 559 } 560 561 ExceptionOr<void> PaymentRequest::updateWith(UpdateReason reason, Ref<DOMPromise>&& promise) 551 562 { 552 563 if (m_state != State::Interactive) … … 556 567 return Exception { InvalidStateError }; 557 568 558 event.stopPropagation();559 event.stopImmediatePropagation();560 569 m_isUpdating = true; 561 570 571 ASSERT(!m_detailsPromise); 562 572 m_detailsPromise = WTFMove(promise); 563 m_detailsPromise->whenSettled([this, protectedThis = makeRefPtr(this), type = event.type()]() {564 settleDetailsPromise( type);573 m_detailsPromise->whenSettled([this, protectedThis = makeRefPtr(this), reason]() { 574 settleDetailsPromise(reason); 565 575 }); 566 576 … … 596 606 } 597 607 598 void PaymentRequest::settleDetailsPromise( const AtomicString& type)608 void PaymentRequest::settleDetailsPromise(UpdateReason reason) 599 609 { 600 610 auto scopeExit = makeScopeExit([&] { 601 611 m_isUpdating = false; 612 m_detailsPromise = nullptr; 602 613 }); 603 614 … … 642 653 m_serializedModifierData = WTFMove(std::get<1>(shippingOptionAndModifierData)); 643 654 644 auto result = m_activePaymentHandler->detailsUpdated( type, paymentDetailsUpdate.error);655 auto result = m_activePaymentHandler->detailsUpdated(reason, paymentDetailsUpdate.error); 645 656 if (result.hasException()) { 646 657 abortWithException(result.releaseException()); 647 658 return; 648 659 } 660 } 661 662 void PaymentRequest::whenDetailsSettled(std::function<void()>&& callback) 663 { 664 if (!m_detailsPromise) { 665 ASSERT(m_state == State::Interactive); 666 ASSERT(!m_isUpdating); 667 callback(); 668 return; 669 } 670 671 m_detailsPromise->whenSettled([this, protectedThis = makeRefPtr(this), callback = WTFMove(callback)] { 672 if (m_state != State::Interactive) 673 return; 674 675 ASSERT(!m_isUpdating); 676 callback(); 677 }); 649 678 } 650 679 -
trunk/Source/WebCore/Modules/paymentrequest/PaymentRequest.h
r226766 r228195 1 1 /* 2 * Copyright (C) 2017 Apple Inc. All rights reserved.2 * Copyright (C) 2017-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 46 46 enum class PaymentComplete; 47 47 enum class PaymentShippingType; 48 struct PaymentDetailsUpdate; 48 49 struct PaymentMethodData; 49 50 50 51 class PaymentRequest final : public RefCounted<PaymentRequest>, public ActiveDOMObject, public EventTargetWithInlineData { 51 52 public: 52 using ShowPromise = DOMPromiseDeferred<IDLInterface<PaymentResponse>>;53 53 using AbortPromise = DOMPromiseDeferred<void>; 54 54 using CanMakePaymentPromise = DOMPromiseDeferred<IDLBoolean>; 55 using ShowPromise = DOMPromiseDeferred<IDLInterface<PaymentResponse>>; 55 56 56 57 static ExceptionOr<Ref<PaymentRequest>> create(Document&, Vector<PaymentMethodData>&&, PaymentDetailsInit&&, PaymentOptions&&); 57 58 ~PaymentRequest(); 58 59 59 void show(Document&, ShowPromise&&);60 void show(Document&, RefPtr<DOMPromise>&& detailsPromise, ShowPromise&&); 60 61 ExceptionOr<void> abort(AbortPromise&&); 61 62 void canMakePayment(Document&, CanMakePaymentPromise&&); … … 72 73 }; 73 74 75 enum class UpdateReason { 76 ShowDetailsResolved, 77 ShippingAddressChanged, 78 ShippingOptionChanged, 79 PaymentMethodChanged, 80 }; 81 74 82 State state() const { return m_state; } 75 83 … … 80 88 void shippingAddressChanged(Ref<PaymentAddress>&&); 81 89 void shippingOptionChanged(const String& shippingOption); 82 ExceptionOr<void> updateWith(Event&, Ref<DOMPromise>&&); 90 void paymentMethodChanged(); 91 ExceptionOr<void> updateWith(UpdateReason, Ref<DOMPromise>&&); 83 92 ExceptionOr<void> completeMerchantValidation(Event&, Ref<DOMPromise>&&); 84 93 void accept(const String& methodName, JSC::Strong<JSC::JSObject>&& details, Ref<PaymentAddress>&& shippingAddress, const String& payerName, const String& payerEmail, const String& payerPhone); … … 98 107 PaymentRequest(Document&, PaymentOptions&&, PaymentDetailsInit&&, Vector<String>&& serializedModifierData, Vector<Method>&& serializedMethodData, String&& selectedShippingOption); 99 108 100 void settleDetailsPromise(const AtomicString& type); 109 void settleDetailsPromise(UpdateReason); 110 void whenDetailsSettled(std::function<void()>&&); 101 111 void abortWithException(Exception&&); 102 112 -
trunk/Source/WebCore/Modules/paymentrequest/PaymentRequest.idl
r226766 r228195 1 1 /* 2 * Copyright (C) 2017 Apple Inc. All rights reserved.2 * Copyright (C) 2017-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 31 31 ConstructorMayThrowException, 32 32 EnabledBySetting=PaymentRequest, 33 SecureContext 33 SecureContext, 34 34 ] interface PaymentRequest : EventTarget { 35 [CallWith=Document] Promise<PaymentResponse> show( );35 [CallWith=Document] Promise<PaymentResponse> show(optional Promise<PaymentDetailsUpdate> detailsPromise); 36 36 [MayThrowException] Promise<void> abort(); 37 37 [CallWith=Document] Promise<boolean> canMakePayment(); -
trunk/Source/WebCore/Modules/paymentrequest/PaymentRequestUpdateEvent.cpp
r223945 r228195 1 1 /* 2 * Copyright (C) 2017 Apple Inc. All rights reserved.2 * Copyright (C) 2017-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 54 54 return Exception { InvalidStateError }; 55 55 56 auto exception = m_paymentRequest->updateWith(*this, WTFMove(detailsPromise)); 56 stopPropagation(); 57 stopImmediatePropagation(); 58 59 PaymentRequest::UpdateReason reason; 60 if (type() == eventNames().shippingaddresschangeEvent) 61 reason = PaymentRequest::UpdateReason::ShippingAddressChanged; 62 else if (type() == eventNames().shippingoptionchangeEvent) 63 reason = PaymentRequest::UpdateReason::ShippingOptionChanged; 64 else { 65 ASSERT_NOT_REACHED(); 66 return Exception { TypeError }; 67 } 68 69 auto exception = m_paymentRequest->updateWith(reason, WTFMove(detailsPromise)); 57 70 if (exception.hasException()) 58 71 return exception.releaseException();
Note:
See TracChangeset
for help on using the changeset viewer.