Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
gitlab-ce
Commits
1877eb49
Commit
1877eb49
authored
6 years ago
by
Luke Bennett
Committed by
Fatih Acet
6 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Attempt to fix lazy loader spec transient failure
parent
ceae9f52
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
149 additions
and
75 deletions
+149
-75
app/assets/javascripts/lazy_loader.js
app/assets/javascripts/lazy_loader.js
+3
-3
spec/javascripts/helpers/scroll_into_view_promise.js
spec/javascripts/helpers/scroll_into_view_promise.js
+28
-0
spec/javascripts/helpers/wait_for_attribute_change.js
spec/javascripts/helpers/wait_for_attribute_change.js
+16
-0
spec/javascripts/lazy_loader_spec.js
spec/javascripts/lazy_loader_spec.js
+102
-72
No files found.
app/assets/javascripts/lazy_loader.js
View file @
1877eb49
...
...
@@ -19,7 +19,7 @@ export default class LazyLoader {
}
searchLazyImages
()
{
requestIdleCallback
(
window
.
requestIdleCallback
(
()
=>
{
const
lazyImages
=
[].
slice
.
call
(
document
.
querySelectorAll
(
'
.lazy
'
));
...
...
@@ -107,7 +107,7 @@ export default class LazyLoader {
}
scrollCheck
()
{
requestAnimationFrame
(()
=>
this
.
checkElementsInView
());
window
.
requestAnimationFrame
(()
=>
this
.
checkElementsInView
());
}
checkElementsInView
()
{
...
...
@@ -122,7 +122,7 @@ export default class LazyLoader {
const
imgBound
=
imgTop
+
imgBoundRect
.
height
;
if
(
scrollTop
<=
imgBound
&&
visHeight
>=
imgTop
)
{
requestAnimationFrame
(()
=>
{
window
.
requestAnimationFrame
(()
=>
{
LazyLoader
.
loadImage
(
selectedImage
);
});
return
false
;
...
...
This diff is collapsed.
Click to expand it.
spec/javascripts/helpers/scroll_into_view_promise.js
0 → 100644
View file @
1877eb49
export
default
function
scrollIntoViewPromise
(
intersectionTarget
,
timeout
=
100
,
maxTries
=
5
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
let
intersectionObserver
;
let
retry
=
0
;
const
intervalId
=
setInterval
(()
=>
{
if
(
retry
>=
maxTries
)
{
intersectionObserver
.
disconnect
();
clearInterval
(
intervalId
);
reject
(
new
Error
(
`Could not scroll target into viewPort within
${
timeout
*
maxTries
}
ms`
));
}
retry
+=
1
;
intersectionTarget
.
scrollIntoView
();
},
timeout
);
intersectionObserver
=
new
IntersectionObserver
(
entries
=>
{
if
(
entries
[
0
].
isIntersecting
)
{
intersectionObserver
.
disconnect
();
clearInterval
(
intervalId
);
resolve
();
}
});
intersectionObserver
.
observe
(
intersectionTarget
);
intersectionTarget
.
scrollIntoView
();
});
}
This diff is collapsed.
Click to expand it.
spec/javascripts/helpers/wait_for_attribute_change.js
0 → 100644
View file @
1877eb49
export
default
(
domElement
,
attributes
,
timeout
=
1500
)
=>
new
Promise
((
resolve
,
reject
)
=>
{
let
observer
;
const
timeoutId
=
setTimeout
(()
=>
{
observer
.
disconnect
();
reject
(
new
Error
(
`Could not see an attribute update within
${
timeout
}
ms`
));
},
timeout
);
observer
=
new
MutationObserver
(()
=>
{
clearTimeout
(
timeoutId
);
observer
.
disconnect
();
resolve
();
});
observer
.
observe
(
domElement
,
{
attributes
:
true
,
attributeFilter
:
attributes
});
});
This diff is collapsed.
Click to expand it.
spec/javascripts/lazy_loader_spec.js
View file @
1877eb49
import
LazyLoader
from
'
~/lazy_loader
'
;
import
{
TEST_HOST
}
from
'
./test_constants
'
;
let
lazyLoader
=
null
;
import
scrollIntoViewPromise
from
'
./helpers/scroll_into_view_promise
'
;
import
waitForPromises
from
'
./helpers/wait_for_promises
'
;
import
waitForAttributeChange
from
'
./helpers/wait_for_attribute_change
'
;
const
execImmediately
=
callback
=>
{
callback
();
};
describe
(
'
LazyLoader
'
,
function
()
{
let
lazyLoader
=
null
;
preloadFixtures
(
'
issues/issue_with_comment.html.raw
'
);
describe
(
'
with
IntersectionObserver disabled
'
,
()
=>
{
describe
(
'
with
out IntersectionObserver
'
,
()
=>
{
beforeEach
(
function
()
{
loadFixtures
(
'
issues/issue_with_comment.html.raw
'
);
...
...
@@ -36,14 +39,15 @@ describe('LazyLoader', function() {
it
(
'
should copy value from data-src to src for img 1
'
,
function
(
done
)
{
const
img
=
document
.
querySelectorAll
(
'
img[data-src]
'
)[
0
];
const
originalDataSrc
=
img
.
getAttribute
(
'
data-src
'
);
img
.
scrollIntoView
();
setTimeout
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
toHaveBeenCalled
();
expect
(
img
.
getAttribute
(
'
src
'
)).
toBe
(
originalDataSrc
);
expect
(
img
).
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
},
50
);
Promise
.
all
([
scrollIntoViewPromise
(
img
),
waitForAttributeChange
(
img
,
[
'
data-src
'
,
'
src
'
])])
.
then
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
toHaveBeenCalled
();
expect
(
img
.
getAttribute
(
'
src
'
)).
toBe
(
originalDataSrc
);
expect
(
img
).
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
})
.
catch
(
done
.
fail
);
});
it
(
'
should lazy load dynamically added data-src images
'
,
function
(
done
)
{
...
...
@@ -52,14 +56,18 @@ describe('LazyLoader', function() {
newImg
.
className
=
'
lazy
'
;
newImg
.
setAttribute
(
'
data-src
'
,
testPath
);
document
.
body
.
appendChild
(
newImg
);
newImg
.
scrollIntoView
();
setTimeout
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
toHaveBeenCalled
();
expect
(
newImg
.
getAttribute
(
'
src
'
)).
toBe
(
testPath
);
expect
(
newImg
).
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
},
50
);
Promise
.
all
([
scrollIntoViewPromise
(
newImg
),
waitForAttributeChange
(
newImg
,
[
'
data-src
'
,
'
src
'
]),
])
.
then
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
toHaveBeenCalled
();
expect
(
newImg
.
getAttribute
(
'
src
'
)).
toBe
(
testPath
);
expect
(
newImg
).
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
})
.
catch
(
done
.
fail
);
});
it
(
'
should not alter normal images
'
,
function
(
done
)
{
...
...
@@ -67,13 +75,15 @@ describe('LazyLoader', function() {
const
testPath
=
`
${
TEST_HOST
}
/img/testimg.png`
;
newImg
.
setAttribute
(
'
src
'
,
testPath
);
document
.
body
.
appendChild
(
newImg
);
newImg
.
scrollIntoView
();
setTimeout
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
not
.
toHaveBeenCalled
();
expect
(
newImg
).
not
.
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
},
50
);
scrollIntoViewPromise
(
newImg
)
.
then
(
waitForPromises
)
.
then
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
not
.
toHaveBeenCalled
();
expect
(
newImg
).
not
.
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
})
.
catch
(
done
.
fail
);
});
it
(
'
should not load dynamically added pictures if content observer is turned off
'
,
done
=>
{
...
...
@@ -84,13 +94,15 @@ describe('LazyLoader', function() {
newImg
.
className
=
'
lazy
'
;
newImg
.
setAttribute
(
'
data-src
'
,
testPath
);
document
.
body
.
appendChild
(
newImg
);
newImg
.
scrollIntoView
();
setTimeout
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
not
.
toHaveBeenCalled
();
expect
(
newImg
).
not
.
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
},
50
);
scrollIntoViewPromise
(
newImg
)
.
then
(
waitForPromises
)
.
then
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
not
.
toHaveBeenCalled
();
expect
(
newImg
).
not
.
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
})
.
catch
(
done
.
fail
);
});
it
(
'
should load dynamically added pictures if content observer is turned off and on again
'
,
done
=>
{
...
...
@@ -102,17 +114,22 @@ describe('LazyLoader', function() {
newImg
.
className
=
'
lazy
'
;
newImg
.
setAttribute
(
'
data-src
'
,
testPath
);
document
.
body
.
appendChild
(
newImg
);
newImg
.
scrollIntoView
();
setTimeout
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
toHaveBeenCalled
();
expect
(
newImg
).
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
},
50
);
Promise
.
all
([
scrollIntoViewPromise
(
newImg
),
waitForAttributeChange
(
newImg
,
[
'
data-src
'
,
'
src
'
]),
])
.
then
(
waitForPromises
)
.
then
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
toHaveBeenCalled
();
expect
(
newImg
).
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
})
.
catch
(
done
.
fail
);
});
});
describe
(
'
with IntersectionObserver
enabled
'
,
()
=>
{
describe
(
'
with IntersectionObserver
'
,
()
=>
{
beforeEach
(
function
()
{
loadFixtures
(
'
issues/issue_with_comment.html.raw
'
);
...
...
@@ -136,14 +153,15 @@ describe('LazyLoader', function() {
it
(
'
should copy value from data-src to src for img 1
'
,
function
(
done
)
{
const
img
=
document
.
querySelectorAll
(
'
img[data-src]
'
)[
0
];
const
originalDataSrc
=
img
.
getAttribute
(
'
data-src
'
);
img
.
scrollIntoView
();
setTimeout
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
toHaveBeenCalled
();
expect
(
img
.
getAttribute
(
'
src
'
)).
toBe
(
originalDataSrc
);
expect
(
img
).
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
},
50
);
Promise
.
all
([
scrollIntoViewPromise
(
img
),
waitForAttributeChange
(
img
,
[
'
data-src
'
,
'
src
'
])])
.
then
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
toHaveBeenCalled
();
expect
(
img
.
getAttribute
(
'
src
'
)).
toBe
(
originalDataSrc
);
expect
(
img
).
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
})
.
catch
(
done
.
fail
);
});
it
(
'
should lazy load dynamically added data-src images
'
,
function
(
done
)
{
...
...
@@ -152,14 +170,18 @@ describe('LazyLoader', function() {
newImg
.
className
=
'
lazy
'
;
newImg
.
setAttribute
(
'
data-src
'
,
testPath
);
document
.
body
.
appendChild
(
newImg
);
newImg
.
scrollIntoView
();
setTimeout
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
toHaveBeenCalled
();
expect
(
newImg
.
getAttribute
(
'
src
'
)).
toBe
(
testPath
);
expect
(
newImg
).
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
},
50
);
Promise
.
all
([
scrollIntoViewPromise
(
newImg
),
waitForAttributeChange
(
newImg
,
[
'
data-src
'
,
'
src
'
]),
])
.
then
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
toHaveBeenCalled
();
expect
(
newImg
.
getAttribute
(
'
src
'
)).
toBe
(
testPath
);
expect
(
newImg
).
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
})
.
catch
(
done
.
fail
);
});
it
(
'
should not alter normal images
'
,
function
(
done
)
{
...
...
@@ -167,13 +189,15 @@ describe('LazyLoader', function() {
const
testPath
=
`
${
TEST_HOST
}
/img/testimg.png`
;
newImg
.
setAttribute
(
'
src
'
,
testPath
);
document
.
body
.
appendChild
(
newImg
);
newImg
.
scrollIntoView
();
setTimeout
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
not
.
toHaveBeenCalled
();
expect
(
newImg
).
not
.
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
},
50
);
scrollIntoViewPromise
(
newImg
)
.
then
(
waitForPromises
)
.
then
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
not
.
toHaveBeenCalled
();
expect
(
newImg
).
not
.
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
})
.
catch
(
done
.
fail
);
});
it
(
'
should not load dynamically added pictures if content observer is turned off
'
,
done
=>
{
...
...
@@ -184,13 +208,15 @@ describe('LazyLoader', function() {
newImg
.
className
=
'
lazy
'
;
newImg
.
setAttribute
(
'
data-src
'
,
testPath
);
document
.
body
.
appendChild
(
newImg
);
newImg
.
scrollIntoView
();
setTimeout
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
not
.
toHaveBeenCalled
();
expect
(
newImg
).
not
.
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
},
50
);
scrollIntoViewPromise
(
newImg
)
.
then
(
waitForPromises
)
.
then
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
not
.
toHaveBeenCalled
();
expect
(
newImg
).
not
.
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
})
.
catch
(
done
.
fail
);
});
it
(
'
should load dynamically added pictures if content observer is turned off and on again
'
,
done
=>
{
...
...
@@ -202,13 +228,17 @@ describe('LazyLoader', function() {
newImg
.
className
=
'
lazy
'
;
newImg
.
setAttribute
(
'
data-src
'
,
testPath
);
document
.
body
.
appendChild
(
newImg
);
newImg
.
scrollIntoView
();
setTimeout
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
toHaveBeenCalled
();
expect
(
newImg
).
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
},
50
);
Promise
.
all
([
scrollIntoViewPromise
(
newImg
),
waitForAttributeChange
(
newImg
,
[
'
data-src
'
,
'
src
'
]),
])
.
then
(()
=>
{
expect
(
LazyLoader
.
loadImage
).
toHaveBeenCalled
();
expect
(
newImg
).
toHaveClass
(
'
js-lazy-loaded
'
);
done
();
})
.
catch
(
done
.
fail
);
});
});
});
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment