Bug 1477117 - Part 3 - dispatch the PaymentMethodChangeEvent. r=baku
☠☠ backed out by 77c14850b8c7 ☠ ☠
authorEden Chuang <echuang@mozilla.com>
Tue, 27 Nov 2018 11:17:33 +0100
changeset 507645 8ffc94b44c3eba19085b07ffefaf3bd27b504b01
parent 507644 ddaac333551453bf356459f068d7b0899a8203ed
child 507646 3b473ca68a5777d754b2a9f79275497309eee9fb
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1477117
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1477117 - Part 3 - dispatch the PaymentMethodChangeEvent. r=baku Save the changing method information in PaymentMethodChangeEvent and dispatch it.
dom/payments/PaymentMethodChangeEvent.cpp
dom/payments/PaymentMethodChangeEvent.h
dom/payments/PaymentRequest.cpp
dom/payments/PaymentRequestUpdateEvent.h
dom/payments/PaymentResponse.h
--- a/dom/payments/PaymentMethodChangeEvent.cpp
+++ b/dom/payments/PaymentMethodChangeEvent.cpp
@@ -1,35 +1,33 @@
 /* -*- 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/. */
 
+#include "BasicCardPayment.h"
 #include "mozilla/dom/PaymentMethodChangeEvent.h"
 #include "mozilla/dom/PaymentRequestUpdateEvent.h"
-#include "mozilla/HoldDropJSObjects.h"
+#include "PaymentRequestUtils.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(PaymentMethodChangeEvent)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PaymentMethodChangeEvent,
                                                 PaymentRequestUpdateEvent)
-  tmp->mMethodDetails = nullptr;
-  mozilla::DropJSObjects(this);
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PaymentMethodChangeEvent,
                                                   PaymentRequestUpdateEvent)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(PaymentMethodChangeEvent,
                                                PaymentRequestUpdateEvent)
-  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mMethodDetails)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_ADDREF_INHERITED(PaymentMethodChangeEvent, PaymentRequestUpdateEvent)
 NS_IMPL_RELEASE_INHERITED(PaymentMethodChangeEvent, PaymentRequestUpdateEvent)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PaymentMethodChangeEvent)
 NS_INTERFACE_MAP_END_INHERITING(PaymentRequestUpdateEvent)
 
@@ -52,50 +50,159 @@ already_AddRefed<PaymentMethodChangeEven
 PaymentMethodChangeEvent::Constructor(
   const GlobalObject& aGlobal,
   const nsAString& aType,
   const PaymentMethodChangeEventInit& aEventInitDict,
   ErrorResult& aRv)
 {
   nsCOMPtr<mozilla::dom::EventTarget> owner =
     do_QueryInterface(aGlobal.GetAsSupports());
-  return Constructor(owner, aType, aEventInitDict);
+  RefPtr<PaymentMethodChangeEvent> event = Constructor(owner, aType, aEventInitDict);
+
+  if (!aEventInitDict.mMethodDetails) {
+    return event.forget();
+  }
+
+  ChangeDetails details;
+  RefPtr<BasicCardService> service = BasicCardService::GetService();
+  MOZ_ASSERT(service);
+  if (service->IsBasicCardPayment(aEventInitDict.mMethodName)) {
+    BasicCardChangeDetails methodDetails;
+    BasicCardDetails bcDetails;
+    JS::RootedValue value(aGlobal.Context(), JS::ObjectValue(*(aEventInitDict.mMethodDetails)));
+    if (!methodDetails.Init(aGlobal.Context(), value)) {
+      return event.forget();
+    } else {
+      if(methodDetails.mBillingAddress.WasPassed()) {
+        RefPtr<PaymentAddress> address = methodDetails.mBillingAddress.Value();
+        address->GetCountry(bcDetails.billingAddress.country);
+        address->GetAddressLine(bcDetails.billingAddress.addressLine);
+        address->GetCity(bcDetails.billingAddress.city);
+        address->GetRegion(bcDetails.billingAddress.region);
+        address->GetRegionCode(bcDetails.billingAddress.regionCode);
+        address->GetDependentLocality(bcDetails.billingAddress.dependentLocality);
+        address->GetPostalCode(bcDetails.billingAddress.postalCode);
+        address->GetSortingCode(bcDetails.billingAddress.sortingCode);
+        address->GetOrganization(bcDetails.billingAddress.organization);
+        address->GetRecipient(bcDetails.billingAddress.recipient);
+        address->GetPhone(bcDetails.billingAddress.phone);
+      }
+      details = bcDetails;
+    }
+  } else {
+    JS::RootedObject object(aGlobal.Context(), aEventInitDict.mMethodDetails);
+    nsAutoString serializedDetails;
+    nsresult rv = SerializeFromJSObject(aGlobal.Context(), object, serializedDetails);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return nullptr;
+    }
+    GeneralDetails gDetails;
+    gDetails.details = serializedDetails;
+    details = gDetails;
+  }
+  event->SetMethodDetails(details);
+
+  return event.forget();
 }
 
 PaymentMethodChangeEvent::PaymentMethodChangeEvent(EventTarget* aOwner)
   : PaymentRequestUpdateEvent(aOwner)
 {
   MOZ_ASSERT(aOwner);
-  mozilla::HoldJSObjects(this);
 }
 
 void
