From a0480e35bb8741c73be1856c4cd38081e8c81d68 Mon Sep 17 00:00:00 2001 From: Pedro Silva Date: Thu, 20 Jul 2023 14:19:18 +0100 Subject: [PATCH] Add paypal widget builder --- modules/ppcp-button/resources/js/button.js | 3 + .../modules/ContextBootstrap/CartBootstap.js | 3 +- .../js/modules/Renderer/MessageRenderer.js | 7 +- .../resources/js/modules/Renderer/Renderer.js | 42 ++++------- .../js/modules/Renderer/WidgetBuilder.js | 75 +++++++++++++++++++ 5 files changed, 100 insertions(+), 30 deletions(-) create mode 100644 modules/ppcp-button/resources/js/modules/Renderer/WidgetBuilder.js diff --git a/modules/ppcp-button/resources/js/button.js b/modules/ppcp-button/resources/js/button.js index 1a4219c48..38ef56112 100644 --- a/modules/ppcp-button/resources/js/button.js +++ b/modules/ppcp-button/resources/js/button.js @@ -19,6 +19,7 @@ import FreeTrialHandler from "./modules/ActionHandler/FreeTrialHandler"; import FormSaver from './modules/Helper/FormSaver'; import FormValidator from "./modules/Helper/FormValidator"; import {loadPaypalScript} from "./modules/Helper/ScriptLoading"; +import widgetBuilder from "./modules/Renderer/WidgetBuilder"; // 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. @@ -267,6 +268,8 @@ document.addEventListener( }); loadPaypalScript(PayPalCommerceGateway, () => { + widgetBuilder.setPaypal(paypal); + bootstrapped = true; bootstrap(); diff --git a/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js b/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js index e3f65e8c5..5790e8f56 100644 --- a/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js +++ b/modules/ppcp-button/resources/js/modules/ContextBootstrap/CartBootstap.js @@ -1,6 +1,5 @@ import CartActionHandler from '../ActionHandler/CartActionHandler'; import BootstrapHelper from "../Helper/BootstrapHelper"; -import {setVisible} from "../Helper/Hiding"; class CartBootstrap { constructor(gateway, renderer, messages, errorHandler) { @@ -46,7 +45,7 @@ class CartBootstrap { if (reloadRequired) { this.gateway.url_params = newParams; - jQuery(this.gateway.button.wrapper).trigger('ppcp-reload-buttons', this.gateway); + jQuery(this.gateway.button.wrapper).trigger('ppcp-reload-buttons'); } // handle button status diff --git a/modules/ppcp-button/resources/js/modules/Renderer/MessageRenderer.js b/modules/ppcp-button/resources/js/modules/Renderer/MessageRenderer.js index d7fa55f11..45f67ac67 100644 --- a/modules/ppcp-button/resources/js/modules/Renderer/MessageRenderer.js +++ b/modules/ppcp-button/resources/js/modules/Renderer/MessageRenderer.js @@ -1,3 +1,5 @@ +import widgetBuilder from "./WidgetBuilder"; + class MessageRenderer { constructor(config) { @@ -28,7 +30,10 @@ class MessageRenderer { oldWrapper.parentElement.removeChild(oldWrapper); sibling.parentElement.insertBefore(newWrapper, sibling); - paypal.Messages(options).render(this.config.wrapper); + widgetBuilder.registerMessages(this.config.wrapper, options); + widgetBuilder.renderMessages(this.config.wrapper); + + // paypal.Messages(options).render(this.config.wrapper); } optionsEqual(options) { diff --git a/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js b/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js index c5e9f0525..828134e46 100644 --- a/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js +++ b/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js @@ -1,6 +1,7 @@ import merge from "deepmerge"; import {loadScript} from "@paypal/paypal-js"; import {keysToCamelCase} from "../Helper/Utils"; +import widgetBuilder from "./WidgetBuilder"; class Renderer { constructor(creditCardRenderer, defaultSettings, onSmartButtonClick, onSmartButtonsInit) { @@ -12,9 +13,9 @@ class Renderer { this.buttonsOptions = {}; this.onButtonsInitListeners = {}; - this.activeButtons = {}; - this.renderedSources = new Set(); + + this.reloadEventName = 'ppcp-reload-buttons'; } render(contextConfig, settingsOverride = {}, contextConfigOverride = () => {}) { @@ -76,8 +77,6 @@ class Renderer { return; } - console.log('rendering', wrapper); - if (fundingSource) { contextConfig.fundingSource = fundingSource; } @@ -96,36 +95,25 @@ class Renderer { } } - const buildButtons = (paypal) => { - const btn = paypal.Buttons(buttonsOptions()); - - this.activeButtons[wrapper] = btn; - - if (!btn.isEligible()) { - return; - } - - btn.render(wrapper); - } - - jQuery(wrapper).off('ppcp-reload-buttons'); - jQuery(wrapper).on('ppcp-reload-buttons', (event, settingsOverride = {}) => { + //jQuery(document).off('ppcp-reload-buttons'); + jQuery(document).on('ppcp-reload-buttons', wrapper, (event, settingsOverride = {}) => { const settings = merge(this.defaultSettings, settingsOverride); - const scriptOptions = keysToCamelCase(settings.url_params); - - // if (this.activeButtons[wrapper]) { - // this.activeButtons[wrapper].close(); - // } + let scriptOptions = keysToCamelCase(settings.url_params); + scriptOptions = merge(scriptOptions, settings.script_attributes); loadScript(scriptOptions).then((paypal) => { - buildButtons(paypal); + widgetBuilder.setPaypal(paypal); + widgetBuilder.registerButtons(wrapper, buttonsOptions()); + widgetBuilder.renderAllButtons(); + widgetBuilder.renderAllMessages(); }); }); - this.renderedSources.add(wrapper + fundingSource ?? ''); + this.renderedSources.add(wrapper + (fundingSource ?? '')); if (typeof paypal !== 'undefined' && typeof paypal.Buttons !== 'undefined') { - buildButtons(paypal); + widgetBuilder.registerButtons(wrapper, buttonsOptions()); + widgetBuilder.renderButtons(wrapper); } } @@ -138,7 +126,7 @@ class Renderer { // if (!hasEnabledSeparateGateways) { // return document.querySelector(wrapper).hasChildNodes(); // } - return this.renderedSources.has(wrapper + fundingSource ?? ''); + return this.renderedSources.has(wrapper + (fundingSource ?? '')); } disableCreditCardFields() { diff --git a/modules/ppcp-button/resources/js/modules/Renderer/WidgetBuilder.js b/modules/ppcp-button/resources/js/modules/Renderer/WidgetBuilder.js new file mode 100644 index 000000000..45d5a0b82 --- /dev/null +++ b/modules/ppcp-button/resources/js/modules/Renderer/WidgetBuilder.js @@ -0,0 +1,75 @@ + +class WidgetBuilder { + + constructor() { + this.paypal = null; + this.buttons = new Map(); + this.messages = new Map(); + + document.ppcpWidgetBuilderStatus = () => { + console.log({ + buttons: this.buttons, + messages: this.messages, + }); + } + } + + setPaypal(paypal) { + this.paypal = paypal; + } + + registerButtons(wrapper, options) { + this.buttons.set(wrapper, { + wrapper: wrapper, + options: options + }); + } + + renderButtons(wrapper) { + if (!this.buttons.has(wrapper)) { + return; + } + + const entry = this.buttons.get(wrapper); + const btn = this.paypal.Buttons(entry.options); + + if (!btn.isEligible()) { + return; + } + + btn.render(entry.wrapper); + } + + renderAllButtons() { + for (const [wrapper, entry] of this.buttons) { + this.renderButtons(wrapper); + } + } + + registerMessages(wrapper, options) { + this.messages.set(wrapper, { + wrapper: wrapper, + options: options + }); + } + + renderMessages(wrapper) { + if (!this.messages.has(wrapper)) { + return; + } + + const entry = this.messages.get(wrapper); + const btn = this.paypal.Messages(entry.options); + + btn.render(entry.wrapper); + } + + renderAllMessages() { + for (const [wrapper, entry] of this.messages) { + this.renderMessages(wrapper); + } + } + +} + +export default new WidgetBuilder();