File "button.js"
Full Path: /home/siazco/grocery.siazco.se/wp-content/plugins/woocommerce-paypal-payments/modules/ppcp-button/resources/js/button.js
File size: 11.32 KB
MIME-type: text/x-java
Charset: utf-8
import MiniCartBootstap from './modules/ContextBootstrap/MiniCartBootstap';
import SingleProductBootstap from './modules/ContextBootstrap/SingleProductBootstap';
import CartBootstrap from './modules/ContextBootstrap/CartBootstap';
import CheckoutBootstap from './modules/ContextBootstrap/CheckoutBootstap';
import PayNowBootstrap from './modules/ContextBootstrap/PayNowBootstrap';
import Renderer from './modules/Renderer/Renderer';
import ErrorHandler from './modules/ErrorHandler';
import HostedFieldsRenderer from './modules/Renderer/HostedFieldsRenderer';
import CardFieldsRenderer from './modules/Renderer/CardFieldsRenderer';
import CardFieldsFreeTrialRenderer from './modules/Renderer/CardFieldsFreeTrialRenderer';
import MessageRenderer from './modules/Renderer/MessageRenderer';
import Spinner from './modules/Helper/Spinner';
import {
getCurrentPaymentMethod,
ORDER_BUTTON_SELECTOR,
PaymentMethods,
} from './modules/Helper/CheckoutMethodState';
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';
import buttonModuleWatcher from './modules/ButtonModuleWatcher';
import MessagesBootstrap from './modules/ContextBootstrap/MessagesBootstap';
import { apmButtonsInit } from './modules/Helper/ApmButtons';
// TODO: could be a good idea to have a separate spinner for each gateway,
// but I think we care mainly about the script loading, so one spinner should be enough.
const buttonsSpinner = new Spinner(
document.querySelector( '.ppc-button-wrapper' )
);
const cardsSpinner = new Spinner( '#ppcp-hosted-fields' );
const bootstrap = () => {
const checkoutFormSelector = 'form.woocommerce-checkout';
const context = PayPalCommerceGateway.context;
const errorHandler = new ErrorHandler(
PayPalCommerceGateway.labels.error.generic,
document.querySelector( checkoutFormSelector ) ??
document.querySelector( '.woocommerce-notices-wrapper' )
);
const spinner = new Spinner();
const formSaver = new FormSaver(
PayPalCommerceGateway.ajax.save_checkout_form.endpoint,
PayPalCommerceGateway.ajax.save_checkout_form.nonce
);
const formValidator =
PayPalCommerceGateway.early_checkout_validation_enabled
? new FormValidator(
PayPalCommerceGateway.ajax.validate_checkout.endpoint,
PayPalCommerceGateway.ajax.validate_checkout.nonce
)
: null;
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,
PaymentMethods.CARDS,
PaymentMethods.CARD_BUTTON,
].includes( getCurrentPaymentMethod() )
) {
e.preventDefault();
}
} );
const hasMessages = () => {
return (
PayPalCommerceGateway.messages.is_hidden === false &&
document.querySelector( PayPalCommerceGateway.messages.wrapper )
);
};
const doBasicCheckoutValidation = () => {
if ( PayPalCommerceGateway.basic_checkout_validation_enabled ) {
// A quick fix to get the errors about empty form fields before attempting PayPal order,
// it should solve #513 for most of the users, but it is not a proper solution.
// Currently it is disabled by default because a better solution is now implemented
// (see woocommerce_paypal_payments_basic_checkout_validation_enabled,
// woocommerce_paypal_payments_early_wc_checkout_validation_enabled filters).
const invalidFields = Array.from(
jQuery(
'form.woocommerce-checkout .validate-required.woocommerce-invalid:visible'
)
);
if ( invalidFields.length ) {
const billingFieldsContainer = document.querySelector(
'.woocommerce-billing-fields'
);
const shippingFieldsContainer = document.querySelector(
'.woocommerce-shipping-fields'
);
const nameMessageMap =
PayPalCommerceGateway.labels.error.required.elements;
const messages = invalidFields
.map( ( el ) => {
const name = el
.querySelector( '[name]' )
?.getAttribute( 'name' );
if ( name && name in nameMessageMap ) {
return nameMessageMap[ name ];
}
let label = el
.querySelector( 'label' )
.textContent.replaceAll( '*', '' )
.trim();
if ( billingFieldsContainer?.contains( el ) ) {
label =
PayPalCommerceGateway.labels.billing_field.replace(
'%s',
label
);
}
if ( shippingFieldsContainer?.contains( el ) ) {
label =
PayPalCommerceGateway.labels.shipping_field.replace(
'%s',
label
);
}
return PayPalCommerceGateway.labels.error.required.field.replace(
'%s',
`<strong>${ label }</strong>`
);
} )
.filter( ( s ) => s.length > 2 );
errorHandler.clear();
if ( messages.length ) {
errorHandler.messages( messages );
} else {
errorHandler.message(
PayPalCommerceGateway.labels.error.required.generic
);
}
return false;
}
}
return true;
};
const onCardFieldsBeforeSubmit = () => {
return doBasicCheckoutValidation();
};
const onSmartButtonClick = async ( data, actions ) => {
window.ppcpFundingSource = data.fundingSource;
const requiredFields = jQuery(
'form.woocommerce-checkout .validate-required:visible :input'
);
requiredFields.each( ( i, input ) => {
jQuery( input ).trigger( 'validate' );
} );
if ( ! doBasicCheckoutValidation() ) {
return actions.reject();
}
const form = document.querySelector( checkoutFormSelector );
if ( form ) {
jQuery( '#ppcp-funding-source-form-input' ).remove();
form.insertAdjacentHTML(
'beforeend',
`<input type="hidden" name="ppcp-funding-source" value="${ data.fundingSource }" id="ppcp-funding-source-form-input">`
);
}
const isFreeTrial = PayPalCommerceGateway.is_free_trial_cart;
if (
isFreeTrial &&
data.fundingSource !== 'card' &&
! PayPalCommerceGateway.subscription_plan_id &&
! PayPalCommerceGateway.vault_v3_enabled
) {
freeTrialHandler.handle();
return actions.reject();
}
if ( context === 'checkout' ) {
try {
await formSaver.save( form );
} catch ( error ) {
console.error( error );
}
}
};
const onSmartButtonsInit = () => {
jQuery( document ).trigger( 'ppcp-smart-buttons-init', this );
buttonsSpinner.unblock();
};
let creditCardRenderer = new HostedFieldsRenderer(
PayPalCommerceGateway,
errorHandler,
spinner
);
if ( typeof paypal.CardFields !== 'undefined' ) {
if (
PayPalCommerceGateway.is_free_trial_cart &&
PayPalCommerceGateway.user?.has_wc_card_payment_tokens !== true
) {
creditCardRenderer = new CardFieldsFreeTrialRenderer(
PayPalCommerceGateway,
errorHandler,
spinner
);
} else {
creditCardRenderer = new CardFieldsRenderer(
PayPalCommerceGateway,
errorHandler,
spinner,
onCardFieldsBeforeSubmit
);
}
}
const renderer = new Renderer(
creditCardRenderer,
PayPalCommerceGateway,
onSmartButtonClick,
onSmartButtonsInit
);
const messageRenderer = new MessageRenderer(
PayPalCommerceGateway.messages
);
if ( PayPalCommerceGateway.mini_cart_buttons_enabled === '1' ) {
const miniCartBootstrap = new MiniCartBootstap(
PayPalCommerceGateway,
renderer,
errorHandler
);
miniCartBootstrap.init();
buttonModuleWatcher.registerContextBootstrap(
'mini-cart',
miniCartBootstrap
);
}
if (
context === 'product' &&
( PayPalCommerceGateway.single_product_buttons_enabled === '1' ||
hasMessages() )
) {
const singleProductBootstrap = new SingleProductBootstap(
PayPalCommerceGateway,
renderer,
errorHandler
);
singleProductBootstrap.init();
buttonModuleWatcher.registerContextBootstrap(
'product',
singleProductBootstrap
);
}
if ( context === 'cart' ) {
const cartBootstrap = new CartBootstrap(
PayPalCommerceGateway,
renderer,
errorHandler
);
cartBootstrap.init();
buttonModuleWatcher.registerContextBootstrap( 'cart', cartBootstrap );
}
if ( context === 'checkout' ) {
const checkoutBootstap = new CheckoutBootstap(
PayPalCommerceGateway,
renderer,
spinner,
errorHandler
);
checkoutBootstap.init();
buttonModuleWatcher.registerContextBootstrap(
'checkout',
checkoutBootstap
);
}
if ( context === 'pay-now' ) {
const payNowBootstrap = new PayNowBootstrap(
PayPalCommerceGateway,
renderer,
spinner,
errorHandler
);
payNowBootstrap.init();
buttonModuleWatcher.registerContextBootstrap(
'pay-now',
payNowBootstrap
);
}
const messagesBootstrap = new MessagesBootstrap(
PayPalCommerceGateway,
messageRenderer
);
messagesBootstrap.init();
apmButtonsInit( PayPalCommerceGateway );
};
document.addEventListener( 'DOMContentLoaded', () => {
if ( ! typeof PayPalCommerceGateway ) {
console.error( 'PayPal button could not be configured.' );
return;
}
if (
PayPalCommerceGateway.context !== 'checkout' &&
PayPalCommerceGateway.data_client_id.user === 0 &&
PayPalCommerceGateway.data_client_id.has_subscriptions
) {
return;
}
const paypalButtonGatewayIds = [
PaymentMethods.PAYPAL,
...Object.entries( PayPalCommerceGateway.separate_buttons ).map(
( [ k, data ] ) => data.id
),
];
// Sometimes PayPal script takes long time to load,
// so we additionally hide the standard order button here to avoid failed orders.
// Normally it is hidden later after the script load.
const hideOrderButtonIfPpcpGateway = () => {
// only in checkout and pay now page, otherwise it may break things (e.g. payment via product page),
// and also the loading spinner may look weird on other pages
if (
! [ 'checkout', 'pay-now' ].includes(
PayPalCommerceGateway.context
) ||
isChangePaymentPage() ||
( PayPalCommerceGateway.is_free_trial_cart &&
PayPalCommerceGateway.vaulted_paypal_email !== '' )
) {
return;
}
const currentPaymentMethod = getCurrentPaymentMethod();
const isPaypalButton =
paypalButtonGatewayIds.includes( currentPaymentMethod );
const isCards = currentPaymentMethod === PaymentMethods.CARDS;
setVisibleByClass(
ORDER_BUTTON_SELECTOR,
! isPaypalButton && ! isCards,
'ppcp-hidden'
);
if ( isPaypalButton ) {
// stopped after the first rendering of the buttons, in onInit
buttonsSpinner.block();
} else {
buttonsSpinner.unblock();
}
if ( isCards ) {
cardsSpinner.block();
} else {
cardsSpinner.unblock();
}
};
jQuery( document ).on( 'hosted_fields_loaded', () => {
cardsSpinner.unblock();
} );
let bootstrapped = false;
let failed = false;
hideOrderButtonIfPpcpGateway();
jQuery( document.body ).on(
'updated_checkout payment_method_selected',
() => {
if ( bootstrapped || failed ) {
return;
}
hideOrderButtonIfPpcpGateway();
}
);
loadPaypalScript(
PayPalCommerceGateway,
() => {
bootstrapped = true;
bootstrap();
},
() => {
failed = true;
setVisibleByClass( ORDER_BUTTON_SELECTOR, true, 'ppcp-hidden' );
buttonsSpinner.unblock();
cardsSpinner.unblock();
}
);
} );