Skip to content

Commit 0f9f4ae

Browse files
committed
Add test waiters
1 parent bd15d6a commit 0f9f4ae

File tree

6 files changed

+106
-41
lines changed

6 files changed

+106
-41
lines changed

addon/components/collection-scroll-view/collection-items/index.js

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ import identity from 'ember-collection/utils/identity';
66
import { tracked } from '@glimmer/tracking';
77
import { reads } from 'macro-decorators';
88

9-
function isElementInViewport (el) {
10-
let rect = el.getBoundingClientRect();
11-
let windowHeight = (window.innerHeight || document.documentElement.clientHeight);
12-
return (rect.top > 0 && rect.top < windowHeight) ||
13-
(rect.bottom > 0 && rect.bottom < windowHeight);
9+
function isElementInViewport(el) {
10+
let rect = el.getBoundingClientRect();
11+
let windowHeight =
12+
window.innerHeight || document.documentElement.clientHeight;
13+
return (
14+
(rect.top > 0 && rect.top < windowHeight) ||
15+
(rect.bottom > 0 && rect.bottom < windowHeight)
16+
);
1417
}
1518

1619
let scrollViewCollectionItemsCellCounter = 0;
@@ -164,7 +167,11 @@ export default class CollectionScrollViewCollectionItems extends Component {
164167
let itemIndex = newItems[i];
165168
let item = items[itemIndex];
166169
let itemKey = identity(item);
167-
let style = cellLayout.formatItemStyle(itemIndex, clientWidth, clientHeight);
170+
let style = cellLayout.formatItemStyle(
171+
itemIndex,
172+
clientWidth,
173+
clientHeight
174+
);
168175
const cell = new Cell(itemKey, item, itemIndex, style);
169176
cellMap[itemKey] = cell;
170177
cells.pushObject(cell);
@@ -179,7 +186,9 @@ export default class CollectionScrollViewCollectionItems extends Component {
179186
for (let i = 0; i < cells.length; i++) {
180187
const cell = cells[i];
181188
if (cell.needsReflow) {
182-
let element = document.querySelector(`[data-collection-scroll-view-cell-container-id="${cell.containerId}"]`);
189+
let element = document.querySelector(
190+
`[data-collection-scroll-view-cell-container-id="${cell.containerId}"]`
191+
);
183192
if (element && isElementInViewport(element)) {
184193
let display = element.style.display;
185194
element.style.display = 'none';

addon/components/collection-scroll-view/index.js

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ import { reads } from 'macro-decorators';
33
import { cached } from 'ember-cached-decorator-polyfill';
44
import { tracked } from '@glimmer/tracking';
55
import { action } from '@ember/object';
6-
import { next, schedule } from '@ember/runloop';
6+
import { next, schedule, run } from '@ember/runloop';
77
import { ref } from 'ember-ref-bucket';
8+
import { invokeResizeCallback } from 'yapp-scroll-view/utils/resize-observer-waiter';
89

910
/* A component which integrates a ScrollView with ember-collection */
1011
export default class CollectionScrollView extends Component {
@@ -59,16 +60,24 @@ export default class CollectionScrollView extends Component {
5960

6061
@action
6162
updateHeaderDimensions(scrollViewApi, entry) {
62-
let isFirstMeasure = !this.headerDimensions;
63-
this.headerDimensions = {
64-
width: entry.contentRect.width,
65-
height: entry.contentRect.height,
66-
};
67-
68-
// If an initialScrollTop was set we need to apply it after the collections rows render
69-
if (isFirstMeasure && this.args.initialScrollTop) {
70-
next(scrollViewApi, scrollViewApi.scrollTo, this.args.initialScrollTop);
71-
}
63+
invokeResizeCallback(() => {
64+
run(() => {
65+
let isFirstMeasure = !this.headerDimensions;
66+
this.headerDimensions = {
67+
width: entry.contentRect.width,
68+
height: entry.contentRect.height,
69+
};
70+
71+
// If an initialScrollTop was set we need to apply it after the collections rows render
72+
if (isFirstMeasure && this.args.initialScrollTop) {
73+
next(
74+
scrollViewApi,
75+
scrollViewApi.scrollTo,
76+
this.args.initialScrollTop
77+
);
78+
}
79+
});
80+
});
7281
}
7382

7483
@action

addon/components/scroll-view.js

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import Ember from 'ember';
1818
import { cached } from 'ember-cached-decorator-polyfill';
1919

2020
let waiter = buildWaiter('yapp-scroll-view:scrolling');
21+
let measurementWaiter = buildWaiter('yapp-scroll-view:measurement');
2122

2223
const FIELD_REGEXP = /input|textarea|select/i;
2324
const MEASUREMENT_INTERVAL = 250;
@@ -114,6 +115,7 @@ class ScrollView extends Component {
114115
_isScrolling = false;
115116
_touchStartTimeStamp = null;
116117
_lastIsScrolling = false;
118+
_measurementWaiterToken = null;
117119

118120
@service('scroll-position-memory')
119121
memory;
@@ -404,8 +406,8 @@ class ScrollView extends Component {
404406
}
405407
}
406408
let lastIsInViewport = true;
409+
// eslint-disable-next-line no-constant-condition
407410
while (true) {
408-
// eslint-disable-line no-constant-condition
409411
await timeout(
410412
lastIsInViewport
411413
? MEASUREMENT_INTERVAL
@@ -419,29 +421,34 @@ class ScrollView extends Component {
419421
});
420422

421423
measureClientAndContent() {
422-
if (!this.scrollViewElement) {
423-
return;
424-
}
425-
this._lastMeasurement = +new Date();
426-
let { clientWidth, clientHeight, contentHeight } =
427-
this.getCurrentClientAndContentSizes();
428-
429-
if (
430-
!this.hasClientOrContentSizeChanged(
424+
this._beginMeasurementWaiter();
425+
try {
426+
if (!this.scrollViewElement) {
427+
return;
428+
}
429+
this._lastMeasurement = +new Date();
430+
let { clientWidth, clientHeight, contentHeight } =
431+
this.getCurrentClientAndContentSizes();
432+
433+
if (
434+
!this.hasClientOrContentSizeChanged(
435+
clientWidth,
436+
clientHeight,
437+
contentHeight
438+
)
439+
) {
440+
return;
441+
}
442+
join(
443+
this,
444+
this.applyNewMeasurements,
431445
clientWidth,
432446
clientHeight,
433447
contentHeight
434-
)
435-
) {
436-
return;
448+
);
449+
} finally {
450+
this._endMeasurementWaiter();
437451
}
438-
join(
439-
this,
440-
this.applyNewMeasurements,
441-
clientWidth,
442-
clientHeight,
443-
contentHeight
444-
);
445452
}
446453

447454
getCurrentClientAndContentSizes() {
@@ -612,6 +619,19 @@ class ScrollView extends Component {
612619
_isScrollingForWaiter() {
613620
return !this._lastIsScrolling;
614621
}
622+
623+
_beginMeasurementWaiter() {
624+
if (DEBUG && Ember.testing && !this._measurementWaiterToken) {
625+
this._measurementWaiterToken = measurementWaiter.beginAsync();
626+
}
627+
}
628+
629+
_endMeasurementWaiter() {
630+
if (this._measurementWaiterToken) {
631+
measurementWaiter.endAsync(this._measurementWaiterToken);
632+
this._measurementWaiterToken = null;
633+
}
634+
}
615635
}
616636

617637
export default ScrollView;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { buildWaiter } from '@ember/test-waiters';
2+
3+
const waiter = buildWaiter('yapp-scroll-view:resize-observer');
4+
5+
export function invokeResizeCallback(callback) {
6+
let token;
7+
8+
if (waiter && typeof waiter.beginAsync === 'function') {
9+
token = waiter.beginAsync();
10+
}
11+
12+
try {
13+
return callback();
14+
} finally {
15+
if (token) {
16+
waiter.endAsync(token);
17+
}
18+
}
19+
}
20+
21+
export function _resizeObserverWaiterForTesting() {
22+
return waiter;
23+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export {
2+
invokeResizeCallback,
3+
_resizeObserverWaiterForTesting,
4+
} from 'yapp-scroll-view/utils/resize-observer-waiter';

yarn.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5932,9 +5932,9 @@ can-symlink@^1.0.0:
59325932
tmp "0.0.28"
59335933

59345934
caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001517:
5935-
version "1.0.30001522"
5936-
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001522.tgz#44b87a406c901269adcdb834713e23582dd71856"
5937-
integrity sha512-TKiyTVZxJGhsTszLuzb+6vUZSjVOAhClszBr2Ta2k9IwtNBT/4dzmL6aywt0HCgEZlmwJzXJd8yNiob6HgwTRg==
5935+
version "1.0.30001751"
5936+
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz"
5937+
integrity sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==
59385938

59395939
capture-exit@^2.0.0:
59405940
version "2.0.0"

0 commit comments

Comments
 (0)