mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-05 08:59:14 +08:00
✨ New helper to monitor multistep checkout forms
The new script adds an interval to monitor the visibility of the “woocommerce-checkout-payment” element to initialize payment buttons with a delay, if needed.
This commit is contained in:
parent
167c2c6883
commit
25c5ef2e9e
2 changed files with 124 additions and 0 deletions
|
@ -17,6 +17,7 @@ import {
|
|||
import {setVisibleByClass} from "./modules/Helper/Hiding";
|
||||
import {isChangePaymentPage} from "./modules/Helper/Subscriptions";
|
||||
import FreeTrialHandler from "./modules/ActionHandler/FreeTrialHandler";
|
||||
import MultistepCheckoutHelper from "./modules/Helper/MultistepCheckoutHelper";
|
||||
import FormSaver from './modules/Helper/FormSaver';
|
||||
import FormValidator from "./modules/Helper/FormValidator";
|
||||
import {loadPaypalScript} from "./modules/Helper/ScriptLoading";
|
||||
|
@ -53,6 +54,8 @@ const bootstrap = () => {
|
|||
|
||||
const freeTrialHandler = new FreeTrialHandler(PayPalCommerceGateway, checkoutFormSelector, formSaver, formValidator, spinner, errorHandler);
|
||||
|
||||
new MultistepCheckoutHelper(checkoutFormSelector);
|
||||
|
||||
jQuery('form.woocommerce-checkout input').on('keydown', e => {
|
||||
if (e.key === 'Enter' && [
|
||||
PaymentMethods.PAYPAL,
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/**
|
||||
* The MultistepCheckoutHelper class ensures the initialization of payment buttons
|
||||
* on websites using a multistep checkout plugin. These plugins usually hide the
|
||||
* payment button on page load up and reveal it later using JS. During the
|
||||
* invisibility period of wrappers, some payment buttons fail to initialize,
|
||||
* so we wait for the payment element to be visible.
|
||||
*
|
||||
* @property {HTMLElement} form - Checkout form element.
|
||||
* @property {HTMLElement} triggerElement - Element, which visibility we need to detect.
|
||||
* @property {boolean} isVisible - Whether the triggerElement is visible.
|
||||
*/
|
||||
class MultistepCheckoutHelper {
|
||||
|
||||
/**
|
||||
* Configuration that defines the HTML selector for the component we are waiting to be visible.
|
||||
* @type {string}
|
||||
*/
|
||||
#triggerElementSelector = '.woocommerce-checkout-payment';
|
||||
|
||||
/**
|
||||
* Interval (in milliseconds) in which the visibility of the trigger element is checked.
|
||||
* @type {number}
|
||||
*/
|
||||
#intervalTime = 150;
|
||||
|
||||
/**
|
||||
* The interval ID returned by the setInterval() method.
|
||||
* @type {number|false}
|
||||
*/
|
||||
#intervalId;
|
||||
|
||||
/**
|
||||
* Selector passed to the constructor that identifies the checkout form
|
||||
* @type {string}
|
||||
*/
|
||||
#formSelector;
|
||||
|
||||
/**
|
||||
* @param {string} formSelector - Selector of the checkout form
|
||||
*/
|
||||
constructor(formSelector) {
|
||||
this.#formSelector = formSelector;
|
||||
this.#intervalId = false;
|
||||
|
||||
/*
|
||||
Start the visibility checker after a brief delay. This allows eventual multistep plugins to
|
||||
dynamically prepare the checkout page, so we can decide whether this helper is needed.
|
||||
*/
|
||||
setTimeout(() => {
|
||||
if (this.form && !this.isVisible) {
|
||||
this.start();
|
||||
}
|
||||
}, 250);
|
||||
}
|
||||
|
||||
/**
|
||||
* The checkout form element.
|
||||
* @returns {Element|null} - Form element or null.
|
||||
*/
|
||||
get form() {
|
||||
return document.querySelector(this.#formSelector);
|
||||
}
|
||||
|
||||
/**
|
||||
* The element which must be visible before payment buttons should be initialized.
|
||||
* @returns {Element|null} - Trigger element or null.
|
||||
*/
|
||||
get triggerElement() {
|
||||
return this.form?.querySelector(this.#triggerElementSelector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the visibility of the payment button wrapper.
|
||||
* @returns {boolean} - returns boolean value on the basis of visibility of element.
|
||||
*/
|
||||
get isVisible() {
|
||||
const box = this.triggerElement?.getBoundingClientRect();
|
||||
|
||||
return !!(box && box.width && box.height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the observation of the DOM, initiates monitoring the checkout form.
|
||||
* To ensure multiple calls to start don't create multiple intervals, we first call stop.
|
||||
*/
|
||||
start() {
|
||||
this.stop();
|
||||
this.#intervalId = setInterval(() => this.checkElement(), this.#intervalTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the observation of the checkout form.
|
||||
* Multiple calls to stop are safe as clearInterval doesn't throw if provided ID doesn't exist.
|
||||
*/
|
||||
stop() {
|
||||
if (this.#intervalId) {
|
||||
clearInterval(this.#intervalId);
|
||||
this.#intervalId = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the trigger element is visible.
|
||||
* If visible, it initialises the payment buttons and stops the observation.
|
||||
*/
|
||||
checkElement() {
|
||||
if (this.isVisible) {
|
||||
this.refreshButtons();
|
||||
this.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the payment buttons on the visibility of wrapper.
|
||||
*/
|
||||
refreshButtons() {
|
||||
document.dispatchEvent(new Event('ppcp_refresh_payment_buttons'));
|
||||
}
|
||||
}
|
||||
|
||||
export default MultistepCheckoutHelper;
|
Loading…
Add table
Add a link
Reference in a new issue