Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix placeholder=blur inside <noscript> #27311

Merged
merged 8 commits into from
Jul 20, 2021
10 changes: 5 additions & 5 deletions packages/next/client/image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -458,16 +458,16 @@ export default function Image({

objectFit,
objectPosition,

...(placeholder === 'blur'
}
const blurStyle =
placeholder === 'blur'
? {
filter: 'blur(20px)',
backgroundSize: objectFit || 'cover',
backgroundImage: `url("${blurDataURL}")`,
backgroundPosition: objectPosition || '0% 0%',
}
: undefined),
}
: {}
if (layout === 'fill') {
// <Image src="i.png" layout="fill" />
wrapperStyle = {
Expand Down Expand Up @@ -607,7 +607,7 @@ export default function Image({
setRef(img)
handleLoading(img, srcString, placeholder, onLoadingComplete)
}}
style={imgStyle}
style={{ ...imgStyle, ...blurStyle }}
/>
{priority ? (
// Note how we omit the `href` attribute, as it would only be relevant
Expand Down
14 changes: 14 additions & 0 deletions test/integration/image-component/default/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,8 @@ describe('Image Component Tests', () => {
const html = await renderViaHTTP(appPort, '/blurry-placeholder')
const $html = cheerio.load(html)

$html('noscript > img').attr('id', 'unused')

expect($html('#blurry-placeholder')[0].attribs.style).toContain(
`background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400' viewBox='0 0 400 400'%3E%3Cfilter id='blur' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='20' edgeMode='duplicate' /%3E%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='1 1' /%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cimage filter='url(%23blur)' href='data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMDAwMDAwQEBAQFBQUFBQcHBgYHBwsICQgJCAsRCwwLCwwLEQ8SDw4PEg8bFRMTFRsfGhkaHyYiIiYwLTA+PlT/wAALCAAKAAoBAREA/8QAMwABAQEAAAAAAAAAAAAAAAAAAAcJEAABAwUAAwAAAAAAAAAAAAAFAAYRAQMEEyEVMlH/2gAIAQEAAD8Az1bLPaxhiuk0QdeCOLDtHixN2dmd2bsc5FPX7VTREX//2Q==' x='0' y='0' height='100%25' width='100%25'/%3E%3C/svg%3E")`
)
Expand All @@ -690,6 +692,18 @@ describe('Image Component Tests', () => {
)
})

it('should not use blurry placeholder for <noscript> image', async () => {
const html = await renderViaHTTP(appPort, '/blurry-placeholder')
const $html = cheerio.load(html)
const style = $html('noscript > img')[0].attribs.style

expect(style).not.toContain(`background-position`)
expect(style).not.toContain(`background-size`)
expect(style).not.toContain(
`background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400' viewBox='0 0 400 400'%3E%3Cfilter id='blur' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='20' edgeMode='duplicate' /%3E%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='1 1' /%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cimage filter='url(%23blur)' href='data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMDAwMDAwQEBAQFBQUFBQcHBgYHBwsICQgJCAsRCwwLCwwLEQ8SDw4PEg8bFRMTFRsfGhkaHyYiIiYwLTA+PlT/wAALCAAKAAoBAREA/8QAMwABAQEAAAAAAAAAAAAAAAAAAAcJEAABAwUAAwAAAAAAAAAAAAAFAAYRAQMEEyEVMlH/2gAIAQEAAD8Az1bLPaxhiuk0QdeCOLDtHixN2dmd2bsc5FPX7VTREX//2Q==' x='0' y='0' height='100%25' width='100%25'/%3E%3C/svg%3E")`
)
})

it('should remove blurry placeholder after image loads', async () => {
let browser
try {
Expand Down