/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_dom_PaymentRequest_h #define mozilla_dom_PaymentRequest_h #include "mozilla/DOMEventTargetHelper.h" #include "mozilla/dom/PaymentRequestBinding.h" #include "mozilla/dom/Promise.h" #include "mozilla/dom/PromiseNativeHandler.h" #include "mozilla/ErrorResult.h" #include "nsIDocumentActivity.h" #include "nsWrapperCache.h" #include "PaymentRequestUpdateEvent.h" namespace mozilla { namespace dom { class EventHandlerNonNull; class PaymentAddress; class PaymentRequestChild; class PaymentResponse; class ResponseData; class PaymentRequest final : public DOMEventTargetHelper , public PromiseNativeHandler , public nsIDocumentActivity { public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(PaymentRequest, DOMEventTargetHelper) NS_DECL_NSIDOCUMENTACTIVITY virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; static already_AddRefed CreatePaymentRequest( nsPIDOMWindowInner* aWindow, nsresult& aRv); static bool PrefEnabled(JSContext* aCx, JSObject* aObj); static nsresult IsValidStandardizedPMI(const nsAString& aIdentifier, nsAString& aErrorMsg); static nsresult IsValidPaymentMethodIdentifier(const nsAString& aIdentifier, nsAString& aErrorMsg); static nsresult IsValidMethodData( JSContext* aCx, const Sequence& aMethodData, nsAString& aErrorMsg); static nsresult IsValidNumber(const nsAString& aItem, const nsAString& aStr, nsAString& aErrorMsg); static nsresult IsNonNegativeNumber(const nsAString& aItem, const nsAString& aStr, nsAString& aErrorMsg); static nsresult IsValidCurrencyAmount(const nsAString& aItem, const PaymentCurrencyAmount& aAmount, const bool aIsTotalItem, nsAString& aErrorMsg); static nsresult IsValidCurrency(const nsAString& aItem, const nsAString& aCurrency, nsAString& aErrorMsg); static nsresult IsValidDetailsInit(const PaymentDetailsInit& aDetails, const bool aRequestShipping, nsAString& aErrorMsg); static nsresult IsValidDetailsUpdate(const PaymentDetailsUpdate& aDetails, const bool aRequestShipping); static nsresult IsValidDetailsBase(const PaymentDetailsBase& aDetails, const bool aRequestShipping, nsAString& aErrorMsg); static already_AddRefed Constructor( const GlobalObject& aGlobal, const Sequence& aMethodData, const PaymentDetailsInit& aDetails, const PaymentOptions& aOptions, ErrorResult& aRv); already_AddRefed CanMakePayment(ErrorResult& aRv); void RespondCanMakePayment(bool aResult); already_AddRefed Show( const Optional>& detailsPromise, ErrorResult& aRv); void RespondShowPayment(const nsAString& aMethodName, const ResponseData& aDetails, const nsAString& aPayerName, const nsAString& aPayerEmail, const nsAString& aPayerPhone, nsresult aRv); void RejectShowPayment(nsresult aRejectReason); void RespondComplete(); already_AddRefed Abort(ErrorResult& aRv); void RespondAbortPayment(bool aResult); nsresult RetryPayment(JSContext* aCx, const PaymentValidationErrors& aErrors); void GetId(nsAString& aRetVal) const; void GetInternalId(nsAString& aRetVal); void SetId(const nsAString& aId); bool Equals(const nsAString& aInternalId) const; bool ReadyForUpdate(); bool IsUpdating() const { return mUpdating; } void SetUpdating(bool aUpdating); already_AddRefed GetResponse() const; already_AddRefed GetShippingAddress() const; // Update mShippingAddress and fire shippingaddresschange event nsresult UpdateShippingAddress(const nsAString& aCountry, const nsTArray& aAddressLine, const nsAString& aRegion, const nsAString& aRegionCode, const nsAString& aCity, const nsAString& aDependentLocality, const nsAString& aPostalCode, const nsAString& aSortingCode, const nsAString& aOrganization, const nsAString& aRecipient, const nsAString& aPhone); void SetShippingOption(const nsAString& aShippingOption); void GetShippingOption(nsAString& aRetVal) const; void GetOptions(PaymentOptions& aRetVal) const; void SetOptions(const PaymentOptions& aOptions); nsresult UpdateShippingOption(const nsAString& aShippingOption); nsresult UpdatePayment(JSContext* aCx, const PaymentDetailsUpdate& aDetails, bool aDeferredShow); void AbortUpdate(nsresult aRv, bool aDeferredShow); void SetShippingType(const Nullable& aShippingType); Nullable GetShippingType() const; inline void ShippingWasRequested() { mRequestShipping = true; } void ResolvedCallback(JSContext* aCx, JS::Handle aValue) override; void RejectedCallback(JSContext* aCx, JS::Handle aValue) override; IMPL_EVENT_HANDLER(merchantvalidation); IMPL_EVENT_HANDLER(shippingaddresschange); IMPL_EVENT_HANDLER(shippingoptionchange); IMPL_EVENT_HANDLER(paymentmethodchange); void SetIPC(PaymentRequestChild* aChild) { mIPC = aChild; } PaymentRequestChild* GetIPC() const { return mIPC; } private: PaymentOptions mOptions; protected: ~PaymentRequest(); void RegisterActivityObserver(); void UnregisterActivityObserver(); nsresult DispatchUpdateEvent(const nsAString& aType); nsresult DispatchMerchantValidationEvent(const nsAString& aType); PaymentRequest(nsPIDOMWindowInner* aWindow, const nsAString& aInternalId); // Id for internal identification nsString mInternalId; // Id for communicating with merchant side // mId is initialized to details.id if it exists // otherwise, mId has the same value as mInternalId. nsString mId; // Promise for "PaymentRequest::CanMakePayment" RefPtr mResultPromise; // Promise for "PaymentRequest::Show" RefPtr mAcceptPromise; // Promise for "PaymentRequest::Abort" RefPtr mAbortPromise; // Resolve mAcceptPromise with mResponse if user accepts the request. RefPtr mResponse; // The redacted shipping address. RefPtr mShippingAddress; // The full shipping address to be used in the response upon payment. RefPtr mFullShippingAddress; // It is populated when the user chooses a shipping option. nsString mShippingOption; Nullable mShippingType; // "true" when there is a pending updateWith() call to update the payment // request and "false" otherwise. bool mUpdating; // Whether shipping was requested. This models [[options]].requestShipping, // but we don't actually store the full [[options]] internal slot. bool mRequestShipping; // True if the user passed a promise to show, causing us to defer telling the // front end about it. bool mDeferredShow; // The error is set in AbortUpdate(). The value is NS_OK by default. nsresult mUpdateError; enum { eUnknown, eCreated, eInteractive, eClosed } mState; PaymentRequestChild* mIPC; }; } // namespace dom } // namespace mozilla #endif // mozilla_dom_PaymentRequest_h