fune/browser/components/payments/res/paymentRequest.js
prathiksha 5f702de150 Bug 1462779 - Auto-select appropriate addresses in select dropdowns in on-boarding forms. r=MattN
MozReview-Commit-ID: 5Lm3djwSeuG

--HG--
extra : rebase_source : 1d2ee6aab4d5ee276dadf7f563911cc5e6fd4070
2018-05-23 16:24:58 -07:00

262 lines
7.6 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/. */
/**
* Loaded in the unprivileged frame of each payment dialog.
*
* Communicates with privileged code via DOM Events.
*/
/* import-globals-from unprivileged-fallbacks.js */
var paymentRequest = {
domReadyPromise: null,
init() {
// listen to content
window.addEventListener("paymentChromeToContent", this);
window.addEventListener("keydown", this);
this.domReadyPromise = new Promise(function dcl(resolve) {
window.addEventListener("DOMContentLoaded", resolve, {once: true});
}).then(this.handleEvent.bind(this));
// This scope is now ready to listen to the initialization data
this.sendMessageToChrome("initializeRequest");
},
handleEvent(event) {
switch (event.type) {
case "DOMContentLoaded": {
this.onPaymentRequestLoad();
break;
}
case "keydown": {
if (event.code != "KeyD" || !event.altKey || !event.ctrlKey) {
break;
}
this.toggleDebuggingConsole();
break;
}
case "unload": {
this.onPaymentRequestUnload();
break;
}
case "paymentChromeToContent": {
this.onChromeToContent(event);
break;
}
default: {
throw new Error("Unexpected event type");
}
}
},
sendMessageToChrome(messageType, detail = {}) {
log.debug("sendMessageToChrome:", messageType, detail);
let event = new CustomEvent("paymentContentToChrome", {
bubbles: true,
detail: Object.assign({
messageType,
}, detail),
});
document.dispatchEvent(event);
},
toggleDebuggingConsole() {
let debuggingConsole = document.getElementById("debugging-console");
if (debuggingConsole.hidden && !debuggingConsole.src) {
debuggingConsole.src = "debugging.html";
}
debuggingConsole.hidden = !debuggingConsole.hidden;
},
onChromeToContent({detail}) {
let {messageType} = detail;
log.debug("onChromeToContent:", messageType);
switch (messageType) {
case "responseSent": {
document.querySelector("payment-dialog").requestStore.setState({
changesPrevented: true,
completionState: "processing",
});
break;
}
case "showPaymentRequest": {
this.onShowPaymentRequest(detail);
break;
}
case "updateState": {
document.querySelector("payment-dialog").setStateFromParent(detail);
break;
}
}
},
onPaymentRequestLoad() {
log.debug("onPaymentRequestLoad");
window.addEventListener("unload", this, {once: true});
this.sendMessageToChrome("paymentDialogReady");
// Automatically show the debugging console if loaded with a truthy `debug` query parameter.
if (new URLSearchParams(location.search).get("debug")) {
this.toggleDebuggingConsole();
}
},
async onShowPaymentRequest(detail) {
// Handle getting called before the DOM is ready.
log.debug("onShowPaymentRequest:", detail);
await this.domReadyPromise;
log.debug("onShowPaymentRequest: domReadyPromise resolved");
log.debug("onShowPaymentRequest, isPrivate?", detail.isPrivate);
let paymentDialog = document.querySelector("payment-dialog");
let hasSavedAddresses = Object.keys(detail.savedAddresses).length != 0;
let hasSavedCards = Object.keys(detail.savedBasicCards).length != 0;
let shippingRequested = detail.request.paymentOptions.requestShipping;
let state = {
request: detail.request,
savedAddresses: detail.savedAddresses,
savedBasicCards: detail.savedBasicCards,
isPrivate: detail.isPrivate,
page: {
id: "payment-summary",
},
};
// Onboarding wizard flow.
if (!hasSavedAddresses && (shippingRequested || !hasSavedCards)) {
state.page = {
id: "address-page",
onboardingWizard: true,
};
state["address-page"] = {
addressFields: null,
guid: null,
};
if (shippingRequested) {
Object.assign(state["address-page"], {
title: paymentDialog.dataset.shippingAddressTitleAdd,
});
state.page.selectedStateKey = ["selectedShippingAddress"];
} else {
Object.assign(state["address-page"], {
title: paymentDialog.dataset.billingAddressTitleAdd,
});
state.page.selectedStateKey = ["basic-card-page", "billingAddressGUID"];
}
} else if (!hasSavedCards) {
state.page = {
id: "basic-card-page",
onboardingWizard: true,
};
}
paymentDialog.setStateFromParent(state);
},
cancel() {
this.sendMessageToChrome("paymentCancel");
},
pay(data) {
this.sendMessageToChrome("pay", data);
},
changeShippingAddress(data) {
this.sendMessageToChrome("changeShippingAddress", data);
},
changeShippingOption(data) {
this.sendMessageToChrome("changeShippingOption", data);
},
/**
* Add/update an autofill storage record.
*
* If the the `guid` argument is provided update the record; otherwise, add it.
* @param {string} collectionName The autofill collection that record belongs to.
* @param {object} record The autofill record to add/update
* @param {string} [guid] The guid of the autofill record to update
*/
updateAutofillRecord(collectionName, record, guid, {
errorStateChange,
preserveOldProperties,
selectedStateKey,
successStateChange,
}) {
this.sendMessageToChrome("updateAutofillRecord", {
collectionName,
guid,
record,
errorStateChange,
preserveOldProperties,
selectedStateKey,
successStateChange,
});
},
/**
* @param {object} state object representing the UI state
* @param {string} methodID (GUID) uniquely identifying the selected payment method
* @returns {object?} the applicable modifier for the payment method
*/
getModifierForPaymentMethod(state, methodID) {
let method = state.savedBasicCards[methodID] || null;
if (method && method.methodName !== "basic-card") {
throw new Error(`${method.methodName} (${methodID}) is not a supported payment method`);
}
let modifiers = state.request.paymentDetails.modifiers;
if (!modifiers || !modifiers.length) {
return null;
}
let modifier = modifiers.find(m => {
// take the first matching modifier
// TODO (bug 1429198): match on supportedTypes and supportedNetworks
return m.supportedMethods == "basic-card";
});
return modifier || null;
},
/**
* @param {object} state object representing the UI state
* @returns {object} in the shape of `nsIPaymentItem` representing the total
* that applies to the selected payment method.
*/
getTotalItem(state) {
let methodID = state.selectedPaymentCard;
if (methodID) {
let modifier = paymentRequest.getModifierForPaymentMethod(state, methodID);
if (modifier && modifier.hasOwnProperty("total")) {
return modifier.total;
}
}
return state.request.paymentDetails.totalItem;
},
onPaymentRequestUnload() {
// remove listeners that may be used multiple times here
window.removeEventListener("paymentChromeToContent", this);
},
getAddresses(state) {
let addresses = Object.assign({}, state.savedAddresses, state.tempAddresses);
return addresses;
},
getBasicCards(state) {
let cards = Object.assign({}, state.savedBasicCards, state.tempBasicCards);
return cards;
},
};
paymentRequest.init();
export default paymentRequest;