Skip to content

Commit 31931bf

Browse files
fix: prevent recursion in sources sizes calculation
fixes #29
1 parent 39a0d76 commit 31931bf

File tree

1 file changed

+26
-18
lines changed

1 file changed

+26
-18
lines changed

packages/core/src/lazyLoad.ts

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export function lazyLoad<T extends HTMLImageElement>(
2323

2424
for (const image of toElementArray<T>(selectorsOrElements)) {
2525
// Calculate the image's `sizes` attribute if `data-sizes="auto"` is set
26-
const onResizeCleanup = updateSizesAttribute(image, updateSizesOnResize)
26+
const onResizeCleanup = updateSizesAttribute(image, { updateOnResize: updateSizesOnResize })
2727
if (updateSizesOnResize && onResizeCleanup)
2828
cleanupFns.add(onResizeCleanup)
2929

@@ -174,7 +174,13 @@ export function createPlaceholderFromHash(
174174
// and need to be updated when their size changes
175175
const resizeElementStore = new WeakMap<HTMLImageElement | HTMLSourceElement, ResizeObserver>()
176176

177-
function updateSizesAttribute(element: HTMLImageElement | HTMLSourceElement, shouldUpdateOnResize = false) {
177+
function updateSizesAttribute(
178+
element: HTMLImageElement | HTMLSourceElement,
179+
options?: {
180+
updateOnResize?: boolean
181+
isRecursiveCall?: boolean
182+
},
183+
) {
178184
if (element.dataset.sizes !== 'auto')
179185
return
180186

@@ -184,27 +190,29 @@ function updateSizesAttribute(element: HTMLImageElement | HTMLSourceElement, sho
184190
element.sizes = `${width}px`
185191

186192
// Calculate the `sizes` attribute for sources inside a `<picture>` element
187-
if (element.parentElement?.tagName.toLowerCase() === 'picture') {
193+
if (
194+
element.parentElement?.tagName.toLowerCase() === 'picture'
195+
&& !options?.isRecursiveCall
196+
) {
188197
[...element.parentElement.getElementsByTagName('source')].forEach(
189-
sourceTag => updateSizesAttribute(sourceTag),
198+
sourceTag => updateSizesAttribute(sourceTag, { isRecursiveCall: true }),
190199
)
191200
}
192201

193-
if (!shouldUpdateOnResize)
194-
return
195-
196-
if (!resizeElementStore.has(element)) {
197-
const debounceResize = debounce(() => updateSizesAttribute(element), 500)
198-
const observerInstance = new ResizeObserver(debounceResize)
199-
resizeElementStore.set(element, observerInstance)
200-
observerInstance.observe(element)
201-
}
202+
if (options?.updateOnResize) {
203+
if (!resizeElementStore.has(element)) {
204+
const debounceResize = debounce(() => updateSizesAttribute(element), 500)
205+
const observerInstance = new ResizeObserver(debounceResize)
206+
resizeElementStore.set(element, observerInstance)
207+
observerInstance.observe(element)
208+
}
202209

203-
return () => {
204-
const observerInstance = resizeElementStore.get(element)
205-
if (observerInstance) {
206-
observerInstance.disconnect()
207-
resizeElementStore.delete(element)
210+
return () => {
211+
const observerInstance = resizeElementStore.get(element)
212+
if (observerInstance) {
213+
observerInstance.disconnect()
214+
resizeElementStore.delete(element)
215+
}
208216
}
209217
}
210218
}

0 commit comments

Comments
 (0)