feat: Implement IntersectionObserver for lazy loading of image sign items instead of immediate triggering.
This commit is contained in:
parent
0f9d0e02e6
commit
65056cb9ea
@ -5,17 +5,13 @@ import { PDFIframe } from "@sign/components/sign_request/PDF_iframe";
|
|||||||
import { SignablePDFIframe } from "@sign/components/sign_request/signable_PDF_iframe";
|
import { SignablePDFIframe } from "@sign/components/sign_request/signable_PDF_iframe";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shared logic for triggered lazy loading of images.
|
* Robust lazy loading trigger for image sign items.
|
||||||
* This ensures that when a sign item element is created or scrolled into view,
|
|
||||||
* its image is loaded from the data-src attribute.
|
|
||||||
*/
|
*/
|
||||||
const lazyLoadMixin = {
|
const triggerLazyLoad = (el) => {
|
||||||
_triggerLazyLoad(el) {
|
|
||||||
if (!el) return;
|
if (!el) return;
|
||||||
const lazyImg = el.querySelector('.o_sign_image_lazy');
|
const lazyImg = el.querySelector('.o_sign_image_lazy');
|
||||||
if (lazyImg && lazyImg.dataset.src) {
|
if (lazyImg && lazyImg.dataset.src) {
|
||||||
const currentSrc = lazyImg.getAttribute('src');
|
const currentSrc = lazyImg.getAttribute('src');
|
||||||
// Check if it's currently showing the transparent placeholder
|
|
||||||
if (!currentSrc || currentSrc.startsWith('data:image/gif')) {
|
if (!currentSrc || currentSrc.startsWith('data:image/gif')) {
|
||||||
lazyImg.src = lazyImg.dataset.src;
|
lazyImg.src = lazyImg.dataset.src;
|
||||||
lazyImg.onload = () => {
|
lazyImg.onload = () => {
|
||||||
@ -25,49 +21,53 @@ const lazyLoadMixin = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
refreshSignItemsForPage(page) {
|
|
||||||
super.refreshSignItemsForPage(page);
|
|
||||||
if (this.signItems && this.signItems[page]) {
|
|
||||||
for (const id in this.signItems[page]) {
|
|
||||||
const item = this.signItems[page][id];
|
|
||||||
if (item && item.el) {
|
|
||||||
this._triggerLazyLoad(item.el);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 1. Patch the base PDFIframe for shared lazy-loading logic (covers read-only views)
|
/**
|
||||||
patch(PDFIframe.prototype, {
|
* Setup IntersectionObserver for an element.
|
||||||
...lazyLoadMixin,
|
*/
|
||||||
|
const setupLazyObserver = (iframeInstance, el) => {
|
||||||
|
const lazyImg = el.querySelector('.o_sign_image_lazy');
|
||||||
|
if (!lazyImg || !lazyImg.dataset.src) return;
|
||||||
|
|
||||||
// We also hook into enableCustom to trigger lazy load for initial items
|
// Use the viewer container as root if possible
|
||||||
|
const root = iframeInstance.root ? iframeInstance.root.querySelector('#viewerContainer') : null;
|
||||||
|
|
||||||
|
const observer = new IntersectionObserver((entries) => {
|
||||||
|
entries.forEach(entry => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
triggerLazyLoad(el);
|
||||||
|
observer.disconnect();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, {
|
||||||
|
root: root,
|
||||||
|
rootMargin: '200px'
|
||||||
|
});
|
||||||
|
observer.observe(el);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 1. Patch PDFIframe for read-only views
|
||||||
|
patch(PDFIframe.prototype, {
|
||||||
enableCustom(signItem) {
|
enableCustom(signItem) {
|
||||||
super.enableCustom(signItem);
|
// Base PDFIframe.enableCustom is empty, no need for super
|
||||||
if (signItem.data.type === 'image') {
|
if (signItem.data.type === 'image') {
|
||||||
this._triggerLazyLoad(signItem.el);
|
setupLazyObserver(this, signItem.el);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 2. Patch SignablePDFIframe for upload handlers and specific behaviors (covers signing views)
|
// 2. Patch SignablePDFIframe for active signer views
|
||||||
patch(SignablePDFIframe.prototype, {
|
patch(SignablePDFIframe.prototype, {
|
||||||
// Note: Mixin methods are already inherited if not overwritten,
|
|
||||||
// but SignablePDFIframe might need its own hooks.
|
|
||||||
|
|
||||||
enableCustom(signItem) {
|
enableCustom(signItem) {
|
||||||
super.enableCustom(signItem);
|
super.enableCustom(signItem); // Safe because SignablePDFIframe extends PDFIframe
|
||||||
if (signItem.data.type === 'image') {
|
if (signItem.data.type === 'image') {
|
||||||
const el = signItem.el;
|
const el = signItem.el;
|
||||||
const data = signItem.data;
|
const data = signItem.data;
|
||||||
|
|
||||||
// Add data-type attribute for CSS targeting
|
|
||||||
el.setAttribute('data-type', 'image');
|
el.setAttribute('data-type', 'image');
|
||||||
|
|
||||||
// Initial font size adjustment for placeholder text
|
// Initial font size adjustment for placeholder
|
||||||
const adjustFontSize = () => {
|
const adjustFontSize = () => {
|
||||||
const placeholder = el.querySelector('.o_placeholder');
|
const placeholder = el.querySelector('.o_placeholder');
|
||||||
if (placeholder) {
|
if (placeholder) {
|
||||||
@ -144,8 +144,8 @@ patch(SignablePDFIframe.prototype, {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Immediately trigger load if value exists
|
// Also setup lazy observer for signer view
|
||||||
this._triggerLazyLoad(el);
|
setupLazyObserver(this, el);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user