Skip to content

Commit f4cb26a

Browse files
authored
Merge pull request #90 from yappbox/bug/android-webview-130
Workaround for cell rerendering issue in Android System WebView 130
2 parents 096b294 + 29c0c15 commit f4cb26a

File tree

2 files changed

+55
-23
lines changed

2 files changed

+55
-23
lines changed

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

Lines changed: 54 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,35 @@ import Component from '@glimmer/component';
55
import identity from 'ember-collection/utils/identity';
66
import { tracked } from '@glimmer/tracking';
77
import { reads } from 'macro-decorators';
8+
import { schedule } from '@ember/runloop';
9+
10+
function isElementInViewport (el) {
11+
var rect = el.getBoundingClientRect();
12+
return (
13+
rect.top >= 0 &&
14+
rect.left >= 0 &&
15+
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
16+
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
17+
);
18+
}
19+
20+
let scrollViewCollectionItemsCellCounter = 0;
821

922
class Cell {
1023
@tracked hidden;
1124
@tracked item;
1225
@tracked index;
1326
@tracked style;
27+
@tracked containerId;
28+
needsReflow = false;
1429

1530
constructor(key, item, index, style) {
1631
this.key = key;
1732
this.hidden = false;
1833
this.item = item;
1934
this.index = index;
2035
this.style = style;
36+
this.containerId = scrollViewCollectionItemsCellCounter++;
2137
}
2238
}
2339

@@ -43,13 +59,6 @@ export default class CollectionScrollViewCollectionItems extends Component {
4359
return clientSize ? clientSize.height : estimatedSize.height;
4460
}
4561

46-
safeRerender() {
47-
if (this.isDestroyed || this.isDestroying) {
48-
return;
49-
}
50-
this.rerender();
51-
}
52-
5362
get contentSize() {
5463
this._contentSize =
5564
this._contentSize ||
@@ -101,18 +110,18 @@ export default class CollectionScrollViewCollectionItems extends Component {
101110
index -= bufferBefore;
102111
count += bufferBefore;
103112
count = Math.min(count + this.buffer, items.length - index);
104-
let i, style, itemIndex, itemKey, cell;
105113

106114
let newItems = [];
107115

108-
for (i = 0; i < count; i++) {
109-
itemIndex = index + i;
110-
itemKey = identity(items[itemIndex]);
116+
for (let i = 0; i < count; i++) {
117+
let cell;
118+
let itemIndex = index + i;
119+
let itemKey = identity(items[itemIndex]);
111120
if (priorMap) {
112121
cell = priorMap[itemKey];
113122
}
114123
if (cell) {
115-
style = cellLayout.formatItemStyle(
124+
let style = cellLayout.formatItemStyle(
116125
itemIndex,
117126
clientWidth,
118127
clientHeight
@@ -127,14 +136,14 @@ export default class CollectionScrollViewCollectionItems extends Component {
127136
}
128137
}
129138

130-
for (i = 0; i < cells.length; i++) {
131-
cell = cells[i];
139+
for (let i = 0; i < cells.length; i++) {
140+
const cell = cells[i];
132141
if (!cellMap[cell.key]) {
133142
if (newItems.length) {
134-
itemIndex = newItems.pop();
143+
let itemIndex = newItems.pop();
135144
let item = items[itemIndex];
136-
itemKey = identity(item);
137-
style = cellLayout.formatItemStyle(
145+
let itemKey = identity(item);
146+
let style = cellLayout.formatItemStyle(
138147
itemIndex,
139148
clientWidth,
140149
clientHeight
@@ -145,24 +154,47 @@ export default class CollectionScrollViewCollectionItems extends Component {
145154
cell.item = item;
146155
cell.hidden = false;
147156
cellMap[itemKey] = cell;
157+
if (window.SCROLL_VIEW_FORCE_REFLOW) {
158+
cell.needsReflow = true;
159+
}
148160
} else {
149161
cell.hidden = true;
150162
cell.style = 'height: 0; display: none;';
151163
}
152164
}
153165
}
154166

155-
for (i = 0; i < newItems.length; i++) {
156-
itemIndex = newItems[i];
167+
for (let i = 0; i < newItems.length; i++) {
168+
let itemIndex = newItems[i];
157169
let item = items[itemIndex];
158-
itemKey = identity(item);
159-
style = cellLayout.formatItemStyle(itemIndex, clientWidth, clientHeight);
160-
cell = new Cell(itemKey, item, itemIndex, style);
170+
let itemKey = identity(item);
171+
let style = cellLayout.formatItemStyle(itemIndex, clientWidth, clientHeight);
172+
const cell = new Cell(itemKey, item, itemIndex, style);
161173
cellMap[itemKey] = cell;
162174
cells.pushObject(cell);
163175
}
164176
this.cellMap = cellMap;
165177
this.contentSize = cellLayout.contentSize(clientWidth, clientHeight);
178+
179+
// Workaround for bug in Android System WebView 130. Cells that are updated when outside
180+
// viewport aren't rerendered. When they are scrolled into view, access offsetHeight to
181+
// force a reflow.
182+
if (window.SCROLL_VIEW_FORCE_REFLOW) {
183+
for (let i = 0; i < cells.length; i++) {
184+
const cell = cells[i];
185+
if (cell.needsReflow) {
186+
let element = document.querySelector(`[data-collection-scroll-view-cell-container-id="${cell.containerId}"]`);
187+
if (element && isElementInViewport(element)) {
188+
let display = element.style.display;
189+
element.style.display = 'none';
190+
element.offsetHeight;
191+
element.style.display = display;
192+
cell.needsReflow = false;
193+
}
194+
}
195+
}
196+
}
197+
166198
return cells;
167199
}
168200
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
as |cells|
4141
>
4242
{{~#each cells as |cell|~}}
43-
<div style={{html-safe cell.style}}>{{yield cell.item cell.index scrollViewApi to="row"}}</div>
43+
<div style={{html-safe cell.style}} data-collection-scroll-view-cell-container-id={{cell.containerId}}>{{yield cell.item cell.index scrollViewApi to="row"}}</div>
4444
{{~/each~}}
4545
</CollectionScrollView::CollectionItems>
4646
</div>

0 commit comments

Comments
 (0)