/* 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/. */
import BasicCardOption from "../components/basic-card-option.js";
import CscInput from "../components/csc-input.js";
import HandleEventMixin from "../mixins/HandleEventMixin.js";
import RichPicker from "./rich-picker.js";
import paymentRequest from "../paymentRequest.js";
/* import-globals-from ../unprivileged-fallbacks.js */
/**
*
* Container around add/edit links and with
* listening to savedBasicCards.
*/
export default class PaymentMethodPicker extends HandleEventMixin(RichPicker) {
constructor() {
super();
this.dropdown.setAttribute("option-type", "basic-card-option");
this.securityCodeInput = new CscInput();
this.securityCodeInput.className = "security-code-container";
this.securityCodeInput.placeholder = this.dataset.cscPlaceholder;
this.securityCodeInput.backTooltip = this.dataset.cscBackTooltip;
this.securityCodeInput.frontTooltip = this.dataset.cscFrontTooltip;
this.securityCodeInput.addEventListener("change", this);
this.securityCodeInput.addEventListener("input", this);
}
connectedCallback() {
super.connectedCallback();
this.dropdown.after(this.securityCodeInput);
}
get fieldNames() {
let fieldNames = [...BasicCardOption.recordAttributes];
return fieldNames;
}
render(state) {
let basicCards = paymentRequest.getBasicCards(state);
let desiredOptions = [];
for (let [guid, basicCard] of Object.entries(basicCards)) {
let optionEl = this.dropdown.getOptionByValue(guid);
if (!optionEl) {
optionEl = document.createElement("option");
optionEl.value = guid;
}
for (let key of BasicCardOption.recordAttributes) {
let val = basicCard[key];
if (val) {
optionEl.setAttribute(key, val);
} else {
optionEl.removeAttribute(key);
}
}
optionEl.textContent = BasicCardOption.formatSingleLineLabel(basicCard);
desiredOptions.push(optionEl);
}
this.dropdown.popupBox.textContent = "";
for (let option of desiredOptions) {
this.dropdown.popupBox.appendChild(option);
}
// Update selectedness after the options are updated
let selectedPaymentCardGUID = state[this.selectedStateKey];
if (selectedPaymentCardGUID) {
this.dropdown.value = selectedPaymentCardGUID;
if (selectedPaymentCardGUID !== this.dropdown.value) {
throw new Error(
`The option ${selectedPaymentCardGUID} ` +
`does not exist in the payment method picker`
);
}
} else {
this.dropdown.value = "";
}
let securityCodeState = state[this.selectedStateKey + "SecurityCode"];
if (
securityCodeState &&
securityCodeState != this.securityCodeInput.value
) {
this.securityCodeInput.defaultValue = securityCodeState;
}
let selectedCardType =
(basicCards[selectedPaymentCardGUID] &&
basicCards[selectedPaymentCardGUID]["cc-type"]) ||
"";
this.securityCodeInput.cardType = selectedCardType;
super.render(state);
}
errorForSelectedOption(state) {
let superError = super.errorForSelectedOption(state);
if (superError) {
return superError;
}
let selectedOption = this.selectedOption;
if (!selectedOption) {
return "";
}
let basicCardMethod = state.request.paymentMethods.find(
method => method.supportedMethods == "basic-card"
);
let merchantNetworks =
basicCardMethod &&
basicCardMethod.data &&
basicCardMethod.data.supportedNetworks;
let acceptedNetworks =
merchantNetworks || PaymentDialogUtils.getCreditCardNetworks();
let selectedCard = paymentRequest.getBasicCards(state)[
selectedOption.value
];
let isSupported =
selectedCard["cc-type"] &&
acceptedNetworks.includes(selectedCard["cc-type"]);
return isSupported ? "" : this.dataset.invalidLabel;
}
get selectedStateKey() {
return this.getAttribute("selected-state-key");
}
onInput(event) {
this.onInputOrChange(event);
}
onChange(event) {
this.onInputOrChange(event);
}
onInputOrChange({ currentTarget }) {
let selectedKey = this.selectedStateKey;
let stateChange = {};
if (!selectedKey) {
return;
}
switch (currentTarget) {
case this.dropdown: {
stateChange[selectedKey] = this.dropdown.value;
break;
}
case this.securityCodeInput: {
stateChange[
selectedKey + "SecurityCode"
] = this.securityCodeInput.value;
break;
}
default: {
return;
}
}
this.requestStore.setState(stateChange);
}
onClick({ target }) {
let nextState = {
page: {
id: "basic-card-page",
},
"basic-card-page": {
selectedStateKey: this.selectedStateKey,
},
};
switch (target) {
case this.addLink: {
nextState["basic-card-page"].guid = null;
break;
}
case this.editLink: {
let state = this.requestStore.getState();
let selectedPaymentCardGUID = state[this.selectedStateKey];
nextState["basic-card-page"].guid = selectedPaymentCardGUID;
break;
}
default: {
throw new Error("Unexpected onClick");
}
}
this.requestStore.setState(nextState);
}
}
customElements.define("payment-method-picker", PaymentMethodPicker);