From 040d2edf38b37e0b9f1d13af2122003dae371f2d Mon Sep 17 00:00:00 2001 From: Steven Date: Fri, 5 Aug 2022 13:13:15 -0400 Subject: [PATCH 1/8] Fix `next/future/image` alt text In most browsers (other than Chrome), the alt text is visible while the image is loading. This causes CLS and is undesirable unless there is an error. --- packages/next/client/future/image.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/next/client/future/image.tsx b/packages/next/client/future/image.tsx index 46a8d92adfd2..bdebb1014007 100644 --- a/packages/next/client/future/image.tsx +++ b/packages/next/client/future/image.tsx @@ -130,6 +130,7 @@ type ImageElementProps = Omit & { placeholder: PlaceholderValue onLoadingCompleteRef: React.MutableRefObject setBlurComplete: (b: boolean) => void + setShowAltText: (b: boolean) => void noscriptSizes: string | undefined } @@ -403,6 +404,7 @@ export default function Image({ } const [blurComplete, setBlurComplete] = useState(false) + const [showAltText, setShowAltText] = useState(false) let widthInt = getInt(width) let heightInt = getInt(height) const qualityInt = getInt(quality) @@ -576,6 +578,7 @@ export default function Image({ width: '100%', } : {}, + showAltText ? {} : { color: 'transparent' }, style ) const svgBlurPlaceholder = `url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http%3A//www.w3.org/2000/svg' viewBox='0 0 ${widthInt} ${heightInt}'%3E%3Cfilter id='b' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='50'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='1 1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cimage filter='url(%23b)' x='0' y='0' height='100%25' width='100%25' href='${blurDataURL}'/%3E%3C/svg%3E")` @@ -655,6 +658,7 @@ export default function Image({ srcString, onLoadingCompleteRef, setBlurComplete, + setShowAltText, noscriptSizes: sizes, ...rest, } @@ -704,6 +708,7 @@ const ImageElement = ({ loader, onLoadingCompleteRef, setBlurComplete, + setShowAltText, onLoad, onError, noscriptSizes, @@ -756,6 +761,8 @@ const ImageElement = ({ } }} onError={(event) => { + // if the real image fails to load, this will ensure "alt" is visible + setShowAltText(true) if (placeholder === 'blur') { // If the real image fails to load, this will still remove the placeholder. setBlurComplete(true) From e2768ac44fb350c7756e4b6d6078102e7629cdea Mon Sep 17 00:00:00 2001 From: Steven Date: Fri, 5 Aug 2022 16:37:46 -0400 Subject: [PATCH 2/8] Fix static tests --- test/integration/image-future/base-path/test/static.test.js | 2 +- test/integration/image-future/default/test/static.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/image-future/base-path/test/static.test.js b/test/integration/image-future/base-path/test/static.test.js index 077fab76c9e9..d6e51ecfed59 100644 --- a/test/integration/image-future/base-path/test/static.test.js +++ b/test/integration/image-future/base-path/test/static.test.js @@ -65,7 +65,7 @@ const runTests = () => { }) it('Should add a blur to a statically imported image', async () => { expect(html).toContain( - `style="background-size:cover;background-position:0% 0%;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http%3A//www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cfilter id='b' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='50'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='1 1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cimage filter='url(%23b)' x='0' y='0' height='100%25' width='100%25' href='data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAoKCgoKCgsMDAsPEA4QDxYUExMUFiIYGhgaGCIzICUgICUgMy03LCksNy1RQDg4QFFeT0pPXnFlZXGPiI+7u/sBCgoKCgoKCwwMCw8QDhAPFhQTExQWIhgaGBoYIjMgJSAgJSAzLTcsKSw3LVFAODhAUV5PSk9ecWVlcY+Ij7u7+//CABEIAAYACAMBIgACEQEDEQH/xAAnAAEBAAAAAAAAAAAAAAAAAAAABwEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAAmgP/xAAcEAACAQUBAAAAAAAAAAAAAAASFBMAAQMFERX/2gAIAQEAAT8AZ1HjrKZX55JysIc4Ff/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Af//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Af//Z'/%3E%3C/svg%3E")` + `style="color:transparent;background-size:cover;background-position:0% 0%;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http%3A//www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cfilter id='b' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='50'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='1 1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cimage filter='url(%23b)' x='0' y='0' height='100%25' width='100%25' href='data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAoKCgoKCgsMDAsPEA4QDxYUExMUFiIYGhgaGCIzICUgICUgMy03LCksNy1RQDg4QFFeT0pPXnFlZXGPiI+7u/sBCgoKCgoKCwwMCw8QDhAPFhQTExQWIhgaGBoYIjMgJSAgJSAzLTcsKSw3LVFAODhAUV5PSk9ecWVlcY+Ij7u7+//CABEIAAYACAMBIgACEQEDEQH/xAAnAAEBAAAAAAAAAAAAAAAAAAAABwEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAAmgP/xAAcEAACAQUBAAAAAAAAAAAAAAASFBMAAQMFERX/2gAIAQEAAT8AZ1HjrKZX55JysIc4Ff/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Af//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Af//Z'/%3E%3C/svg%3E")` ) }) } diff --git a/test/integration/image-future/default/test/static.test.js b/test/integration/image-future/default/test/static.test.js index 11b8df8e0dbc..8f120a6cad96 100644 --- a/test/integration/image-future/default/test/static.test.js +++ b/test/integration/image-future/default/test/static.test.js @@ -65,7 +65,7 @@ const runTests = () => { }) it('Should add a blur to a statically imported image in "raw" mode', async () => { expect(html).toContain( - `style="background-size:cover;background-position:0% 0%;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http%3A//www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cfilter id='b' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='50'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='1 1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cimage filter='url(%23b)' x='0' y='0' height='100%25' width='100%25' href='data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAoKCgoKCgsMDAsPEA4QDxYUExMUFiIYGhgaGCIzICUgICUgMy03LCksNy1RQDg4QFFeT0pPXnFlZXGPiI+7u/sBCgoKCgoKCwwMCw8QDhAPFhQTExQWIhgaGBoYIjMgJSAgJSAzLTcsKSw3LVFAODhAUV5PSk9ecWVlcY+Ij7u7+//CABEIAAYACAMBIgACEQEDEQH/xAAnAAEBAAAAAAAAAAAAAAAAAAAABwEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAAmgP/xAAcEAACAQUBAAAAAAAAAAAAAAASFBMAAQMFERX/2gAIAQEAAT8AZ1HjrKZX55JysIc4Ff/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Af//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Af//Z'/%3E%3C/svg%3E")` + `style="color:transparent;background-size:cover;background-position:0% 0%;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http%3A//www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cfilter id='b' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='50'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='1 1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cimage filter='url(%23b)' x='0' y='0' height='100%25' width='100%25' href='data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAoKCgoKCgsMDAsPEA4QDxYUExMUFiIYGhgaGCIzICUgICUgMy03LCksNy1RQDg4QFFeT0pPXnFlZXGPiI+7u/sBCgoKCgoKCwwMCw8QDhAPFhQTExQWIhgaGBoYIjMgJSAgJSAzLTcsKSw3LVFAODhAUV5PSk9ecWVlcY+Ij7u7+//CABEIAAYACAMBIgACEQEDEQH/xAAnAAEBAAAAAAAAAAAAAAAAAAAABwEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAAmgP/xAAcEAACAQUBAAAAAAAAAAAAAAASFBMAAQMFERX/2gAIAQEAAT8AZ1HjrKZX55JysIc4Ff/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Af//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Af//Z'/%3E%3C/svg%3E")` ) }) } From 1e63b5c3d601356ce10e69b0ff5159a467c1f707 Mon Sep 17 00:00:00 2001 From: Steven Date: Fri, 5 Aug 2022 16:37:58 -0400 Subject: [PATCH 3/8] Update onError test --- test/integration/image-future/default/test/index.test.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/integration/image-future/default/test/index.test.js b/test/integration/image-future/default/test/index.test.js index 962d94517908..7c87f57613af 100644 --- a/test/integration/image-future/default/test/index.test.js +++ b/test/integration/image-future/default/test/index.test.js @@ -361,6 +361,9 @@ function runTests(mode) { () => browser.eval(`document.getElementById("msg1").textContent`), 'no error occured for img1' ) + expect(browser.eval(`document.getElementById("img1").style.color`)).toBe( + 'transparent' + ) await browser.eval( `document.getElementById("img2").scrollIntoView({behavior: "smooth"})` ) @@ -368,11 +371,17 @@ function runTests(mode) { () => browser.eval(`document.getElementById("msg2").textContent`), 'no error occured for img2' ) + expect(browser.eval(`document.getElementById("img2").style.color`)).toBe( + 'transparent' + ) await browser.eval(`document.getElementById("toggle").click()`) await check( () => browser.eval(`document.getElementById("msg2").textContent`), 'error occured while loading img2' ) + expect( + browser.eval(`document.getElementById("img2").style.color`) + ).toBeFalsy() }) it('should work with image with blob src', async () => { From e4900ec884a1152f5e06db07e374a76d37f8fc9b Mon Sep 17 00:00:00 2001 From: Steven Date: Fri, 5 Aug 2022 22:10:16 -0400 Subject: [PATCH 4/8] Fix style so its not present on blur placeholder --- packages/next/client/future/image.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/client/future/image.tsx b/packages/next/client/future/image.tsx index bdebb1014007..d4a11ae14605 100644 --- a/packages/next/client/future/image.tsx +++ b/packages/next/client/future/image.tsx @@ -578,7 +578,7 @@ export default function Image({ width: '100%', } : {}, - showAltText ? {} : { color: 'transparent' }, + showAltText || placeholder === 'blur' ? {} : { color: 'transparent' }, style ) const svgBlurPlaceholder = `url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http%3A//www.w3.org/2000/svg' viewBox='0 0 ${widthInt} ${heightInt}'%3E%3Cfilter id='b' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='50'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='1 1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cimage filter='url(%23b)' x='0' y='0' height='100%25' width='100%25' href='${blurDataURL}'/%3E%3C/svg%3E")` From 137c4db9b21d32b948a5b5bdac41c6fe159c5daa Mon Sep 17 00:00:00 2001 From: Steven Date: Fri, 5 Aug 2022 22:10:30 -0400 Subject: [PATCH 5/8] Fix other tests checking styles --- .../image-future/default/test/index.test.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/test/integration/image-future/default/test/index.test.js b/test/integration/image-future/default/test/index.test.js index 7c87f57613af..1c4e60dd9740 100644 --- a/test/integration/image-future/default/test/index.test.js +++ b/test/integration/image-future/default/test/index.test.js @@ -453,7 +453,9 @@ function runTests(mode) { ) expect(childElementType).toBe('IMG') - expect(await browser.elementById('img1').getAttribute('style')).toBeNull() + expect(await browser.elementById('img1').getAttribute('style')).toBe( + 'color:transparent' + ) expect(await browser.elementById('img1').getAttribute('height')).toBe( '700' ) @@ -468,7 +470,7 @@ function runTests(mode) { ) expect(await browser.elementById('img2').getAttribute('style')).toBe( - 'padding-left:4rem;width:100%;object-position:30% 30%' + 'color:transparent;padding-left:4rem;width:100%;object-position:30% 30%' ) expect(await browser.elementById('img2').getAttribute('height')).toBe( '700' @@ -483,7 +485,9 @@ function runTests(mode) { 'lazy' ) - expect(await browser.elementById('img3').getAttribute('style')).toBeNull() + expect(await browser.elementById('img3').getAttribute('style')).toBe( + 'color:transparent' + ) expect(await browser.elementById('img3').getAttribute('srcset')).toBe( `/_next/image?url=%2Ftest.png&w=640&q=75 1x, /_next/image?url=%2Ftest.png&w=828&q=75 2x` ) @@ -600,14 +604,14 @@ function runTests(mode) { const browser = await webdriver(appPort, '/style-prop') expect(await browser.elementById('with-styles').getAttribute('style')).toBe( - 'border-radius:10px;padding:10px' + 'color:transparent;border-radius:10px;padding:10px' ) expect( await browser.elementById('with-overlapping-styles').getAttribute('style') - ).toBe('width:10px;border-radius:10px;margin:15px') + ).toBe('color:transparent;width:10px;border-radius:10px;margin:15px') expect( await browser.elementById('without-styles').getAttribute('style') - ).toBeNull() + ).toBe('color:transparent') }) if (mode === 'dev') { From f49ea91c92f7944f99a38cc92ceae69d3cb8a9f9 Mon Sep 17 00:00:00 2001 From: Steven Date: Fri, 5 Aug 2022 22:21:17 -0400 Subject: [PATCH 6/8] Revert static blur test --- test/integration/image-future/default/test/static.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/image-future/default/test/static.test.js b/test/integration/image-future/default/test/static.test.js index 8f120a6cad96..11b8df8e0dbc 100644 --- a/test/integration/image-future/default/test/static.test.js +++ b/test/integration/image-future/default/test/static.test.js @@ -65,7 +65,7 @@ const runTests = () => { }) it('Should add a blur to a statically imported image in "raw" mode', async () => { expect(html).toContain( - `style="color:transparent;background-size:cover;background-position:0% 0%;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http%3A//www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cfilter id='b' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='50'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='1 1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cimage filter='url(%23b)' x='0' y='0' height='100%25' width='100%25' href='data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAoKCgoKCgsMDAsPEA4QDxYUExMUFiIYGhgaGCIzICUgICUgMy03LCksNy1RQDg4QFFeT0pPXnFlZXGPiI+7u/sBCgoKCgoKCwwMCw8QDhAPFhQTExQWIhgaGBoYIjMgJSAgJSAzLTcsKSw3LVFAODhAUV5PSk9ecWVlcY+Ij7u7+//CABEIAAYACAMBIgACEQEDEQH/xAAnAAEBAAAAAAAAAAAAAAAAAAAABwEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAAmgP/xAAcEAACAQUBAAAAAAAAAAAAAAASFBMAAQMFERX/2gAIAQEAAT8AZ1HjrKZX55JysIc4Ff/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Af//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Af//Z'/%3E%3C/svg%3E")` + `style="background-size:cover;background-position:0% 0%;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http%3A//www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cfilter id='b' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='50'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='1 1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cimage filter='url(%23b)' x='0' y='0' height='100%25' width='100%25' href='data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAoKCgoKCgsMDAsPEA4QDxYUExMUFiIYGhgaGCIzICUgICUgMy03LCksNy1RQDg4QFFeT0pPXnFlZXGPiI+7u/sBCgoKCgoKCwwMCw8QDhAPFhQTExQWIhgaGBoYIjMgJSAgJSAzLTcsKSw3LVFAODhAUV5PSk9ecWVlcY+Ij7u7+//CABEIAAYACAMBIgACEQEDEQH/xAAnAAEBAAAAAAAAAAAAAAAAAAAABwEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAAmgP/xAAcEAACAQUBAAAAAAAAAAAAAAASFBMAAQMFERX/2gAIAQEAAT8AZ1HjrKZX55JysIc4Ff/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Af//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Af//Z'/%3E%3C/svg%3E")` ) }) } From 742283825e124d7b1d5dabd8837df98f604d721d Mon Sep 17 00:00:00 2001 From: Steven Date: Fri, 5 Aug 2022 22:36:30 -0400 Subject: [PATCH 7/8] Add missing await --- .../image-future/default/test/index.test.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/test/integration/image-future/default/test/index.test.js b/test/integration/image-future/default/test/index.test.js index 1c4e60dd9740..fb800d9a36d8 100644 --- a/test/integration/image-future/default/test/index.test.js +++ b/test/integration/image-future/default/test/index.test.js @@ -361,7 +361,8 @@ function runTests(mode) { () => browser.eval(`document.getElementById("msg1").textContent`), 'no error occured for img1' ) - expect(browser.eval(`document.getElementById("img1").style.color`)).toBe( + await check( + () => browser.eval(`document.getElementById("img1").style.color`), 'transparent' ) await browser.eval( @@ -371,7 +372,8 @@ function runTests(mode) { () => browser.eval(`document.getElementById("msg2").textContent`), 'no error occured for img2' ) - expect(browser.eval(`document.getElementById("img2").style.color`)).toBe( + await check( + () => browser.eval(`document.getElementById("img2").style.color`), 'transparent' ) await browser.eval(`document.getElementById("toggle").click()`) @@ -379,9 +381,10 @@ function runTests(mode) { () => browser.eval(`document.getElementById("msg2").textContent`), 'error occured while loading img2' ) - expect( - browser.eval(`document.getElementById("img2").style.color`) - ).toBeFalsy() + await check( + () => browser.eval(`document.getElementById("img2").style.color`), + '' + ) }) it('should work with image with blob src', async () => { From 604cb7b6aa4c9ed90b6419931e17be43a9ae1783 Mon Sep 17 00:00:00 2001 From: Steven Date: Fri, 5 Aug 2022 23:03:16 -0400 Subject: [PATCH 8/8] uno mas --- test/integration/image-future/base-path/test/static.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/image-future/base-path/test/static.test.js b/test/integration/image-future/base-path/test/static.test.js index d6e51ecfed59..077fab76c9e9 100644 --- a/test/integration/image-future/base-path/test/static.test.js +++ b/test/integration/image-future/base-path/test/static.test.js @@ -65,7 +65,7 @@ const runTests = () => { }) it('Should add a blur to a statically imported image', async () => { expect(html).toContain( - `style="color:transparent;background-size:cover;background-position:0% 0%;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http%3A//www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cfilter id='b' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='50'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='1 1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cimage filter='url(%23b)' x='0' y='0' height='100%25' width='100%25' href='data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAoKCgoKCgsMDAsPEA4QDxYUExMUFiIYGhgaGCIzICUgICUgMy03LCksNy1RQDg4QFFeT0pPXnFlZXGPiI+7u/sBCgoKCgoKCwwMCw8QDhAPFhQTExQWIhgaGBoYIjMgJSAgJSAzLTcsKSw3LVFAODhAUV5PSk9ecWVlcY+Ij7u7+//CABEIAAYACAMBIgACEQEDEQH/xAAnAAEBAAAAAAAAAAAAAAAAAAAABwEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAAmgP/xAAcEAACAQUBAAAAAAAAAAAAAAASFBMAAQMFERX/2gAIAQEAAT8AZ1HjrKZX55JysIc4Ff/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Af//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Af//Z'/%3E%3C/svg%3E")` + `style="background-size:cover;background-position:0% 0%;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http%3A//www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cfilter id='b' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='50'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='1 1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cimage filter='url(%23b)' x='0' y='0' height='100%25' width='100%25' href='data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAoKCgoKCgsMDAsPEA4QDxYUExMUFiIYGhgaGCIzICUgICUgMy03LCksNy1RQDg4QFFeT0pPXnFlZXGPiI+7u/sBCgoKCgoKCwwMCw8QDhAPFhQTExQWIhgaGBoYIjMgJSAgJSAzLTcsKSw3LVFAODhAUV5PSk9ecWVlcY+Ij7u7+//CABEIAAYACAMBIgACEQEDEQH/xAAnAAEBAAAAAAAAAAAAAAAAAAAABwEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAAmgP/xAAcEAACAQUBAAAAAAAAAAAAAAASFBMAAQMFERX/2gAIAQEAAT8AZ1HjrKZX55JysIc4Ff/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Af//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Af//Z'/%3E%3C/svg%3E")` ) }) }