1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/MerchantValidationEvent.h"
9 #include "mozilla/dom/Document.h"
10 #include "mozilla/dom/PaymentRequest.h"
11 #include "mozilla/dom/Location.h"
12 #include "mozilla/dom/URL.h"
13 #include "mozilla/ResultExtensions.h"
15 #include "nsNetUtil.h"
17 namespace mozilla::dom
{
19 NS_IMPL_CYCLE_COLLECTION_INHERITED(MerchantValidationEvent
, Event
,
20 mValidationURL
, mRequest
)
22 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(MerchantValidationEvent
, Event
)
23 NS_IMPL_CYCLE_COLLECTION_TRACE_END
25 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MerchantValidationEvent
)
26 NS_INTERFACE_MAP_END_INHERITING(Event
)
28 NS_IMPL_ADDREF_INHERITED(MerchantValidationEvent
, Event
)
29 NS_IMPL_RELEASE_INHERITED(MerchantValidationEvent
, Event
)
31 // User-land code constructor
32 already_AddRefed
<MerchantValidationEvent
> MerchantValidationEvent::Constructor(
33 const GlobalObject
& aGlobal
, const nsAString
& aType
,
34 const MerchantValidationEventInit
& aEventInitDict
, ErrorResult
& aRv
) {
35 // validate passed URL
36 nsCOMPtr
<mozilla::dom::EventTarget
> owner
=
37 do_QueryInterface(aGlobal
.GetAsSupports());
38 return Constructor(owner
, aType
, aEventInitDict
, aRv
);
41 // Internal JS object constructor
42 already_AddRefed
<MerchantValidationEvent
> MerchantValidationEvent::Constructor(
43 EventTarget
* aOwner
, const nsAString
& aType
,
44 const MerchantValidationEventInit
& aEventInitDict
, ErrorResult
& aRv
) {
45 RefPtr
<MerchantValidationEvent
> e
= new MerchantValidationEvent(aOwner
);
46 bool trusted
= e
->Init(aOwner
);
47 e
->InitEvent(aType
, aEventInitDict
.mBubbles
, aEventInitDict
.mCancelable
);
48 e
->init(aEventInitDict
, aRv
);
52 e
->SetTrusted(trusted
);
53 e
->SetComposed(aEventInitDict
.mComposed
);
57 void MerchantValidationEvent::init(
58 const MerchantValidationEventInit
& aEventInitDict
, ErrorResult
& aRv
) {
59 // Check methodName is valid
60 if (!aEventInitDict
.mMethodName
.IsEmpty()) {
61 PaymentRequest::IsValidPaymentMethodIdentifier(aEventInitDict
.mMethodName
,
67 SetMethodName(aEventInitDict
.mMethodName
);
68 nsCOMPtr
<nsPIDOMWindowInner
> window
= do_QueryInterface(GetParentObject());
69 auto doc
= window
->GetExtantDoc();
71 aRv
.ThrowAbortError("The owner document does not exist");
75 Result
<OwningNonNull
<nsIURI
>, nsresult
> rv
=
76 doc
->ResolveWithBaseURI(aEventInitDict
.mValidationURL
);
78 aRv
.ThrowTypeError("validationURL cannot be parsed");
81 mValidationURL
= rv
.unwrap();
84 MerchantValidationEvent::MerchantValidationEvent(EventTarget
* aOwner
)
85 : Event(aOwner
, nullptr, nullptr), mWaitForUpdate(false) {
89 void MerchantValidationEvent::ResolvedCallback(JSContext
* aCx
,
90 JS::Handle
<JS::Value
> aValue
,
95 if (!mWaitForUpdate
) {
98 mWaitForUpdate
= false;
100 // If we eventually end up supporting merchant validation
101 // we would validate `aValue` here, as per:
102 // https://w3c.github.io/payment-request/#validate-merchant-s-details-algorithm
104 // Right now, MerchantValidationEvent is only implemented for standards
105 // conformance, which is why at this point we throw a
106 // NS_ERROR_DOM_NOT_SUPPORTED_ERR.
109 result
.ThrowNotSupportedError(
110 "complete() is not supported by Firefox currently");
111 mRequest
->AbortUpdate(result
);
112 mRequest
->SetUpdating(false);
115 void MerchantValidationEvent::RejectedCallback(JSContext
* aCx
,
116 JS::Handle
<JS::Value
> aValue
,
118 MOZ_ASSERT(mRequest
);
119 if (!mWaitForUpdate
) {
122 mWaitForUpdate
= false;
124 result
.ThrowAbortError(
125 "The promise for MerchantValidtaionEvent.complete() is rejected");
126 mRequest
->AbortUpdate(result
);
127 mRequest
->SetUpdating(false);
130 void MerchantValidationEvent::Complete(Promise
& aPromise
, ErrorResult
& aRv
) {
132 aRv
.ThrowInvalidStateError("Called on an untrusted event");
136 MOZ_ASSERT(mRequest
);
138 if (mWaitForUpdate
) {
139 aRv
.ThrowInvalidStateError(
140 "The MerchantValidationEvent is waiting for update");
144 if (!mRequest
->ReadyForUpdate()) {
145 aRv
.ThrowInvalidStateError(
146 "The PaymentRequest state is not eInteractive or the PaymentRequest is "
151 aPromise
.AppendNativeHandler(this);
154 StopImmediatePropagation();
155 mWaitForUpdate
= true;
156 mRequest
->SetUpdating(true);
159 void MerchantValidationEvent::SetRequest(PaymentRequest
* aRequest
) {
160 MOZ_ASSERT(IsTrusted());
161 MOZ_ASSERT(!mRequest
);
162 MOZ_ASSERT(aRequest
);
167 void MerchantValidationEvent::GetValidationURL(nsAString
& aValidationURL
) {
168 nsAutoCString utf8href
;
169 nsresult rv
= mValidationURL
->GetSpec(utf8href
);
170 MOZ_ASSERT(NS_SUCCEEDED(rv
));
172 aValidationURL
.Assign(NS_ConvertUTF8toUTF16(utf8href
));
175 void MerchantValidationEvent::GetMethodName(nsAString
& aMethodName
) {
176 aMethodName
.Assign(mMethodName
);
179 void MerchantValidationEvent::SetMethodName(const nsAString
& aMethodName
) {
180 mMethodName
.Assign(aMethodName
);
183 MerchantValidationEvent::~MerchantValidationEvent() = default;
185 JSObject
* MerchantValidationEvent::WrapObjectInternal(
186 JSContext
* aCx
, JS::Handle
<JSObject
*> aGivenProto
) {
187 return MerchantValidationEvent_Binding::Wrap(aCx
, this, aGivenProto
);
190 } // namespace mozilla::dom