( img: ImgElementWithDataProp, src: string, layout: LayoutValue, placeholder: PlaceholderValue, onLoadingCompleteRef: React.MutableRefObject<OnLoadingComplete | undefined>, setBlurComplete: (b: boolean) => void )
| 498 | // See https://stackoverflow.com/q/39777833/266535 for why we use this ref |
| 499 | // handler instead of the img's onLoad attribute. |
| 500 | function handleLoading( |
| 501 | img: ImgElementWithDataProp, |
| 502 | src: string, |
| 503 | layout: LayoutValue, |
| 504 | placeholder: PlaceholderValue, |
| 505 | onLoadingCompleteRef: React.MutableRefObject<OnLoadingComplete | undefined>, |
| 506 | setBlurComplete: (b: boolean) => void |
| 507 | ) { |
| 508 | if (!img || img.src === emptyDataURL || img['data-loaded-src'] === src) { |
| 509 | return |
| 510 | } |
| 511 | img['data-loaded-src'] = src |
| 512 | const p = 'decode' in img ? img.decode() : Promise.resolve() |
| 513 | p.catch(() => {}).then(() => { |
| 514 | if (!img.parentNode) { |
| 515 | // Exit early in case of race condition: |
| 516 | // - onload() is called |
| 517 | // - decode() is called but incomplete |
| 518 | // - unmount is called |
| 519 | // - decode() completes |
| 520 | return |
| 521 | } |
| 522 | loadedImageURLs.add(src) |
| 523 | if (placeholder === 'blur') { |
| 524 | setBlurComplete(true) |
| 525 | } |
| 526 | if (onLoadingCompleteRef?.current) { |
| 527 | const { naturalWidth, naturalHeight } = img |
| 528 | // Pass back read-only primitive values but not the |
| 529 | // underlying DOM element because it could be misused. |
| 530 | onLoadingCompleteRef.current({ naturalWidth, naturalHeight }) |
| 531 | } |
| 532 | if (process.env.NODE_ENV !== 'production') { |
| 533 | if (img.parentElement?.parentElement) { |
| 534 | const parent = getComputedStyle(img.parentElement.parentElement) |
| 535 | if (!parent.position) { |
| 536 | // The parent has not been rendered to the dom yet and therefore it has no position. Skip the warnings for such cases. |
| 537 | } else if (layout === 'responsive' && parent.display === 'flex') { |
| 538 | warnOnce( |
| 539 | `Image with src "${src}" may not render properly as a child of a flex container. Consider wrapping the image with a div to configure the width.` |
| 540 | ) |
| 541 | } else if ( |
| 542 | layout === 'fill' && |
| 543 | parent.position !== 'relative' && |
| 544 | parent.position !== 'fixed' && |
| 545 | parent.position !== 'absolute' |
| 546 | ) { |
| 547 | warnOnce( |
| 548 | `Image with src "${src}" may not render properly with a parent using position:"${parent.position}". Consider changing the parent style to position:"relative" with a width and height.` |
| 549 | ) |
| 550 | } |
| 551 | } |
| 552 | } |
| 553 | }) |
| 554 | } |
| 555 | |
| 556 | const ImageElement = ({ |
| 557 | imgAttributes, |
no test coverage detected