From ee0f879acf6edbab4c080195a4b476fb9c4273a3 Mon Sep 17 00:00:00 2001 From: 11koukou Date: Thu, 3 Feb 2022 01:42:38 +0200 Subject: [PATCH 1/9] fixed lazyRoot functionality --- packages/next/client/use-intersection.tsx | 32 +++++++++++++++--- .../default/pages/lazy-noref.js | 32 ------------------ .../default/pages/lazy-withref.js | 32 ++++++++++++++++-- .../default/test/index.test.js | 33 +++++++++++++++++-- 4 files changed, 89 insertions(+), 40 deletions(-) delete mode 100644 test/integration/image-component/default/pages/lazy-noref.js diff --git a/packages/next/client/use-intersection.tsx b/packages/next/client/use-intersection.tsx index 94ee9d97f1d1e8d..7cc8904d692f21b 100644 --- a/packages/next/client/use-intersection.tsx +++ b/packages/next/client/use-intersection.tsx @@ -13,8 +13,12 @@ type UseIntersection = { disabled?: boolean } & UseIntersectionObserverInit & { rootRef?: React.RefObject | null } type ObserveCallback = (isVisible: boolean) => void +type idKey = { + root: Element | Document | null + margin: string +} type Observer = { - id: string + id: idKey observer: IntersectionObserver elements: Map } @@ -87,10 +91,30 @@ function observe( } } -const observers = new Map() +const observers = new Map() + +const idList: idKey[] = [] +function getKeyIndex(x: idKey) { + for (let i = 0; i < idList.length; i++) { + if (idList[i].root === x.root && idList[i].margin === x.margin) { + return i + } + } + return -1 +} function createObserver(options: UseIntersectionObserverInit): Observer { - const id = options.rootMargin || '' - let instance = observers.get(id) + const id = { + root: options.root || null, + margin: options.rootMargin || '', + } + let index = getKeyIndex(id) + let instance + if (index > -1) { + instance = observers.get(idList[index]) + } else { + instance = observers.get(id) + idList.push(id) + } if (instance) { return instance } diff --git a/test/integration/image-component/default/pages/lazy-noref.js b/test/integration/image-component/default/pages/lazy-noref.js deleted file mode 100644 index 3edfe7df79028d4..000000000000000 --- a/test/integration/image-component/default/pages/lazy-noref.js +++ /dev/null @@ -1,32 +0,0 @@ -import React, { useRef } from 'react' -import Image from 'next/image' - -const Page = () => { - const myRef = useRef(null) - - return ( - <> -
-
hello
-
- -
-
- - ) -} -export default Page diff --git a/test/integration/image-component/default/pages/lazy-withref.js b/test/integration/image-component/default/pages/lazy-withref.js index d21a4c0a9dad417..be990a9d4e7cda3 100644 --- a/test/integration/image-component/default/pages/lazy-withref.js +++ b/test/integration/image-component/default/pages/lazy-withref.js @@ -18,13 +18,41 @@ const Page = () => {
hello
mine + mine + mine + + mine
diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js index 35cad0906ac75ce..629ebbe3f430982 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.js @@ -1013,12 +1013,23 @@ function runTests(mode) { it('should load the image when the lazyRoot prop is used', async () => { let browser try { - //trying on '/lazy-noref' it fails browser = await webdriver(appPort, '/lazy-withref') await check(async () => { const result = await browser.eval( - `document.getElementById('myImage').naturalWidth` + `document.getElementById('myImage2').naturalWidth` + ) + + if (result < 400) { + throw new Error('Incorrectly loaded image') + } + + return 'result-correct' + }, /result-correct/) + + await check(async () => { + const result = await browser.eval( + `document.getElementById('myImage3').naturalWidth` ) if (result < 400) { @@ -1033,7 +1044,25 @@ function runTests(mode) { browser, `http://localhost:${appPort}/_next/image?url=%2Ftest.jpg&w=828&q=75` ) + ).toBe(false) + expect( + await hasImageMatchingUrl( + browser, + `http://localhost:${appPort}/_next/image?url=%2Ftest.png&w=828&q=75` + ) + ).toBe(true) + expect( + await hasImageMatchingUrl( + browser, + `http://localhost:${appPort}/_next/image?url=%2Ftest.svg&w=828&q=75` + ) ).toBe(true) + expect( + await hasImageMatchingUrl( + browser, + `http://localhost:${appPort}/_next/image?url=%2Ftest.webp&w=828&q=75` + ) + ).toBe(false) } finally { if (browser) { await browser.close() From 42fcec3d851b2ead9c831545ff8bb87090a47c2b Mon Sep 17 00:00:00 2001 From: 11koukou <97431276+11koukou@users.noreply.github.com> Date: Fri, 4 Feb 2022 09:12:55 +0200 Subject: [PATCH 2/9] Update packages/next/client/use-intersection.tsx Co-authored-by: Steven --- packages/next/client/use-intersection.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/client/use-intersection.tsx b/packages/next/client/use-intersection.tsx index 7cc8904d692f21b..54cf3c701fb0964 100644 --- a/packages/next/client/use-intersection.tsx +++ b/packages/next/client/use-intersection.tsx @@ -13,7 +13,7 @@ type UseIntersection = { disabled?: boolean } & UseIntersectionObserverInit & { rootRef?: React.RefObject | null } type ObserveCallback = (isVisible: boolean) => void -type idKey = { +type Identifier = { root: Element | Document | null margin: string } From bf847d8ec636a4fd55ae941313c1e72ea36a4450 Mon Sep 17 00:00:00 2001 From: 11koukou <97431276+11koukou@users.noreply.github.com> Date: Fri, 4 Feb 2022 09:13:10 +0200 Subject: [PATCH 3/9] Update packages/next/client/use-intersection.tsx Co-authored-by: Steven --- packages/next/client/use-intersection.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/client/use-intersection.tsx b/packages/next/client/use-intersection.tsx index 54cf3c701fb0964..b05b50dc1662833 100644 --- a/packages/next/client/use-intersection.tsx +++ b/packages/next/client/use-intersection.tsx @@ -18,7 +18,7 @@ type Identifier = { margin: string } type Observer = { - id: idKey + id: Identifier observer: IntersectionObserver elements: Map } From cf70d1bb4f6ec8eb49c50c1d124cd4f6d6ca63d3 Mon Sep 17 00:00:00 2001 From: 11koukou <97431276+11koukou@users.noreply.github.com> Date: Fri, 4 Feb 2022 09:13:18 +0200 Subject: [PATCH 4/9] Update packages/next/client/use-intersection.tsx Co-authored-by: Steven --- packages/next/client/use-intersection.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/client/use-intersection.tsx b/packages/next/client/use-intersection.tsx index b05b50dc1662833..8caddf9ae9498f9 100644 --- a/packages/next/client/use-intersection.tsx +++ b/packages/next/client/use-intersection.tsx @@ -91,7 +91,7 @@ function observe( } } -const observers = new Map() +const observers = new Map() const idList: idKey[] = [] function getKeyIndex(x: idKey) { From 74f9d2b4e38a4133542a7cb09e352343bc505a2a Mon Sep 17 00:00:00 2001 From: 11koukou <97431276+11koukou@users.noreply.github.com> Date: Fri, 4 Feb 2022 09:13:33 +0200 Subject: [PATCH 5/9] Update packages/next/client/use-intersection.tsx Co-authored-by: Steven --- packages/next/client/use-intersection.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/next/client/use-intersection.tsx b/packages/next/client/use-intersection.tsx index 8caddf9ae9498f9..43644c084637406 100644 --- a/packages/next/client/use-intersection.tsx +++ b/packages/next/client/use-intersection.tsx @@ -93,8 +93,8 @@ function observe( const observers = new Map() -const idList: idKey[] = [] -function getKeyIndex(x: idKey) { +const idList: Identifier[] = [] +function getKeyIndex(x: Identifier) { for (let i = 0; i < idList.length; i++) { if (idList[i].root === x.root && idList[i].margin === x.margin) { return i From 021e79c3260156c1911c9f1e818df18ef86d8796 Mon Sep 17 00:00:00 2001 From: 11koukou <97431276+11koukou@users.noreply.github.com> Date: Fri, 4 Feb 2022 09:14:47 +0200 Subject: [PATCH 6/9] Update packages/next/client/use-intersection.tsx Co-authored-by: Steven --- packages/next/client/use-intersection.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/next/client/use-intersection.tsx b/packages/next/client/use-intersection.tsx index 43644c084637406..ecac69f184a6d15 100644 --- a/packages/next/client/use-intersection.tsx +++ b/packages/next/client/use-intersection.tsx @@ -107,10 +107,10 @@ function createObserver(options: UseIntersectionObserverInit): Observer { root: options.root || null, margin: options.rootMargin || '', } - let index = getKeyIndex(id) + let existing = idList.find(obj => obj.root === id.root && obj.margin === id.margin) let instance - if (index > -1) { - instance = observers.get(idList[index]) + if (existing) { + instance = observers.get(existing) } else { instance = observers.get(id) idList.push(id) From 3d6d309ae4476195feb31ef73577a820cdc0e3ab Mon Sep 17 00:00:00 2001 From: 11koukou Date: Fri, 4 Feb 2022 23:58:55 +0200 Subject: [PATCH 7/9] removed getKeyIndex --- packages/next/client/use-intersection.tsx | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/packages/next/client/use-intersection.tsx b/packages/next/client/use-intersection.tsx index ecac69f184a6d15..88506c9f85eeb71 100644 --- a/packages/next/client/use-intersection.tsx +++ b/packages/next/client/use-intersection.tsx @@ -94,20 +94,15 @@ function observe( const observers = new Map() const idList: Identifier[] = [] -function getKeyIndex(x: Identifier) { - for (let i = 0; i < idList.length; i++) { - if (idList[i].root === x.root && idList[i].margin === x.margin) { - return i - } - } - return -1 -} + function createObserver(options: UseIntersectionObserverInit): Observer { const id = { root: options.root || null, margin: options.rootMargin || '', } - let existing = idList.find(obj => obj.root === id.root && obj.margin === id.margin) + let existing = idList.find( + (obj) => obj.root === id.root && obj.margin === id.margin + ) let instance if (existing) { instance = observers.get(existing) From 7d9fb0d9132764c11770bf632b6590c4e57f9139 Mon Sep 17 00:00:00 2001 From: 11koukou Date: Sat, 5 Feb 2022 23:48:18 +0200 Subject: [PATCH 8/9] fixed freeing observers' idList --- packages/next/client/use-intersection.tsx | 6 ++++++ test/integration/image-component/default/test/index.test.js | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/next/client/use-intersection.tsx b/packages/next/client/use-intersection.tsx index 88506c9f85eeb71..1b3a39db57d9d3e 100644 --- a/packages/next/client/use-intersection.tsx +++ b/packages/next/client/use-intersection.tsx @@ -87,6 +87,12 @@ function observe( if (elements.size === 0) { observer.disconnect() observers.delete(id) + let index = idList.findIndex( + (obj) => obj.root === id.root && obj.margin === id.margin + ) + if (index > -1) { + idList.splice(index, 1) + } } } } diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js index 629ebbe3f430982..4add9cbd22ce8b9 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.js @@ -1010,7 +1010,7 @@ function runTests(mode) { } }) - it('should load the image when the lazyRoot prop is used', async () => { + it('should initially load only two of four images using lazyroot', async () => { let browser try { browser = await webdriver(appPort, '/lazy-withref') From c14950434a4aa4baae46ed366cb146e6945b5416 Mon Sep 17 00:00:00 2001 From: 11koukou Date: Sun, 6 Feb 2022 00:55:53 +0200 Subject: [PATCH 9/9] fixed the test --- .../default/test/index.test.js | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js index 4add9cbd22ce8b9..8267389e1c948b2 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.js @@ -1014,6 +1014,29 @@ function runTests(mode) { let browser try { browser = await webdriver(appPort, '/lazy-withref') + await check(async () => { + const result = await browser.eval( + `document.getElementById('myImage1').naturalWidth` + ) + + if (result >= 400) { + throw new Error('Incorrectly loaded image') + } + + return 'result-correct' + }, /result-correct/) + + await check(async () => { + const result = await browser.eval( + `document.getElementById('myImage4').naturalWidth` + ) + + if (result >= 400) { + throw new Error('Incorrectly loaded image') + } + + return 'result-correct' + }, /result-correct/) await check(async () => { const result = await browser.eval(