From 2edfc74a92bc361bc6d60c6f39700efa37b91f33 Mon Sep 17 00:00:00 2001 From: atcastle Date: Fri, 29 Jan 2021 11:08:25 -0800 Subject: [PATCH 1/8] Allow smaller-than-viewport sizes in srcset for image with fill layout and sizes property --- packages/next/client/image.tsx | 16 ++++++++++++++-- .../image-component/default/pages/layout-fill.js | 4 ++-- .../image-component/default/test/index.test.js | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index 2cd80c1d0c6ba..158ab69c26e22 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -89,13 +89,25 @@ allSizes.sort((a, b) => a - b) function getWidths( width: number | undefined, - layout: LayoutValue + layout: LayoutValue, + sizes: string | undefined ): { widths: number[]; kind: 'w' | 'x' } { if ( typeof width !== 'number' || layout === 'fill' || layout === 'responsive' ) { + if (sizes) { + const percentSize = sizes.match(/^(1?\d?\d)vw$/) + if (percentSize) { + const ratio = parseInt(percentSize[1]) * 0.01 + return { + widths: allSizes.filter((s) => s >= configDeviceSizes[0] * ratio), + kind: 'w', + } + } + return { widths: allSizes, kind: 'w' } + } return { widths: configDeviceSizes, kind: 'w' } } @@ -146,7 +158,7 @@ function generateImgAttrs({ return { src, srcSet: undefined, sizes: undefined } } - const { widths, kind } = getWidths(width, layout) + const { widths, kind } = getWidths(width, layout, sizes) const last = widths.length - 1 return { diff --git a/test/integration/image-component/default/pages/layout-fill.js b/test/integration/image-component/default/pages/layout-fill.js index e442c041b9a2e..f774fd9045678 100644 --- a/test/integration/image-component/default/pages/layout-fill.js +++ b/test/integration/image-component/default/pages/layout-fill.js @@ -5,8 +5,8 @@ const Page = () => { return (

Layout Fill

-
- +
+

Layout Fill

diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js index bed5dec4337a3..1fc9b3e2b1e82 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.js @@ -339,7 +339,7 @@ function runTests(mode) { '/_next/image?url=%2Fwide.png&w=3840&q=75' ) expect(await browser.elementById(id).getAttribute('srcset')).toBe( - '/_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w' + '/_next/image?url=%2Fwide.png&w=256&q=75 256w, /_next/image?url=%2Fwide.png&w=384&q=75 384w, /_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w' ) expect(await browser.elementById(id).getAttribute('sizes')).toBe('100vw') await browser.setDimensions({ From 7cae0a29fdf16591d4631fe3642ae21abbbf7338 Mon Sep 17 00:00:00 2001 From: atcastle Date: Fri, 29 Jan 2021 11:25:43 -0800 Subject: [PATCH 2/8] Adjust integration test values --- .../image-component/default/pages/layout-fill.js | 7 ++++--- .../integration/image-component/default/test/index.test.js | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/test/integration/image-component/default/pages/layout-fill.js b/test/integration/image-component/default/pages/layout-fill.js index f774fd9045678..2ddbb8f356f48 100644 --- a/test/integration/image-component/default/pages/layout-fill.js +++ b/test/integration/image-component/default/pages/layout-fill.js @@ -5,17 +5,18 @@ const Page = () => { return (

Layout Fill

-
- +
+

Layout Fill

-
+

Layout Fill

diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js index 1fc9b3e2b1e82..ef207efe6644a 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.js @@ -339,7 +339,7 @@ function runTests(mode) { '/_next/image?url=%2Fwide.png&w=3840&q=75' ) expect(await browser.elementById(id).getAttribute('srcset')).toBe( - '/_next/image?url=%2Fwide.png&w=256&q=75 256w, /_next/image?url=%2Fwide.png&w=384&q=75 384w, /_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w' + '/_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w' ) expect(await browser.elementById(id).getAttribute('sizes')).toBe('100vw') await browser.setDimensions({ @@ -379,7 +379,7 @@ function runTests(mode) { '/_next/image?url=%2Fwide.png&w=3840&q=75' ) expect(await browser.elementById(id).getAttribute('srcset')).toBe( - '/_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w' + 'srcset="/_next/image?url=%2Fwide.png&w=384&q=75 384w, /_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w"' ) expect(await browser.elementById(id).getAttribute('sizes')).toBe('100vw') expect(await getComputed(browser, id, 'width')).toBe(width) From d7bfe910388f9c1befb61c60235175998290bee3 Mon Sep 17 00:00:00 2001 From: atcastle Date: Fri, 29 Jan 2021 11:33:08 -0800 Subject: [PATCH 3/8] Separate image fill sizing integration test into separate expect statement --- .../image-component/default/pages/layout-fill.js | 13 +++++++++++-- .../image-component/default/test/index.test.js | 3 +++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/test/integration/image-component/default/pages/layout-fill.js b/test/integration/image-component/default/pages/layout-fill.js index 2ddbb8f356f48..5631daef0cdc1 100644 --- a/test/integration/image-component/default/pages/layout-fill.js +++ b/test/integration/image-component/default/pages/layout-fill.js @@ -9,17 +9,26 @@ const Page = () => {

Layout Fill

-
+

Layout Fill

+
+ +
) } diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js index ef207efe6644a..783ede01f643d 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.js @@ -379,6 +379,9 @@ function runTests(mode) { '/_next/image?url=%2Fwide.png&w=3840&q=75' ) expect(await browser.elementById(id).getAttribute('srcset')).toBe( + '/_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w"' + ) + expect(await browser.elementById('fill3').getAttribute('srcset')).toBe( 'srcset="/_next/image?url=%2Fwide.png&w=384&q=75 384w, /_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w"' ) expect(await browser.elementById(id).getAttribute('sizes')).toBe('100vw') From 130c8fb2e3d5feeb2300e082c1e58757ce695a4a Mon Sep 17 00:00:00 2001 From: atcastle Date: Fri, 29 Jan 2021 12:48:35 -0800 Subject: [PATCH 4/8] Update optimization to take into account more complex sizes values --- packages/next/client/image.tsx | 12 ++++++++---- .../image-component/default/pages/layout-fill.js | 4 +++- .../image-component/default/test/index.test.js | 4 ++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index 158ab69c26e22..184e87c3cab79 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -98,11 +98,15 @@ function getWidths( layout === 'responsive' ) { if (sizes) { - const percentSize = sizes.match(/^(1?\d?\d)vw$/) - if (percentSize) { - const ratio = parseInt(percentSize[1]) * 0.01 + const percentSizes = [...sizes.matchAll(/(^|\s)(1?\d?\d)vw/g)].map((m) => + parseInt(m[2]) + ) + if (percentSizes.length) { + const smallestRatio = Math.min(...percentSizes) * 0.01 return { - widths: allSizes.filter((s) => s >= configDeviceSizes[0] * ratio), + widths: allSizes.filter( + (s) => s >= configDeviceSizes[0] * smallestRatio + ), kind: 'w', } } diff --git a/test/integration/image-component/default/pages/layout-fill.js b/test/integration/image-component/default/pages/layout-fill.js index 5631daef0cdc1..e5858152307a2 100644 --- a/test/integration/image-component/default/pages/layout-fill.js +++ b/test/integration/image-component/default/pages/layout-fill.js @@ -26,7 +26,9 @@ const Page = () => { layout="fill" objectFit="cover" objectPosition="left center" - sizes="50vw" + sizes="(min-width: 1200px) 90vw, + (min-width: 800px) 30vw, + 100vw" />
diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js index 783ede01f643d..ac495b0d9597f 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.js @@ -379,10 +379,10 @@ function runTests(mode) { '/_next/image?url=%2Fwide.png&w=3840&q=75' ) expect(await browser.elementById(id).getAttribute('srcset')).toBe( - '/_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w"' + '/_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w' ) expect(await browser.elementById('fill3').getAttribute('srcset')).toBe( - 'srcset="/_next/image?url=%2Fwide.png&w=384&q=75 384w, /_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w"' + '/_next/image?url=%2Fwide.png&w=256&q=75 256w, /_next/image?url=%2Fwide.png&w=384&q=75 384w, /_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w' ) expect(await browser.elementById(id).getAttribute('sizes')).toBe('100vw') expect(await getComputed(browser, id, 'width')).toBe(width) From 3317dbbbcdddae668d493f496aaf0748f55ede2d Mon Sep 17 00:00:00 2001 From: atcastle Date: Fri, 29 Jan 2021 13:11:31 -0800 Subject: [PATCH 5/8] Add layout fill sizing integration test case for px values --- .../image-component/default/pages/layout-fill.js | 11 +++++++++++ .../image-component/default/test/index.test.js | 3 +++ 2 files changed, 14 insertions(+) diff --git a/test/integration/image-component/default/pages/layout-fill.js b/test/integration/image-component/default/pages/layout-fill.js index e5858152307a2..739b36f46b848 100644 --- a/test/integration/image-component/default/pages/layout-fill.js +++ b/test/integration/image-component/default/pages/layout-fill.js @@ -31,6 +31,17 @@ const Page = () => { 100vw" />
+

Layout Fill

+
+ +
) } diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js index ac495b0d9597f..7f7f4d54e122c 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.js @@ -384,6 +384,9 @@ function runTests(mode) { expect(await browser.elementById('fill3').getAttribute('srcset')).toBe( '/_next/image?url=%2Fwide.png&w=256&q=75 256w, /_next/image?url=%2Fwide.png&w=384&q=75 384w, /_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w' ) + expect(await browser.elementById('fill4').getAttribute('srcset')).toBe( + '/_next/image?url=%2Fwide.png&w=16&q=75 16w, /_next/image?url=%2Fwide.png&w=32&q=75 32w, /_next/image?url=%2Fwide.png&w=48&q=75 48w, /_next/image?url=%2Fwide.png&w=64&q=75 64w, /_next/image?url=%2Fwide.png&w=96&q=75 96w, /_next/image?url=%2Fwide.png&w=128&q=75 128w, /_next/image?url=%2Fwide.png&w=256&q=75 256w, /_next/image?url=%2Fwide.png&w=384&q=75 384w, /_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w' + ) expect(await browser.elementById(id).getAttribute('sizes')).toBe('100vw') expect(await getComputed(browser, id, 'width')).toBe(width) expect(await getComputed(browser, id, 'height')).toBe(height) From 562f7f4c03c44eeb63a92b788a4dade7a00871b7 Mon Sep 17 00:00:00 2001 From: atcastle Date: Fri, 29 Jan 2021 13:48:17 -0800 Subject: [PATCH 6/8] Don't apply new image component sizes rule to responsive layout, and tweak integration tests --- packages/next/client/image.tsx | 2 +- .../image-component/default/test/index.test.js | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index 184e87c3cab79..f475ce826273e 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -97,7 +97,7 @@ function getWidths( layout === 'fill' || layout === 'responsive' ) { - if (sizes) { + if (sizes && layout === 'fill') { const percentSizes = [...sizes.matchAll(/(^|\s)(1?\d?\d)vw/g)].map((m) => parseInt(m[2]) ) diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js index 7f7f4d54e122c..464bb24456633 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.js @@ -381,12 +381,6 @@ function runTests(mode) { expect(await browser.elementById(id).getAttribute('srcset')).toBe( '/_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w' ) - expect(await browser.elementById('fill3').getAttribute('srcset')).toBe( - '/_next/image?url=%2Fwide.png&w=256&q=75 256w, /_next/image?url=%2Fwide.png&w=384&q=75 384w, /_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w' - ) - expect(await browser.elementById('fill4').getAttribute('srcset')).toBe( - '/_next/image?url=%2Fwide.png&w=16&q=75 16w, /_next/image?url=%2Fwide.png&w=32&q=75 32w, /_next/image?url=%2Fwide.png&w=48&q=75 48w, /_next/image?url=%2Fwide.png&w=64&q=75 64w, /_next/image?url=%2Fwide.png&w=96&q=75 96w, /_next/image?url=%2Fwide.png&w=128&q=75 128w, /_next/image?url=%2Fwide.png&w=256&q=75 256w, /_next/image?url=%2Fwide.png&w=384&q=75 384w, /_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w' - ) expect(await browser.elementById(id).getAttribute('sizes')).toBe('100vw') expect(await getComputed(browser, id, 'width')).toBe(width) expect(await getComputed(browser, id, 'height')).toBe(height) @@ -416,6 +410,14 @@ function runTests(mode) { ) expect(objectFit).toBe('cover') expect(objectPosition).toBe('left center') + await browser.eval(`document.getElementById("fill3").scrollIntoView()`) + expect(await browser.elementById('fill3').getAttribute('srcset')).toBe( + '/_next/image?url=%2Fwide.png&w=256&q=75 256w, /_next/image?url=%2Fwide.png&w=384&q=75 384w, /_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w' + ) + await browser.eval(`document.getElementById("fill4").scrollIntoView()`) + expect(await browser.elementById('fill4').getAttribute('srcset')).toBe( + '/_next/image?url=%2Fwide.png&w=16&q=75 16w, /_next/image?url=%2Fwide.png&w=32&q=75 32w, /_next/image?url=%2Fwide.png&w=48&q=75 48w, /_next/image?url=%2Fwide.png&w=64&q=75 64w, /_next/image?url=%2Fwide.png&w=96&q=75 96w, /_next/image?url=%2Fwide.png&w=128&q=75 128w, /_next/image?url=%2Fwide.png&w=256&q=75 256w, /_next/image?url=%2Fwide.png&w=384&q=75 384w, /_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w' + ) } finally { if (browser) { await browser.close() From 72320f00577245109178a1be75cb10455f2db96e Mon Sep 17 00:00:00 2001 From: atcastle Date: Fri, 29 Jan 2021 16:29:15 -0800 Subject: [PATCH 7/8] Refactor support for responsive layout with sizes prop and clean up integration test --- packages/next/client/image.tsx | 31 ++++++++++--------- .../default/test/index.test.js | 4 +-- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index f475ce826273e..43a4a32da4014 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -92,26 +92,27 @@ function getWidths( layout: LayoutValue, sizes: string | undefined ): { widths: number[]; kind: 'w' | 'x' } { + if (sizes && (layout === 'fill' || layout === 'responsive')) { + // Find all the "vw" percent sizes used in the sizes prop + const percentSizes = [...sizes.matchAll(/(^|\s)(1?\d?\d)vw/g)].map((m) => + parseInt(m[2]) + ) + if (percentSizes.length) { + const smallestRatio = Math.min(...percentSizes) * 0.01 + return { + widths: allSizes.filter( + (s) => s >= configDeviceSizes[0] * smallestRatio + ), + kind: 'w', + } + } + return { widths: allSizes, kind: 'w' } + } if ( typeof width !== 'number' || layout === 'fill' || layout === 'responsive' ) { - if (sizes && layout === 'fill') { - const percentSizes = [...sizes.matchAll(/(^|\s)(1?\d?\d)vw/g)].map((m) => - parseInt(m[2]) - ) - if (percentSizes.length) { - const smallestRatio = Math.min(...percentSizes) * 0.01 - return { - widths: allSizes.filter( - (s) => s >= configDeviceSizes[0] * smallestRatio - ), - kind: 'w', - } - } - return { widths: allSizes, kind: 'w' } - } return { widths: configDeviceSizes, kind: 'w' } } diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js index 464bb24456633..4d8f90329ba7e 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.js @@ -416,7 +416,7 @@ function runTests(mode) { ) await browser.eval(`document.getElementById("fill4").scrollIntoView()`) expect(await browser.elementById('fill4').getAttribute('srcset')).toBe( - '/_next/image?url=%2Fwide.png&w=16&q=75 16w, /_next/image?url=%2Fwide.png&w=32&q=75 32w, /_next/image?url=%2Fwide.png&w=48&q=75 48w, /_next/image?url=%2Fwide.png&w=64&q=75 64w, /_next/image?url=%2Fwide.png&w=96&q=75 96w, /_next/image?url=%2Fwide.png&w=128&q=75 128w, /_next/image?url=%2Fwide.png&w=256&q=75 256w, /_next/image?url=%2Fwide.png&w=384&q=75 384w, /_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w' + '/_next/image?url=%2Fwide.png&w=16&q=75 16w, /_next/image?url=%2Fwide.png&w=32&q=75 32w, /_next/image?url=%2Fwide.png&w=48&q=75 48w, /_next/image?url=%2Fwide.png&w=64&q=75 64w, /_next/image?url=%2Fwide.png&w=96&q=75 96w, /_next/image?url=%2Fwide.png&w=128&q=75 128w, /_next/image?url=%2Fwide.png&w=256&q=75 256w, /_next/image?url=%2Fwide.png&w=384&q=75 384w, /_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w' ) } finally { if (browser) { @@ -437,7 +437,7 @@ function runTests(mode) { '/_next/image?url=%2Fwide.png&w=3840&q=75' ) expect(await browser.elementById(id).getAttribute('srcset')).toBe( - '/_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w' + '/_next/image?url=%2Fwide.png&w=16&q=75 16w, /_next/image?url=%2Fwide.png&w=32&q=75 32w, /_next/image?url=%2Fwide.png&w=48&q=75 48w, /_next/image?url=%2Fwide.png&w=64&q=75 64w, /_next/image?url=%2Fwide.png&w=96&q=75 96w, /_next/image?url=%2Fwide.png&w=128&q=75 128w, /_next/image?url=%2Fwide.png&w=256&q=75 256w, /_next/image?url=%2Fwide.png&w=384&q=75 384w, /_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w' ) expect(await browser.elementById(id).getAttribute('sizes')).toBe( '(max-width: 2048px) 1200px, 3840px' From fa82398cfa4681b390f1b37960b5750c50033cd5 Mon Sep 17 00:00:00 2001 From: atcastle Date: Wed, 24 Feb 2021 13:56:01 -0800 Subject: [PATCH 8/8] Update base-path image component test to reflect new sizes behavior --- test/integration/image-component/base-path/test/index.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/image-component/base-path/test/index.test.js b/test/integration/image-component/base-path/test/index.test.js index ec75f57b1e62f..e5c98edf13f20 100644 --- a/test/integration/image-component/base-path/test/index.test.js +++ b/test/integration/image-component/base-path/test/index.test.js @@ -371,7 +371,7 @@ function runTests(mode) { '/docs/_next/image?url=%2Fdocs%2Fwide.png&w=3840&q=75' ) expect(await browser.elementById(id).getAttribute('srcset')).toBe( - '/docs/_next/image?url=%2Fdocs%2Fwide.png&w=640&q=75 640w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=750&q=75 750w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=828&q=75 828w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=1080&q=75 1080w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=1200&q=75 1200w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=1920&q=75 1920w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=2048&q=75 2048w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=3840&q=75 3840w' + '/docs/_next/image?url=%2Fdocs%2Fwide.png&w=16&q=75 16w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=32&q=75 32w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=48&q=75 48w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=64&q=75 64w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=96&q=75 96w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=128&q=75 128w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=256&q=75 256w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=384&q=75 384w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=640&q=75 640w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=750&q=75 750w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=828&q=75 828w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=1080&q=75 1080w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=1200&q=75 1200w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=1920&q=75 1920w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=2048&q=75 2048w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=3840&q=75 3840w' ) expect(await browser.elementById(id).getAttribute('sizes')).toBe( '(max-width: 2048px) 1200px, 3840px'