-PaymentMethodChangeEvent::init(
-  const PaymentMethodChangeEventInit& aEventInitDict)
+PaymentMethodChangeEvent::init(const PaymentMethodChangeEventInit& aEventInitDict)
 {
   mMethodName.Assign(aEventInitDict.mMethodName);
-  mMethodDetails = aEventInitDict.mMethodDetails;
 }
 
 void
 PaymentMethodChangeEvent::GetMethodName(nsAString& aMethodName)
 {
   aMethodName.Assign(mMethodName);
 }
 
 void
-PaymentMethodChangeEvent::GetMethodDetails(JSContext* cx,
-                                           JS::MutableHandle<JSObject*> retval)
+PaymentMethodChangeEvent::SetMethodName(const nsAString& aMethodName)
+{
+  mMethodName = aMethodName;
+}
+
+void
+PaymentMethodChangeEvent::GetMethodDetails(JSContext* aCx,
+                                           JS::MutableHandle<JSObject*> aRetVal)
 {
-  retval.set(mMethodDetails.get());
+  MOZ_ASSERT(aCx);
+  RefPtr<BasicCardService> service = BasicCardService::GetService();
+  MOZ_ASSERT(service);
+
+  aRetVal.set(nullptr);
+  switch(mMethodDetails.type()) {
+    case ChangeDetails::GeneralMethodDetails: {
+      const GeneralDetails& rawDetails = mMethodDetails.generalDetails();
+      DeserializeToJSObject(rawDetails.details, aCx, aRetVal);
+      break;
+    }
+    case ChangeDetails::BasicCardMethodDetails: {
+      const BasicCardDetails& rawDetails = mMethodDetails.basicCardDetails();
+      BasicCardChangeDetails basicCardDetails;
+      PaymentOptions options;
+      mRequest->GetOptions(options);
+      if (options.mRequestBillingAddress) {
+        if (!rawDetails.billingAddress.country.IsEmpty() ||
+            !rawDetails.billingAddress.addressLine.IsEmpty() ||
+            !rawDetails.billingAddress.region.IsEmpty() ||
+            !rawDetails.billingAddress.regionCode.IsEmpty() ||
+            !rawDetails.billingAddress.city.IsEmpty() ||
+            !rawDetails.billingAddress.dependentLocality.IsEmpty() ||
+            !rawDetails.billingAddress.postalCode.IsEmpty() ||
+            !rawDetails.billingAddress.sortingCode.IsEmpty() ||
+            !rawDetails.billingAddress.organization.IsEmpty() ||
+            !rawDetails.billingAddress.recipient.IsEmpty() ||
+            !rawDetails.billingAddress.phone.IsEmpty()) {
+          nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(GetParentObject());
+          basicCardDetails.mBillingAddress.Construct();
+          basicCardDetails.mBillingAddress.Value() =
+            new PaymentAddress(window,
+                               rawDetails.billingAddress.country,
+                               rawDetails.billingAddress.addressLine,
+                               rawDetails.billingAddress.region,
+                               rawDetails.billingAddress.regionCode,
+                               rawDetails.billingAddress.city,
+                               rawDetails.billingAddress.dependentLocality,
+                               rawDetails.billingAddress.postalCode,
+                               rawDetails.billingAddress.sortingCode,
+                               rawDetails.billingAddress.organization,
+                               rawDetails.billingAddress.recipient,
+                               rawDetails.billingAddress.phone);
+        }
+      }
+      MOZ_ASSERT(aCx);
+      JS::RootedValue value(aCx);
+      if (NS_WARN_IF(!basicCardDetails.ToObjectInternal(aCx, &value))) {
+        return;
+      }
+      aRetVal.set(&value.toObject());
+      break;
+    }
+    default: {
+      break;
+    }
+  }
+}
+
+void
+PaymentMethodChangeEvent::SetMethodDetails(const ChangeDetails& aMethodDetails)
+{
+  mMethodDetails = aMethodDetails;
 }
 
 PaymentMethodChangeEvent::~PaymentMethodChangeEvent()
 {
-  mozilla::DropJSObjects(this);
 }
 
 JSObject*
 PaymentMethodChangeEvent::WrapObjectInternal(JSContext* aCx,
                                              JS::Handle<JSObject*> aGivenProto)
 {
   return PaymentMethodChangeEvent_Binding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/payments/PaymentMethodChangeEvent.h
+++ b/dom/payments/PaymentMethodChangeEvent.h
@@ -37,24 +37,26 @@ public:
   // Called by WebIDL constructor
   static already_AddRefed<PaymentMethodChangeEvent> Constructor(
     const GlobalObject& aGlobal,
     const nsAString& aType,
     const PaymentMethodChangeEventInit& aEventInitDict,
     ErrorResult& aRv);
 
   void GetMethodName(nsAString& aMethodName);
+  void SetMethodName(const nsAString& aMethodName);
 
   void GetMethodDetails(JSContext* cx, JS::MutableHandle<JSObject*> retval);
+  void SetMethodDetails(const ChangeDetails& aMethodDetails);
 
 protected:
   void init(const PaymentMethodChangeEventInit& aEventInitDict);
   ~PaymentMethodChangeEvent();
 
 private:
-  JS::Heap<JSObject*> mMethodDetails;
+  ChangeDetails mMethodDetails;
   nsString mMethodName;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_PaymentMethodChangeEvent_h
--- a/dom/payments/PaymentRequest.cpp
+++ b/dom/payments/PaymentRequest.cpp
@@ -1042,18 +1042,33 @@ PaymentRequest::DispatchMerchantValidati
   return rv.StealNSResult();
 }
 
 nsresult
 PaymentRequest::DispatchPaymentMethodChangeEvent(const nsAString& aMethodName,
                                                  const ChangeDetails& aMethodDetails)
 {
   MOZ_ASSERT(ReadyForUpdate());
-  // TODO: create and dispatch a PaymentMethodChangeEvent
-  return NS_OK;
+
+  PaymentMethodChangeEventInit init;
+  init.mBubbles = false;
+  init.mCancelable = false;
+
+  RefPtr<PaymentMethodChangeEvent> event =
+    PaymentMethodChangeEvent::Constructor(this,
+                                          NS_LITERAL_STRING("paymentmethodchange"),
+                                          init);
+  event->SetTrusted(true);
+  event->SetMethodName(aMethodName);
+  event->SetMethodDetails(aMethodDetails);
+  event->SetRequest(this);
+
+  ErrorResult rv;
+  DispatchEvent(*event, rv);
+  return rv.StealNSResult();
 }
 
 already_AddRefed<PaymentAddress>
 PaymentRequest::GetShippingAddress() const
 {
   RefPtr<PaymentAddress> address = mShippingAddress;
   return address.forget();
 }
