mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-06 16:24:33 +08:00
Merge pull request #965 from woocommerce/pcp-456-aub-choice
Improve cart subscriptions check and "All products for subscriptions" compatibility
This commit is contained in:
commit
1debc92453
15 changed files with 241 additions and 107 deletions
|
@ -6,7 +6,6 @@ import PayNowBootstrap from "./modules/ContextBootstrap/PayNowBootstrap";
|
|||
import Renderer from './modules/Renderer/Renderer';
|
||||
import ErrorHandler from './modules/ErrorHandler';
|
||||
import CreditCardRenderer from "./modules/Renderer/CreditCardRenderer";
|
||||
import dataClientIdAttributeHandler from "./modules/DataClientIdAttributeHandler";
|
||||
import MessageRenderer from "./modules/Renderer/MessageRenderer";
|
||||
import Spinner from "./modules/Helper/Spinner";
|
||||
import {
|
||||
|
@ -19,6 +18,7 @@ import {isChangePaymentPage} from "./modules/Helper/Subscriptions";
|
|||
import FreeTrialHandler from "./modules/ActionHandler/FreeTrialHandler";
|
||||
import FormSaver from './modules/Helper/FormSaver';
|
||||
import FormValidator from "./modules/Helper/FormValidator";
|
||||
import {loadPaypalScript} from "./modules/Helper/ScriptLoading";
|
||||
|
||||
// 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.
|
||||
|
@ -258,24 +258,10 @@ document.addEventListener(
|
|||
hideOrderButtonIfPpcpGateway();
|
||||
});
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.addEventListener('load', (event) => {
|
||||
loadPaypalScript(PayPalCommerceGateway, () => {
|
||||
bootstrapped = true;
|
||||
|
||||
bootstrap();
|
||||
});
|
||||
script.setAttribute('src', PayPalCommerceGateway.button.url);
|
||||
Object.entries(PayPalCommerceGateway.script_attributes).forEach(
|
||||
(keyValue) => {
|
||||
script.setAttribute(keyValue[0], keyValue[1]);
|
||||
}
|
||||
);
|
||||
|
||||
if (PayPalCommerceGateway.data_client_id.set_attribute) {
|
||||
dataClientIdAttributeHandler(script, PayPalCommerceGateway.data_client_id);
|
||||
return;
|
||||
}
|
||||
|
||||
document.body.appendChild(script);
|
||||
},
|
||||
);
|
||||
|
|
|
@ -9,31 +9,17 @@ class SingleProductActionHandler {
|
|||
constructor(
|
||||
config,
|
||||
updateCart,
|
||||
showButtonCallback,
|
||||
hideButtonCallback,
|
||||
formElement,
|
||||
errorHandler
|
||||
) {
|
||||
this.config = config;
|
||||
this.updateCart = updateCart;
|
||||
this.showButtonCallback = showButtonCallback;
|
||||
this.hideButtonCallback = hideButtonCallback;
|
||||
this.formElement = formElement;
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
configuration()
|
||||
{
|
||||
|
||||
if ( this.hasVariations() ) {
|
||||
const observer = new ButtonsToggleListener(
|
||||
this.formElement.querySelector('.single_add_to_cart_button'),
|
||||
this.showButtonCallback,
|
||||
this.hideButtonCallback
|
||||
);
|
||||
observer.init();
|
||||
}
|
||||
|
||||
return {
|
||||
createOrder: this.createOrder(),
|
||||
onApprove: onApprove(this, this.errorHandler),
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import CartActionHandler from '../ActionHandler/CartActionHandler';
|
||||
import {setVisible} from "../Helper/Hiding";
|
||||
|
||||
class CartBootstrap {
|
||||
constructor(gateway, renderer, errorHandler) {
|
||||
|
@ -16,13 +17,31 @@ class CartBootstrap {
|
|||
|
||||
jQuery(document.body).on('updated_cart_totals updated_checkout', () => {
|
||||
this.render();
|
||||
|
||||
fetch(
|
||||
this.gateway.ajax.cart_script_params.endpoint,
|
||||
{
|
||||
method: 'GET',
|
||||
credentials: 'same-origin',
|
||||
}
|
||||
)
|
||||
.then(result => result.json())
|
||||
.then(result => {
|
||||
if (! result.success) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newParams = result.data;
|
||||
const reloadRequired = this.gateway.url_params.intent !== newParams.intent;
|
||||
|
||||
// TODO: should reload the script instead
|
||||
setVisible(this.gateway.button.wrapper, !reloadRequired)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
shouldRender() {
|
||||
return document.querySelector(this.gateway.button.wrapper) !==
|
||||
null || document.querySelector(this.gateway.hosted_fields.wrapper) !==
|
||||
null;
|
||||
return document.querySelector(this.gateway.button.wrapper) !== null;
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import UpdateCart from "../Helper/UpdateCart";
|
||||
import SingleProductActionHandler from "../ActionHandler/SingleProductActionHandler";
|
||||
import {hide, show, setVisible} from "../Helper/Hiding";
|
||||
import ButtonsToggleListener from "../Helper/ButtonsToggleListener";
|
||||
|
||||
class SingleProductBootstap {
|
||||
constructor(gateway, renderer, messages, errorHandler) {
|
||||
|
@ -12,10 +14,10 @@ class SingleProductBootstap {
|
|||
|
||||
|
||||
handleChange() {
|
||||
if (!this.shouldRender()) {
|
||||
this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);
|
||||
this.renderer.hideButtons(this.gateway.button.wrapper);
|
||||
this.messages.hideMessages();
|
||||
const shouldRender = this.shouldRender();
|
||||
setVisible(this.gateway.button.wrapper, shouldRender);
|
||||
setVisible(this.gateway.messages.wrapper, shouldRender);
|
||||
if (!shouldRender) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -23,7 +25,6 @@ class SingleProductBootstap {
|
|||
}
|
||||
|
||||
init() {
|
||||
|
||||
const form = document.querySelector('form.cart');
|
||||
if (!form) {
|
||||
return;
|
||||
|
@ -32,20 +33,33 @@ class SingleProductBootstap {
|
|||
form.addEventListener('change', this.handleChange.bind(this));
|
||||
this.mutationObserver.observe(form, {childList: true, subtree: true});
|
||||
|
||||
const buttonObserver = new ButtonsToggleListener(
|
||||
form.querySelector('.single_add_to_cart_button'),
|
||||
() => {
|
||||
show(this.gateway.button.wrapper);
|
||||
show(this.gateway.messages.wrapper);
|
||||
this.messages.renderWithAmount(this.priceAmount())
|
||||
},
|
||||
() => {
|
||||
hide(this.gateway.button.wrapper);
|
||||
hide(this.gateway.messages.wrapper);
|
||||
},
|
||||
);
|
||||
buttonObserver.init();
|
||||
|
||||
if (!this.shouldRender()) {
|
||||
this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);
|
||||
this.messages.hideMessages();
|
||||
hide(this.gateway.button.wrapper);
|
||||
hide(this.gateway.messages.wrapper);
|
||||
return;
|
||||
}
|
||||
|
||||
this.render();
|
||||
|
||||
}
|
||||
|
||||
shouldRender() {
|
||||
|
||||
return document.querySelector('form.cart') !== null && !this.priceAmountIsZero();
|
||||
|
||||
return document.querySelector('form.cart') !== null
|
||||
&& !this.priceAmountIsZero()
|
||||
&& !this.isSubscriptionMode();
|
||||
}
|
||||
|
||||
priceAmount() {
|
||||
|
@ -74,6 +88,12 @@ class SingleProductBootstap {
|
|||
return !price || price === 0;
|
||||
}
|
||||
|
||||
isSubscriptionMode() {
|
||||
// Check "All products for subscriptions" plugin.
|
||||
return document.querySelector('.wcsatt-options-product:not(.wcsatt-options-product--hidden) .subscription-option input[type="radio"]:checked') !== null
|
||||
|| document.querySelector('.wcsatt-options-prompt-label-subscription input[type="radio"]:checked') !== null; // grouped
|
||||
}
|
||||
|
||||
render() {
|
||||
const actionHandler = new SingleProductActionHandler(
|
||||
this.gateway,
|
||||
|
@ -81,16 +101,6 @@ class SingleProductBootstap {
|
|||
this.gateway.ajax.change_cart.endpoint,
|
||||
this.gateway.ajax.change_cart.nonce,
|
||||
),
|
||||
() => {
|
||||
this.renderer.showButtons(this.gateway.button.wrapper);
|
||||
this.renderer.showButtons(this.gateway.hosted_fields.wrapper);
|
||||
this.messages.renderWithAmount(this.priceAmount())
|
||||
},
|
||||
() => {
|
||||
this.renderer.hideButtons(this.gateway.button.wrapper);
|
||||
this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);
|
||||
this.messages.hideMessages();
|
||||
},
|
||||
document.querySelector('form.cart'),
|
||||
this.errorHandler,
|
||||
);
|
||||
|
|
|
@ -14,6 +14,9 @@ class ButtonsToggleListener {
|
|||
|
||||
init()
|
||||
{
|
||||
if (!this.element) {
|
||||
return;
|
||||
}
|
||||
const config = { attributes : true };
|
||||
const callback = () => {
|
||||
if (this.element.classList.contains('disabled')) {
|
||||
|
@ -33,4 +36,4 @@ class ButtonsToggleListener {
|
|||
}
|
||||
}
|
||||
|
||||
export default ButtonsToggleListener;
|
||||
export default ButtonsToggleListener;
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import dataClientIdAttributeHandler from "../DataClientIdAttributeHandler";
|
||||
|
||||
export const loadPaypalScript = (config, onLoaded) => {
|
||||
if (typeof paypal !== 'undefined') {
|
||||
onLoaded();
|
||||
return;
|
||||
}
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.addEventListener('load', onLoaded);
|
||||
script.setAttribute('src', config.url);
|
||||
Object.entries(config.script_attributes).forEach(
|
||||
(keyValue) => {
|
||||
script.setAttribute(keyValue[0], keyValue[1]);
|
||||
}
|
||||
);
|
||||
|
||||
if (config.data_client_id.set_attribute) {
|
||||
dataClientIdAttributeHandler(script, config.data_client_id);
|
||||
return;
|
||||
}
|
||||
|
||||
document.body.appendChild(script);
|
||||
}
|
|
@ -53,14 +53,5 @@ class MessageRenderer {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
hideMessages() {
|
||||
const domElement = document.querySelector(this.config.wrapper);
|
||||
if (! domElement ) {
|
||||
return false;
|
||||
}
|
||||
domElement.style.display = 'none';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
export default MessageRenderer;
|
||||
|
|
|
@ -99,24 +99,6 @@ class Renderer {
|
|||
return this.renderedSources.has(wrapper + fundingSource ?? '');
|
||||
}
|
||||
|
||||
hideButtons(element) {
|
||||
const domElement = document.querySelector(element);
|
||||
if (! domElement ) {
|
||||
return false;
|
||||
}
|
||||
domElement.style.display = 'none';
|
||||
return true;
|
||||
}
|
||||
|
||||
showButtons(element) {
|
||||
const domElement = document.querySelector(element);
|
||||
if (! domElement ) {
|
||||
return false;
|
||||
}
|
||||
domElement.style.display = 'block';
|
||||
return true;
|
||||
}
|
||||
|
||||
disableCreditCardFields() {
|
||||
this.creditCardRenderer.disableFields();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue