forked from mirrors/gecko-dev
Differential Revision: https://phabricator.services.mozilla.com/D7473 --HG-- extra : moz-landing-system : lando
612 lines
16 KiB
JavaScript
612 lines
16 KiB
JavaScript
/* 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/. */
|
|
|
|
const paymentDialog = window.parent.document.querySelector("payment-dialog");
|
|
// The requestStore should be manipulated for most changes but autofill storage changes
|
|
// happen through setStateFromParent which includes some consistency checks.
|
|
const requestStore = paymentDialog.requestStore;
|
|
|
|
// keep the payment options checkboxes in sync w. actual state
|
|
const paymentOptionsUpdater = {
|
|
stateChangeCallback(state) {
|
|
this.render(state);
|
|
},
|
|
render(state) {
|
|
let {
|
|
completeStatus,
|
|
paymentOptions,
|
|
} = state.request;
|
|
|
|
document.getElementById("setChangesPrevented").checked = state.changesPrevented;
|
|
|
|
let paymentOptionInputs = document.querySelectorAll("#paymentOptions input[type='checkbox']");
|
|
for (let input of paymentOptionInputs) {
|
|
if (paymentOptions.hasOwnProperty(input.name)) {
|
|
input.checked = paymentOptions[input.name];
|
|
}
|
|
}
|
|
|
|
let completeStatusInputs = document
|
|
.querySelectorAll("input[type='radio'][name='setCompleteStatus']");
|
|
for (let input of completeStatusInputs) {
|
|
input.checked = input.value == completeStatus;
|
|
}
|
|
},
|
|
};
|
|
|
|
let REQUEST_1 = {
|
|
tabId: 9,
|
|
topLevelPrincipal: {URI: {displayHost: "debugging.example.com"}},
|
|
requestId: "3797081f-a96b-c34b-a58b-1083c6e66e25",
|
|
completeStatus: "",
|
|
paymentMethods: [],
|
|
paymentDetails: {
|
|
id: "",
|
|
totalItem: {label: "Demo total", amount: {currency: "EUR", value: "1.00"}, pending: false},
|
|
displayItems: [
|
|
{
|
|
label: "Square",
|
|
amount: {
|
|
currency: "USD",
|
|
value: "5",
|
|
},
|
|
},
|
|
],
|
|
payer: {},
|
|
paymentMethod: {},
|
|
shippingAddressErrors: {},
|
|
shippingOptions: [
|
|
{
|
|
id: "std",
|
|
label: "Standard (3-5 business days)",
|
|
amount: {
|
|
currency: "USD",
|
|
value: 10,
|
|
},
|
|
selected: false,
|
|
},
|
|
{
|
|
id: "super-slow",
|
|
// Long to test truncation
|
|
label: "Ssssssssuuuuuuuuupppppeeeeeeerrrrr sssssllllllloooooowwwwww",
|
|
amount: {
|
|
currency: "USD",
|
|
value: 1.50,
|
|
},
|
|
selected: true,
|
|
},
|
|
],
|
|
modifiers: null,
|
|
error: "",
|
|
},
|
|
paymentOptions: {
|
|
requestPayerName: true,
|
|
requestPayerEmail: false,
|
|
requestPayerPhone: false,
|
|
requestShipping: true,
|
|
shippingType: "shipping",
|
|
},
|
|
shippingOption: "std",
|
|
};
|
|
|
|
let REQUEST_2 = {
|
|
tabId: 9,
|
|
topLevelPrincipal: {URI: {displayHost: "example.com"}},
|
|
requestId: "3797081f-a96b-c34b-a58b-1083c6e66e25",
|
|
completeStatus: "",
|
|
paymentMethods: [
|
|
{
|
|
"supportedMethods": "basic-card",
|
|
"data": {
|
|
"supportedNetworks": [
|
|
"amex",
|
|
"discover",
|
|
"mastercard",
|
|
"visa",
|
|
],
|
|
},
|
|
},
|
|
],
|
|
paymentDetails: {
|
|
id: "",
|
|
totalItem: {label: "", amount: {currency: "CAD", value: "25.75"}, pending: false},
|
|
displayItems: [
|
|
{
|
|
label: "Triangle",
|
|
amount: {
|
|
currency: "CAD",
|
|
value: "3",
|
|
},
|
|
},
|
|
{
|
|
label: "Circle",
|
|
amount: {
|
|
currency: "EUR",
|
|
value: "10.50",
|
|
},
|
|
},
|
|
{
|
|
label: "Tax",
|
|
type: "tax",
|
|
amount: {
|
|
currency: "USD",
|
|
value: "1.50",
|
|
},
|
|
},
|
|
],
|
|
payer: {},
|
|
paymentMethod: {},
|
|
shippingAddressErrors: {},
|
|
shippingOptions: [
|
|
{
|
|
id: "123",
|
|
label: "Fast (default)",
|
|
amount: {
|
|
currency: "USD",
|
|
value: 10,
|
|
},
|
|
selected: true,
|
|
},
|
|
{
|
|
id: "947",
|
|
label: "Slow",
|
|
amount: {
|
|
currency: "USD",
|
|
value: 1,
|
|
},
|
|
selected: false,
|
|
},
|
|
],
|
|
modifiers: [
|
|
{
|
|
supportedMethods: "basic-card",
|
|
total: {
|
|
label: "Total",
|
|
amount: {
|
|
currency: "CAD",
|
|
value: "28.75",
|
|
},
|
|
pending: false,
|
|
},
|
|
additionalDisplayItems: [
|
|
{
|
|
label: "Credit card fee",
|
|
amount: {
|
|
currency: "CAD",
|
|
value: "1.50",
|
|
},
|
|
},
|
|
],
|
|
data: {
|
|
supportedTypes: "credit",
|
|
},
|
|
},
|
|
],
|
|
error: "",
|
|
},
|
|
paymentOptions: {
|
|
requestPayerName: false,
|
|
requestPayerEmail: false,
|
|
requestPayerPhone: false,
|
|
requestShipping: true,
|
|
shippingType: "shipping",
|
|
},
|
|
shippingOption: "123",
|
|
};
|
|
|
|
let ADDRESSES_1 = {
|
|
"48bnds6854t": {
|
|
"address-level1": "MI",
|
|
"address-level2": "Some City",
|
|
"country": "US",
|
|
"email": "foo@bar.com",
|
|
"family-name": "Smith",
|
|
"given-name": "John",
|
|
"guid": "48bnds6854t",
|
|
"name": "John Smith",
|
|
"postal-code": "90210",
|
|
"street-address": "123 Sesame Street,\nApt 40",
|
|
"tel": "+1 519 555-5555",
|
|
},
|
|
"68gjdh354j": {
|
|
"additional-name": "Z.",
|
|
"address-level1": "CA",
|
|
"address-level2": "Mountain View",
|
|
"country": "US",
|
|
"family-name": "Doe",
|
|
"given-name": "Jane",
|
|
"guid": "68gjdh354j",
|
|
"name": "Jane Z. Doe",
|
|
"postal-code": "94041",
|
|
"street-address": "P.O. Box 123",
|
|
"tel": "+1 650 555-5555",
|
|
},
|
|
"abcde12345": {
|
|
"address-level2": "Mountain View",
|
|
"country": "US",
|
|
"family-name": "Fields",
|
|
"given-name": "Mrs.",
|
|
"guid": "abcde12345",
|
|
"name": "Mrs. Fields",
|
|
},
|
|
"german1": {
|
|
"additional-name": "Y.",
|
|
"address-level1": "",
|
|
"address-level2": "Berlin",
|
|
"country": "DE",
|
|
"email": "de@example.com",
|
|
"family-name": "Mouse",
|
|
"given-name": "Anon",
|
|
"guid": "german1",
|
|
"name": "Anon Y. Mouse",
|
|
"organization": "Mozilla",
|
|
"postal-code": "10997",
|
|
"street-address": "Schlesische Str. 27",
|
|
"tel": "+49 30 983333002",
|
|
},
|
|
"missing-country": {
|
|
"address-level1": "ON",
|
|
"address-level2": "Toronto",
|
|
"family-name": "Bogard",
|
|
"given-name": "Kristin",
|
|
"guid": "missing-country",
|
|
"name": "Kristin Bogard",
|
|
"postal-code": "H0H 0H0",
|
|
"street-address": "123 Yonge Street\nSuite 2300",
|
|
"tel": "+1 416 555-5555",
|
|
},
|
|
};
|
|
|
|
let DUPED_ADDRESSES = {
|
|
"a9e830667189": {
|
|
"street-address": "Unit 1\n1505 Northeast Kentucky Industrial Parkway \n",
|
|
"address-level2": "Greenup",
|
|
"address-level1": "KY",
|
|
"postal-code": "41144",
|
|
"country": "US",
|
|
"email": "bob@example.com",
|
|
"family-name": "Smith",
|
|
"given-name": "Bob",
|
|
"guid": "a9e830667189",
|
|
"tel": "+19871234567",
|
|
"name": "Bob Smith",
|
|
},
|
|
"72a15aed206d": {
|
|
"street-address": "1 New St",
|
|
"address-level2": "York",
|
|
"address-level1": "SC",
|
|
"postal-code": "29745",
|
|
"country": "US",
|
|
"given-name": "Mary Sue",
|
|
"guid": "72a15aed206d",
|
|
"tel": "+19871234567",
|
|
"name": "Mary Sue",
|
|
"address-line1": "1 New St",
|
|
},
|
|
"2b4dce0fbc1f": {
|
|
"street-address": "123 Park St",
|
|
"address-level2": "Springfield",
|
|
"address-level1": "OR",
|
|
"postal-code": "97403",
|
|
"country": "US",
|
|
"email": "rita@foo.com",
|
|
"family-name": "Foo",
|
|
"given-name": "Rita",
|
|
"guid": "2b4dce0fbc1f",
|
|
"name": "Rita Foo",
|
|
"address-line1": "123 Park St",
|
|
},
|
|
"46b2635a5b26": {
|
|
"street-address": "432 Another St",
|
|
"address-level2": "Springfield",
|
|
"address-level1": "OR",
|
|
"postal-code": "97402",
|
|
"country": "US",
|
|
"email": "rita@foo.com",
|
|
"family-name": "Foo",
|
|
"given-name": "Rita",
|
|
"guid": "46b2635a5b26",
|
|
"name": "Rita Foo",
|
|
"address-line1": "432 Another St",
|
|
},
|
|
};
|
|
|
|
let BASIC_CARDS_1 = {
|
|
"53f9d009aed2": {
|
|
billingAddressGUID: "68gjdh354j",
|
|
methodName: "basic-card",
|
|
"cc-number": "************5461",
|
|
"guid": "53f9d009aed2",
|
|
"version": 1,
|
|
"timeCreated": 1505240896213,
|
|
"timeLastModified": 1515609524588,
|
|
"timeLastUsed": 0,
|
|
"timesUsed": 0,
|
|
"cc-name": "John Smith",
|
|
"cc-exp-month": 6,
|
|
"cc-exp-year": 2024,
|
|
"cc-type": "visa",
|
|
"cc-given-name": "John",
|
|
"cc-additional-name": "",
|
|
"cc-family-name": "Smith",
|
|
"cc-exp": "2024-06",
|
|
},
|
|
"9h5d4h6f4d1s": {
|
|
methodName: "basic-card",
|
|
"cc-number": "************0954",
|
|
"guid": "9h5d4h6f4d1s",
|
|
"version": 1,
|
|
"timeCreated": 1517890536491,
|
|
"timeLastModified": 1517890564518,
|
|
"timeLastUsed": 0,
|
|
"timesUsed": 0,
|
|
"cc-name": "Jane Doe",
|
|
"cc-exp-month": 5,
|
|
"cc-exp-year": 2023,
|
|
"cc-type": "mastercard",
|
|
"cc-given-name": "Jane",
|
|
"cc-additional-name": "",
|
|
"cc-family-name": "Doe",
|
|
"cc-exp": "2023-05",
|
|
},
|
|
"123456789abc": {
|
|
methodName: "basic-card",
|
|
"cc-number": "************1234",
|
|
"guid": "123456789abc",
|
|
"version": 1,
|
|
"timeCreated": 1517890536491,
|
|
"timeLastModified": 1517890564518,
|
|
"timeLastUsed": 0,
|
|
"timesUsed": 0,
|
|
"cc-name": "Jane Fields",
|
|
"cc-given-name": "Jane",
|
|
"cc-additional-name": "",
|
|
"cc-family-name": "Fields",
|
|
"cc-type": "discover",
|
|
},
|
|
"amex-card": {
|
|
methodName: "basic-card",
|
|
billingAddressGUID: "68gjdh354j",
|
|
"cc-number": "************1941",
|
|
"guid": "amex-card",
|
|
"version": 1,
|
|
"timeCreated": 1517890536491,
|
|
"timeLastModified": 1517890564518,
|
|
"timeLastUsed": 0,
|
|
"timesUsed": 0,
|
|
"cc-name": "Capt America",
|
|
"cc-given-name": "Capt",
|
|
"cc-additional-name": "",
|
|
"cc-family-name": "America",
|
|
"cc-type": "amex",
|
|
"cc-exp-month": 6,
|
|
"cc-exp-year": 2023,
|
|
"cc-exp": "2023-06",
|
|
},
|
|
"missing-cc-name": {
|
|
methodName: "basic-card",
|
|
"cc-number": "************8563",
|
|
"guid": "missing-cc-name",
|
|
"version": 1,
|
|
"timeCreated": 1517890536491,
|
|
"timeLastModified": 1517890564518,
|
|
"timeLastUsed": 0,
|
|
"timesUsed": 0,
|
|
"cc-exp-month": 8,
|
|
"cc-exp-year": 2024,
|
|
"cc-exp": "2024-08",
|
|
},
|
|
};
|
|
|
|
let buttonActions = {
|
|
debugFrame() {
|
|
let event = new CustomEvent("paymentContentToChrome", {
|
|
bubbles: true,
|
|
detail: {
|
|
messageType: "debugFrame",
|
|
},
|
|
});
|
|
document.dispatchEvent(event);
|
|
},
|
|
|
|
delete1Address() {
|
|
let savedAddresses = Object.assign({}, requestStore.getState().savedAddresses);
|
|
delete savedAddresses[Object.keys(savedAddresses)[0]];
|
|
// Use setStateFromParent since it ensures there is no dangling
|
|
// `selectedShippingAddress` foreign key (FK) reference.
|
|
paymentDialog.setStateFromParent({
|
|
savedAddresses,
|
|
});
|
|
},
|
|
|
|
delete1Card() {
|
|
let savedBasicCards = Object.assign({}, requestStore.getState().savedBasicCards);
|
|
delete savedBasicCards[Object.keys(savedBasicCards)[0]];
|
|
// Use setStateFromParent since it ensures there is no dangling
|
|
// `selectedPaymentCard` foreign key (FK) reference.
|
|
paymentDialog.setStateFromParent({
|
|
savedBasicCards,
|
|
});
|
|
},
|
|
|
|
logState() {
|
|
let state = requestStore.getState();
|
|
// eslint-disable-next-line no-console
|
|
console.log(state);
|
|
dump(`${JSON.stringify(state, null, 2)}\n`);
|
|
},
|
|
|
|
refresh() {
|
|
window.parent.location.reload(true);
|
|
},
|
|
|
|
rerender() {
|
|
requestStore.setState({});
|
|
},
|
|
|
|
saveVisibleForm() {
|
|
// Bypasses field validation which is useful to test error handling.
|
|
paymentDialog.querySelector("#main-container > .page:not([hidden])").saveRecord();
|
|
},
|
|
|
|
setAddresses1() {
|
|
paymentDialog.setStateFromParent({savedAddresses: ADDRESSES_1});
|
|
},
|
|
|
|
setDupesAddresses() {
|
|
paymentDialog.setStateFromParent({savedAddresses: DUPED_ADDRESSES});
|
|
},
|
|
|
|
setBasicCards1() {
|
|
paymentDialog.setStateFromParent({savedBasicCards: BASIC_CARDS_1});
|
|
},
|
|
|
|
setBasicCardErrors() {
|
|
let request = Object.assign({}, requestStore.getState().request);
|
|
request.paymentDetails = Object.assign({}, requestStore.getState().request.paymentDetails);
|
|
request.paymentDetails.paymentMethod = {
|
|
cardNumber: "",
|
|
cardholderName: "",
|
|
cardSecurityCode: "",
|
|
expiryMonth: "",
|
|
expiryYear: "",
|
|
billingAddress: {
|
|
addressLine: "Can only buy from ROADS, not DRIVES, BOULEVARDS, or STREETS",
|
|
city: "Can only buy from CITIES, not TOWNSHIPS or VILLAGES",
|
|
country: "Can only buy from US, not CA",
|
|
organization: "Can only buy from CORPORATIONS, not CONSORTIUMS",
|
|
phone: "Only allowed to buy from area codes that start with 9",
|
|
postalCode: "Only allowed to buy from postalCodes that start with 0",
|
|
recipient: "Can only buy from names that start with J",
|
|
region: "Can only buy from regions that start with M",
|
|
},
|
|
};
|
|
requestStore.setState({
|
|
request,
|
|
});
|
|
},
|
|
|
|
|
|
setChangesPrevented(evt) {
|
|
requestStore.setState({
|
|
changesPrevented: evt.target.checked,
|
|
});
|
|
},
|
|
|
|
setCompleteStatus() {
|
|
let input = document.querySelector("[name='setCompleteStatus']:checked");
|
|
let completeStatus = input.value;
|
|
let request = requestStore.getState().request;
|
|
paymentDialog.setStateFromParent({
|
|
request: Object.assign({}, request, { completeStatus }),
|
|
});
|
|
},
|
|
|
|
setPayerErrors() {
|
|
let request = Object.assign({}, requestStore.getState().request);
|
|
request.paymentDetails = Object.assign({}, requestStore.getState().request.paymentDetails);
|
|
request.paymentDetails.payer = {
|
|
email: "Only @mozilla.com emails are supported",
|
|
name: "Payer name must start with M",
|
|
phone: "Payer area codes must start with 1",
|
|
};
|
|
requestStore.setState({
|
|
request,
|
|
});
|
|
},
|
|
|
|
setPaymentOptions() {
|
|
let options = {};
|
|
let checkboxes = document.querySelectorAll("#paymentOptions input[type='checkbox']");
|
|
for (let input of checkboxes) {
|
|
options[input.name] = input.checked;
|
|
}
|
|
let req = Object.assign({}, requestStore.getState().request, {
|
|
paymentOptions: options,
|
|
});
|
|
requestStore.setState({ request: req });
|
|
},
|
|
|
|
setRequest1() {
|
|
paymentDialog.setStateFromParent({request: REQUEST_1});
|
|
},
|
|
|
|
setRequest2() {
|
|
paymentDialog.setStateFromParent({request: REQUEST_2});
|
|
},
|
|
|
|
setRequestPayerName() {
|
|
buttonActions.setPaymentOptions();
|
|
},
|
|
setRequestPayerEmail() {
|
|
buttonActions.setPaymentOptions();
|
|
},
|
|
setRequestPayerPhone() {
|
|
buttonActions.setPaymentOptions();
|
|
},
|
|
setRequestShipping() {
|
|
buttonActions.setPaymentOptions();
|
|
},
|
|
|
|
setShippingError() {
|
|
let request = Object.assign({}, requestStore.getState().request);
|
|
request.paymentDetails = Object.assign({}, requestStore.getState().request.paymentDetails);
|
|
request.paymentDetails.error = "Shipping Error!";
|
|
request.paymentDetails.shippingOptions = [];
|
|
requestStore.setState({
|
|
request,
|
|
});
|
|
},
|
|
|
|
setShippingAddressErrors() {
|
|
let request = Object.assign({}, requestStore.getState().request);
|
|
request.paymentDetails = Object.assign({}, requestStore.getState().request.paymentDetails);
|
|
request.paymentDetails.shippingAddressErrors = {
|
|
addressLine: "Can only ship to ROADS, not DRIVES, BOULEVARDS, or STREETS",
|
|
city: "Can only ship to CITIES, not TOWNSHIPS or VILLAGES",
|
|
country: "Can only ship to USA, not CA",
|
|
organization: "Can only ship to CORPORATIONS, not CONSORTIUMS",
|
|
phone: "Only allowed to ship to area codes that start with 9",
|
|
postalCode: "Only allowed to ship to postalCodes that start with 0",
|
|
recipient: "Can only ship to names that start with J",
|
|
region: "Can only ship to regions that start with M",
|
|
};
|
|
requestStore.setState({
|
|
request,
|
|
});
|
|
},
|
|
|
|
toggleDirectionality() {
|
|
let body = paymentDialog.ownerDocument.body;
|
|
body.dir = body.dir == "rtl" ? "ltr" : "rtl";
|
|
},
|
|
|
|
toggleBranding() {
|
|
for (let container of paymentDialog.querySelectorAll("accepted-cards")) {
|
|
container.classList.toggle("branded");
|
|
}
|
|
},
|
|
};
|
|
|
|
window.addEventListener("click", function onButtonClick(evt) {
|
|
let id = evt.target.id || evt.target.name;
|
|
if (!id || typeof(buttonActions[id]) != "function") {
|
|
return;
|
|
}
|
|
|
|
buttonActions[id](evt);
|
|
});
|
|
|
|
window.addEventListener("DOMContentLoaded", function onDCL() {
|
|
if (window.location.protocol == "resource:") {
|
|
// Only show the debug frame button if we're running from a resource URI
|
|
// so it doesn't show during development over file: or http: since it won't work.
|
|
// Note that the button still won't work if resource://payments/paymentRequest.xhtml
|
|
// is manually loaded in a tab but will be shown.
|
|
document.getElementById("debugFrame").hidden = false;
|
|
}
|
|
|
|
requestStore.subscribe(paymentOptionsUpdater);
|
|
paymentOptionsUpdater.render(requestStore.getState());
|
|
});
|