@html-next/vertical-collection 4.0.2 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +64 -79
- package/{addon → src}/-private/data-view/elements/occluded-content.js +1 -1
- package/{addon/-private/data-view → src/-private/data-view/elements}/viewport-container.js +35 -25
- package/{addon → src}/-private/data-view/elements/virtual-component.js +13 -5
- package/{addon → src}/-private/data-view/radar/dynamic-radar.js +41 -40
- package/{addon → src}/-private/data-view/radar/radar.js +211 -112
- package/{addon → src}/-private/data-view/radar/static-radar.js +19 -7
- package/{addon → src}/-private/data-view/skip-list.js +20 -21
- package/{addon → src}/-private/data-view/utils/insert-range-before.js +6 -1
- package/{addon → src}/-private/data-view/utils/mutation-checkers.js +12 -4
- package/src/-private/data-view/utils/object-at.js +10 -0
- package/{addon → src}/-private/data-view/utils/scroll-handler.js +19 -9
- package/{addon → src}/-private/data-view/utils/supports-passive.js +2 -2
- package/{addon/-private/data-view/elements → src/-private/data-view}/viewport-container.js +35 -25
- package/{addon → src}/-private/ember-internals/key-for-item.js +9 -3
- package/{addon → src}/-private/index.js +8 -8
- package/{addon → src}/-private/utils/element/closest.js +8 -2
- package/{addon → src}/-private/utils/element/estimate-element-height.js +11 -5
- package/{addon/components/vertical-collection/component.js → src/components/vertical-collection.gjs} +155 -71
- package/src/index.js +3 -0
- package/{addon/styles/app.css → src/occluded-content.css} +11 -1
- package/.github/workflows/ci.yml +0 -102
- package/CHANGELOG.md +0 -176
- package/README.md +0 -122
- package/RELEASE.md +0 -74
- package/addon/-private/data-view/utils/object-at.js +0 -7
- package/addon/components/vertical-collection/template.hbs +0 -13
- package/app/components/vertical-collection.js +0 -1
- package/bin/restore-env.sh +0 -1
- package/bin/run-tests-with-retry.sh +0 -24
- package/bin/stash-env.sh +0 -1
- package/config/ember-cli-toolbelts.json +0 -1
- package/config/environment.js +0 -5
- package/index.js +0 -157
- package/vendor/debug.css +0 -62
- /package/{addon → src}/-private/data-view/utils/round-to.js +0 -0
- /package/{addon → src}/-private/ember-internals/identity.js +0 -0
- /package/{addon → src}/-private/utils/document-shim.js +0 -0
- /package/{addon → src}/-private/utils/element/get-scaled-client-rect.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { assert } from '@ember/debug';
|
|
2
2
|
import { DEBUG } from '@glimmer/env';
|
|
3
3
|
|
|
4
|
-
import roundTo from './utils/round-to';
|
|
4
|
+
import roundTo from './utils/round-to.js';
|
|
5
5
|
|
|
6
6
|
/*
|
|
7
7
|
* `SkipList` is a data structure designed with two main uses in mind:
|
|
@@ -83,7 +83,7 @@ export default class SkipList {
|
|
|
83
83
|
fill(layer, defaultValue);
|
|
84
84
|
|
|
85
85
|
left = prevLayer[(length - 1) * 2] || 0;
|
|
86
|
-
right = prevLayer[(
|
|
86
|
+
right = prevLayer[(length - 1) * 2 + 1] || 0;
|
|
87
87
|
|
|
88
88
|
// Layers are not powers of 2, and sometimes they may by odd sizes.
|
|
89
89
|
// Only the last value of a layer will be different, so we calculate
|
|
@@ -92,7 +92,7 @@ export default class SkipList {
|
|
|
92
92
|
} else {
|
|
93
93
|
for (i = 0; i < length; i++) {
|
|
94
94
|
left = prevLayer[i * 2];
|
|
95
|
-
right = prevLayer[
|
|
95
|
+
right = prevLayer[i * 2 + 1];
|
|
96
96
|
layer[i] = right ? left + right : left;
|
|
97
97
|
}
|
|
98
98
|
}
|
|
@@ -101,7 +101,12 @@ export default class SkipList {
|
|
|
101
101
|
prevLayer = layer;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
this.total =
|
|
104
|
+
this.total =
|
|
105
|
+
layer.length > 0
|
|
106
|
+
? layer.length > 1
|
|
107
|
+
? layer[0] + layer[1]
|
|
108
|
+
: layer[0]
|
|
109
|
+
: 0;
|
|
105
110
|
|
|
106
111
|
assert('total must be a number', typeof this.total === 'number');
|
|
107
112
|
|
|
@@ -147,7 +152,10 @@ export default class SkipList {
|
|
|
147
152
|
index = index / 2;
|
|
148
153
|
|
|
149
154
|
assert('index must be a number', typeof index === 'number');
|
|
150
|
-
assert(
|
|
155
|
+
assert(
|
|
156
|
+
'index must be within bounds',
|
|
157
|
+
index >= 0 && index < this.values.length,
|
|
158
|
+
);
|
|
151
159
|
|
|
152
160
|
totalAfter = total - (totalBefore + values[index]);
|
|
153
161
|
|
|
@@ -190,7 +198,10 @@ export default class SkipList {
|
|
|
190
198
|
assert('value must be a number', typeof value === 'number');
|
|
191
199
|
assert('value must non-negative', value >= 0);
|
|
192
200
|
assert('index must be a number', typeof index === 'number');
|
|
193
|
-
assert(
|
|
201
|
+
assert(
|
|
202
|
+
'index must be within bounds',
|
|
203
|
+
index >= 0 && index < this.values.length,
|
|
204
|
+
);
|
|
194
205
|
|
|
195
206
|
const { layers } = this;
|
|
196
207
|
const oldValue = layers[layers.length - 1][index];
|
|
@@ -216,11 +227,7 @@ export default class SkipList {
|
|
|
216
227
|
}
|
|
217
228
|
|
|
218
229
|
prepend(numPrepended) {
|
|
219
|
-
const {
|
|
220
|
-
values: oldValues,
|
|
221
|
-
length: oldLength,
|
|
222
|
-
defaultValue
|
|
223
|
-
} = this;
|
|
230
|
+
const { values: oldValues, length: oldLength, defaultValue } = this;
|
|
224
231
|
|
|
225
232
|
const newLength = numPrepended + oldLength;
|
|
226
233
|
|
|
@@ -234,11 +241,7 @@ export default class SkipList {
|
|
|
234
241
|
}
|
|
235
242
|
|
|
236
243
|
append(numAppended) {
|
|
237
|
-
const {
|
|
238
|
-
values: oldValues,
|
|
239
|
-
length: oldLength,
|
|
240
|
-
defaultValue
|
|
241
|
-
} = this;
|
|
244
|
+
const { values: oldValues, length: oldLength, defaultValue } = this;
|
|
242
245
|
|
|
243
246
|
const newLength = numAppended + oldLength;
|
|
244
247
|
|
|
@@ -252,11 +255,7 @@ export default class SkipList {
|
|
|
252
255
|
}
|
|
253
256
|
|
|
254
257
|
reset(newLength) {
|
|
255
|
-
const {
|
|
256
|
-
values: oldValues,
|
|
257
|
-
length: oldLength,
|
|
258
|
-
defaultValue
|
|
259
|
-
} = this;
|
|
258
|
+
const { values: oldValues, length: oldLength, defaultValue } = this;
|
|
260
259
|
|
|
261
260
|
if (oldLength === newLength) {
|
|
262
261
|
return;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { get } from '@ember/object';
|
|
2
|
-
import objectAt from './object-at';
|
|
3
|
-
import keyForItem from '../../ember-internals/key-for-item';
|
|
2
|
+
import objectAt from './object-at.js';
|
|
3
|
+
import keyForItem from '../../ember-internals/key-for-item.js';
|
|
4
4
|
|
|
5
5
|
export function isPrepend(lenDiff, newItems, key, oldFirstKey, oldLastKey) {
|
|
6
6
|
const newItemsLength = get(newItems, 'length');
|
|
@@ -10,7 +10,11 @@ export function isPrepend(lenDiff, newItems, key, oldFirstKey, oldLastKey) {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
const newFirstKey = keyForItem(objectAt(newItems, lenDiff), key, lenDiff);
|
|
13
|
-
const newLastKey = keyForItem(
|
|
13
|
+
const newLastKey = keyForItem(
|
|
14
|
+
objectAt(newItems, newItemsLength - 1),
|
|
15
|
+
key,
|
|
16
|
+
newItemsLength - 1,
|
|
17
|
+
);
|
|
14
18
|
|
|
15
19
|
return oldFirstKey === newFirstKey && oldLastKey === newLastKey;
|
|
16
20
|
}
|
|
@@ -23,7 +27,11 @@ export function isAppend(lenDiff, newItems, key, oldFirstKey, oldLastKey) {
|
|
|
23
27
|
}
|
|
24
28
|
|
|
25
29
|
const newFirstKey = keyForItem(objectAt(newItems, 0), key, 0);
|
|
26
|
-
const newLastKey = keyForItem(
|
|
30
|
+
const newLastKey = keyForItem(
|
|
31
|
+
objectAt(newItems, newItemsLength - lenDiff - 1),
|
|
32
|
+
key,
|
|
33
|
+
newItemsLength - lenDiff - 1,
|
|
34
|
+
);
|
|
27
35
|
|
|
28
36
|
return oldFirstKey === newFirstKey && oldLastKey === newLastKey;
|
|
29
37
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { assert } from '@ember/debug';
|
|
2
|
+
|
|
3
|
+
export default function objectAt(arr, index) {
|
|
4
|
+
assert(
|
|
5
|
+
'arr must be an instance of a Javascript Array or implement `objectAt`',
|
|
6
|
+
Array.isArray(arr) || typeof arr.objectAt === 'function',
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
return arr.objectAt ? arr.objectAt(index) : arr[index];
|
|
10
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { begin, end } from '@ember/runloop';
|
|
2
2
|
import { scheduler } from 'ember-raf-scheduler';
|
|
3
|
-
import SUPPORTS_PASSIVE from './supports-passive';
|
|
3
|
+
import SUPPORTS_PASSIVE from './supports-passive.js';
|
|
4
4
|
const DEFAULT_ARRAY_SIZE = 10;
|
|
5
5
|
const UNDEFINED_VALUE = Object.create(null);
|
|
6
6
|
|
|
@@ -33,11 +33,11 @@ export class ScrollHandler {
|
|
|
33
33
|
cache = this.handlers[index] = {
|
|
34
34
|
top: element.scrollTop,
|
|
35
35
|
left: element.scrollLeft,
|
|
36
|
-
handlers
|
|
36
|
+
handlers,
|
|
37
37
|
};
|
|
38
38
|
// TODO add explicit test
|
|
39
39
|
if (SUPPORTS_PASSIVE) {
|
|
40
|
-
cache.passiveHandler = function() {
|
|
40
|
+
cache.passiveHandler = function () {
|
|
41
41
|
ScrollHandler.triggerElementHandlers(element, cache);
|
|
42
42
|
};
|
|
43
43
|
} else {
|
|
@@ -50,10 +50,16 @@ export class ScrollHandler {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
// TODO add explicit test
|
|
53
|
-
if (this.isUsingPassive
|
|
54
|
-
|
|
53
|
+
if (this.isUsingPassive) {
|
|
54
|
+
// Only add the event listener once, if more handlers are present.
|
|
55
|
+
if (handlers.length === 1) {
|
|
56
|
+
element.addEventListener('scroll', cache.passiveHandler, {
|
|
57
|
+
capture: true,
|
|
58
|
+
passive: true,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
55
61
|
|
|
56
|
-
|
|
62
|
+
// TODO add explicit test
|
|
57
63
|
} else if (!this.isPolling) {
|
|
58
64
|
this.poll();
|
|
59
65
|
}
|
|
@@ -88,12 +94,16 @@ export class ScrollHandler {
|
|
|
88
94
|
|
|
89
95
|
// TODO add explicit test
|
|
90
96
|
if (this.isUsingPassive) {
|
|
91
|
-
element.removeEventListener('scroll', elementCache.passiveHandler, {
|
|
97
|
+
element.removeEventListener('scroll', elementCache.passiveHandler, {
|
|
98
|
+
capture: true,
|
|
99
|
+
passive: true,
|
|
100
|
+
});
|
|
92
101
|
}
|
|
93
102
|
}
|
|
94
|
-
|
|
95
103
|
} else {
|
|
96
|
-
throw new Error(
|
|
104
|
+
throw new Error(
|
|
105
|
+
'Attempted to remove a handler from an unknown element or an element with no handlers',
|
|
106
|
+
);
|
|
97
107
|
}
|
|
98
108
|
}
|
|
99
109
|
|
|
@@ -13,58 +13,68 @@
|
|
|
13
13
|
*
|
|
14
14
|
*/
|
|
15
15
|
export function ViewportContainer() {
|
|
16
|
-
|
|
17
16
|
// A bug occurs in Chrome when we reload the browser at a lower
|
|
18
17
|
// scrollTop, window.scrollY becomes stuck on a single value.
|
|
19
18
|
Object.defineProperty(this, 'scrollTop', {
|
|
20
19
|
get() {
|
|
21
|
-
return document.body.scrollTop
|
|
22
|
-
|| document.documentElement.scrollTop;
|
|
20
|
+
return document.body.scrollTop || document.documentElement.scrollTop;
|
|
23
21
|
},
|
|
24
22
|
set(v) {
|
|
25
23
|
document.body.scrollTop = document.documentElement.scrollTop = v;
|
|
26
|
-
}
|
|
24
|
+
},
|
|
27
25
|
});
|
|
28
26
|
|
|
29
27
|
Object.defineProperty(this, 'scrollLeft', {
|
|
30
28
|
get() {
|
|
31
|
-
return
|
|
32
|
-
|
|
33
|
-
||
|
|
34
|
-
|
|
29
|
+
return (
|
|
30
|
+
window.scrollX ||
|
|
31
|
+
window.pageXOffset ||
|
|
32
|
+
document.body.scrollLeft ||
|
|
33
|
+
document.documentElement.scrollLeft
|
|
34
|
+
);
|
|
35
35
|
},
|
|
36
36
|
set(v) {
|
|
37
|
-
window.scrollX
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
window.scrollX =
|
|
38
|
+
window.pageXOffset =
|
|
39
|
+
document.body.scrollLeft =
|
|
40
|
+
document.documentElement.scrollLeft =
|
|
41
|
+
v;
|
|
42
|
+
},
|
|
42
43
|
});
|
|
43
44
|
|
|
44
45
|
Object.defineProperty(this, 'offsetHeight', {
|
|
45
46
|
get() {
|
|
46
47
|
return window.innerHeight;
|
|
47
|
-
}
|
|
48
|
+
},
|
|
48
49
|
});
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
ViewportContainer.prototype.addEventListener = function addEventListener(
|
|
52
|
+
ViewportContainer.prototype.addEventListener = function addEventListener(
|
|
53
|
+
event,
|
|
54
|
+
handler,
|
|
55
|
+
options,
|
|
56
|
+
) {
|
|
52
57
|
return window.addEventListener(event, handler, options);
|
|
53
58
|
};
|
|
54
59
|
|
|
55
|
-
ViewportContainer.prototype.removeEventListener = function addEventListener(
|
|
60
|
+
ViewportContainer.prototype.removeEventListener = function addEventListener(
|
|
61
|
+
event,
|
|
62
|
+
handler,
|
|
63
|
+
options,
|
|
64
|
+
) {
|
|
56
65
|
return window.removeEventListener(event, handler, options);
|
|
57
66
|
};
|
|
58
67
|
|
|
59
|
-
ViewportContainer.prototype.getBoundingClientRect =
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
ViewportContainer.prototype.getBoundingClientRect =
|
|
69
|
+
function getBoundingClientRect() {
|
|
70
|
+
return {
|
|
71
|
+
height: window.innerHeight,
|
|
72
|
+
width: window.innerWidth,
|
|
73
|
+
top: 0,
|
|
74
|
+
left: 0,
|
|
75
|
+
right: window.innerWidth,
|
|
76
|
+
bottom: window.innerHeight,
|
|
77
|
+
};
|
|
67
78
|
};
|
|
68
|
-
};
|
|
69
79
|
|
|
70
80
|
export default new ViewportContainer();
|
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
import { get } from '@ember/object';
|
|
2
2
|
import { assert } from '@ember/debug';
|
|
3
3
|
|
|
4
|
-
import identity from './identity';
|
|
4
|
+
import identity from './identity.js';
|
|
5
5
|
|
|
6
6
|
export default function keyForItem(item, keyPath, index) {
|
|
7
7
|
let key;
|
|
8
8
|
|
|
9
|
-
assert(
|
|
9
|
+
assert(
|
|
10
|
+
`keyPath must be a string, received: ${keyPath}`,
|
|
11
|
+
typeof keyPath === 'string',
|
|
12
|
+
);
|
|
10
13
|
|
|
11
14
|
switch (keyPath) {
|
|
12
15
|
case '@index':
|
|
13
|
-
assert(
|
|
16
|
+
assert(
|
|
17
|
+
`A numerical index must be supplied for keyForItem when keyPath is @index, received: ${index}`,
|
|
18
|
+
typeof index === 'number',
|
|
19
|
+
);
|
|
14
20
|
key = index;
|
|
15
21
|
break;
|
|
16
22
|
case '@identity':
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
export { default as keyForItem } from './ember-internals/key-for-item';
|
|
1
|
+
export { default as keyForItem } from './ember-internals/key-for-item.js';
|
|
2
2
|
|
|
3
|
-
export { default as closestElement } from './utils/element/closest';
|
|
3
|
+
export { default as closestElement } from './utils/element/closest.js';
|
|
4
4
|
|
|
5
|
-
export { default as DynamicRadar } from './data-view/radar/dynamic-radar';
|
|
6
|
-
export { default as StaticRadar } from './data-view/radar/static-radar';
|
|
5
|
+
export { default as DynamicRadar } from './data-view/radar/dynamic-radar.js';
|
|
6
|
+
export { default as StaticRadar } from './data-view/radar/static-radar.js';
|
|
7
7
|
|
|
8
|
-
export { default as ViewportContainer } from './data-view/viewport-container';
|
|
9
|
-
export { default as objectAt } from './data-view/utils/object-at';
|
|
8
|
+
export { default as ViewportContainer } from './data-view/viewport-container.js';
|
|
9
|
+
export { default as objectAt } from './data-view/utils/object-at.js';
|
|
10
10
|
|
|
11
11
|
export {
|
|
12
12
|
addScrollHandler,
|
|
13
13
|
removeScrollHandler,
|
|
14
|
-
ScrollHandler
|
|
15
|
-
} from './data-view/utils/scroll-handler';
|
|
14
|
+
ScrollHandler,
|
|
15
|
+
} from './data-view/utils/scroll-handler.js';
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
const VENDOR_MATCH_FNS = [
|
|
1
|
+
const VENDOR_MATCH_FNS = [
|
|
2
|
+
'matches',
|
|
3
|
+
'webkitMatchesSelector',
|
|
4
|
+
'mozMatchesSelector',
|
|
5
|
+
'msMatchesSelector',
|
|
6
|
+
'oMatchesSelector',
|
|
7
|
+
];
|
|
2
8
|
let ELEMENT_MATCH_FN;
|
|
3
9
|
|
|
4
10
|
function setElementMatchFn(el) {
|
|
5
11
|
VENDOR_MATCH_FNS.forEach((fn) => {
|
|
6
|
-
if (
|
|
12
|
+
if (ELEMENT_MATCH_FN === undefined && typeof el[fn] === 'function') {
|
|
7
13
|
ELEMENT_MATCH_FN = fn;
|
|
8
14
|
}
|
|
9
15
|
});
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { assert } from '@ember/debug';
|
|
2
2
|
|
|
3
3
|
export default function estimateElementHeight(element, fallbackHeight) {
|
|
4
|
-
assert(
|
|
4
|
+
assert(
|
|
5
|
+
`You called estimateElement height without a fallbackHeight`,
|
|
6
|
+
fallbackHeight,
|
|
7
|
+
);
|
|
5
8
|
assert(`You called estimateElementHeight without an element`, element);
|
|
6
9
|
|
|
7
10
|
if (fallbackHeight.indexOf('%') !== -1) {
|
|
@@ -21,12 +24,15 @@ function getPercentageHeight(element, fallbackHeight) {
|
|
|
21
24
|
let parentHeight = element.offsetHeight;
|
|
22
25
|
let percent = parseFloat(fallbackHeight);
|
|
23
26
|
|
|
24
|
-
return (percent * parentHeight / 100.0
|
|
27
|
+
return (percent * parentHeight) / 100.0;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
function getEmHeight(element, fallbackHeight) {
|
|
28
|
-
const fontSizeElement =
|
|
29
|
-
|
|
31
|
+
const fontSizeElement =
|
|
32
|
+
fallbackHeight.indexOf('rem') !== -1 ? document.documentElement : element;
|
|
33
|
+
const fontSize = window
|
|
34
|
+
.getComputedStyle(fontSizeElement)
|
|
35
|
+
.getPropertyValue('font-size');
|
|
30
36
|
|
|
31
|
-
return
|
|
37
|
+
return parseFloat(fallbackHeight) * parseFloat(fontSize);
|
|
32
38
|
}
|