@ahmedhfarag/ngx-virtual-scroller 4.0.3

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.
@@ -0,0 +1,1071 @@
1
+ import * as i0 from '@angular/core';
2
+ import { EventEmitter, PLATFORM_ID, ElementRef, ContentChild, ViewChild, Output, Input, Inject, Optional, Component } from '@angular/core';
3
+ import { isPlatformServer, CommonModule } from '@angular/common';
4
+ import * as tween from '@tweenjs/tween.js';
5
+
6
+ function VIRTUAL_SCROLLER_DEFAULT_OPTIONS_FACTORY() {
7
+ return {
8
+ checkResizeInterval: 1000,
9
+ modifyOverflowStyleOfParentScroll: true,
10
+ resizeBypassRefreshThreshold: 5,
11
+ scrollAnimationTime: 750,
12
+ scrollDebounceTime: 0,
13
+ scrollThrottlingTime: 0,
14
+ stripedTable: false
15
+ };
16
+ }
17
+ class VirtualScrollerComponent {
18
+ element;
19
+ renderer;
20
+ zone;
21
+ changeDetectorRef;
22
+ viewPortItems;
23
+ window = window;
24
+ get viewPortInfo() {
25
+ let pageInfo = this.previousViewPort || {};
26
+ return {
27
+ startIndex: pageInfo.startIndex || 0,
28
+ endIndex: pageInfo.endIndex || 0,
29
+ scrollStartPosition: pageInfo.scrollStartPosition || 0,
30
+ scrollEndPosition: pageInfo.scrollEndPosition || 0,
31
+ maxScrollPosition: pageInfo.maxScrollPosition || 0,
32
+ startIndexWithBuffer: pageInfo.startIndexWithBuffer || 0,
33
+ endIndexWithBuffer: pageInfo.endIndexWithBuffer || 0
34
+ };
35
+ }
36
+ executeRefreshOutsideAngularZone = false;
37
+ _enableUnequalChildrenSizes = false;
38
+ get enableUnequalChildrenSizes() {
39
+ return this._enableUnequalChildrenSizes;
40
+ }
41
+ set enableUnequalChildrenSizes(value) {
42
+ if (this._enableUnequalChildrenSizes === value) {
43
+ return;
44
+ }
45
+ this._enableUnequalChildrenSizes = value;
46
+ this.minMeasuredChildWidth = undefined;
47
+ this.minMeasuredChildHeight = undefined;
48
+ }
49
+ RTL = false;
50
+ useMarginInsteadOfTranslate = false;
51
+ modifyOverflowStyleOfParentScroll;
52
+ stripedTable;
53
+ scrollbarWidth;
54
+ scrollbarHeight;
55
+ childWidth;
56
+ childHeight;
57
+ ssrChildWidth;
58
+ ssrChildHeight;
59
+ ssrViewportWidth = 1920;
60
+ ssrViewportHeight = 1080;
61
+ _bufferAmount;
62
+ get bufferAmount() {
63
+ if (typeof (this._bufferAmount) === 'number' && this._bufferAmount >= 0) {
64
+ return this._bufferAmount;
65
+ }
66
+ else {
67
+ return this.enableUnequalChildrenSizes ? 5 : 0;
68
+ }
69
+ }
70
+ set bufferAmount(value) {
71
+ this._bufferAmount = value;
72
+ }
73
+ scrollAnimationTime;
74
+ resizeBypassRefreshThreshold;
75
+ _scrollThrottlingTime;
76
+ get scrollThrottlingTime() {
77
+ return this._scrollThrottlingTime;
78
+ }
79
+ set scrollThrottlingTime(value) {
80
+ this._scrollThrottlingTime = value;
81
+ this.updateOnScrollFunction();
82
+ }
83
+ _scrollDebounceTime;
84
+ get scrollDebounceTime() {
85
+ return this._scrollDebounceTime;
86
+ }
87
+ set scrollDebounceTime(value) {
88
+ this._scrollDebounceTime = value;
89
+ this.updateOnScrollFunction();
90
+ }
91
+ onScroll;
92
+ updateOnScrollFunction() {
93
+ if (this.scrollDebounceTime) {
94
+ this.onScroll = this.debounce(() => {
95
+ this.refresh_internal(false);
96
+ }, this.scrollDebounceTime);
97
+ }
98
+ else if (this.scrollThrottlingTime) {
99
+ this.onScroll = this.throttleTrailing(() => {
100
+ this.refresh_internal(false);
101
+ }, this.scrollThrottlingTime);
102
+ }
103
+ else {
104
+ this.onScroll = () => {
105
+ this.refresh_internal(false);
106
+ };
107
+ }
108
+ }
109
+ checkScrollElementResizedTimer;
110
+ _checkResizeInterval;
111
+ get checkResizeInterval() {
112
+ return this._checkResizeInterval;
113
+ }
114
+ set checkResizeInterval(value) {
115
+ if (this._checkResizeInterval === value) {
116
+ return;
117
+ }
118
+ this._checkResizeInterval = value;
119
+ this.addScrollEventHandlers();
120
+ }
121
+ _items = [];
122
+ get items() {
123
+ return this._items;
124
+ }
125
+ set items(value) {
126
+ if (value === this._items) {
127
+ return;
128
+ }
129
+ this._items = value || [];
130
+ this.refresh_internal(true);
131
+ }
132
+ compareItems = (item1, item2) => item1 === item2;
133
+ _horizontal;
134
+ get horizontal() {
135
+ return this._horizontal;
136
+ }
137
+ set horizontal(value) {
138
+ this._horizontal = value;
139
+ this.updateDirection();
140
+ }
141
+ revertParentOverscroll() {
142
+ const scrollElement = this.getScrollElement();
143
+ if (scrollElement && this.oldParentScrollOverflow) {
144
+ scrollElement.style['overflow-y'] = this.oldParentScrollOverflow.y;
145
+ scrollElement.style['overflow-x'] = this.oldParentScrollOverflow.x;
146
+ }
147
+ this.oldParentScrollOverflow = undefined;
148
+ }
149
+ oldParentScrollOverflow;
150
+ _parentScroll;
151
+ get parentScroll() {
152
+ return this._parentScroll;
153
+ }
154
+ set parentScroll(value) {
155
+ if (this._parentScroll === value) {
156
+ return;
157
+ }
158
+ this.revertParentOverscroll();
159
+ this._parentScroll = value;
160
+ this.addScrollEventHandlers();
161
+ const scrollElement = this.getScrollElement();
162
+ if (this.modifyOverflowStyleOfParentScroll && scrollElement !== this.element.nativeElement) {
163
+ this.oldParentScrollOverflow = { x: scrollElement.style['overflow-x'], y: scrollElement.style['overflow-y'] };
164
+ scrollElement.style['overflow-y'] = this.horizontal ? 'visible' : 'auto';
165
+ scrollElement.style['overflow-x'] = this.horizontal ? 'auto' : 'visible';
166
+ }
167
+ }
168
+ vsUpdate = new EventEmitter();
169
+ vsChange = new EventEmitter();
170
+ vsStart = new EventEmitter();
171
+ vsEnd = new EventEmitter();
172
+ contentElementRef;
173
+ invisiblePaddingElementRef;
174
+ headerElementRef;
175
+ containerElementRef;
176
+ ngOnInit() {
177
+ this.addScrollEventHandlers();
178
+ }
179
+ ngOnDestroy() {
180
+ this.removeScrollEventHandlers();
181
+ this.revertParentOverscroll();
182
+ }
183
+ ngOnChanges(changes) {
184
+ let indexLengthChanged = this.cachedItemsLength !== this.items.length;
185
+ this.cachedItemsLength = this.items.length;
186
+ const firstRun = !changes.items || !changes.items.previousValue || changes.items.previousValue.length === 0;
187
+ this.refresh_internal(indexLengthChanged || firstRun);
188
+ }
189
+ ngDoCheck() {
190
+ if (this.cachedItemsLength !== this.items.length) {
191
+ this.cachedItemsLength = this.items.length;
192
+ this.refresh_internal(true);
193
+ return;
194
+ }
195
+ if (this.previousViewPort && this.viewPortItems && this.viewPortItems.length > 0) {
196
+ let itemsArrayChanged = false;
197
+ for (let i = 0; i < this.viewPortItems.length; ++i) {
198
+ if (!this.compareItems(this.items[this.previousViewPort.startIndexWithBuffer + i], this.viewPortItems[i])) {
199
+ itemsArrayChanged = true;
200
+ break;
201
+ }
202
+ }
203
+ if (itemsArrayChanged) {
204
+ this.refresh_internal(true);
205
+ }
206
+ }
207
+ }
208
+ refresh() {
209
+ this.refresh_internal(true);
210
+ }
211
+ invalidateAllCachedMeasurements() {
212
+ this.wrapGroupDimensions = {
213
+ maxChildSizePerWrapGroup: [],
214
+ numberOfKnownWrapGroupChildSizes: 0,
215
+ sumOfKnownWrapGroupChildWidths: 0,
216
+ sumOfKnownWrapGroupChildHeights: 0
217
+ };
218
+ this.minMeasuredChildWidth = undefined;
219
+ this.minMeasuredChildHeight = undefined;
220
+ this.refresh_internal(false);
221
+ }
222
+ invalidateCachedMeasurementForItem(item) {
223
+ if (this.enableUnequalChildrenSizes) {
224
+ let index = this.items && this.items.indexOf(item);
225
+ if (index >= 0) {
226
+ this.invalidateCachedMeasurementAtIndex(index);
227
+ }
228
+ }
229
+ else {
230
+ this.minMeasuredChildWidth = undefined;
231
+ this.minMeasuredChildHeight = undefined;
232
+ }
233
+ this.refresh_internal(false);
234
+ }
235
+ invalidateCachedMeasurementAtIndex(index) {
236
+ if (this.enableUnequalChildrenSizes) {
237
+ let cachedMeasurement = this.wrapGroupDimensions.maxChildSizePerWrapGroup[index];
238
+ if (cachedMeasurement) {
239
+ this.wrapGroupDimensions.maxChildSizePerWrapGroup[index] = undefined;
240
+ --this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
241
+ this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths -= cachedMeasurement.childWidth || 0;
242
+ this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights -= cachedMeasurement.childHeight || 0;
243
+ }
244
+ }
245
+ else {
246
+ this.minMeasuredChildWidth = undefined;
247
+ this.minMeasuredChildHeight = undefined;
248
+ }
249
+ this.refresh_internal(false);
250
+ }
251
+ scrollInto(item, alignToBeginning = true, additionalOffset = 0, animationMilliseconds = undefined, animationCompletedCallback = undefined) {
252
+ let index = this.items.indexOf(item);
253
+ if (index === -1) {
254
+ return;
255
+ }
256
+ this.scrollToIndex(index, alignToBeginning, additionalOffset, animationMilliseconds, animationCompletedCallback);
257
+ }
258
+ scrollToIndex(index, alignToBeginning = true, additionalOffset = 0, animationMilliseconds = undefined, animationCompletedCallback = undefined) {
259
+ let maxRetries = 5;
260
+ let retryIfNeeded = () => {
261
+ --maxRetries;
262
+ if (maxRetries <= 0) {
263
+ if (animationCompletedCallback) {
264
+ animationCompletedCallback();
265
+ }
266
+ return;
267
+ }
268
+ let dimensions = this.calculateDimensions();
269
+ let desiredStartIndex = Math.min(Math.max(index, 0), dimensions.itemCount - 1);
270
+ if (this.previousViewPort.startIndex === desiredStartIndex) {
271
+ if (animationCompletedCallback) {
272
+ animationCompletedCallback();
273
+ }
274
+ return;
275
+ }
276
+ this.scrollToIndex_internal(index, alignToBeginning, additionalOffset, 0, retryIfNeeded);
277
+ };
278
+ this.scrollToIndex_internal(index, alignToBeginning, additionalOffset, animationMilliseconds, retryIfNeeded);
279
+ }
280
+ scrollToIndex_internal(index, alignToBeginning = true, additionalOffset = 0, animationMilliseconds = undefined, animationCompletedCallback = undefined) {
281
+ animationMilliseconds = animationMilliseconds === undefined ? this.scrollAnimationTime : animationMilliseconds;
282
+ let dimensions = this.calculateDimensions();
283
+ let scroll = this.calculatePadding(index, dimensions) + additionalOffset;
284
+ if (!alignToBeginning) {
285
+ scroll -= dimensions.wrapGroupsPerPage * dimensions[this._childScrollDim];
286
+ }
287
+ this.scrollToPosition(scroll, animationMilliseconds, animationCompletedCallback);
288
+ }
289
+ scrollToPosition(scrollPosition, animationMilliseconds = undefined, animationCompletedCallback = undefined) {
290
+ scrollPosition += this.getElementsOffset();
291
+ animationMilliseconds = animationMilliseconds === undefined ? this.scrollAnimationTime : animationMilliseconds;
292
+ let scrollElement = this.getScrollElement();
293
+ let animationRequest;
294
+ if (this.currentTween) {
295
+ this.currentTween.stop();
296
+ this.currentTween = undefined;
297
+ }
298
+ if (!animationMilliseconds) {
299
+ this.renderer.setProperty(scrollElement, this._scrollType, scrollPosition);
300
+ this.refresh_internal(false, animationCompletedCallback);
301
+ return;
302
+ }
303
+ const tweenConfigObj = { scrollPosition: scrollElement[this._scrollType] };
304
+ let newTween = new tween.Tween(tweenConfigObj)
305
+ .to({ scrollPosition }, animationMilliseconds)
306
+ .easing(tween.Easing.Quadratic.Out)
307
+ .onUpdate((data) => {
308
+ if (isNaN(data.scrollPosition)) {
309
+ return;
310
+ }
311
+ this.renderer.setProperty(scrollElement, this._scrollType, data.scrollPosition);
312
+ this.refresh_internal(false);
313
+ })
314
+ .onStop(() => {
315
+ cancelAnimationFrame(animationRequest);
316
+ })
317
+ .start();
318
+ const animate = (time) => {
319
+ if (!newTween["isPlaying"]()) {
320
+ return;
321
+ }
322
+ newTween.update(time);
323
+ if (tweenConfigObj.scrollPosition === scrollPosition) {
324
+ this.refresh_internal(false, animationCompletedCallback);
325
+ return;
326
+ }
327
+ this.zone.runOutsideAngular(() => {
328
+ animationRequest = requestAnimationFrame(animate);
329
+ });
330
+ };
331
+ animate();
332
+ this.currentTween = newTween;
333
+ }
334
+ isAngularUniversalSSR;
335
+ constructor(element, renderer, zone, changeDetectorRef, platformId, options) {
336
+ this.element = element;
337
+ this.renderer = renderer;
338
+ this.zone = zone;
339
+ this.changeDetectorRef = changeDetectorRef;
340
+ this.isAngularUniversalSSR = isPlatformServer(platformId);
341
+ this.checkResizeInterval = options.checkResizeInterval;
342
+ this.modifyOverflowStyleOfParentScroll = options.modifyOverflowStyleOfParentScroll;
343
+ this.resizeBypassRefreshThreshold = options.resizeBypassRefreshThreshold;
344
+ this.scrollAnimationTime = options.scrollAnimationTime;
345
+ this.scrollDebounceTime = options.scrollDebounceTime;
346
+ this.scrollThrottlingTime = options.scrollThrottlingTime;
347
+ this.scrollbarHeight = options.scrollbarHeight;
348
+ this.scrollbarWidth = options.scrollbarWidth;
349
+ this.stripedTable = options.stripedTable;
350
+ this.horizontal = false;
351
+ this.resetWrapGroupDimensions();
352
+ }
353
+ getElementSize(element) {
354
+ const result = element.getBoundingClientRect();
355
+ const styles = getComputedStyle(element);
356
+ const marginTop = parseInt(styles['margin-top'], 10) || 0;
357
+ const marginBottom = parseInt(styles['margin-bottom'], 10) || 0;
358
+ const marginLeft = parseInt(styles['margin-left'], 10) || 0;
359
+ const marginRight = parseInt(styles['margin-right'], 10) || 0;
360
+ return {
361
+ x: result.left,
362
+ y: result.top,
363
+ top: result.top + marginTop,
364
+ bottom: result.bottom + marginBottom,
365
+ left: result.left + marginLeft,
366
+ right: result.right + marginRight,
367
+ width: result.width + marginLeft + marginRight,
368
+ height: result.height + marginTop + marginBottom,
369
+ toJSON: () => null
370
+ };
371
+ }
372
+ previousScrollBoundingRect;
373
+ checkScrollElementResized() {
374
+ let boundingRect = this.getElementSize(this.getScrollElement());
375
+ let sizeChanged;
376
+ if (!this.previousScrollBoundingRect) {
377
+ sizeChanged = true;
378
+ }
379
+ else {
380
+ let widthChange = Math.abs(boundingRect.width - this.previousScrollBoundingRect.width);
381
+ let heightChange = Math.abs(boundingRect.height - this.previousScrollBoundingRect.height);
382
+ sizeChanged = widthChange > this.resizeBypassRefreshThreshold || heightChange > this.resizeBypassRefreshThreshold;
383
+ }
384
+ if (sizeChanged) {
385
+ this.previousScrollBoundingRect = boundingRect;
386
+ if (boundingRect.width > 0 && boundingRect.height > 0) {
387
+ this.refresh_internal(false);
388
+ }
389
+ }
390
+ }
391
+ _invisiblePaddingProperty;
392
+ _offsetType;
393
+ _scrollType;
394
+ _pageOffsetType;
395
+ _childScrollDim;
396
+ _translateDir;
397
+ _marginDir;
398
+ updateDirection() {
399
+ if (this.horizontal) {
400
+ this._childScrollDim = 'childWidth';
401
+ this._invisiblePaddingProperty = 'scaleX';
402
+ this._marginDir = 'margin-left';
403
+ this._offsetType = 'offsetLeft';
404
+ this._pageOffsetType = 'pageXOffset';
405
+ this._scrollType = 'scrollLeft';
406
+ this._translateDir = 'translateX';
407
+ }
408
+ else {
409
+ this._childScrollDim = 'childHeight';
410
+ this._invisiblePaddingProperty = 'scaleY';
411
+ this._marginDir = 'margin-top';
412
+ this._offsetType = 'offsetTop';
413
+ this._pageOffsetType = 'pageYOffset';
414
+ this._scrollType = 'scrollTop';
415
+ this._translateDir = 'translateY';
416
+ }
417
+ }
418
+ debounce(func, wait) {
419
+ const throttled = this.throttleTrailing(func, wait);
420
+ const result = function () {
421
+ throttled['cancel']();
422
+ throttled.apply(this, arguments);
423
+ };
424
+ result['cancel'] = function () {
425
+ throttled['cancel']();
426
+ };
427
+ return result;
428
+ }
429
+ throttleTrailing(func, wait) {
430
+ let timeout = undefined;
431
+ let _arguments = arguments;
432
+ const result = function () {
433
+ const _this = this;
434
+ _arguments = arguments;
435
+ if (timeout) {
436
+ return;
437
+ }
438
+ if (wait <= 0) {
439
+ func.apply(_this, _arguments);
440
+ }
441
+ else {
442
+ timeout = setTimeout(function () {
443
+ timeout = undefined;
444
+ func.apply(_this, _arguments);
445
+ }, wait);
446
+ }
447
+ };
448
+ result['cancel'] = function () {
449
+ if (timeout) {
450
+ clearTimeout(timeout);
451
+ timeout = undefined;
452
+ }
453
+ };
454
+ return result;
455
+ }
456
+ calculatedScrollbarWidth = 0;
457
+ calculatedScrollbarHeight = 0;
458
+ padding = 0;
459
+ previousViewPort = {};
460
+ currentTween;
461
+ cachedItemsLength;
462
+ disposeScrollHandler;
463
+ disposeResizeHandler;
464
+ refresh_internal(itemsArrayModified, refreshCompletedCallback = undefined, maxRunTimes = 2) {
465
+ //note: maxRunTimes is to force it to keep recalculating if the previous iteration caused a re-render (different sliced items in viewport or scrollPosition changed).
466
+ //The default of 2x max will probably be accurate enough without causing too large a performance bottleneck
467
+ //The code would typically quit out on the 2nd iteration anyways. The main time it'd think more than 2 runs would be necessary would be for vastly different sized child items or if this is the 1st time the items array was initialized.
468
+ //Without maxRunTimes, If the user is actively scrolling this code would become an infinite loop until they stopped scrolling. This would be okay, except each scroll event would start an additional infinte loop. We want to short-circuit it to prevent this.
469
+ if (itemsArrayModified && this.previousViewPort && this.previousViewPort.scrollStartPosition > 0) {
470
+ //if items were prepended, scroll forward to keep same items visible
471
+ let oldViewPort = this.previousViewPort;
472
+ let oldViewPortItems = this.viewPortItems;
473
+ let oldRefreshCompletedCallback = refreshCompletedCallback;
474
+ refreshCompletedCallback = () => {
475
+ let scrollLengthDelta = this.previousViewPort.scrollLength - oldViewPort.scrollLength;
476
+ if (scrollLengthDelta > 0 && this.viewPortItems) {
477
+ let oldStartItem = oldViewPortItems[0];
478
+ let oldStartItemIndex = this.items.findIndex(x => this.compareItems(oldStartItem, x));
479
+ if (oldStartItemIndex > this.previousViewPort.startIndexWithBuffer) {
480
+ let itemOrderChanged = false;
481
+ for (let i = 1; i < this.viewPortItems.length; ++i) {
482
+ if (!this.compareItems(this.items[oldStartItemIndex + i], oldViewPortItems[i])) {
483
+ itemOrderChanged = true;
484
+ break;
485
+ }
486
+ }
487
+ if (!itemOrderChanged) {
488
+ this.scrollToPosition(this.previousViewPort.scrollStartPosition + scrollLengthDelta, 0, oldRefreshCompletedCallback);
489
+ return;
490
+ }
491
+ }
492
+ }
493
+ if (oldRefreshCompletedCallback) {
494
+ oldRefreshCompletedCallback();
495
+ }
496
+ };
497
+ }
498
+ this.zone.runOutsideAngular(() => {
499
+ requestAnimationFrame(() => {
500
+ if (itemsArrayModified) {
501
+ this.resetWrapGroupDimensions();
502
+ }
503
+ let viewport = this.calculateViewport();
504
+ let startChanged = itemsArrayModified || viewport.startIndex !== this.previousViewPort.startIndex;
505
+ let endChanged = itemsArrayModified || viewport.endIndex !== this.previousViewPort.endIndex;
506
+ let scrollLengthChanged = viewport.scrollLength !== this.previousViewPort.scrollLength;
507
+ let paddingChanged = viewport.padding !== this.previousViewPort.padding;
508
+ let scrollPositionChanged = viewport.scrollStartPosition !== this.previousViewPort.scrollStartPosition || viewport.scrollEndPosition !== this.previousViewPort.scrollEndPosition || viewport.maxScrollPosition !== this.previousViewPort.maxScrollPosition;
509
+ this.previousViewPort = viewport;
510
+ if (scrollLengthChanged) {
511
+ this.renderer.setStyle(this.invisiblePaddingElementRef.nativeElement, 'transform', `${this._invisiblePaddingProperty}(${viewport.scrollLength})`);
512
+ this.renderer.setStyle(this.invisiblePaddingElementRef.nativeElement, 'webkitTransform', `${this._invisiblePaddingProperty}(${viewport.scrollLength})`);
513
+ }
514
+ if (paddingChanged) {
515
+ if (this.useMarginInsteadOfTranslate) {
516
+ this.renderer.setStyle(this.contentElementRef.nativeElement, this._marginDir, `${viewport.padding}px`);
517
+ }
518
+ else {
519
+ this.renderer.setStyle(this.contentElementRef.nativeElement, 'transform', `${this._translateDir}(${viewport.padding}px)`);
520
+ this.renderer.setStyle(this.contentElementRef.nativeElement, 'webkitTransform', `${this._translateDir}(${viewport.padding}px)`);
521
+ }
522
+ }
523
+ if (this.headerElementRef) {
524
+ let scrollPosition = this.getScrollElement()[this._scrollType];
525
+ let containerOffset = this.getElementsOffset();
526
+ let offset = Math.max(scrollPosition - viewport.padding - containerOffset + this.headerElementRef.nativeElement.clientHeight, 0);
527
+ this.renderer.setStyle(this.headerElementRef.nativeElement, 'transform', `${this._translateDir}(${offset}px)`);
528
+ this.renderer.setStyle(this.headerElementRef.nativeElement, 'webkitTransform', `${this._translateDir}(${offset}px)`);
529
+ }
530
+ const changeEventArg = (startChanged || endChanged) ? {
531
+ startIndex: viewport.startIndex,
532
+ endIndex: viewport.endIndex,
533
+ scrollStartPosition: viewport.scrollStartPosition,
534
+ scrollEndPosition: viewport.scrollEndPosition,
535
+ startIndexWithBuffer: viewport.startIndexWithBuffer,
536
+ endIndexWithBuffer: viewport.endIndexWithBuffer,
537
+ maxScrollPosition: viewport.maxScrollPosition
538
+ } : undefined;
539
+ if (startChanged || endChanged || scrollPositionChanged) {
540
+ const handleChanged = () => {
541
+ // update the scroll list to trigger re-render of components in viewport
542
+ this.viewPortItems = viewport.startIndexWithBuffer >= 0 && viewport.endIndexWithBuffer >= 0 ? this.items.slice(viewport.startIndexWithBuffer, viewport.endIndexWithBuffer + 1) : [];
543
+ this.vsUpdate.emit(this.viewPortItems);
544
+ if (startChanged) {
545
+ this.vsStart.emit(changeEventArg);
546
+ }
547
+ if (endChanged) {
548
+ this.vsEnd.emit(changeEventArg);
549
+ }
550
+ if (startChanged || endChanged) {
551
+ this.changeDetectorRef.markForCheck();
552
+ this.vsChange.emit(changeEventArg);
553
+ }
554
+ if (maxRunTimes > 0) {
555
+ this.refresh_internal(false, refreshCompletedCallback, maxRunTimes - 1);
556
+ return;
557
+ }
558
+ if (refreshCompletedCallback) {
559
+ refreshCompletedCallback();
560
+ }
561
+ };
562
+ if (this.executeRefreshOutsideAngularZone) {
563
+ handleChanged();
564
+ }
565
+ else {
566
+ this.zone.run(handleChanged);
567
+ }
568
+ }
569
+ else {
570
+ if (maxRunTimes > 0 && (scrollLengthChanged || paddingChanged)) {
571
+ this.refresh_internal(false, refreshCompletedCallback, maxRunTimes - 1);
572
+ return;
573
+ }
574
+ if (refreshCompletedCallback) {
575
+ refreshCompletedCallback();
576
+ }
577
+ }
578
+ });
579
+ });
580
+ }
581
+ getScrollElement() {
582
+ return this.parentScroll instanceof Window ? document.scrollingElement || document.documentElement || document.body : this.parentScroll || this.element.nativeElement;
583
+ }
584
+ addScrollEventHandlers() {
585
+ if (this.isAngularUniversalSSR) {
586
+ return;
587
+ }
588
+ let scrollElement = this.getScrollElement();
589
+ this.removeScrollEventHandlers();
590
+ this.zone.runOutsideAngular(() => {
591
+ if (this.parentScroll instanceof Window) {
592
+ this.disposeScrollHandler = this.renderer.listen('window', 'scroll', this.onScroll);
593
+ this.disposeResizeHandler = this.renderer.listen('window', 'resize', this.onScroll);
594
+ }
595
+ else {
596
+ this.disposeScrollHandler = this.renderer.listen(scrollElement, 'scroll', this.onScroll);
597
+ if (this._checkResizeInterval > 0) {
598
+ this.checkScrollElementResizedTimer = setInterval(() => { this.checkScrollElementResized(); }, this._checkResizeInterval);
599
+ }
600
+ }
601
+ });
602
+ }
603
+ removeScrollEventHandlers() {
604
+ if (this.checkScrollElementResizedTimer) {
605
+ clearInterval(this.checkScrollElementResizedTimer);
606
+ }
607
+ if (this.disposeScrollHandler) {
608
+ this.disposeScrollHandler();
609
+ this.disposeScrollHandler = undefined;
610
+ }
611
+ if (this.disposeResizeHandler) {
612
+ this.disposeResizeHandler();
613
+ this.disposeResizeHandler = undefined;
614
+ }
615
+ }
616
+ getElementsOffset() {
617
+ if (this.isAngularUniversalSSR) {
618
+ return 0;
619
+ }
620
+ let offset = 0;
621
+ if (this.containerElementRef && this.containerElementRef.nativeElement) {
622
+ offset += this.containerElementRef.nativeElement[this._offsetType];
623
+ }
624
+ if (this.parentScroll) {
625
+ let scrollElement = this.getScrollElement();
626
+ let elementClientRect = this.getElementSize(this.element.nativeElement);
627
+ let scrollClientRect = this.getElementSize(scrollElement);
628
+ if (this.horizontal) {
629
+ offset += elementClientRect.left - scrollClientRect.left;
630
+ }
631
+ else {
632
+ offset += elementClientRect.top - scrollClientRect.top;
633
+ }
634
+ if (!(this.parentScroll instanceof Window)) {
635
+ offset += scrollElement[this._scrollType];
636
+ }
637
+ }
638
+ return offset;
639
+ }
640
+ countItemsPerWrapGroup() {
641
+ if (this.isAngularUniversalSSR) {
642
+ return Math.round(this.horizontal ? this.ssrViewportHeight / this.ssrChildHeight : this.ssrViewportWidth / this.ssrChildWidth);
643
+ }
644
+ let propertyName = this.horizontal ? 'offsetLeft' : 'offsetTop';
645
+ let children = ((this.containerElementRef && this.containerElementRef.nativeElement) || this.contentElementRef.nativeElement).children;
646
+ let childrenLength = children ? children.length : 0;
647
+ if (childrenLength === 0) {
648
+ return 1;
649
+ }
650
+ let firstOffset = children[0][propertyName];
651
+ let result = 1;
652
+ while (result < childrenLength && firstOffset === children[result][propertyName]) {
653
+ ++result;
654
+ }
655
+ return result;
656
+ }
657
+ getScrollStartPosition() {
658
+ let windowScrollValue = undefined;
659
+ if (this.parentScroll instanceof Window) {
660
+ windowScrollValue = window[this._pageOffsetType];
661
+ }
662
+ return windowScrollValue || this.getScrollElement()[this._scrollType] || 0;
663
+ }
664
+ minMeasuredChildWidth;
665
+ minMeasuredChildHeight;
666
+ wrapGroupDimensions;
667
+ resetWrapGroupDimensions() {
668
+ const oldWrapGroupDimensions = this.wrapGroupDimensions;
669
+ this.invalidateAllCachedMeasurements();
670
+ if (!this.enableUnequalChildrenSizes || !oldWrapGroupDimensions || oldWrapGroupDimensions.numberOfKnownWrapGroupChildSizes === 0) {
671
+ return;
672
+ }
673
+ const itemsPerWrapGroup = this.countItemsPerWrapGroup();
674
+ for (let wrapGroupIndex = 0; wrapGroupIndex < oldWrapGroupDimensions.maxChildSizePerWrapGroup.length; ++wrapGroupIndex) {
675
+ const oldWrapGroupDimension = oldWrapGroupDimensions.maxChildSizePerWrapGroup[wrapGroupIndex];
676
+ if (!oldWrapGroupDimension || !oldWrapGroupDimension.items || !oldWrapGroupDimension.items.length) {
677
+ continue;
678
+ }
679
+ if (oldWrapGroupDimension.items.length !== itemsPerWrapGroup) {
680
+ return;
681
+ }
682
+ let itemsChanged = false;
683
+ let arrayStartIndex = itemsPerWrapGroup * wrapGroupIndex;
684
+ for (let i = 0; i < itemsPerWrapGroup; ++i) {
685
+ if (!this.compareItems(oldWrapGroupDimension.items[i], this.items[arrayStartIndex + i])) {
686
+ itemsChanged = true;
687
+ break;
688
+ }
689
+ }
690
+ if (!itemsChanged) {
691
+ ++this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
692
+ this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths += oldWrapGroupDimension.childWidth || 0;
693
+ this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights += oldWrapGroupDimension.childHeight || 0;
694
+ this.wrapGroupDimensions.maxChildSizePerWrapGroup[wrapGroupIndex] = oldWrapGroupDimension;
695
+ }
696
+ }
697
+ }
698
+ calculateDimensions() {
699
+ let scrollElement = this.getScrollElement();
700
+ const maxCalculatedScrollBarSize = 25; // Note: Formula to auto-calculate doesn't work for ParentScroll, so we default to this if not set by consuming application
701
+ this.calculatedScrollbarHeight = Math.max(Math.min(scrollElement.offsetHeight - scrollElement.clientHeight, maxCalculatedScrollBarSize), this.calculatedScrollbarHeight);
702
+ this.calculatedScrollbarWidth = Math.max(Math.min(scrollElement.offsetWidth - scrollElement.clientWidth, maxCalculatedScrollBarSize), this.calculatedScrollbarWidth);
703
+ let viewportWidth = scrollElement.offsetWidth - (this.scrollbarWidth || this.calculatedScrollbarWidth || (this.horizontal ? 0 : maxCalculatedScrollBarSize));
704
+ let viewportHeight = scrollElement.offsetHeight - (this.scrollbarHeight || this.calculatedScrollbarHeight || (this.horizontal ? maxCalculatedScrollBarSize : 0));
705
+ let content = (this.containerElementRef && this.containerElementRef.nativeElement) || this.contentElementRef.nativeElement;
706
+ let itemsPerWrapGroup = this.countItemsPerWrapGroup();
707
+ let wrapGroupsPerPage;
708
+ let defaultChildWidth;
709
+ let defaultChildHeight;
710
+ if (this.isAngularUniversalSSR) {
711
+ viewportWidth = this.ssrViewportWidth;
712
+ viewportHeight = this.ssrViewportHeight;
713
+ defaultChildWidth = this.ssrChildWidth;
714
+ defaultChildHeight = this.ssrChildHeight;
715
+ let itemsPerRow = Math.max(Math.ceil(viewportWidth / defaultChildWidth), 1);
716
+ let itemsPerCol = Math.max(Math.ceil(viewportHeight / defaultChildHeight), 1);
717
+ wrapGroupsPerPage = this.horizontal ? itemsPerRow : itemsPerCol;
718
+ }
719
+ else if (!this.enableUnequalChildrenSizes) {
720
+ if (content.children.length > 0) {
721
+ if (!this.childWidth || !this.childHeight) {
722
+ if (!this.minMeasuredChildWidth && viewportWidth > 0) {
723
+ this.minMeasuredChildWidth = viewportWidth;
724
+ }
725
+ if (!this.minMeasuredChildHeight && viewportHeight > 0) {
726
+ this.minMeasuredChildHeight = viewportHeight;
727
+ }
728
+ }
729
+ let child = content.children[0];
730
+ let clientRect = this.getElementSize(child);
731
+ this.minMeasuredChildWidth = Math.min(this.minMeasuredChildWidth, clientRect.width);
732
+ this.minMeasuredChildHeight = Math.min(this.minMeasuredChildHeight, clientRect.height);
733
+ }
734
+ defaultChildWidth = this.childWidth || this.minMeasuredChildWidth || viewportWidth;
735
+ defaultChildHeight = this.childHeight || this.minMeasuredChildHeight || viewportHeight;
736
+ let itemsPerRow = Math.max(Math.ceil(viewportWidth / defaultChildWidth), 1);
737
+ let itemsPerCol = Math.max(Math.ceil(viewportHeight / defaultChildHeight), 1);
738
+ wrapGroupsPerPage = this.horizontal ? itemsPerRow : itemsPerCol;
739
+ }
740
+ else {
741
+ let scrollOffset = scrollElement[this._scrollType] - (this.previousViewPort ? this.previousViewPort.padding : 0);
742
+ let arrayStartIndex = this.previousViewPort.startIndexWithBuffer || 0;
743
+ let wrapGroupIndex = Math.ceil(arrayStartIndex / itemsPerWrapGroup);
744
+ let maxWidthForWrapGroup = 0;
745
+ let maxHeightForWrapGroup = 0;
746
+ let sumOfVisibleMaxWidths = 0;
747
+ let sumOfVisibleMaxHeights = 0;
748
+ wrapGroupsPerPage = 0;
749
+ for (let i = 0; i < content.children.length; ++i) {
750
+ ++arrayStartIndex;
751
+ let child = content.children[i];
752
+ let clientRect = this.getElementSize(child);
753
+ maxWidthForWrapGroup = Math.max(maxWidthForWrapGroup, clientRect.width);
754
+ maxHeightForWrapGroup = Math.max(maxHeightForWrapGroup, clientRect.height);
755
+ if (arrayStartIndex % itemsPerWrapGroup === 0) {
756
+ let oldValue = this.wrapGroupDimensions.maxChildSizePerWrapGroup[wrapGroupIndex];
757
+ if (oldValue) {
758
+ --this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
759
+ this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths -= oldValue.childWidth || 0;
760
+ this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights -= oldValue.childHeight || 0;
761
+ }
762
+ ++this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
763
+ const items = this.items.slice(arrayStartIndex - itemsPerWrapGroup, arrayStartIndex);
764
+ this.wrapGroupDimensions.maxChildSizePerWrapGroup[wrapGroupIndex] = {
765
+ childWidth: maxWidthForWrapGroup,
766
+ childHeight: maxHeightForWrapGroup,
767
+ items: items
768
+ };
769
+ this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths += maxWidthForWrapGroup;
770
+ this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights += maxHeightForWrapGroup;
771
+ if (this.horizontal) {
772
+ let maxVisibleWidthForWrapGroup = Math.min(maxWidthForWrapGroup, Math.max(viewportWidth - sumOfVisibleMaxWidths, 0));
773
+ if (scrollOffset > 0) {
774
+ let scrollOffsetToRemove = Math.min(scrollOffset, maxVisibleWidthForWrapGroup);
775
+ maxVisibleWidthForWrapGroup -= scrollOffsetToRemove;
776
+ scrollOffset -= scrollOffsetToRemove;
777
+ }
778
+ sumOfVisibleMaxWidths += maxVisibleWidthForWrapGroup;
779
+ if (maxVisibleWidthForWrapGroup > 0 && viewportWidth >= sumOfVisibleMaxWidths) {
780
+ ++wrapGroupsPerPage;
781
+ }
782
+ }
783
+ else {
784
+ let maxVisibleHeightForWrapGroup = Math.min(maxHeightForWrapGroup, Math.max(viewportHeight - sumOfVisibleMaxHeights, 0));
785
+ if (scrollOffset > 0) {
786
+ let scrollOffsetToRemove = Math.min(scrollOffset, maxVisibleHeightForWrapGroup);
787
+ maxVisibleHeightForWrapGroup -= scrollOffsetToRemove;
788
+ scrollOffset -= scrollOffsetToRemove;
789
+ }
790
+ sumOfVisibleMaxHeights += maxVisibleHeightForWrapGroup;
791
+ if (maxVisibleHeightForWrapGroup > 0 && viewportHeight >= sumOfVisibleMaxHeights) {
792
+ ++wrapGroupsPerPage;
793
+ }
794
+ }
795
+ ++wrapGroupIndex;
796
+ maxWidthForWrapGroup = 0;
797
+ maxHeightForWrapGroup = 0;
798
+ }
799
+ }
800
+ let averageChildWidth = this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths / this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
801
+ let averageChildHeight = this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights / this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
802
+ defaultChildWidth = this.childWidth || averageChildWidth || viewportWidth;
803
+ defaultChildHeight = this.childHeight || averageChildHeight || viewportHeight;
804
+ if (this.horizontal) {
805
+ if (viewportWidth > sumOfVisibleMaxWidths) {
806
+ wrapGroupsPerPage += Math.ceil((viewportWidth - sumOfVisibleMaxWidths) / defaultChildWidth);
807
+ }
808
+ }
809
+ else {
810
+ if (viewportHeight > sumOfVisibleMaxHeights) {
811
+ wrapGroupsPerPage += Math.ceil((viewportHeight - sumOfVisibleMaxHeights) / defaultChildHeight);
812
+ }
813
+ }
814
+ }
815
+ let itemCount = this.items.length;
816
+ let itemsPerPage = itemsPerWrapGroup * wrapGroupsPerPage;
817
+ let pageCount_fractional = itemCount / itemsPerPage;
818
+ let numberOfWrapGroups = Math.ceil(itemCount / itemsPerWrapGroup);
819
+ let scrollLength = 0;
820
+ let defaultScrollLengthPerWrapGroup = this.horizontal ? defaultChildWidth : defaultChildHeight;
821
+ if (this.enableUnequalChildrenSizes) {
822
+ let numUnknownChildSizes = 0;
823
+ for (let i = 0; i < numberOfWrapGroups; ++i) {
824
+ let childSize = this.wrapGroupDimensions.maxChildSizePerWrapGroup[i] && this.wrapGroupDimensions.maxChildSizePerWrapGroup[i][this._childScrollDim];
825
+ if (childSize) {
826
+ scrollLength += childSize;
827
+ }
828
+ else {
829
+ ++numUnknownChildSizes;
830
+ }
831
+ }
832
+ scrollLength += Math.round(numUnknownChildSizes * defaultScrollLengthPerWrapGroup);
833
+ }
834
+ else {
835
+ scrollLength = numberOfWrapGroups * defaultScrollLengthPerWrapGroup;
836
+ }
837
+ if (this.headerElementRef) {
838
+ scrollLength += this.headerElementRef.nativeElement.clientHeight;
839
+ }
840
+ let viewportLength = this.horizontal ? viewportWidth : viewportHeight;
841
+ let maxScrollPosition = Math.max(scrollLength - viewportLength, 0);
842
+ return {
843
+ childHeight: defaultChildHeight,
844
+ childWidth: defaultChildWidth,
845
+ itemCount: itemCount,
846
+ itemsPerPage: itemsPerPage,
847
+ itemsPerWrapGroup: itemsPerWrapGroup,
848
+ maxScrollPosition: maxScrollPosition,
849
+ pageCount_fractional: pageCount_fractional,
850
+ scrollLength: scrollLength,
851
+ viewportLength: viewportLength,
852
+ wrapGroupsPerPage: wrapGroupsPerPage,
853
+ };
854
+ }
855
+ cachedPageSize = 0;
856
+ previousScrollNumberElements = 0;
857
+ calculatePadding(arrayStartIndexWithBuffer, dimensions) {
858
+ if (dimensions.itemCount === 0) {
859
+ return 0;
860
+ }
861
+ let defaultScrollLengthPerWrapGroup = dimensions[this._childScrollDim];
862
+ let startingWrapGroupIndex = Math.floor(arrayStartIndexWithBuffer / dimensions.itemsPerWrapGroup) || 0;
863
+ if (!this.enableUnequalChildrenSizes) {
864
+ return defaultScrollLengthPerWrapGroup * startingWrapGroupIndex;
865
+ }
866
+ let numUnknownChildSizes = 0;
867
+ let result = 0;
868
+ for (let i = 0; i < startingWrapGroupIndex; ++i) {
869
+ let childSize = this.wrapGroupDimensions.maxChildSizePerWrapGroup[i] && this.wrapGroupDimensions.maxChildSizePerWrapGroup[i][this._childScrollDim];
870
+ if (childSize) {
871
+ result += childSize;
872
+ }
873
+ else {
874
+ ++numUnknownChildSizes;
875
+ }
876
+ }
877
+ result += Math.round(numUnknownChildSizes * defaultScrollLengthPerWrapGroup);
878
+ return result;
879
+ }
880
+ calculatePageInfo(scrollPosition, dimensions) {
881
+ let scrollPercentage = 0;
882
+ if (this.enableUnequalChildrenSizes) {
883
+ const numberOfWrapGroups = Math.ceil(dimensions.itemCount / dimensions.itemsPerWrapGroup);
884
+ let totalScrolledLength = 0;
885
+ let defaultScrollLengthPerWrapGroup = dimensions[this._childScrollDim];
886
+ for (let i = 0; i < numberOfWrapGroups; ++i) {
887
+ let childSize = this.wrapGroupDimensions.maxChildSizePerWrapGroup[i] && this.wrapGroupDimensions.maxChildSizePerWrapGroup[i][this._childScrollDim];
888
+ if (childSize) {
889
+ totalScrolledLength += childSize;
890
+ }
891
+ else {
892
+ totalScrolledLength += defaultScrollLengthPerWrapGroup;
893
+ }
894
+ if (scrollPosition < totalScrolledLength) {
895
+ scrollPercentage = i / numberOfWrapGroups;
896
+ break;
897
+ }
898
+ }
899
+ }
900
+ else {
901
+ scrollPercentage = scrollPosition / dimensions.scrollLength;
902
+ }
903
+ let startingArrayIndex_fractional = Math.min(Math.max(scrollPercentage * dimensions.pageCount_fractional, 0), dimensions.pageCount_fractional) * dimensions.itemsPerPage;
904
+ let maxStart = dimensions.itemCount - dimensions.itemsPerPage - 1;
905
+ let arrayStartIndex = Math.min(Math.floor(startingArrayIndex_fractional), maxStart);
906
+ arrayStartIndex -= arrayStartIndex % dimensions.itemsPerWrapGroup; // round down to start of wrapGroup
907
+ if (this.stripedTable) {
908
+ let bufferBoundary = 2 * dimensions.itemsPerWrapGroup;
909
+ if (arrayStartIndex % bufferBoundary !== 0) {
910
+ arrayStartIndex = Math.max(arrayStartIndex - arrayStartIndex % bufferBoundary, 0);
911
+ }
912
+ }
913
+ let arrayEndIndex = Math.ceil(startingArrayIndex_fractional) + dimensions.itemsPerPage - 1;
914
+ let endIndexWithinWrapGroup = (arrayEndIndex + 1) % dimensions.itemsPerWrapGroup;
915
+ if (endIndexWithinWrapGroup > 0) {
916
+ arrayEndIndex += dimensions.itemsPerWrapGroup - endIndexWithinWrapGroup; // round up to end of wrapGroup
917
+ }
918
+ if (isNaN(arrayStartIndex)) {
919
+ arrayStartIndex = 0;
920
+ }
921
+ if (isNaN(arrayEndIndex)) {
922
+ arrayEndIndex = 0;
923
+ }
924
+ arrayStartIndex = Math.min(Math.max(arrayStartIndex, 0), dimensions.itemCount - 1);
925
+ arrayEndIndex = Math.min(Math.max(arrayEndIndex, 0), dimensions.itemCount - 1);
926
+ let bufferSize = this.bufferAmount * dimensions.itemsPerWrapGroup;
927
+ let startIndexWithBuffer = Math.min(Math.max(arrayStartIndex - bufferSize, 0), dimensions.itemCount - 1);
928
+ let endIndexWithBuffer = Math.min(Math.max(arrayEndIndex + bufferSize, 0), dimensions.itemCount - 1);
929
+ return {
930
+ startIndex: arrayStartIndex,
931
+ endIndex: arrayEndIndex,
932
+ startIndexWithBuffer: startIndexWithBuffer,
933
+ endIndexWithBuffer: endIndexWithBuffer,
934
+ scrollStartPosition: scrollPosition,
935
+ scrollEndPosition: scrollPosition + dimensions.viewportLength,
936
+ maxScrollPosition: dimensions.maxScrollPosition
937
+ };
938
+ }
939
+ calculateViewport() {
940
+ let dimensions = this.calculateDimensions();
941
+ let offset = this.getElementsOffset();
942
+ let scrollStartPosition = this.getScrollStartPosition();
943
+ if (scrollStartPosition > (dimensions.scrollLength + offset) && !(this.parentScroll instanceof Window)) {
944
+ scrollStartPosition = dimensions.scrollLength;
945
+ }
946
+ else {
947
+ scrollStartPosition -= offset;
948
+ }
949
+ scrollStartPosition = Math.max(0, scrollStartPosition);
950
+ let pageInfo = this.calculatePageInfo(scrollStartPosition, dimensions);
951
+ let newPadding = this.calculatePadding(pageInfo.startIndexWithBuffer, dimensions);
952
+ let newScrollLength = dimensions.scrollLength;
953
+ return {
954
+ startIndex: pageInfo.startIndex,
955
+ endIndex: pageInfo.endIndex,
956
+ startIndexWithBuffer: pageInfo.startIndexWithBuffer,
957
+ endIndexWithBuffer: pageInfo.endIndexWithBuffer,
958
+ padding: Math.round(newPadding),
959
+ scrollLength: Math.round(newScrollLength),
960
+ scrollStartPosition: pageInfo.scrollStartPosition,
961
+ scrollEndPosition: pageInfo.scrollEndPosition,
962
+ maxScrollPosition: pageInfo.maxScrollPosition
963
+ };
964
+ }
965
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: VirtualScrollerComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: PLATFORM_ID }, { token: 'virtual-scroller-default-options', optional: true }], target: i0.ɵɵFactoryTarget.Component });
966
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.4", type: VirtualScrollerComponent, isStandalone: true, selector: "virtual-scroller,[virtualScroller]", inputs: { executeRefreshOutsideAngularZone: "executeRefreshOutsideAngularZone", enableUnequalChildrenSizes: "enableUnequalChildrenSizes", RTL: "RTL", useMarginInsteadOfTranslate: "useMarginInsteadOfTranslate", modifyOverflowStyleOfParentScroll: "modifyOverflowStyleOfParentScroll", stripedTable: "stripedTable", scrollbarWidth: "scrollbarWidth", scrollbarHeight: "scrollbarHeight", childWidth: "childWidth", childHeight: "childHeight", ssrChildWidth: "ssrChildWidth", ssrChildHeight: "ssrChildHeight", ssrViewportWidth: "ssrViewportWidth", ssrViewportHeight: "ssrViewportHeight", bufferAmount: "bufferAmount", scrollAnimationTime: "scrollAnimationTime", resizeBypassRefreshThreshold: "resizeBypassRefreshThreshold", scrollThrottlingTime: "scrollThrottlingTime", scrollDebounceTime: "scrollDebounceTime", checkResizeInterval: "checkResizeInterval", items: "items", compareItems: "compareItems", horizontal: "horizontal", parentScroll: "parentScroll" }, outputs: { vsUpdate: "vsUpdate", vsChange: "vsChange", vsStart: "vsStart", vsEnd: "vsEnd" }, host: { properties: { "class.horizontal": "horizontal", "class.vertical": "!horizontal", "class.selfScroll": "!parentScroll", "class.rtl": "RTL" } }, queries: [{ propertyName: "headerElementRef", first: true, predicate: ["header"], descendants: true, read: ElementRef }, { propertyName: "containerElementRef", first: true, predicate: ["container"], descendants: true, read: ElementRef }], viewQueries: [{ propertyName: "contentElementRef", first: true, predicate: ["content"], descendants: true, read: ElementRef, static: true }, { propertyName: "invisiblePaddingElementRef", first: true, predicate: ["invisiblePadding"], descendants: true, read: ElementRef, static: true }], exportAs: ["virtualScroller"], usesOnChanges: true, ngImport: i0, template: `
967
+ <div class="total-padding" #invisiblePadding></div>
968
+ <div class="scrollable-content" #content>
969
+ <ng-content></ng-content>
970
+ </div>
971
+ `, isInline: true, styles: [":host{position:relative;display:block;-webkit-overflow-scrolling:touch}:host.horizontal.selfScroll{overflow-y:visible;overflow-x:auto}:host.horizontal.selfScroll.rtl{transform:scaleX(-1)}:host.vertical.selfScroll{overflow-y:auto;overflow-x:visible}.scrollable-content{top:0;left:0;width:100%;height:100%;max-width:100vw;max-height:100vh;position:absolute}.scrollable-content ::ng-deep>*{box-sizing:border-box}:host.horizontal{white-space:nowrap}:host.horizontal .scrollable-content{display:flex}:host.horizontal .scrollable-content ::ng-deep>*{flex-shrink:0;flex-grow:0;white-space:initial}:host.horizontal.rtl .scrollable-content ::ng-deep>*{transform:scaleX(-1)}.total-padding{position:absolute;top:0;left:0;height:1px;width:1px;transform-origin:0 0;opacity:0}:host.horizontal .total-padding{height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
972
+ }
973
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: VirtualScrollerComponent, decorators: [{
974
+ type: Component,
975
+ args: [{ selector: 'virtual-scroller,[virtualScroller]', standalone: true, imports: [CommonModule], exportAs: 'virtualScroller', template: `
976
+ <div class="total-padding" #invisiblePadding></div>
977
+ <div class="scrollable-content" #content>
978
+ <ng-content></ng-content>
979
+ </div>
980
+ `, host: {
981
+ '[class.horizontal]': 'horizontal',
982
+ '[class.vertical]': '!horizontal',
983
+ '[class.selfScroll]': '!parentScroll',
984
+ '[class.rtl]': 'RTL'
985
+ }, styles: [":host{position:relative;display:block;-webkit-overflow-scrolling:touch}:host.horizontal.selfScroll{overflow-y:visible;overflow-x:auto}:host.horizontal.selfScroll.rtl{transform:scaleX(-1)}:host.vertical.selfScroll{overflow-y:auto;overflow-x:visible}.scrollable-content{top:0;left:0;width:100%;height:100%;max-width:100vw;max-height:100vh;position:absolute}.scrollable-content ::ng-deep>*{box-sizing:border-box}:host.horizontal{white-space:nowrap}:host.horizontal .scrollable-content{display:flex}:host.horizontal .scrollable-content ::ng-deep>*{flex-shrink:0;flex-grow:0;white-space:initial}:host.horizontal.rtl .scrollable-content ::ng-deep>*{transform:scaleX(-1)}.total-padding{position:absolute;top:0;left:0;height:1px;width:1px;transform-origin:0 0;opacity:0}:host.horizontal .total-padding{height:100%}\n"] }]
986
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: Object, decorators: [{
987
+ type: Inject,
988
+ args: [PLATFORM_ID]
989
+ }] }, { type: undefined, decorators: [{
990
+ type: Optional
991
+ }, {
992
+ type: Inject,
993
+ args: ['virtual-scroller-default-options']
994
+ }] }], propDecorators: { executeRefreshOutsideAngularZone: [{
995
+ type: Input
996
+ }], enableUnequalChildrenSizes: [{
997
+ type: Input
998
+ }], RTL: [{
999
+ type: Input
1000
+ }], useMarginInsteadOfTranslate: [{
1001
+ type: Input
1002
+ }], modifyOverflowStyleOfParentScroll: [{
1003
+ type: Input
1004
+ }], stripedTable: [{
1005
+ type: Input
1006
+ }], scrollbarWidth: [{
1007
+ type: Input
1008
+ }], scrollbarHeight: [{
1009
+ type: Input
1010
+ }], childWidth: [{
1011
+ type: Input
1012
+ }], childHeight: [{
1013
+ type: Input
1014
+ }], ssrChildWidth: [{
1015
+ type: Input
1016
+ }], ssrChildHeight: [{
1017
+ type: Input
1018
+ }], ssrViewportWidth: [{
1019
+ type: Input
1020
+ }], ssrViewportHeight: [{
1021
+ type: Input
1022
+ }], bufferAmount: [{
1023
+ type: Input
1024
+ }], scrollAnimationTime: [{
1025
+ type: Input
1026
+ }], resizeBypassRefreshThreshold: [{
1027
+ type: Input
1028
+ }], scrollThrottlingTime: [{
1029
+ type: Input
1030
+ }], scrollDebounceTime: [{
1031
+ type: Input
1032
+ }], checkResizeInterval: [{
1033
+ type: Input
1034
+ }], items: [{
1035
+ type: Input
1036
+ }], compareItems: [{
1037
+ type: Input
1038
+ }], horizontal: [{
1039
+ type: Input
1040
+ }], parentScroll: [{
1041
+ type: Input
1042
+ }], vsUpdate: [{
1043
+ type: Output
1044
+ }], vsChange: [{
1045
+ type: Output
1046
+ }], vsStart: [{
1047
+ type: Output
1048
+ }], vsEnd: [{
1049
+ type: Output
1050
+ }], contentElementRef: [{
1051
+ type: ViewChild,
1052
+ args: ['content', { read: ElementRef, static: true }]
1053
+ }], invisiblePaddingElementRef: [{
1054
+ type: ViewChild,
1055
+ args: ['invisiblePadding', { read: ElementRef, static: true }]
1056
+ }], headerElementRef: [{
1057
+ type: ContentChild,
1058
+ args: ['header', { read: ElementRef, static: false }]
1059
+ }], containerElementRef: [{
1060
+ type: ContentChild,
1061
+ args: ['container', { read: ElementRef, static: false }]
1062
+ }] } });
1063
+ class VirtualScrollerModule {
1064
+ }
1065
+
1066
+ /**
1067
+ * Generated bundle index. Do not edit.
1068
+ */
1069
+
1070
+ export { VIRTUAL_SCROLLER_DEFAULT_OPTIONS_FACTORY, VirtualScrollerComponent, VirtualScrollerModule };
1071
+ //# sourceMappingURL=ahmedfharag-ngx-virtual-scroller.mjs.map