@vaadin/component-base 24.3.0-alpha1 → 24.3.0-alpha11
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 +4 -4
- package/src/data-provider-controller/cache.d.ts +146 -0
- package/src/data-provider-controller/cache.js +90 -12
- package/src/data-provider-controller/data-provider-controller.d.ts +172 -0
- package/src/data-provider-controller/data-provider-controller.js +55 -33
- package/src/data-provider-controller/helpers.d.ts +63 -0
- package/src/data-provider-controller/helpers.js +57 -8
- package/src/define.js +7 -0
- package/src/element-mixin.js +0 -4
- package/src/url-utils.d.ts +2 -1
- package/src/url-utils.js +5 -2
- package/src/virtualizer-iron-list-adapter.js +34 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/component-base",
|
|
3
|
-
"version": "24.3.0-
|
|
3
|
+
"version": "24.3.0-alpha11",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -35,12 +35,12 @@
|
|
|
35
35
|
"@polymer/polymer": "^3.0.0",
|
|
36
36
|
"@vaadin/vaadin-development-mode-detector": "^2.0.0",
|
|
37
37
|
"@vaadin/vaadin-usage-statistics": "^2.1.0",
|
|
38
|
-
"lit": "^
|
|
38
|
+
"lit": "^3.0.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@esm-bundle/chai": "^4.3.4",
|
|
42
|
-
"@vaadin/testing-helpers": "^0.
|
|
42
|
+
"@vaadin/testing-helpers": "^0.6.0",
|
|
43
43
|
"sinon": "^13.0.2"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "123cf569a1b6ef6f4ef5fe8e60cb8d988699b98c"
|
|
46
46
|
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2021 - 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import type { DataProviderCallback } from './data-provider-controller.js';
|
|
7
|
+
|
|
8
|
+
export type CacheContext<TItem> = { isExpanded(item: TItem): boolean };
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A class that stores items with their associated sub-caches.
|
|
12
|
+
*/
|
|
13
|
+
export class Cache<TItem> {
|
|
14
|
+
/**
|
|
15
|
+
* A context object.
|
|
16
|
+
*/
|
|
17
|
+
context: CacheContext<TItem>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The number of items.
|
|
21
|
+
*/
|
|
22
|
+
size: number;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The number of items to display per page.
|
|
26
|
+
*/
|
|
27
|
+
pageSize: number;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* An array of cached items.
|
|
31
|
+
*/
|
|
32
|
+
items: TItem[];
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A map where the key is a requested page and the value is a callback
|
|
36
|
+
* that will be called with data once the request is complete.
|
|
37
|
+
*/
|
|
38
|
+
pendingRequests: Record<number, DataProviderCallback<TItem>>;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* An item in the parent cache that the current cache is associated with.
|
|
42
|
+
*/
|
|
43
|
+
get parentItem(): TItem | undefined;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* An array of sub-caches sorted in the same order as their associated items
|
|
47
|
+
* appear in the `items` array.
|
|
48
|
+
*/
|
|
49
|
+
get subCaches(): Array<Cache<TItem>>;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Whether the cache or any of its descendant caches have pending requests.
|
|
53
|
+
*/
|
|
54
|
+
get isLoading(): boolean;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The total number of items, including items from expanded sub-caches.
|
|
58
|
+
*/
|
|
59
|
+
get flatSize(): number;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The total number of items, including items from expanded sub-caches.
|
|
63
|
+
*
|
|
64
|
+
* @protected
|
|
65
|
+
* @deprecated since 24.3 and will be removed in Vaadin 25.
|
|
66
|
+
*/
|
|
67
|
+
get effectiveSize(): number;
|
|
68
|
+
|
|
69
|
+
constructor(
|
|
70
|
+
context: CacheContext<TItem>,
|
|
71
|
+
pageSize: number,
|
|
72
|
+
size: number,
|
|
73
|
+
parentCache?: Cache<TItem>,
|
|
74
|
+
parentCacheIndex?: number,
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Recalculates the flattened size for the cache and its descendant caches recursively.
|
|
79
|
+
*/
|
|
80
|
+
recalculateFlatSize(): void;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Adds an array of items corresponding to the given page
|
|
84
|
+
* to the `items` array.
|
|
85
|
+
*/
|
|
86
|
+
setPage(page: number, items: unknown[]): void;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Retrieves the sub-cache associated with the item at the given index
|
|
90
|
+
* in the `items` array.
|
|
91
|
+
*/
|
|
92
|
+
getSubCache(index: number): Cache<TItem> | undefined;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Removes the sub-cache associated with the item at the given index
|
|
96
|
+
* in the `items` array.
|
|
97
|
+
*/
|
|
98
|
+
removeSubCache(index: number): void;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Removes all sub-caches.
|
|
102
|
+
*/
|
|
103
|
+
removeSubCaches(): void;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Creates and associates a sub-cache for the item at the given index
|
|
107
|
+
* in the `items` array.
|
|
108
|
+
*/
|
|
109
|
+
createSubCache(index: number): Cache<TItem>;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Retrieves the flattened index corresponding to the given index
|
|
113
|
+
* of an item in the `items` array.
|
|
114
|
+
*/
|
|
115
|
+
getFlatIndex(index: number): number;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @deprecated since 24.3 and will be removed in Vaadin 25.
|
|
119
|
+
*/
|
|
120
|
+
getItemForIndex(index: number): TItem | undefined;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @deprecated since 24.3 and will be removed in Vaadin 25.
|
|
124
|
+
*/
|
|
125
|
+
getCacheAndIndex(index: number): { cache: Cache<TItem>; scaledIndex: number };
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* @deprecated since 24.3 and will be removed in Vaadin 25.
|
|
129
|
+
*/
|
|
130
|
+
updateSize(): void;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* @deprecated since 24.3 and will be removed in Vaadin 25.
|
|
134
|
+
*/
|
|
135
|
+
ensureSubCacheForScaledIndex(scaledIndex: number): void;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* @deprecated since 24.3 and will be removed in Vaadin 25.
|
|
139
|
+
*/
|
|
140
|
+
get grid(): HTMLElement;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @deprecated since 24.3 and will be removed in Vaadin 25.
|
|
144
|
+
*/
|
|
145
|
+
get itemCaches(): object;
|
|
146
|
+
}
|
|
@@ -3,12 +3,15 @@
|
|
|
3
3
|
* Copyright (c) 2021 - 2023 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
+
import { getFlatIndexContext } from './helpers.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* A class that stores items with their associated sub-caches.
|
|
9
10
|
*/
|
|
10
11
|
export class Cache {
|
|
11
12
|
/**
|
|
13
|
+
* A context object.
|
|
14
|
+
*
|
|
12
15
|
* @type {{ isExpanded: (item: unknown) => boolean }}
|
|
13
16
|
*/
|
|
14
17
|
context;
|
|
@@ -38,9 +41,9 @@ export class Cache {
|
|
|
38
41
|
* A map where the key is a requested page and the value is a callback
|
|
39
42
|
* that will be called with data once the request is complete.
|
|
40
43
|
*
|
|
41
|
-
* @type {
|
|
44
|
+
* @type {Record<number, Function>}
|
|
42
45
|
*/
|
|
43
|
-
pendingRequests =
|
|
46
|
+
pendingRequests = {};
|
|
44
47
|
|
|
45
48
|
/**
|
|
46
49
|
* A map where the key is the index of an item in the `items` array
|
|
@@ -61,7 +64,7 @@ export class Cache {
|
|
|
61
64
|
* @type {number}
|
|
62
65
|
* @private
|
|
63
66
|
*/
|
|
64
|
-
|
|
67
|
+
__flatSize = 0;
|
|
65
68
|
|
|
66
69
|
/**
|
|
67
70
|
* @param {Cache['context']} context
|
|
@@ -76,7 +79,7 @@ export class Cache {
|
|
|
76
79
|
this.size = size || 0;
|
|
77
80
|
this.parentCache = parentCache;
|
|
78
81
|
this.parentCacheIndex = parentCacheIndex;
|
|
79
|
-
this.
|
|
82
|
+
this.__flatSize = size || 0;
|
|
80
83
|
}
|
|
81
84
|
|
|
82
85
|
/**
|
|
@@ -104,7 +107,7 @@ export class Cache {
|
|
|
104
107
|
* @return {boolean}
|
|
105
108
|
*/
|
|
106
109
|
get isLoading() {
|
|
107
|
-
if (this.pendingRequests.
|
|
110
|
+
if (Object.keys(this.pendingRequests).length > 0) {
|
|
108
111
|
return true;
|
|
109
112
|
}
|
|
110
113
|
|
|
@@ -116,20 +119,33 @@ export class Cache {
|
|
|
116
119
|
*
|
|
117
120
|
* @return {number}
|
|
118
121
|
*/
|
|
122
|
+
get flatSize() {
|
|
123
|
+
return this.__flatSize;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* The total number of items, including items from expanded sub-caches.
|
|
128
|
+
*
|
|
129
|
+
* @protected
|
|
130
|
+
* @deprecated since 24.3 and will be removed in Vaadin 25.
|
|
131
|
+
*/
|
|
119
132
|
get effectiveSize() {
|
|
120
|
-
|
|
133
|
+
console.warn(
|
|
134
|
+
'<vaadin-grid> The `effectiveSize` property of ItemCache is deprecated and will be removed in Vaadin 25.',
|
|
135
|
+
);
|
|
136
|
+
return this.flatSize;
|
|
121
137
|
}
|
|
122
138
|
|
|
123
139
|
/**
|
|
124
|
-
* Recalculates the
|
|
140
|
+
* Recalculates the flattened size for the cache and its descendant caches recursively.
|
|
125
141
|
*/
|
|
126
|
-
|
|
127
|
-
this.
|
|
142
|
+
recalculateFlatSize() {
|
|
143
|
+
this.__flatSize =
|
|
128
144
|
!this.parentItem || this.context.isExpanded(this.parentItem)
|
|
129
145
|
? this.size +
|
|
130
146
|
this.subCaches.reduce((total, subCache) => {
|
|
131
|
-
subCache.
|
|
132
|
-
return total + subCache.
|
|
147
|
+
subCache.recalculateFlatSize();
|
|
148
|
+
return total + subCache.flatSize;
|
|
133
149
|
}, 0)
|
|
134
150
|
: 0;
|
|
135
151
|
}
|
|
@@ -201,7 +217,69 @@ export class Cache {
|
|
|
201
217
|
|
|
202
218
|
return this.subCaches.reduce((prev, subCache) => {
|
|
203
219
|
const index = subCache.parentCacheIndex;
|
|
204
|
-
return clampedIndex > index ? prev + subCache.
|
|
220
|
+
return clampedIndex > index ? prev + subCache.flatSize : prev;
|
|
205
221
|
}, clampedIndex);
|
|
206
222
|
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* @deprecated since 24.3 and will be removed in Vaadin 25.
|
|
226
|
+
*/
|
|
227
|
+
getItemForIndex(index) {
|
|
228
|
+
console.warn(
|
|
229
|
+
'<vaadin-grid> The `getItemForIndex` method of ItemCache is deprecated and will be removed in Vaadin 25.',
|
|
230
|
+
);
|
|
231
|
+
const { item } = getFlatIndexContext(this, index);
|
|
232
|
+
return item;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* @deprecated since 24.3 and will be removed in Vaadin 25.
|
|
237
|
+
*/
|
|
238
|
+
getCacheAndIndex(index) {
|
|
239
|
+
console.warn(
|
|
240
|
+
'<vaadin-grid> The `getCacheAndIndex` method of ItemCache is deprecated and will be removed in Vaadin 25.',
|
|
241
|
+
);
|
|
242
|
+
const { cache, index: scaledIndex } = getFlatIndexContext(this, index);
|
|
243
|
+
return { cache, scaledIndex };
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* @deprecated since 24.3 and will be removed in Vaadin 25.
|
|
248
|
+
*/
|
|
249
|
+
updateSize() {
|
|
250
|
+
console.warn('<vaadin-grid> The `updateSize` method of ItemCache is deprecated and will be removed in Vaadin 25.');
|
|
251
|
+
this.recalculateFlatSize();
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* @deprecated since 24.3 and will be removed in Vaadin 25.
|
|
256
|
+
*/
|
|
257
|
+
ensureSubCacheForScaledIndex(scaledIndex) {
|
|
258
|
+
console.warn(
|
|
259
|
+
'<vaadin-grid> The `ensureSubCacheForScaledIndex` method of ItemCache is deprecated and will be removed in Vaadin 25.',
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
if (!this.getSubCache(scaledIndex)) {
|
|
263
|
+
const subCache = this.createSubCache(scaledIndex);
|
|
264
|
+
this.context.__controller.__loadCachePage(subCache, 0);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* @deprecated since 24.3 and will be removed in Vaadin 25.
|
|
270
|
+
*/
|
|
271
|
+
get grid() {
|
|
272
|
+
console.warn('<vaadin-grid> The `grid` property of ItemCache is deprecated and will be removed in Vaadin 25.');
|
|
273
|
+
return this.context.__controller.host;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* @deprecated since 24.3 and will be removed in Vaadin 25.
|
|
278
|
+
*/
|
|
279
|
+
get itemCaches() {
|
|
280
|
+
console.warn(
|
|
281
|
+
'<vaadin-grid> The `itemCaches` property of ItemCache is deprecated and will be removed in Vaadin 25.',
|
|
282
|
+
);
|
|
283
|
+
return this.__subCacheByIndex;
|
|
284
|
+
}
|
|
207
285
|
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2021 - 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import type { ReactiveController } from 'lit';
|
|
7
|
+
import type { Cache } from './cache.js';
|
|
8
|
+
import type { getFlatIndexByPath, getFlatIndexContext, getItemContext } from './helpers.js';
|
|
9
|
+
|
|
10
|
+
type DataProviderDefaultParams = {
|
|
11
|
+
page: number;
|
|
12
|
+
pageSize: number;
|
|
13
|
+
parentItem?: unknown;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type DataProviderCallback<TItem> = (items: TItem[], size?: number) => void;
|
|
17
|
+
|
|
18
|
+
export type DataProvider<TItem, TDataProviderParams extends Record<string, unknown>> = (
|
|
19
|
+
params: DataProviderDefaultParams & TDataProviderParams,
|
|
20
|
+
callback: DataProviderCallback<TItem>,
|
|
21
|
+
) => void;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A controller that stores and manages items loaded with a data provider.
|
|
25
|
+
*/
|
|
26
|
+
export class DataProviderController<TItem, TDataProviderParams extends Record<string, unknown>>
|
|
27
|
+
implements ReactiveController
|
|
28
|
+
{
|
|
29
|
+
/**
|
|
30
|
+
* The controller host element.
|
|
31
|
+
*/
|
|
32
|
+
host: HTMLElement;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A callback that returns data based on the passed params such as
|
|
36
|
+
* `page`, `pageSize`, `parentItem`, etc.
|
|
37
|
+
*/
|
|
38
|
+
dataProvider: DataProvider<TItem, TDataProviderParams>;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* A callback that returns additional params that need to be passed
|
|
42
|
+
* to the data provider callback with every request.
|
|
43
|
+
*/
|
|
44
|
+
dataProviderParams: () => TDataProviderParams;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* A number of items in the root cache.
|
|
48
|
+
*/
|
|
49
|
+
size?: number;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* A number of items to display per page.
|
|
53
|
+
*/
|
|
54
|
+
pageSize: number;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* A callback that returns whether the given item is expanded.
|
|
58
|
+
*/
|
|
59
|
+
isExpanded: (item: TItem) => boolean;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* A callback that returns the id for the given item and that
|
|
63
|
+
* is used when checking object items for equality.
|
|
64
|
+
*/
|
|
65
|
+
getItemId: (item: TItem) => unknown;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* A reference to the root cache instance.
|
|
69
|
+
*/
|
|
70
|
+
rootCache: Cache<TItem>;
|
|
71
|
+
|
|
72
|
+
constructor(
|
|
73
|
+
host: HTMLElement,
|
|
74
|
+
config: {
|
|
75
|
+
size?: number;
|
|
76
|
+
pageSize: number;
|
|
77
|
+
getItemId(item: TItem): unknown;
|
|
78
|
+
isExpanded(item: TItem): boolean;
|
|
79
|
+
dataProvider: DataProvider<TItem, TDataProviderParams>;
|
|
80
|
+
dataProviderParams(): TDataProviderParams;
|
|
81
|
+
},
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* The total number of items, including items from expanded sub-caches.
|
|
86
|
+
*/
|
|
87
|
+
get flatSize(): number;
|
|
88
|
+
|
|
89
|
+
hostConnected(): void;
|
|
90
|
+
|
|
91
|
+
hostDisconnected(): void;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Whether the root cache or any of its decendant caches have pending requests.
|
|
95
|
+
*/
|
|
96
|
+
isLoading(): boolean;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Sets the size for the root cache and recalculates the flattened size.
|
|
100
|
+
*/
|
|
101
|
+
setSize(size: number): void;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Sets the page size and clears the cache.
|
|
105
|
+
*/
|
|
106
|
+
setPageSize(pageSize: number): void;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Sets the data provider callback and clears the cache.
|
|
110
|
+
*/
|
|
111
|
+
setDataProvider(dataProvider: DataProvider<TItem, TDataProviderParams>): void;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Recalculates the flattened size.
|
|
115
|
+
*/
|
|
116
|
+
recalculateFlatSize(): void;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Clears the cache.
|
|
120
|
+
*/
|
|
121
|
+
clearCache(): void;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Returns context for the given flattened index, including:
|
|
125
|
+
* - the corresponding cache
|
|
126
|
+
* - the cache level
|
|
127
|
+
* - the corresponding item (if loaded)
|
|
128
|
+
* - the item's index in the cache's items array
|
|
129
|
+
* - the page containing the item
|
|
130
|
+
*/
|
|
131
|
+
getFlatIndexContext(flatIndex: number): ReturnType<typeof getFlatIndexContext<TItem>>;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Returns context for the given item, including:
|
|
135
|
+
* - the cache containing the item
|
|
136
|
+
* - the cache level
|
|
137
|
+
* - the item
|
|
138
|
+
* - the item's index in the cache's items array
|
|
139
|
+
* - the item's flattened index
|
|
140
|
+
* - the item's sub-cache (if exists)
|
|
141
|
+
* - the page containing the item
|
|
142
|
+
*
|
|
143
|
+
* If the item isn't found, the method returns undefined.
|
|
144
|
+
*/
|
|
145
|
+
getItemContext(item: TItem): ReturnType<typeof getItemContext<TItem>>;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Returns the flattened index for the item that the given indexes point to.
|
|
149
|
+
* Each index in the path array points to a sub-item of the previous index.
|
|
150
|
+
* Using `Infinity` as an index will point to the last item on the level.
|
|
151
|
+
*/
|
|
152
|
+
getFlatIndexByPath(path: number[]): ReturnType<typeof getFlatIndexByPath<TItem>>;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Requests the data provider to load the page with the item corresponding
|
|
156
|
+
* to the given flattened index. If the item is already loaded, the method
|
|
157
|
+
* returns immediatelly.
|
|
158
|
+
*/
|
|
159
|
+
ensureFlatIndexLoaded(flatIndex: number): void;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Creates a sub-cache for the item corresponding to the given flattened index and
|
|
163
|
+
* requests the data provider to load the first page into the created sub-cache.
|
|
164
|
+
* If the sub-cache already exists, the method returns immediatelly.
|
|
165
|
+
*/
|
|
166
|
+
ensureFlatIndexHierarchy(flatIndex: number): void;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Loads the first page into the root cache.
|
|
170
|
+
*/
|
|
171
|
+
loadFirstPage(): void;
|
|
172
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import { Cache } from './cache.js';
|
|
7
|
-
import { getFlatIndexByPath, getFlatIndexContext } from './helpers.js';
|
|
7
|
+
import { getFlatIndexByPath, getFlatIndexContext, getItemContext } from './helpers.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* A controller that stores and manages items loaded with a data provider.
|
|
@@ -50,6 +50,14 @@ export class DataProviderController extends EventTarget {
|
|
|
50
50
|
*/
|
|
51
51
|
isExpanded;
|
|
52
52
|
|
|
53
|
+
/**
|
|
54
|
+
* A callback that returns the id for the given item and that
|
|
55
|
+
* is used when checking object items for equality.
|
|
56
|
+
*
|
|
57
|
+
* @type { (item: unknown) => unknown}
|
|
58
|
+
*/
|
|
59
|
+
getItemId;
|
|
60
|
+
|
|
53
61
|
/**
|
|
54
62
|
* A reference to the root cache instance.
|
|
55
63
|
*
|
|
@@ -57,27 +65,31 @@ export class DataProviderController extends EventTarget {
|
|
|
57
65
|
*/
|
|
58
66
|
rootCache;
|
|
59
67
|
|
|
60
|
-
constructor(host, { size, pageSize, isExpanded, dataProvider, dataProviderParams }) {
|
|
68
|
+
constructor(host, { size, pageSize, isExpanded, getItemId, dataProvider, dataProviderParams }) {
|
|
61
69
|
super();
|
|
62
70
|
this.host = host;
|
|
63
|
-
this.size = size;
|
|
64
71
|
this.pageSize = pageSize;
|
|
72
|
+
this.getItemId = getItemId;
|
|
65
73
|
this.isExpanded = isExpanded;
|
|
66
74
|
this.dataProvider = dataProvider;
|
|
67
75
|
this.dataProviderParams = dataProviderParams;
|
|
68
|
-
this.rootCache = this.__createRootCache();
|
|
76
|
+
this.rootCache = this.__createRootCache(size);
|
|
69
77
|
}
|
|
70
78
|
|
|
71
79
|
/**
|
|
72
80
|
* The total number of items, including items from expanded sub-caches.
|
|
73
81
|
*/
|
|
74
|
-
get
|
|
75
|
-
return this.rootCache.
|
|
82
|
+
get flatSize() {
|
|
83
|
+
return this.rootCache.flatSize;
|
|
76
84
|
}
|
|
77
85
|
|
|
78
86
|
/** @private */
|
|
79
87
|
get __cacheContext() {
|
|
80
|
-
return {
|
|
88
|
+
return {
|
|
89
|
+
isExpanded: this.isExpanded,
|
|
90
|
+
// The controller instance is needed to ensure deprecated cache methods work.
|
|
91
|
+
__controller: this,
|
|
92
|
+
};
|
|
81
93
|
}
|
|
82
94
|
|
|
83
95
|
/**
|
|
@@ -89,17 +101,6 @@ export class DataProviderController extends EventTarget {
|
|
|
89
101
|
return this.rootCache.isLoading;
|
|
90
102
|
}
|
|
91
103
|
|
|
92
|
-
/**
|
|
93
|
-
* Sets the size for the root cache and recalculates the effective size.
|
|
94
|
-
*
|
|
95
|
-
* @param {number} size
|
|
96
|
-
*/
|
|
97
|
-
setSize(size) {
|
|
98
|
-
this.size = size;
|
|
99
|
-
this.rootCache.size = size;
|
|
100
|
-
this.recalculateEffectiveSize();
|
|
101
|
-
}
|
|
102
|
-
|
|
103
104
|
/**
|
|
104
105
|
* Sets the page size and clears the cache.
|
|
105
106
|
*
|
|
@@ -121,31 +122,49 @@ export class DataProviderController extends EventTarget {
|
|
|
121
122
|
}
|
|
122
123
|
|
|
123
124
|
/**
|
|
124
|
-
* Recalculates the
|
|
125
|
+
* Recalculates the flattened size.
|
|
125
126
|
*/
|
|
126
|
-
|
|
127
|
-
this.rootCache.
|
|
127
|
+
recalculateFlatSize() {
|
|
128
|
+
this.rootCache.recalculateFlatSize();
|
|
128
129
|
}
|
|
129
130
|
|
|
130
131
|
/**
|
|
131
132
|
* Clears the cache.
|
|
132
133
|
*/
|
|
133
134
|
clearCache() {
|
|
134
|
-
this.rootCache = this.__createRootCache();
|
|
135
|
+
this.rootCache = this.__createRootCache(this.rootCache.size);
|
|
135
136
|
}
|
|
136
137
|
|
|
137
138
|
/**
|
|
138
139
|
* Returns context for the given flattened index, including:
|
|
139
140
|
* - the corresponding cache
|
|
140
|
-
* - the associated item (if loaded)
|
|
141
|
-
* - the corresponding index in the cache's items array.
|
|
142
|
-
* - the page containing the index.
|
|
143
141
|
* - the cache level
|
|
142
|
+
* - the corresponding item (if loaded)
|
|
143
|
+
* - the item's index in the cache's items array
|
|
144
|
+
* - the page containing the item
|
|
145
|
+
*
|
|
146
|
+
* @param {number} flatIndex
|
|
144
147
|
*/
|
|
145
148
|
getFlatIndexContext(flatIndex) {
|
|
146
149
|
return getFlatIndexContext(this.rootCache, flatIndex);
|
|
147
150
|
}
|
|
148
151
|
|
|
152
|
+
/**
|
|
153
|
+
* Returns context for the given item, including:
|
|
154
|
+
* - the cache containing the item
|
|
155
|
+
* - the cache level
|
|
156
|
+
* - the item
|
|
157
|
+
* - the item's index in the cache's items array
|
|
158
|
+
* - the item's flattened index
|
|
159
|
+
* - the item's sub-cache (if exists)
|
|
160
|
+
* - the page containing the item
|
|
161
|
+
*
|
|
162
|
+
* If the item isn't found, the method returns undefined.
|
|
163
|
+
*/
|
|
164
|
+
getItemContext(item) {
|
|
165
|
+
return getItemContext({ getItemId: this.getItemId }, this.rootCache, item);
|
|
166
|
+
}
|
|
167
|
+
|
|
149
168
|
/**
|
|
150
169
|
* Returns the flattened index for the item that the given indexes point to.
|
|
151
170
|
* Each index in the path array points to a sub-item of the previous index.
|
|
@@ -197,23 +216,26 @@ export class DataProviderController extends EventTarget {
|
|
|
197
216
|
}
|
|
198
217
|
|
|
199
218
|
/** @private */
|
|
200
|
-
__createRootCache() {
|
|
201
|
-
return new Cache(this.__cacheContext, this.pageSize,
|
|
219
|
+
__createRootCache(size) {
|
|
220
|
+
return new Cache(this.__cacheContext, this.pageSize, size);
|
|
202
221
|
}
|
|
203
222
|
|
|
204
223
|
/** @private */
|
|
205
224
|
__loadCachePage(cache, page) {
|
|
206
|
-
if (!this.dataProvider || cache.pendingRequests
|
|
225
|
+
if (!this.dataProvider || cache.pendingRequests[page]) {
|
|
207
226
|
return;
|
|
208
227
|
}
|
|
209
228
|
|
|
210
|
-
|
|
229
|
+
let params = {
|
|
211
230
|
page,
|
|
212
231
|
pageSize: this.pageSize,
|
|
213
232
|
parentItem: cache.parentItem,
|
|
214
|
-
...this.dataProviderParams(),
|
|
215
233
|
};
|
|
216
234
|
|
|
235
|
+
if (this.dataProviderParams) {
|
|
236
|
+
params = { ...params, ...this.dataProviderParams() };
|
|
237
|
+
}
|
|
238
|
+
|
|
217
239
|
const callback = (items, size) => {
|
|
218
240
|
if (size !== undefined) {
|
|
219
241
|
cache.size = size;
|
|
@@ -223,16 +245,16 @@ export class DataProviderController extends EventTarget {
|
|
|
223
245
|
|
|
224
246
|
cache.setPage(page, items);
|
|
225
247
|
|
|
226
|
-
this.
|
|
248
|
+
this.recalculateFlatSize();
|
|
227
249
|
|
|
228
250
|
this.dispatchEvent(new CustomEvent('page-received'));
|
|
229
251
|
|
|
230
|
-
cache.pendingRequests
|
|
252
|
+
delete cache.pendingRequests[page];
|
|
231
253
|
|
|
232
254
|
this.dispatchEvent(new CustomEvent('page-loaded'));
|
|
233
255
|
};
|
|
234
256
|
|
|
235
|
-
cache.pendingRequests
|
|
257
|
+
cache.pendingRequests[page] = callback;
|
|
236
258
|
|
|
237
259
|
this.dispatchEvent(new CustomEvent('page-requested'));
|
|
238
260
|
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2021 - 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import type { Cache } from './cache.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Returns context for the given flattened index, including:
|
|
10
|
+
* - the corresponding cache
|
|
11
|
+
* - the cache level
|
|
12
|
+
* - the corresponding item (if loaded)
|
|
13
|
+
* - the item's index in the cache's items array
|
|
14
|
+
* - the page containing the item
|
|
15
|
+
*/
|
|
16
|
+
export function getFlatIndexContext<TItem>(
|
|
17
|
+
cache: Cache<TItem>,
|
|
18
|
+
flatIndex: number,
|
|
19
|
+
level: number,
|
|
20
|
+
): {
|
|
21
|
+
cache: Cache<TItem>;
|
|
22
|
+
item: TItem | undefined;
|
|
23
|
+
index: number;
|
|
24
|
+
page: number;
|
|
25
|
+
level: number;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Returns context for the given item, including:
|
|
30
|
+
* - the cache containing the item
|
|
31
|
+
* - the cache level
|
|
32
|
+
* - the item
|
|
33
|
+
* - the item's index in the cache's items array
|
|
34
|
+
* - the item's flattened index
|
|
35
|
+
* - the item's sub-cache (if exists)
|
|
36
|
+
* - the page containing the item
|
|
37
|
+
*
|
|
38
|
+
* If the item isn't found, the method returns undefined.
|
|
39
|
+
*/
|
|
40
|
+
export function getItemContext<TItem>(
|
|
41
|
+
context: { getItemId(item: TItem): unknown },
|
|
42
|
+
cache: Cache<TItem>,
|
|
43
|
+
targetItem: TItem,
|
|
44
|
+
level: number,
|
|
45
|
+
levelFlatIndex: number,
|
|
46
|
+
):
|
|
47
|
+
| {
|
|
48
|
+
level: number;
|
|
49
|
+
item: TItem;
|
|
50
|
+
index: number;
|
|
51
|
+
page: number;
|
|
52
|
+
flatIndex: number;
|
|
53
|
+
cache: Cache<TItem>;
|
|
54
|
+
subCache: Cache<TItem> | undefined;
|
|
55
|
+
}
|
|
56
|
+
| undefined;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Recursively returns the globally flat index of the item the given indexes point to.
|
|
60
|
+
* Each index in the array points to a sub-item of the previous index.
|
|
61
|
+
* Using `Infinity` as an index will point to the last item on the level.
|
|
62
|
+
*/
|
|
63
|
+
export function getFlatIndexByPath<TItem>(cache: Cache<TItem>, path: number[], flatIndex: number): number;
|
|
@@ -4,17 +4,20 @@
|
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {import('./cache.js').Cache} Cache
|
|
9
|
+
*/
|
|
10
|
+
|
|
7
11
|
/**
|
|
8
12
|
* Returns context for the given flattened index, including:
|
|
9
13
|
* - the corresponding cache
|
|
10
|
-
* - the associated item (if loaded)
|
|
11
|
-
* - the corresponding index in the cache's items array.
|
|
12
|
-
* - the page containing the index.
|
|
13
14
|
* - the cache level
|
|
15
|
+
* - the corresponding item (if loaded)
|
|
16
|
+
* - the item's index in the cache's items array
|
|
17
|
+
* - the page containing the item
|
|
14
18
|
*
|
|
15
|
-
* @param {
|
|
19
|
+
* @param {Cache} cache
|
|
16
20
|
* @param {number} flatIndex
|
|
17
|
-
* @return {{ cache: Cache, item: object | undefined, index: number, page: number, level: number }}
|
|
18
21
|
*/
|
|
19
22
|
export function getFlatIndexContext(cache, flatIndex, level = 0) {
|
|
20
23
|
let levelIndex = flatIndex;
|
|
@@ -23,10 +26,10 @@ export function getFlatIndexContext(cache, flatIndex, level = 0) {
|
|
|
23
26
|
const index = subCache.parentCacheIndex;
|
|
24
27
|
if (levelIndex <= index) {
|
|
25
28
|
break;
|
|
26
|
-
} else if (levelIndex <= index + subCache.
|
|
29
|
+
} else if (levelIndex <= index + subCache.flatSize) {
|
|
27
30
|
return getFlatIndexContext(subCache, levelIndex - index - 1, level + 1);
|
|
28
31
|
}
|
|
29
|
-
levelIndex -= subCache.
|
|
32
|
+
levelIndex -= subCache.flatSize;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
return {
|
|
@@ -38,6 +41,52 @@ export function getFlatIndexContext(cache, flatIndex, level = 0) {
|
|
|
38
41
|
};
|
|
39
42
|
}
|
|
40
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Returns context for the given item, including:
|
|
46
|
+
* - the cache containing the item
|
|
47
|
+
* - the cache level
|
|
48
|
+
* - the item
|
|
49
|
+
* - the item's index in the cache's items array
|
|
50
|
+
* - the item's flattened index
|
|
51
|
+
* - the item's sub-cache (if exists)
|
|
52
|
+
* - the page containing the item
|
|
53
|
+
*
|
|
54
|
+
* If the item isn't found, the method returns undefined.
|
|
55
|
+
*
|
|
56
|
+
* @param {Cache} cache
|
|
57
|
+
* @param {{ getItemId: (item: unknown) => unknown}} context
|
|
58
|
+
* @param {Cache} cache
|
|
59
|
+
* @param {unknown} targetItem
|
|
60
|
+
* @param {number} level
|
|
61
|
+
* @param {number} levelFlatIndex
|
|
62
|
+
*/
|
|
63
|
+
export function getItemContext({ getItemId }, cache, targetItem, level = 0, levelFlatIndex = 0) {
|
|
64
|
+
// Start looking in this cache
|
|
65
|
+
for (let index = 0; index < cache.items.length; index++) {
|
|
66
|
+
const item = cache.items[index];
|
|
67
|
+
if (!!item && getItemId(item) === getItemId(targetItem)) {
|
|
68
|
+
return {
|
|
69
|
+
cache,
|
|
70
|
+
level,
|
|
71
|
+
item,
|
|
72
|
+
index,
|
|
73
|
+
page: Math.floor(index / cache.pageSize),
|
|
74
|
+
subCache: cache.getSubCache(index),
|
|
75
|
+
flatIndex: levelFlatIndex + cache.getFlatIndex(index),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Look through sub-caches
|
|
81
|
+
for (const subCache of cache.subCaches) {
|
|
82
|
+
const parentItemFlatIndex = levelFlatIndex + cache.getFlatIndex(subCache.parentCacheIndex);
|
|
83
|
+
const result = getItemContext({ getItemId }, subCache, targetItem, level + 1, parentItemFlatIndex + 1);
|
|
84
|
+
if (result) {
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
41
90
|
/**
|
|
42
91
|
* Recursively returns the globally flat index of the item the given indexes point to.
|
|
43
92
|
* Each index in the array points to a sub-item of the previous index.
|
|
@@ -56,7 +105,7 @@ export function getFlatIndexByPath(cache, [levelIndex, ...subIndexes], flatIndex
|
|
|
56
105
|
|
|
57
106
|
const flatIndexOnLevel = cache.getFlatIndex(levelIndex);
|
|
58
107
|
const subCache = cache.getSubCache(levelIndex);
|
|
59
|
-
if (subCache && subCache.
|
|
108
|
+
if (subCache && subCache.flatSize > 0 && subIndexes.length) {
|
|
60
109
|
return getFlatIndexByPath(subCache, subIndexes, flatIndex + flatIndexOnLevel + 1);
|
|
61
110
|
}
|
|
62
111
|
return flatIndex + flatIndexOnLevel;
|
package/src/define.js
CHANGED
|
@@ -3,9 +3,16 @@
|
|
|
3
3
|
* Copyright (c) 2021 - 2023 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
+
|
|
6
7
|
export function defineCustomElement(CustomElement) {
|
|
7
8
|
const defined = customElements.get(CustomElement.is);
|
|
8
9
|
if (!defined) {
|
|
10
|
+
Object.defineProperty(CustomElement, 'version', {
|
|
11
|
+
get() {
|
|
12
|
+
return '24.3.0-alpha11';
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
|
|
9
16
|
customElements.define(CustomElement.is, CustomElement);
|
|
10
17
|
} else {
|
|
11
18
|
const definedVersion = defined.version;
|
package/src/element-mixin.js
CHANGED
|
@@ -44,10 +44,6 @@ const registered = new Set();
|
|
|
44
44
|
*/
|
|
45
45
|
export const ElementMixin = (superClass) =>
|
|
46
46
|
class VaadinElementMixin extends DirMixin(superClass) {
|
|
47
|
-
static get version() {
|
|
48
|
-
return '24.3.0-alpha1';
|
|
49
|
-
}
|
|
50
|
-
|
|
51
47
|
/** @protected */
|
|
52
48
|
static finalize() {
|
|
53
49
|
super.finalize();
|
package/src/url-utils.d.ts
CHANGED
package/src/url-utils.js
CHANGED
|
@@ -5,12 +5,15 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Check if two paths
|
|
8
|
+
* Check if two paths can be resolved as URLs
|
|
9
|
+
* with the same origin and pathname.
|
|
9
10
|
*
|
|
10
11
|
* @param {string} path1
|
|
11
12
|
* @param {string} path2
|
|
12
13
|
*/
|
|
13
14
|
export function matchPaths(path1, path2) {
|
|
14
15
|
const base = document.baseURI;
|
|
15
|
-
|
|
16
|
+
const url1 = new URL(path1, base);
|
|
17
|
+
const url2 = new URL(path2, base);
|
|
18
|
+
return url1.origin === url2.origin && url1.pathname === url2.pathname;
|
|
16
19
|
}
|
|
@@ -82,10 +82,24 @@ export class IronListAdapter {
|
|
|
82
82
|
return this.lastVisibleIndex + this._vidxOffset;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
__hasPlaceholders() {
|
|
86
|
+
return this.__getVisibleElements().some((el) => el.__virtualizerPlaceholder);
|
|
87
|
+
}
|
|
88
|
+
|
|
85
89
|
scrollToIndex(index) {
|
|
86
90
|
if (typeof index !== 'number' || isNaN(index) || this.size === 0 || !this.scrollTarget.offsetHeight) {
|
|
87
91
|
return;
|
|
88
92
|
}
|
|
93
|
+
delete this.__pendingScrollToIndex;
|
|
94
|
+
|
|
95
|
+
if (this._physicalCount <= 3 /* iron-list-core.DEFAULT_PHYSICAL_COUNT */) {
|
|
96
|
+
// The condition here is a performance improvement to avoid an unnecessary
|
|
97
|
+
// re-render when the physical item pool is already covered.
|
|
98
|
+
|
|
99
|
+
// Finish rendering at the current scroll position before scrolling
|
|
100
|
+
this.flush();
|
|
101
|
+
}
|
|
102
|
+
|
|
89
103
|
index = this._clamp(index, 0, this.size - 1);
|
|
90
104
|
|
|
91
105
|
const visibleElementCount = this.__getVisibleElements().length;
|
|
@@ -113,9 +127,16 @@ export class IronListAdapter {
|
|
|
113
127
|
this._scrollTop -= this.__getIndexScrollOffset(index) || 0;
|
|
114
128
|
}
|
|
115
129
|
this._scrollHandler();
|
|
130
|
+
|
|
131
|
+
if (this.__hasPlaceholders()) {
|
|
132
|
+
// After rendering synchronously, there are still placeholders in the DOM.
|
|
133
|
+
// Try again after the next elements update.
|
|
134
|
+
this.__pendingScrollToIndex = index;
|
|
135
|
+
}
|
|
116
136
|
}
|
|
117
137
|
|
|
118
138
|
flush() {
|
|
139
|
+
const startPhysicalCount = this._physicalCount;
|
|
119
140
|
// The scroll target is hidden.
|
|
120
141
|
if (this.scrollTarget.offsetHeight === 0) {
|
|
121
142
|
return;
|
|
@@ -133,6 +154,11 @@ export class IronListAdapter {
|
|
|
133
154
|
if (this.__debouncerWheelAnimationFrame) {
|
|
134
155
|
this.__debouncerWheelAnimationFrame.flush();
|
|
135
156
|
}
|
|
157
|
+
|
|
158
|
+
if (this._physicalCount !== startPhysicalCount) {
|
|
159
|
+
// Flushing again until physical count stabilizes fixes https://github.com/vaadin/flow-components/issues/5595#issuecomment-1770278913
|
|
160
|
+
this.flush();
|
|
161
|
+
}
|
|
136
162
|
}
|
|
137
163
|
|
|
138
164
|
update(startIndex = 0, endIndex = this.size - 1) {
|
|
@@ -199,8 +225,9 @@ export class IronListAdapter {
|
|
|
199
225
|
|
|
200
226
|
__updateElement(el, index, forceSameIndexUpdates) {
|
|
201
227
|
// Clean up temporary placeholder sizing
|
|
202
|
-
if (el.
|
|
228
|
+
if (el.__virtualizerPlaceholder) {
|
|
203
229
|
el.style.paddingTop = '';
|
|
230
|
+
el.__virtualizerPlaceholder = false;
|
|
204
231
|
}
|
|
205
232
|
|
|
206
233
|
if (!this.__preventElementUpdates && (el.__lastUpdatedIndex !== index || forceSameIndexUpdates)) {
|
|
@@ -224,6 +251,7 @@ export class IronListAdapter {
|
|
|
224
251
|
// Assign a temporary placeholder sizing to elements that would otherwise end up having
|
|
225
252
|
// no height.
|
|
226
253
|
el.style.paddingTop = `${this.__placeholderHeight}px`;
|
|
254
|
+
el.__virtualizerPlaceholder = true;
|
|
227
255
|
|
|
228
256
|
// Manually schedule the resize handler to make sure the placeholder padding is
|
|
229
257
|
// cleared in case the resize observer never triggers.
|
|
@@ -241,6 +269,10 @@ export class IronListAdapter {
|
|
|
241
269
|
this.__placeholderHeight = Math.round(filteredHeights.reduce((a, b) => a + b, 0) / filteredHeights.length);
|
|
242
270
|
}
|
|
243
271
|
});
|
|
272
|
+
|
|
273
|
+
if (this.__pendingScrollToIndex !== undefined && !this.__hasPlaceholders()) {
|
|
274
|
+
this.scrollToIndex(this.__pendingScrollToIndex);
|
|
275
|
+
}
|
|
244
276
|
}
|
|
245
277
|
|
|
246
278
|
__getIndexScrollOffset(index) {
|
|
@@ -278,6 +310,7 @@ export class IronListAdapter {
|
|
|
278
310
|
this.__preventElementUpdates = false;
|
|
279
311
|
} else {
|
|
280
312
|
// Already initialized, just update _virtualCount
|
|
313
|
+
this._updateScrollerSize();
|
|
281
314
|
this._virtualCount = this.items.length;
|
|
282
315
|
}
|
|
283
316
|
|