--- a/dom/payments/PaymentRequestUpdateEvent.h
+++ b/dom/payments/PaymentRequestUpdateEvent.h
@@ -49,18 +49,16 @@ public:
               ErrorResult& aRv);
 
   void UpdateWith(Promise& aPromise, ErrorResult& aRv);
 
   void SetRequest(PaymentRequest* aRequest);
 
 protected:
   ~PaymentRequestUpdateEvent();
-
-private:
   // Indicating whether an updateWith()-initiated update is currently in progress.
   bool mWaitForUpdate;
   RefPtr<PaymentRequest> mRequest;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/payments/PaymentResponse.h
+++ b/dom/payments/PaymentResponse.h
@@ -80,17 +80,17 @@ public:
     return *this;
   }
   ResponseData& operator = (const BasicCardData& aBasicCardData) {
     mType = BasicCardResponse;
     mGeneralData = GeneralData();
     mBasicCardData = aBasicCardData;
     return *this;
   }
-  virtual ~ResponseData() = default;
+  ~ResponseData() = default;
 
   const Type& type() const { return mType; }
   const GeneralData& generalData() const { return mGeneralData; }
   const BasicCardData& basicCardData() const { return mBasicCardData;}
 private:
   Type mType;
   GeneralData mGeneralData;
   BasicCardData mBasicCardData;