mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-06 12:25:15 +08:00
Add ability in WidgetBuilder to have multiple buttons rendered per wrapper.
This commit is contained in:
parent
cc79f62cab
commit
0fed872c13
4 changed files with 104 additions and 15 deletions
|
@ -40,8 +40,7 @@ class SingleProductActionHandler {
|
|||
}).then((res)=>{
|
||||
return res.json();
|
||||
}).then(() => {
|
||||
const id = document.querySelector('[name="add-to-cart"]').value;
|
||||
const products = [new Product(id, 1, null)];
|
||||
const products = this.getSubscriptionProducts();
|
||||
|
||||
fetch(this.config.ajax.change_cart.endpoint, {
|
||||
method: 'POST',
|
||||
|
@ -71,6 +70,12 @@ class SingleProductActionHandler {
|
|||
}
|
||||
}
|
||||
|
||||
getSubscriptionProducts()
|
||||
{
|
||||
const id = document.querySelector('[name="add-to-cart"]').value;
|
||||
return [new Product(id, 1, null)];
|
||||
}
|
||||
|
||||
configuration()
|
||||
{
|
||||
return {
|
||||
|
|
|
@ -163,6 +163,13 @@ class SingleProductBootstap {
|
|||
this.errorHandler,
|
||||
);
|
||||
|
||||
const hasSubscriptions = PayPalCommerceGateway.data_client_id.has_subscriptions
|
||||
&& PayPalCommerceGateway.data_client_id.paypal_subscriptions_enabled;
|
||||
|
||||
const products = hasSubscriptions
|
||||
? actionHandler.getSubscriptionProducts()
|
||||
: actionHandler.getProducts();
|
||||
|
||||
(new SimulateCart(
|
||||
this.gateway.ajax.simulate_cart.endpoint,
|
||||
this.gateway.ajax.simulate_cart.nonce,
|
||||
|
@ -198,7 +205,7 @@ class SingleProductBootstap {
|
|||
|
||||
this.handleButtonStatus(false);
|
||||
|
||||
}, actionHandler.getProducts());
|
||||
}, products);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ class Renderer {
|
|||
renderButtons(wrapper, style, contextConfig, hasEnabledSeparateGateways, fundingSource = null) {
|
||||
if (! document.querySelector(wrapper) || this.isAlreadyRendered(wrapper, fundingSource, hasEnabledSeparateGateways) ) {
|
||||
// Try to render registered buttons again in case they were removed from the DOM by an external source.
|
||||
widgetBuilder.renderButtons(wrapper);
|
||||
widgetBuilder.renderButtons([wrapper, fundingSource]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -99,14 +99,20 @@ class Renderer {
|
|||
|
||||
jQuery(document)
|
||||
.off(this.reloadEventName, wrapper)
|
||||
.on(this.reloadEventName, wrapper, (event, settingsOverride = {}) => {
|
||||
.on(this.reloadEventName, wrapper, (event, settingsOverride = {}, triggeredFundingSource) => {
|
||||
|
||||
// Only accept events from the matching funding source
|
||||
if (fundingSource && triggeredFundingSource && (triggeredFundingSource !== fundingSource)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const settings = merge(this.defaultSettings, settingsOverride);
|
||||
let scriptOptions = keysToCamelCase(settings.url_params);
|
||||
scriptOptions = merge(scriptOptions, settings.script_attributes);
|
||||
|
||||
loadScript(scriptOptions).then((paypal) => {
|
||||
widgetBuilder.setPaypal(paypal);
|
||||
widgetBuilder.registerButtons(wrapper, buttonsOptions());
|
||||
widgetBuilder.registerButtons([wrapper, fundingSource], buttonsOptions());
|
||||
widgetBuilder.renderAll();
|
||||
});
|
||||
});
|
||||
|
@ -114,8 +120,8 @@ class Renderer {
|
|||
this.renderedSources.add(wrapper + (fundingSource ?? ''));
|
||||
|
||||
if (typeof paypal !== 'undefined' && typeof paypal.Buttons !== 'undefined') {
|
||||
widgetBuilder.registerButtons(wrapper, buttonsOptions());
|
||||
widgetBuilder.renderButtons(wrapper);
|
||||
widgetBuilder.registerButtons([wrapper, fundingSource], buttonsOptions());
|
||||
widgetBuilder.renderButtons([wrapper, fundingSource]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
|
||||
/**
|
||||
* Handles the registration and rendering of PayPal widgets: Buttons and Messages.
|
||||
* To have several Buttons per wrapper, an array should be provided, ex: [wrapper, fundingSource].
|
||||
*/
|
||||
class WidgetBuilder {
|
||||
|
||||
constructor() {
|
||||
|
@ -19,14 +22,18 @@ class WidgetBuilder {
|
|||
}
|
||||
|
||||
registerButtons(wrapper, options) {
|
||||
this.buttons.set(wrapper, {
|
||||
wrapper = this.sanitizeWrapper(wrapper);
|
||||
|
||||
this.buttons.set(this.toKey(wrapper), {
|
||||
wrapper: wrapper,
|
||||
options: options
|
||||
options: options,
|
||||
});
|
||||
}
|
||||
|
||||
renderButtons(wrapper) {
|
||||
if (!this.buttons.has(wrapper)) {
|
||||
wrapper = this.sanitizeWrapper(wrapper);
|
||||
|
||||
if (!this.buttons.has(this.toKey(wrapper))) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -34,14 +41,21 @@ class WidgetBuilder {
|
|||
return;
|
||||
}
|
||||
|
||||
const entry = this.buttons.get(wrapper);
|
||||
const entry = this.buttons.get(this.toKey(wrapper));
|
||||
const btn = this.paypal.Buttons(entry.options);
|
||||
|
||||
if (!btn.isEligible()) {
|
||||
this.buttons.delete(this.toKey(wrapper));
|
||||
return;
|
||||
}
|
||||
|
||||
btn.render(entry.wrapper);
|
||||
let target = this.buildWrapperTarget(wrapper);
|
||||
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
|
||||
btn.render(target);
|
||||
}
|
||||
|
||||
renderAllButtons() {
|
||||
|
@ -84,7 +98,64 @@ class WidgetBuilder {
|
|||
}
|
||||
|
||||
hasRendered(wrapper) {
|
||||
return document.querySelector(wrapper).hasChildNodes();
|
||||
let selector = wrapper;
|
||||
|
||||
if (Array.isArray(wrapper)) {
|
||||
selector = wrapper[0];
|
||||
for (const item of wrapper.slice(1)) {
|
||||
selector += ' .item-' + item;
|
||||
}
|
||||
}
|
||||
|
||||
const element = document.querySelector(selector);
|
||||
return element && element.hasChildNodes();
|
||||
}
|
||||
|
||||
sanitizeWrapper(wrapper) {
|
||||
if (Array.isArray(wrapper)) {
|
||||
wrapper = wrapper.filter(item => !!item);
|
||||
if (wrapper.length === 1) {
|
||||
wrapper = wrapper[0];
|
||||
}
|
||||
}
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
buildWrapperTarget(wrapper) {
|
||||
let target = wrapper;
|
||||
|
||||
if (Array.isArray(wrapper)) {
|
||||
const $wrapper = jQuery(wrapper[0]);
|
||||
|
||||
if (!$wrapper.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const itemClass = 'item-' + wrapper[1];
|
||||
|
||||
// Check if the parent element exists and it doesn't already have the div with the class
|
||||
let $item = $wrapper.find('.' + itemClass);
|
||||
|
||||
if (!$item.length) {
|
||||
$item = jQuery(`<div class="${itemClass}"></div>`);
|
||||
$wrapper.append($item);
|
||||
}
|
||||
|
||||
target = $item.get(0);
|
||||
}
|
||||
|
||||
if (!jQuery(target).length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
toKey(wrapper) {
|
||||
if (Array.isArray(wrapper)) {
|
||||
return JSON.stringify(wrapper);
|
||||
}
|
||||
return wrapper;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue