From b631692bc60f3d30cd337e0a3fc2f17d9bf4416d Mon Sep 17 00:00:00 2001 From: Himad M Date: Fri, 1 Aug 2025 15:31:46 -0400 Subject: [PATCH] Add polling mechanism for renderer wrapper --- .../ContextBootstrap/MessagesBootstrap.js | 23 +++++++------ .../js/modules/Helper/WaitForElement.js | 32 +++++++++++++++++++ 2 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 modules/ppcp-button/resources/js/modules/Helper/WaitForElement.js diff --git a/modules/ppcp-button/resources/js/modules/ContextBootstrap/MessagesBootstrap.js b/modules/ppcp-button/resources/js/modules/ContextBootstrap/MessagesBootstrap.js index be9b654bb..f74a86f9c 100644 --- a/modules/ppcp-button/resources/js/modules/ContextBootstrap/MessagesBootstrap.js +++ b/modules/ppcp-button/resources/js/modules/ContextBootstrap/MessagesBootstrap.js @@ -1,5 +1,6 @@ import { setVisible } from '../Helper/Hiding'; import MessageRenderer from '../Renderer/MessageRenderer'; +import { waitForElement } from '../Helper/WaitForElement'; class MessagesBootstrap { constructor( gateway, messageRenderer ) { @@ -93,17 +94,21 @@ class MessagesBootstrap { render() { this.renderers.forEach( ( renderer ) => { - const shouldShow = this.shouldShow( renderer ); - setVisible( renderer.config.wrapper, shouldShow ); - if ( ! shouldShow ) { - return; - } + waitForElement( renderer.config.wrapper ) + .then( () => { + const shouldShow = this.shouldShow( renderer ); + setVisible( renderer.config.wrapper, shouldShow ); + if ( ! shouldShow ) { + return; + } - if ( ! renderer.shouldRender() ) { - return; - } + if ( ! renderer.shouldRender() ) { + return; + } - renderer.renderWithAmount( this.lastAmount ); + renderer.renderWithAmount( this.lastAmount ); + } ) + .catch( ( err ) => console.error( err ) ); } ); } } diff --git a/modules/ppcp-button/resources/js/modules/Helper/WaitForElement.js b/modules/ppcp-button/resources/js/modules/Helper/WaitForElement.js new file mode 100644 index 000000000..3c6fab6a0 --- /dev/null +++ b/modules/ppcp-button/resources/js/modules/Helper/WaitForElement.js @@ -0,0 +1,32 @@ +/** + * Waits for a DOM element using setTimeout polling + * @param {string} selector - CSS selector for the element + * @param {number} timeout - Maximum time to wait in milliseconds (default: 3000) + * @param {number} interval - Polling interval in milliseconds (default: 100) + * @return {Promise} - Resolves with the element or rejects if timeout + */ +export function waitForElement( selector, timeout = 3000, interval = 100 ) { + return new Promise( ( resolve, reject ) => { + const timeoutId = setTimeout( () => { + clearInterval( intervalId ); + reject( `Element "${ selector }" not found within ${ timeout }ms` ); + }, timeout ); + + const element = document.querySelector( selector ); + if ( element ) { + clearTimeout( timeoutId ); + resolve( element ); + return; + } + + const intervalId = setInterval( () => { + const el = document.querySelector( selector ); + + if ( el ) { + clearTimeout( timeoutId ); + clearInterval( intervalId ); + resolve( el ); + } + }, interval ); + } ); +}