From c98aa6777ebb642fc095281f94a3e49b49835bed Mon Sep 17 00:00:00 2001 From: Suherdy Yacob Date: Mon, 16 Mar 2026 15:32:05 +0700 Subject: [PATCH] feat: Improve image field lazy loading by checking `src` attribute and reducing timeout, and refine image field setup with role-based access in `PDFIframe` and `SignablePDFIframe`. --- static/src/js/sign_image_upload.js | 39 ++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/static/src/js/sign_image_upload.js b/static/src/js/sign_image_upload.js index d4048f7..0fd7e17 100755 --- a/static/src/js/sign_image_upload.js +++ b/static/src/js/sign_image_upload.js @@ -33,10 +33,10 @@ const setupLazyObserver = (iframeInstance, el) => { return; } const lazyImg = el.querySelector('.o_sign_image_lazy'); - if (!lazyImg || !lazyImg.dataset.src) return; + if (!lazyImg || (!lazyImg.dataset.src && !lazyImg.src)) return; // Use a safety timeout to ensure it loads even if observer fails - const safetyTimeout = setTimeout(() => triggerLazyLoad(el), 5000); + const safetyTimeout = setTimeout(() => triggerLazyLoad(el), 3000); const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { @@ -52,30 +52,44 @@ const setupLazyObserver = (iframeInstance, el) => { observer.observe(el); }; -// 1. Patch PDFIframe (Base class) -// We patch only what is strictly necessary and avoid super calls if possible for base classes +// 1. Patch PDFIframe (Base class) for read-only / non-signer views patch(PDFIframe.prototype, { enableCustom(signItem) { - // PDFIframe.enableCustom is normally empty - if (typeof super.enableCustom === 'function') { - super.enableCustom(signItem); - } + // Shared logic: Ensure lazy loading is set up for all image fields if (signItem && signItem.data && signItem.data.type === 'image') { setupLazyObserver(this, signItem.el); } + + // Base PDFIframe.enableCustom is empty, but we call super just in case of other patches + if (typeof super.enableCustom === 'function') { + super.enableCustom(signItem); + } } }); -// 2. Patch SignablePDFIframe (Subclass) +// 2. Patch SignablePDFIframe (Subclass) for active signers patch(SignablePDFIframe.prototype, { enableCustom(signItem) { - // Ensure we call the base implementation (which now includes our lazy loading) + // IMPORTANT: Execute shared logic first! + // PDFIframe.enableCustom (our patch above) will handle lazy loading. + // However, SignablePDFIframe does NOT normally call super.enableCustom(). + // We manually trigger the shared observation logic here to be sure. + if (signItem && signItem.data && signItem.data.type === 'image') { + setupLazyObserver(this, signItem.el); + } + + // Now call the original SignablePDFIframe.enableCustom (which has the role check) super.enableCustom(signItem); - if (signItem && signItem.data && signItem.data.type === 'image') { + // Additional setup only for the current signer + if (signItem && signItem.data && signItem.data.type === 'image' && signItem.el) { const el = signItem.el; const data = signItem.data; - if (!el) return; + + // Check if we are responsible for this field (duplicate check from original but needed for our additions) + if (this.readonly || data.responsible !== this.currentRole) { + return; + } el.setAttribute('data-type', 'image'); @@ -95,7 +109,6 @@ patch(SignablePDFIframe.prototype, { const input = el.querySelector('.o_sign_image_upload_input'); if (input) { el.addEventListener('click', (e) => { - if (this.readonly || (data.responsible > 0 && data.responsible !== this.currentRole)) return; if (e.target !== input) { input.click(); }