mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-06 18:16:38 +08:00
179 lines
3.6 KiB
JavaScript
179 lines
3.6 KiB
JavaScript
/**
|
|
* 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() {
|
|
this.paypal = null;
|
|
this.buttons = new Map();
|
|
this.messages = new Map();
|
|
|
|
this.renderEventName = 'ppcp-render';
|
|
|
|
document.ppcpWidgetBuilderStatus = () => {
|
|
console.log( {
|
|
buttons: this.buttons,
|
|
messages: this.messages,
|
|
} );
|
|
};
|
|
|
|
jQuery( document )
|
|
.off( this.renderEventName )
|
|
.on( this.renderEventName, () => {
|
|
this.renderAll();
|
|
} );
|
|
}
|
|
|
|
setPaypal( paypal ) {
|
|
this.paypal = paypal;
|
|
jQuery( document ).trigger( 'ppcp-paypal-loaded', paypal );
|
|
}
|
|
|
|
registerButtons( wrapper, options ) {
|
|
wrapper = this.sanitizeWrapper( wrapper );
|
|
|
|
this.buttons.set( this.toKey( wrapper ), {
|
|
wrapper,
|
|
options,
|
|
} );
|
|
}
|
|
|
|
renderButtons( wrapper ) {
|
|
wrapper = this.sanitizeWrapper( wrapper );
|
|
|
|
if ( ! this.buttons.has( this.toKey( wrapper ) ) ) {
|
|
return;
|
|
}
|
|
|
|
if ( this.hasRendered( wrapper ) ) {
|
|
return;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
const target = this.buildWrapperTarget( wrapper );
|
|
|
|
if ( ! target ) {
|
|
return;
|
|
}
|
|
|
|
btn.render( target );
|
|
}
|
|
|
|
renderAllButtons() {
|
|
for ( const [ wrapper, entry ] of this.buttons ) {
|
|
this.renderButtons( wrapper );
|
|
}
|
|
}
|
|
|
|
registerMessages( wrapper, options ) {
|
|
this.messages.set( wrapper, {
|
|
wrapper,
|
|
options,
|
|
} );
|
|
}
|
|
|
|
renderMessages( wrapper ) {
|
|
if ( ! this.messages.has( wrapper ) ) {
|
|
return;
|
|
}
|
|
|
|
const entry = this.messages.get( wrapper );
|
|
|
|
if ( this.hasRendered( wrapper ) ) {
|
|
const element = document.querySelector( wrapper );
|
|
element.setAttribute( 'data-pp-amount', entry.options.amount );
|
|
return;
|
|
}
|
|
|
|
const btn = this.paypal.Messages( entry.options );
|
|
|
|
btn.render( entry.wrapper );
|
|
|
|
// watchdog to try to handle some strange cases where the wrapper may not be present
|
|
setTimeout( () => {
|
|
if ( ! this.hasRendered( wrapper ) ) {
|
|
btn.render( entry.wrapper );
|
|
}
|
|
}, 100 );
|
|
}
|
|
|
|
renderAllMessages() {
|
|
for ( const [ wrapper, entry ] of this.messages ) {
|
|
this.renderMessages( wrapper );
|
|
}
|
|
}
|
|
|
|
renderAll() {
|
|
this.renderAllButtons();
|
|
this.renderAllMessages();
|
|
}
|
|
|
|
hasRendered( wrapper ) {
|
|
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;
|
|
}
|
|
}
|
|
export default window.widgetBuilder;
|