const taskIndex = que.findIndex((item) => item === task); removeFromQue(task); } function scheduleExecution() { task.isPlanned = true; if (task.isCanceled) { return; } task.timerId = setTimeout(() => { task.execute(); task.isPlanned = false; removeFromQue(task); if (task.nextTask) { task.nextTask.prevTask = null; task.nextTask.scheduleExecution(); } }, ms); } if (que.length) { const prevTask = que[que.length - 1]; prevTask.nextTask = task; task.prevTask = prevTask; } else { task.scheduleExecution(); } task.id = ++index; que.push(task); return task; } return { execute, } } const scheduler = createScheduler(300); const schedulerList = new Map(); const observer = new IntersectionObserver((entries, observer) => { entries.forEach((entry) => { const { target, isIntersecting, intersectionRect: { y: intersectedElementPositionY, bottom: intersectedElementPositionBottom }, boundingClientRect: { y: elementPositionY, bottom: elementPositionBottom }, } = entry; if ( (!isIntersecting && elementPositionY < 0) || (isIntersecting && elementPositionY < 0 && elementPositionBottom >= 0) ) { setObservedSlots(entry, observer); if(schedulerList.get(entry.target)) { schedulerList.get(entry.target).immidiatelyExecute(); }; observer.unobserve(target); return; } if (isIntersecting && elementPositionY >= 0) { const task = scheduler.execute(() => { const { target } = entry; observeSlots(entry, observer); }); schedulerList.set(entry.target, task); } }); }); document.querySelectorAll('ws-block').forEach((blockNode) => { if (blockNode.clearObservedSlots) blockNode.clearObservedSlots(); }); document.querySelectorAll('[slot]').forEach((slot) => { if (slot.closest('[slot="header"], [slot="footer"]')) { if (slot.getAttribute('slot') !== 'header' && slot.getAttribute('slot') !== 'footer') { return; } } slot.closest('ws-block').observedSlots = new Set(); observer.observe(slot); }); function setObservedAttrs(target, attributes) { if (!target.firstElementChild) return; target.firstElementChild.setAttribute(DATA_OBSERVED_ATTRIBUTE, attributes); } function observeSlots(entry, observer) { const { target, boundingClientRect: { y: elementPositionY }, } = entry; if (elementPositionY >= 0) { const slotAttribute = target.getAttribute('slot'); const observedSlots = target.closest('ws-block').observedSlots; if (slotAttribute) { observedSlots.add(slotAttribute); } if (observedSlots.size) { setObservedAttrs(target.closest('ws-block'), Array.from(observedSlots).join(' ')); } } } function setObservedSlots(entry, observer) { const { target, boundingClientRect: { y: elementPositionY }, } = entry; if (elementPositionY < 0) { const slotAttribute = target.getAttribute('slot'); const observedSlots = target.closest('ws-block').observedSlots; observedSlots.add(slotAttribute); if (observedSlots.size) { setObservedAttrs(target.closest('ws-block'), Array.from(observedSlots).join(' ')); } } } })();