Merge mozilla-central to autoland on a CLOSED TREE
[gecko.git] / dom / payments / MerchantValidationEvent.cpp
blobcd1c8f1800b7d9394aee18b0c21d5ba1b335cc51
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"
8 #include "nsNetCID.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"
14 #include "nsIURI.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);
49 if (aRv.Failed()) {
50 return nullptr;
52 e->SetTrusted(trusted);
53 e->SetComposed(aEventInitDict.mComposed);
54 return e.forget();
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,
62 aRv);
63 if (aRv.Failed()) {
64 return;
67 SetMethodName(aEventInitDict.mMethodName);
68 nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(GetParentObject());
69 auto doc = window->GetExtantDoc();
70 if (!doc) {
71 aRv.ThrowAbortError("The owner document does not exist");
72 return;
75 Result<OwningNonNull<nsIURI>, nsresult> rv =
76 doc->ResolveWithBaseURI(aEventInitDict.mValidationURL);
77 if (rv.isErr()) {
78 aRv.ThrowTypeError("validationURL cannot be parsed");
79 return;
81 mValidationURL = rv.unwrap();
84 MerchantValidationEvent::MerchantValidationEvent(EventTarget* aOwner)
85 : Event(aOwner, nullptr, nullptr), mWaitForUpdate(false) {
86 MOZ_ASSERT(aOwner);
89 void MerchantValidationEvent::ResolvedCallback(JSContext* aCx,
90 JS::Handle<JS::Value> aValue,
91 ErrorResult& aRv) {
92 MOZ_ASSERT(aCx);
93 MOZ_ASSERT(mRequest);
95 if (!mWaitForUpdate) {
96 return;
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.
108 ErrorResult result;
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,
117 ErrorResult& aRv) {
118 MOZ_ASSERT(mRequest);
119 if (!mWaitForUpdate) {
120 return;
122 mWaitForUpdate = false;
123 ErrorResult result;
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) {
131 if (!IsTrusted()) {
132 aRv.ThrowInvalidStateError("Called on an untrusted event");
133 return;
136 MOZ_ASSERT(mRequest);
138 if (mWaitForUpdate) {
139 aRv.ThrowInvalidStateError(
140 "The MerchantValidationEvent is waiting for update");
141 return;
144 if (!mRequest->ReadyForUpdate()) {
145 aRv.ThrowInvalidStateError(
146 "The PaymentRequest state is not eInteractive or the PaymentRequest is "
147 "updating");
148 return;
151 aPromise.AppendNativeHandler(this);
153 StopPropagation();
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);
164 mRequest = aRequest;
167 void MerchantValidationEvent::GetValidationURL(nsAString& aValidationURL) {
168 nsAutoCString utf8href;
169 nsresult rv = mValidationURL->GetSpec(utf8href);
170 MOZ_ASSERT(NS_SUCCEEDED(rv));
171 Unused << 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