mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-06 18:16:38 +08:00
♻️ Decouple init logic from global PPCP config
Allow Google Pay logic to initialize on pages that do not provide a global PayPalCommerceGateway object. Required to use CheckoutBootstrap to popuplate billing fields in continuation mode.
This commit is contained in:
parent
07c73985e3
commit
5b05458103
2 changed files with 83 additions and 34 deletions
|
@ -13,12 +13,34 @@ export class CheckoutBootstrap {
|
||||||
#storage;
|
#storage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {null|HTMLFormElement}
|
* @type {HTMLFormElement|null}
|
||||||
*/
|
*/
|
||||||
#checkoutForm = null;
|
#checkoutForm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {GooglePayStorage} storage
|
||||||
|
*/
|
||||||
constructor( storage ) {
|
constructor( storage ) {
|
||||||
this.#storage = storage;
|
this.#storage = storage;
|
||||||
|
this.#checkoutForm = CheckoutBootstrap.getCheckoutForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if the current page contains a checkout form.
|
||||||
|
*
|
||||||
|
* @return {boolean} True if a checkout form is present.
|
||||||
|
*/
|
||||||
|
static isPageWithCheckoutForm() {
|
||||||
|
return null !== CheckoutBootstrap.getCheckoutForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the WooCommerce checkout form element.
|
||||||
|
*
|
||||||
|
* @return {HTMLFormElement|null} The form, or null if not a checkout page.
|
||||||
|
*/
|
||||||
|
static getCheckoutForm() {
|
||||||
|
return document.querySelector( CHECKOUT_FORM_SELECTOR );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,37 +49,32 @@ export class CheckoutBootstrap {
|
||||||
* @return {HTMLFormElement|null} The form, or null if not a checkout page.
|
* @return {HTMLFormElement|null} The form, or null if not a checkout page.
|
||||||
*/
|
*/
|
||||||
get checkoutForm() {
|
get checkoutForm() {
|
||||||
if ( null === this.#checkoutForm ) {
|
|
||||||
this.#checkoutForm = document.querySelector(
|
|
||||||
CHECKOUT_FORM_SELECTOR
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.#checkoutForm;
|
return this.#checkoutForm;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates, if the current page contains a checkout form.
|
* Initializes the checkout process.
|
||||||
*
|
*
|
||||||
* @return {boolean} True, if a checkout form is present.
|
* @throws {Error} If called on a page without a checkout form.
|
||||||
*/
|
*/
|
||||||
get isPageWithCheckoutForm() {
|
|
||||||
return null !== this.checkoutForm;
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
if ( ! this.isPageWithCheckoutForm ) {
|
if ( ! this.#checkoutForm ) {
|
||||||
return;
|
throw new Error(
|
||||||
|
'Checkout form not found. Cannot initialize CheckoutBootstrap.'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#populateCheckoutFields();
|
this.#populateCheckoutFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates checkout fields with stored or customer data.
|
||||||
|
*/
|
||||||
#populateCheckoutFields() {
|
#populateCheckoutFields() {
|
||||||
const loggedInData = getWooCommerceCustomerDetails();
|
const loggedInData = getWooCommerceCustomerDetails();
|
||||||
|
|
||||||
// If customer is logged in, we use the details from the customer profile.
|
|
||||||
if ( loggedInData ) {
|
if ( loggedInData ) {
|
||||||
|
// If customer is logged in, we use the details from the customer profile.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,11 +85,17 @@ export class CheckoutBootstrap {
|
||||||
}
|
}
|
||||||
|
|
||||||
setPayerData( billingData, true );
|
setPayerData( billingData, true );
|
||||||
this.checkoutForm.addEventListener( 'submit', () =>
|
this.checkoutForm.addEventListener(
|
||||||
this.#onFormSubmit()
|
'submit',
|
||||||
|
this.#onFormSubmit.bind( this )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean-up when checkout form is submitted.
|
||||||
|
*
|
||||||
|
* Immediately removes the payer details from the localStorage.
|
||||||
|
*/
|
||||||
#onFormSubmit() {
|
#onFormSubmit() {
|
||||||
this.#storage.clearPayer();
|
this.#storage.clearPayer();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
|
/**
|
||||||
|
* Initialize the GooglePay module in the front end.
|
||||||
|
* In some cases, this module is loaded when the `window.PayPalCommerceGateway` object is not
|
||||||
|
* present. In that case, the page does not contain a Google Pay button, but some other logic
|
||||||
|
* that is related to Google Pay (e.g., the CheckoutBootstrap module)
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
*/
|
||||||
|
|
||||||
import { loadCustomScript } from '@paypal/paypal-js';
|
import { loadCustomScript } from '@paypal/paypal-js';
|
||||||
import { loadPaypalScript } from '../../../ppcp-button/resources/js/modules/Helper/ScriptLoading';
|
import { loadPaypalScript } from '../../../ppcp-button/resources/js/modules/Helper/ScriptLoading';
|
||||||
import GooglepayManager from './GooglepayManager';
|
import GooglepayManager from './GooglepayManager';
|
||||||
|
@ -5,31 +14,48 @@ import { setupButtonEvents } from '../../../ppcp-button/resources/js/modules/Hel
|
||||||
import { CheckoutBootstrap } from './ContextBootstrap/CheckoutBootstrap';
|
import { CheckoutBootstrap } from './ContextBootstrap/CheckoutBootstrap';
|
||||||
import moduleStorage from './Helper/GooglePayStorage';
|
import moduleStorage from './Helper/GooglePayStorage';
|
||||||
|
|
||||||
( function ( { buttonConfig, ppcpConfig } ) {
|
( function ( { buttonConfig, ppcpConfig = {} } ) {
|
||||||
const context = ppcpConfig.context;
|
const context = ppcpConfig.context;
|
||||||
|
|
||||||
let manager;
|
function bootstrapPayButton() {
|
||||||
|
if ( ! buttonConfig || ! ppcpConfig ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const bootstrap = function () {
|
const manager = new GooglepayManager( buttonConfig, ppcpConfig );
|
||||||
manager = new GooglepayManager( buttonConfig, ppcpConfig );
|
|
||||||
manager.init();
|
manager.init();
|
||||||
|
|
||||||
if ( 'continuation' === context || 'checkout' === context ) {
|
setupButtonEvents( function () {
|
||||||
const checkoutBootstap = new CheckoutBootstrap( moduleStorage );
|
|
||||||
|
|
||||||
checkoutBootstap.init();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
setupButtonEvents( function () {
|
|
||||||
if ( manager ) {
|
|
||||||
manager.reinit();
|
manager.reinit();
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
function bootstrapCheckout() {
|
||||||
|
if ( context && ! [ 'continuation', 'checkout' ].includes( context ) ) {
|
||||||
|
// Context must be missing/empty, or "continuation"/"checkout" to proceed.
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} );
|
if ( ! CheckoutBootstrap.isPageWithCheckoutForm() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkoutBootstrap = new CheckoutBootstrap( moduleStorage );
|
||||||
|
checkoutBootstrap.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
function bootstrap() {
|
||||||
|
bootstrapPayButton();
|
||||||
|
bootstrapCheckout();
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener( 'DOMContentLoaded', () => {
|
document.addEventListener( 'DOMContentLoaded', () => {
|
||||||
if ( ! buttonConfig || ! ppcpConfig ) {
|
if ( ! buttonConfig || ! ppcpConfig ) {
|
||||||
// No PayPal buttons present on this page.
|
/*
|
||||||
|
* No PayPal buttons present on this page, but maybe a bootstrap module needs to be
|
||||||
|
* initialized. Run bootstrap without trying to load an SDK or payment configuration.
|
||||||
|
*/
|
||||||
|
bootstrap();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue